var CronJob = require('cron').CronJob,

    logger = require('./logger'),
    TargetNodes = require('./targets/nodes').TargetNodes,

    job,
    state,

    STATE = {
        IDLE: 0,
        ACTIVE: 1
    };

function setIdle() {
    state = STATE.IDLE;
}

function setActive() {
    state = STATE.ACTIVE;
}

function isActive() {
    return state === STATE.ACTIVE;
}

function execute () {
    logger.info('=== CRON CHECK FOR DATA START ===', module);

    if (isActive()) {
        logger.warn('Previous synchronization process was not completed yet', module);
        return;
    }

    setActive();
    return (new TargetNodes({})).execute()
        .then(function () {
            setIdle();
            logger.info('=== CRON CHECK FOR DATA END ===', module);
        })
        .fail(function () {
            setIdle();
            logger.error('=== CRON CHECK FOR DATA ERROR ===', module);
        });
}

module.exports = {
    /**
     * Initialize cron job for commit and push tasks perform
     */
    init: function () {
        state = STATE.IDLE;
        job = new CronJob({
            cronTime: '0 */1 * * * *',
            onTick: execute,
            start: true
        });
    }
};

var CronJob = require('cron').CronJob,

    logger = require('./logger'),
    TargetNodes = require('./targets/nodes').TargetNodes,

    job,
    state,
    target = new TargetNodes({}),

    STATE = {
        IDLE: 0,
        ACTIVE: 1
    };

function setIdle() {
    state = STATE.IDLE;
}

function setActive() {
    state = STATE.ACTIVE;
}

function isActive() {
    return state === STATE.ACTIVE;
}

function execute () {
    logger.info('=== CRON CHECK FOR DATA START ===', module);

    if (isActive()) {
        logger.warn('Previous synchronization process was not completed yet', module);
        return;
    }

    setActive();
    return target.execute()
        .then(function () {
            setIdle();
            logger.info('=== CRON CHECK FOR DATA END ===', module);
        })
        .fail(function () {
            setIdle();
            logger.error('=== CRON CHECK FOR DATA ERROR ===', module);
        });
}

module.exports = {
    /**
     * Initialize cron job for commit and push tasks perform
     */
    init: function () {
        state = STATE.IDLE;
        job = new CronJob({
            cronTime: '0 */1 * * * *',
            onTick: execute,
            start: true
        });
    }
};

Remove creating multiple instances of target for execution


/* jshint node: true */

'use strict';

function getTaskConfig(projectConfig) {
	//Browser Sync options object
	//https://www.browsersync.io/docs/options

	var taskConfig = {
		//Server config options
		server: {
			baseDir: projectConfig.dirs.build,
			// directory: true, // directory listing
			// index: "index.htm", // specific index filename
		},
		ghostMode: false, // Mirror behaviour on all devices
		online: false, // Speed up startup time (When xip & tunnel aren't being used)
		// notify: false // Turn off UI notifications
		// browser: 'google chrome' //Set what browser to open on start - https://www.browsersync.io/docs/options#option-browser
		// open: false // Stop browser automatically opening
	};

	return taskConfig;
}

module.exports = getTaskConfig;

/* jshint node: true */

'use strict';

var path = require('path');

function getTaskConfig(projectConfig) {
	//Browser Sync options object
	//https://www.browsersync.io/docs/options

	var taskConfig = {
		//Server config options
		server: {
			baseDir: path.join(__dirname + '/..', projectConfig.paths.dest.static_html),
			// directory: true, // directory listing
			// index: "index.htm", // specific index filename
		},
		ghostMode: false, // Mirror behaviour on all devices
		online: false, // Speed up startup time (When xip & tunnel aren't being used)
		// notify: false // Turn off UI notifications
		// browser: 'google chrome' //Set what browser to open on start - https://www.browsersync.io/docs/options#option-browser
		// open: false // Stop browser automatically opening
	};

	return taskConfig;
}

module.exports = getTaskConfig;

Update config after real world testing :)


<<<<<<< HEAD
import ZeroClipboard from 'ember-cli-zero-clipboard/components/zero-clipboard';

export default ZeroClipboard.extend({
    layoutName: 'components/bs-button',
    tagName: 'button',
    classNameBindings: 'class',
    class: 'btn btn-default btn-xs',
    icon: 'fa fa-icon fa-clipboard',

    actions: {
        afterCopy: function() {
        }
    }
});
=======
import Ember from 'ember';

export default Ember.Component.extend({
    tagName: 'embed',
    text: '',
    src: 'assets/clippy.swf',
    width:"14",
    height: "14",
    scale: "noscale",
    name: "clippy",
    quality: "high",
    allowScriptAccess: "always",
    type: "application/x-shockwave-flash",
    pluginspage: "http://www.macromedia.com/go/getflashplayer",

    flashvars: function() {
        return 'text=' + this.get('text');
    }.property('text'),

    attributeBindings: ['src', 'width', 'height', 'name', 'quality', 'allowScriptAccess',
        'type', 'pluginspage', 'flashvars', 'scale'],
});
>>>>>>> Port App to Ember-Cli. Start Plugin System. Adds #133 and #136

Move from clippy.swf to ZeroClipboard


import {field, isFunction, isObject} from 'vega-util';

function isBuffer(_) {
  return (typeof Buffer === 'function' && isFunction(Buffer.isBuffer))
    ? Buffer.isBuffer(_) : false;
}

export default function(data, format) {
  data = isObject(data) && !isBuffer(data) ? data : JSON.parse(data);
  return (format && format.property)
    ? field(format.property)(data)
    : data;
}

import {field, identity, isFunction, isObject} from 'vega-util';

function isBuffer(_) {
  return (typeof Buffer === 'function' && isFunction(Buffer.isBuffer))
    ? Buffer.isBuffer(_) : false;
}

export default function(data, format) {
  var prop = (format && format.property) ? field(format.property) : identity;
  return isObject(data) && !isBuffer(data)
    ? parseJSON(prop(data))
    : prop(JSON.parse(data));
}

function parseJSON(data, format) {
  return (format && format.copy)
    ? JSON.parse(JSON.stringify(data))
    : data;
}

Add copy option for JSON input data.


import React from 'react'
import PropTypes from 'prop-types'

import { siteTitle } from '../../../App'
import Help from '../../../components/Help'
import Notice from '../../../components/Notice'

import { morphInfo } from '../'

const MorphHelp = props => (
  <Help toolInfo={morphInfo}>
    <Notice>This tool is still in development.</Notice>

      Using {siteTitle}
      {morphInfo.title}

Acknowledgments

      Much thanks should be given to Mark Rosenfelder and{' '}

        the Sound Change Applier 2 (SCA
        2)

      . {siteTitle}
      {morphInfo.title} was mainly built as a modernized and updated version of
      SCA
      2.

  </Help>
)

MorphHelp.propTypes = {
  classes: PropTypes.object
}

export default MorphHelp

import React from 'react'
import PropTypes from 'prop-types'

import { siteTitle } from '../../../App'
import Help from '../../../components/Help'
import Notice from '../../../components/Notice'

import { morphInfo } from '../'

const MorphHelp = props => (
  <Help toolInfo={morphInfo}>
    <Notice>This tool is still in development.</Notice>

      Using {siteTitle}
      {morphInfo.title}

Acknowledgments

      Much thanks should be given to Mark Rosenfelder and{' '}

        the Sound Change Applier 2
      {' '}
      (SCA
      2
      ). {siteTitle}
      {morphInfo.title} was mainly built as a modernized and updated version of
      SCA
      2.

  </Help>
)

MorphHelp.propTypes = {
  classes: PropTypes.object
}

export default MorphHelp

Move SCA2 outside of link in acknowledgment


import store from '../store';

export const getInstance = () => {
  return store.getState().pouchdb;
};

export const getDocument = async (dbName) => {
  const { instance } = getInstance();

  try {
    const result = await instance.get(dbName);

    return result;
  } catch (e) {
    throw e;
  }
};

export const updateDocument = async (ebudgie) => {
  const { instance } = getInstance();

  try {
    const result = await instance.put(ebudgie);

    return result;
  } catch (e) {
    throw e;
  }
};

import store from '../store';

export const getInstance = () => {
  return store.getState().pouchdb;
};

export const getDocument = async (docId) => {
  const { instance } = getInstance();

  try {
    const result = await instance.get(docId);

    return result;
  } catch (e) {
    throw e;
  }
};

export const updateDocument = async (ebudgie) => {
  const { instance } = getInstance();

  try {
    const result = await instance.put(ebudgie);

    return result;
  } catch (e) {
    throw e;
  }
};

Fix naming for getting document from pouchdb


if (typeof document !== "undefined") {
  (function() {
    minispade = {
      root: null,
      modules: {},
      loaded: {},

      require: function(name) {
        var loaded = minispade.loaded[name];
        var mod = minispade.modules[name];

        if (!loaded) {
          if (mod) {
            loaded = mod() || true;
            minispade.loaded[name] = loaded;
          } else {
            if (minispade.root && name.substr(0,minispade.root.length) !== minispade.root) {
              return minispade.require(minispade.root+name);
            } else {
              throw "The module '" + name + "' could not be found";
            }
          }
        }

        return loaded;
      },

      register: function(name, callback) {
        minispade.modules[name] = callback;
      }
    };

    setTimeout(function() {
      var modules = minispade.modules;

      for (var name in modules) {
        if (modules.hasOwnProperty(name)) {
          minispade.require(name);
        }
      }
    });
  })();
}

if (typeof document !== "undefined") {
  (function() {
    minispade = {
      root: null,
      modules: {},
      loaded: {},

      require: function(name) {
        var loaded = minispade.loaded[name];
        var mod = minispade.modules[name];

        if (!loaded) {
          if (mod) {
            if (typeof mod === "string") {
              eval(mod);
            } else {
              mod();
            }

            minispade.loaded[name] = true;
          } else {
            if (minispade.root && name.substr(0,minispade.root.length) !== minispade.root) {
              return minispade.require(minispade.root+name);
            } else {
              throw "The module '" + name + "' could not be found";
            }
          }
        }

        return loaded;
      },

      register: function(name, callback) {
        minispade.modules[name] = callback;
      }
    };

    setTimeout(function() {
      var modules = minispade.modules;

      for (var name in modules) {
        if (modules.hasOwnProperty(name)) {
          minispade.require(name);
        }
      }
    });
  })();
}

Support string transport for modules


'use strict';

var memoize          = require('memoizee/plain')
  , defineStringLine = require('../string-line');

module.exports = memoize(function (db) {
	return defineStringLine(db).extend('Filename', {
		pattern: { value: /^(?:[a-zA-Z]:\\)?[\u0009 -9;-\uffff]*$/ },
		min: { value: 1 }
	});
}, { normalizer: require('memoizee/normalizers/get-1')() });

'use strict';

var memoize          = require('memoizee/plain')
  , defineStringLine = require('../string-line');

module.exports = memoize(function (db) {
	return defineStringLine(db).extend('Filename', {
		pattern: { value: /^(?:[a-zA-Z]:\\)?[\u0009 -9;-\uffff]*$/ },
		min: { value: 1 },
		adapt: { value: function (name) {
			var prefix = '';
			if (name.slice(0, 2).test(/[a-zA-Z]:/)) {
				prefix = name.slice(0, 2);
				name = name.slice(2);
			}
			return prefix + String(name).replace(/[\0-\u0008\u0010-\u001f:]/g, '-');
		}, type: db.Function }
	});
}, { normalizer: require('memoizee/normalizers/get-1')() });

Introduce adapt function for Filename


import React from 'react'
import { storiesOf } from '@storybook/react'
import { Timestamp } from '../src/index.js'

const stories = storiesOf('Timestamp', module)

const customFormatter = timestamp => `Yes!: ${timestamp}`

stories.add('default', () => (
  <Timestamp timestamp='10:41am' />
))

stories.add('live', () => (
  <Timestamp timestamp='10:41am' live />
))

stories.add('formatter', () => (
  <Timestamp timestamp='10:41am' live formatter={customFormatter} />
))

import React from 'react'
import { storiesOf } from '@storybook/react'
import { Timestamp } from '../src/index.js'

const stories = storiesOf('Timestamp', module)

let count = 0
const customFormatter = timestamp => {
  const now = (new Date()).toISOString()

  return `${timestamp} (update ${count++} at ${now})`
}

stories.add('default', () => (
  <Timestamp timestamp='10:41am' />
))

stories.add('live', () => (
  <Timestamp timestamp={(new Date()).toISOString()} live />
))

stories.add('formatter', () => (
  <Timestamp timestamp={(new Date()).toISOString()} live formatter={customFormatter} />
))

Update story to show when the timestamp is updated


var markdown = require('markdown');

(function(dust) {
  dust.helpers.markdown = function(chunk, context, bodies, params) {
    if (bodies.block) {
      return chunk.capture(bodies.block, context, function(string, chunk) {
        chunk.end(markdown.parse(string));
      });
    }
    return chunk;
  };
}(typeof exports !== 'undefined' ? module.exports = require('dustjs-linkedin') : dust));

var markdown = require('markdown');

module.exports = function (dust) {
  dust.helpers.markdown = function(chunk, context, bodies, params) {
    if (bodies.block) {
      return chunk.capture(bodies.block, context, function(string, chunk) {
        chunk.end(markdown.parse(string));
      });
    }
    return chunk;
  };
};

module.exports.registerWith = module.exports;

Update to work with makara


const expect = require('chai').expect
const nunjucks = require('nunjucks')
const components = require('../../../lib/components')

const expectComponentRenders = (name, input) => {
  let componentPath = components.templatePathFor(name)
  expect(() => {
    nunjucks.render(componentPath, input)
  }).to.not.throw()
}

describe('Components render examples without errors', () => {
  Object.keys(components.all).map(name => {
    it(`${name} component renders all variants without errors`, () => {
      let component = components.get(name)
      let variants = [{context: component.context}].concat(component.variants)
      for (let variant of variants) {
        expectComponentRenders(name, variant.context)
      }
    })
  })
})

const expect = require('chai').expect
const nunjucks = require('nunjucks')
const components = require('../../../lib/components')

const expectComponentRenders = (name, input) => {
  let componentPath = components.templatePathFor(name)
  expect(() => {
    nunjucks.render(componentPath, input)
  }).to.not.throw()
}

describe('All components variants render without errrors', () => {
  Object.keys(components.all).map(name => {
    describe(`${name}`, () => {
      let component = components.get(name)
      let variants = [{name: 'defaut', context: component.context}].concat(component.variants)
      for (let variant of variants) {
        it(`${variant.name}`, () => {
          expectComponentRenders(name, variant.context)
        })
      }
    })
  })
})

Refactor component smoke test output more readable


;(function() {
    window.stubFileUpload = function(el) {
        return new FakeFileUpload(el);
    };

    function FakeFileUpload(fileInputElement) {
        var self = this;
        spyOn($.fn, 'fileupload').andCallFake(function(uploadOptions) {
            self.options = uploadOptions;
        });
    }

    _.extend(FakeFileUpload.prototype, {
        add: function(filenames) {
            var self = this;
            this.files = _.map(filenames, function(name) {
                return {
                    name: name,
                    size: 1234,
                    type: "text/plain"
                };
            });

            this.options.add(this.fakeEvent(), {
                files: self.files,
                submit: function() {
                    self.wasSubmitted = true;
                    return self.fakeRequest();
                }
            });
        },

        fakeEvent: function() {
            return { preventDefault: $.noop };
        },

        fakeRequest: function() {
            var self = this;
            return {
                abort: function() {
                    self.wasAborted = true;
                }
            };
        },

        succeed: function(bodyJson) {
            this.options.done({}, {
                result: JSON.stringify(bodyJson)
            });
        },

        fail: function(bodyJson) {
            this.options.fail(this.fakeEvent(), {
                jqXHR: {
                    responseText: JSON.stringify(bodyJson)
                }
            })
        }
    });
})();

Remove extraneous semicolon at beginning of js helper


( function() {
	var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1,
	    is_opera  = navigator.userAgent.toLowerCase().indexOf( 'opera' )  > -1,
	    is_ie     = navigator.userAgent.toLowerCase().indexOf( 'msie' )   > -1;

	if ( ( is_webkit || is_opera || is_ie ) && document.getElementById && window.addEventListener ) {
		window.addEventListener( 'hashchange', function() {
			var element = document.getElementById( location.hash.substring( 1 ) );

			if ( element ) {
				if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) )
					element.tabIndex = -1;

				element.focus();
			}
		}, false );
	}
})();

( function() {
	var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1,
	    is_opera  = navigator.userAgent.toLowerCase().indexOf( 'opera' )  > -1,
	    is_ie     = navigator.userAgent.toLowerCase().indexOf( 'msie' )   > -1;

	if ( ( is_webkit || is_opera || is_ie ) && document.getElementById && window.addEventListener ) {
		window.addEventListener( 'hashchange', function() {
			var element = document.getElementById( location.hash.substring( 1 ) );

			if ( element ) {
				if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) {
					element.tabIndex = -1;
				}

				element.focus();
			}
		}, false );
	}
})();

Add braces around if statement.


import { uniq, sort } from '@ember/object/computed';
import Controller from '@ember/controller';

export default Controller.extend({
  sortProperties: [
    'statusSort:asc',
    'organizationKindSort:asc',
    'nomen:asc',
  ],
  uniqueSessions: uniq(
    'model',
  ),
  sortedSessions: sort(
    'uniqueSessions',
    'sortProperties'
  ),
  actions: {
    sortBy(sortProperties) {
      this.set('sortProperties', [sortProperties]);
    },
  }
});

import { sort } from '@ember/object/computed';
import Controller from '@ember/controller';

export default Controller.extend({
  sortProperties: [
    'statusSort:asc',
    'organizationKindSort:asc',
    'nomen:asc',
  ],
  sortedSessions: sort(
    'model',
    'sortProperties'
  ),
  actions: {
    sortBy(sortProperties) {
      this.set('sortProperties', [sortProperties]);
    },
  }
});

Remove unique on Session controller


exports.listeners = {
	hit: function (l10n) {
		return function (room, attacker, defender, players, hitLocation, damageDealt) {
			checkForCrit(attacker, defender, damageDealt);
		}
	},
};

function checkForCrit(attacker, defender, damageDealt) {
	var defenderHealth    = defender.getAttribute('health');
	var defenderMaxHealth = defender.getAttribute('max_health');

	var massiveDamage = damageDealt > defenderMaxHealth * .5;
	var almostDead  = defenderHealth <= defenderMaxHealth * .2;
	var coupDeGrace = almostDead && damageDealt >= defenderHealth;

	if (massiveDamage || coupDeGrace) {
		attacker.say('<bold><cyan>You have dealt a critical blow!</cyan></bold>');
	}
}

'use strict';

exports.listeners = {
	hit: function (l10n) {
		return function (room, attacker, defender, players, hitLocation, damageDealt) {
			checkForCrit(attacker, defender, damageDealt);
		}
	},

	deathblow: function(l10n) {
		return function (room, attacker, defender, players, hitLocation) {

		}
	}
};

function checkForCrit(attacker, defender, damageDealt) {
	var defenderHealth    = defender.getAttribute('health');
	var defenderMaxHealth = defender.getAttribute('max_health');

	var massiveDamage = damageDealt > defenderMaxHealth * .5;
	var almostDead  = defenderHealth <= defenderMaxHealth * .2;
	var coupDeGrace = almostDead && damageDealt >= defenderHealth;

	if (massiveDamage || coupDeGrace) {
		attacker.say('<bold><cyan>You have dealt a critical blow!</cyan></bold>');
	}
}

Add an event emitter for deathblows with a wielded weapon.


/* eslint-env serviceworker */

self.addEventListener('push', (event) => {
  const icon = '/images/icon-256x256.png';
  event.waitUntil(fetch('/event').then((res) => {
    if (res.status !== 200) {
      console.log('Error fetching latest notification:', res.status);
      throw new Error();
    }

    return res.json().then((data) => {
      const title = data.title;
      const body = data.body;
      const tag = 'canaritus-notification-tag';

      return self.registration.showNotification(title, {
        body: body,
        icon: icon,
        tag: tag,
      });
    });
  }).catch((err) => {
    console.error('Unable to retrieve data', err);

    const title = 'An error occurred';
    const body = 'We were unable to get the information for this push message';
    const tag = 'notification-error';

    return self.registration.showNotification(title, {
      body: body,
      icon: icon,
      tag: tag,
    });
  }));
});

self.addEventListener('notificationclick', (event) => {
  console.log('On notification click: ', event.notification.tag);
  // Android doesn't close the notification when you click on it
  // See: http://crbug.com/463146
  event.notification.close();

  // This looks to see if the current is already open and
  // focuses if it is
  event.waitUntil(clients.matchAll({
    type: 'window',
  }).then((clientList) => {
    for (let i = 0; i < clientList.length; i++) {
      const client = clientList[i];
      if (client.url === '/' && 'focus' in client) {
        return client.focus();
      }
    }
    if (clients.openWindow) {
      return clients.openWindow('/');
    }
  }));
});

Add notification click handler for android


Template.elasticsearchHealth.onCreated(function () {
  // Get reference to template instance
  const templateInstance = this;

  // Create reactive variable for Elasticsearch health
  templateInstance.elasticsearchHealth = new ReactiveVar();

  templateInstance.autorun(function () {
    const host = Template.currentData().host;

    Meteor.call('getElasticsearchHealth', host, function (error, health) {
      if (error) {
        throw new Meteor.Error(error);
      } else {
        // update Elasticsearch health reactive variable
        templateInstance.elasticsearchHealth.set(health);
      }
    });
  });
});

Template.elasticsearchHealth.helpers({
  health () {
    // Get reference to template instance
    const templateInstance = Template.instance();

    return templateInstance.elasticsearchHealth.get();
  }
});

Template.elasticsearchHealth.onCreated(function () {
  // Get reference to template instance
  const templateInstance = this;

  // Create reactive variable for Elasticsearch health
  templateInstance.elasticsearchHealth = new ReactiveVar();

  templateInstance.autorun(function () {
    const elasticsearchHost = Template.currentData().elasticsearchHost;

    if (elasticsearchHost) {
      Meteor.call('getElasticsearchHealth', elasticsearchHost, function (error, health) {
        if (error) {
          throw new Meteor.Error(error);
        } else {
          // update Elasticsearch health reactive variable
          templateInstance.elasticsearchHealth.set(health);
        }
      });
    }
  });
});

Template.elasticsearchHealth.helpers({
  health () {
    // Get reference to template instance
    const templateInstance = Template.instance();

    return templateInstance.elasticsearchHealth.get();
  }
});

Check for elasticsearchHost before using


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree
//= require bootstrap-datepicker/core
//= require bootstrap-datepicker/locales/bootstrap-datepicker.es.js

Add es locale for bootstrap datepicker.


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require typeahead.min
//= require coderwall
//= require jquery.timeago
//= require jquery.datetimepicker
//= require emojione
//= require lodash
//= require gmaps/google
//= require_tree .
//= stub maps
//

Revert "Don’t stub out the maps.js file for now"


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery_ujs
//= require turbolinks
//= require_tree .

Remove jquery because it is loaded from a CDN


/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  refines: 'foam.dao.DAOProperty',
  properties: [
    {
      name: 'swiftType',
      expression: function(required) {
        return '(DAO & FObject)' + (required ? '' : '?');
      },
    },
  ],
  methods: [
    function writeToSwiftClass(cls, superAxiom, parentCls) {
      this.SUPER(cls, superAxiom, parentCls);
      cls.fields.push(
        foam.swift.Field.create({
          lazy: true,
          visibility: 'public',
          name: this.swiftName + '$proxy',
          type: 'ProxyDAO',
          initializer: `
let d = __context__.create(ProxyDAO.self, args: ["delegate": ${this.swiftName}])!
_ = ${this.swiftSlotName}.sub(listener: { _, topics in
  d.delegate = topics.last as! DAO
})
return d
          `,
        })
      )
    },
  ],
});

/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  refines: 'foam.dao.DAOProperty',
  properties: [
    {
      name: 'swiftType',
      expression: function(required) {
        return '(DAO & FObject)' + (required ? '' : '?');
      },
    },
  ],
  methods: [
    function writeToSwiftClass(cls, superAxiom, parentCls) {
      this.SUPER(cls, superAxiom, parentCls);
      cls.fields.push(
        foam.swift.Field.create({
          lazy: true,
          visibility: 'public',
          name: this.swiftName + '$proxy',
          type: 'ProxyDAO',
          initializer: `
let d = __context__.create(ProxyDAO.self, args: ["delegate": ${this.swiftName}])!
_ = ${this.swiftSlotName}.sub(listener: { sub, topics in
  if let dao = topics.last as? DAO {
    d.delegate = dao
  } else {
    d.clearProperty("delegate")
  }
})
return d
          `,
        })
      )
    },
  ],
});

Update swift's daoproperty proxydao initializer to check the last element of the topics before blindly using them to handle detaches properly.


import { test } from 'qunit';
import moduleForAcceptance from 'cargo/tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | crate page');

test('visiting a crate page from the front page', function(assert) {
    visit('/');
    click('#just-updated ul > li:first a');

    andThen(function() {
        assert.equal(currentURL(), '/crates/nanomsg');
        assert.equal(document.title, 'nanomsg - Cargo: packages for Rust');
    });
});

test('visiting a crate page directly', function(assert) {
    visit('/crates/nanomsg');

    andThen(function() {
        assert.equal(currentURL(), '/crates/nanomsg');
        assert.equal(document.title, 'nanomsg - Cargo: packages for Rust');
    });
});

test('navigating to the all versions page', function(assert) {
    visit('/crates/nanomsg');
    click('#crate-versions span.small a');

    andThen(function() {
        matchesText(assert, '.info', /All 12 versions of nanomsg since December \d+, 2014/);
    });
});

test('navigating to the reverse dependencies page', function(assert) {
    visit('/crates/nanomsg');
    click('a:contains("Dependent crates")');

    andThen(function() {
        assert.equal(currentURL(), '/crates/nanomsg/reverse_dependencies');

        const $revDep = findWithAssert('#crate-all-reverse-dependencies a[href="/crates/unicorn-rpc"]:first');

        hasText(assert, $revDep, 'unicorn-rpc');
    });
});

Test for navigating to the Dependent Crates page


var ExpandingList = new Vue({
  el: "#expandingList",
  data: {
    names: ['']
  },
  methods: {
    addBlankName: function () {
      if (this.hasBlankName()) {
        return
      }
      this.names.push('')
    },

    hasBlankName: function () {
      for (var i = this.names.length - 1; i >= 0; i--) {
        var name = this.names[i]
        if (name === '') {
          return true
        }
      }
      return false
    }
  }
})

var ExpandingList = Vue.extend({
  data: function () { return { names: [''] } },
  methods: {
    addBlankName: function () {
      if (this.hasBlankName()) {
        return
      }
      this.names.push('')
    },

    hasBlankName: function () {
      for (var i = this.names.length - 1; i >= 0; i--) {
        var name = this.names[i]
        if (name === '') {
          return true
        }
      }
      return false
    }
  }
})

var list = new ExpandingList()
list.$mount('#expandingList')

Move more in the direction of components


/**
 * @fileoverview Define the map component of the map module.
 */
'use strict';

angular.module('map').component('mapComponent', {
    templateUrl: 'map/map.template.html',
    controller: function($scope, $http) {

        let googleMapOption = {
            zoom: 4,
            center: new google.maps.LatLng(25, 80)
        };

        $scope.gMap = new google.maps.Map(document.getElementById('map-container'), googleMapOption);

        // Add a marker to the map
        const addMarker = function(marker) {

            new google.maps.Marker({
                map: $scope.gMap,
                position: new google.maps.LatLng(marker.lat, marker.long),
                title: marker.animal
            });

        };

        // Iterate over the markers json and add all of them to the map
        $http.get('map/markers/markers.json').then(function(response){
            angular.forEach(response.data, function(marker){
                addMarker(marker);
           });
        });
    }
});

/**
 * @fileoverview Define the map component of the map module.
 */
'use strict';

angular.module('map').component('mapComponent', {
    templateUrl: 'map/map.template.html',
    controller: function($scope, $http) {

        let googleMapOption = {
            zoom: 4,
            center: new google.maps.LatLng(25, 80)
        };

        $scope.gMap = new google.maps.Map(document.getElementById('map-container'), googleMapOption);

        // Add a marker to the map
        const addMarker = function(marker) {

            new google.maps.Marker({
                map: $scope.gMap,
                position: new google.maps.LatLng(marker.lat, marker.long),
                title: marker.animal
            });

        };

        // Iterate over the markers json and add all of them to the map
        $http.get('map/markers/markers.json').then((response) => angular.forEach(response.data, addMarker));
    }
});

Change markers iteration to lambda function


import React from 'react';
import { Image, requireNativeComponent } from 'react-native';
import { meetOrSliceTypes, alignEnum } from '../lib/extract/extractViewBox';
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
import Shape from './Shape';

const spacesRegExp = /\s+/;

export default class SvgImage extends Shape {
  static displayName = 'Image';

  static defaultProps = {
    x: 0,
    y: 0,
    width: 0,
    height: 0,
    preserveAspectRatio: 'xMidYMid meet',
  };

  render() {
    const { props } = this;
    const {
      preserveAspectRatio,
      x,
      y,
      width,
      height,
      xlinkHref,
      href = xlinkHref,
    } = props;
    const modes = preserveAspectRatio.trim().split(spacesRegExp);
    return (
      <RNSVGImage
        ref={this.refMethod}
        {...extractProps({ ...propsAndStyles(props), x: null, y: null }, this)}
        x={x}
        y={y}
        width={width}
        height={height}
        meetOrSlice={meetOrSliceTypes[modes[1]] || 0}
        align={alignEnum[modes[0]] || 'xMidYMid'}
        src={Image.resolveAssetSource(href)}
      />
    );
  }
}

const RNSVGImage = requireNativeComponent('RNSVGImage');

import React from 'react';
import { Image, requireNativeComponent } from 'react-native';
import { meetOrSliceTypes, alignEnum } from '../lib/extract/extractViewBox';
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
import Shape from './Shape';

const spacesRegExp = /\s+/;

export default class SvgImage extends Shape {
  static displayName = 'Image';

  static defaultProps = {
    x: 0,
    y: 0,
    width: 0,
    height: 0,
    preserveAspectRatio: 'xMidYMid meet',
  };

  render() {
    const { props } = this;
    const {
      preserveAspectRatio,
      x,
      y,
      width,
      height,
      xlinkHref,
      href = xlinkHref,
    } = props;
    const modes = preserveAspectRatio.trim().split(spacesRegExp);
    return (
      <RNSVGImage
        ref={this.refMethod}
        {...extractProps({ ...propsAndStyles(props), x: null, y: null }, this)}
        x={x}
        y={y}
        width={width}
        height={height}
        meetOrSlice={meetOrSliceTypes[modes[1]] || 0}
        align={alignEnum[modes[0]] || 'xMidYMid'}
        src={Image.resolveAssetSource(
          typeof href === 'string' ? { uri: href } : href,
        )}
      />
    );
  }
}

const RNSVGImage = requireNativeComponent('RNSVGImage');

Fix compatibility with svgr and images


module.exports = function (config) {
  let storage = config.common.storage
  config.common.dbIndexes = {
    'users': { user: 1, username: 1, email: 1 },
    'users.code': { user: 1 },
    'rooms': { active: 1, status: 1 },
    'rooms.objects': { room: 1, user: 1 },
    'rooms.terrain': { room: 1 },
    'rooms.flags': { room: 1, user: 1 },
    'transactions': { user: 1 },
    'users.console': { user: 1 },
    'users.money': { user: 1 },
    'users.notifications': { user: 1 },
    'users.resources': { user: 1 }
  }
  storage._connect = require('./_connect')(config)
}

module.exports = function (config) {
  let storage = config.common.storage
  config.common.dbIndexes = {
    'users': { user: 1, username: 1, email: 1 },
    'users.code': { user: 1 },
    'rooms': { active: 1, status: 1 },
    'rooms.objects': { room: 1, user: 1 },
    'rooms.terrain': { room: 1 },
    'rooms.flags': { room: 1, user: 1 },
    'transactions': { user: 1 },
    'users.console': { user: 1 },
    'users.money': { user: 1 },
    'users.notifications': { user: 1 },
    'users.power_creeps': { user: 1 },
    'users.resources': { user: 1 }
  }
  storage._connect = require('./_connect')(config)
}

Add `user` index to `users.power_creeps`


Template.profileShow.helpers({
  initiatives: function(){
    return Initiatives.find({
      createdBy: Meteor.userId(),
      usersVoted: Meteor.userId()
    });
  }
})

Template.profileShow.helpers({
  initiatives: function(){
    return Initiatives.find({
      usersVoted: Meteor.userId()
    });
  }
})

Fix CreatedBy error in profile


/**
 * @ngdoc service
 * @name just.service.service:faqService
 * @description
 * # faqService
 * Service to handle FAQ's.
 */
angular.module('just.service')
  .service('faqService', ['i18nService', 'Resources', '$q',  function (i18nService, resources, $q) {

    var that = this;

    this.getFaqs = function() {
      return that.faqsResolve;
    };

    this.faqsResolve = $q(function(resolve, reject) {
      resources.faqs.query({id: i18nService.getLanguage().id}, function(faqs) {
        resolve(faqs);
      });
    });

  }]
);

/**
 * @ngdoc service
 * @name just.service.service:faqService
 * @description
 * # faqService
 * Service to handle FAQ's.
 */
angular.module('just.service')
  .service('faqService', ['i18nService', 'Resources', '$q',  function (i18nService, resources, $q) {

    var that = this;

    this.getFaqs = function() {
      return that.faqsResolve;
    };

    this.faqsResolve = $q(function(resolve, reject) {
      resources.faqs.query({id: i18nService.current_language.id}, function(faqs) {
        resolve(faqs);
      });
    });

  }]
);

Fix i18nservice get language id return null value


//= require_tree ./lib
//= require_tree .
//= require_self

//= require select2

GOVUK.orderedLists.init();
GOVUK.curatedLists.init();

(function() {
  "use strict";
  window.GOVUK = window.GOVUK || {};
  var $ = window.jQuery;

  $('.js-confirm').each(function(_, button) {
    var $button = $(button);

    $button.closest('form').submit(function(event) {
      if (!confirm($button.data('confirm-text'))) {
        event.preventDefault();
      }
    });
  });
}());

//= require_tree ./lib
//= require_tree .
//= require_self

//= require select2

GOVUK.orderedLists.init();
GOVUK.curatedLists.init();

(function() {
  "use strict";
  window.GOVUK = window.GOVUK || {};
  var $ = window.jQuery;

  $('.js-confirm').each(function(_, button) {
    var $button = $(button);

    $button.closest('form').submit(function(event) {
      if (!confirm($button.data('confirm-text'))) {
        event.preventDefault();
      }
    });
  });

  $(document).ready(function() {
    $(".select2").select2();
  });
}());

Apply select2-rails against .select2 elements


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require_tree .
$( document ).ready(function() {
  $("#notes").focus(function(){
    $("#actions_notes").prop('checked', true);
  });
});

Remove unused Javascript from previous prototype


module.exports = {
  "extends": "justinlocsei/configurations/es6",
  "ecmaFeatures": {
    "jsx": true
  },
  "env": {
    "browser": true
  },
  "plugins": [
    "react"
  ],
  "rules": {
    "jsx-quotes": [2, "prefer-double"],
    "react/jsx-boolean-value": [2, "always"],
    "react/jsx-curly-spacing": [2, "never"],
    "react/jsx-handler-names": 2,
    "react/jsx-no-bind": 2,
    "react/jsx-no-duplicate-props": [2, {"ignoreCase": true}],
    "react/jsx-no-undef": 2,
    "react/jsx-pascal-case": 2,
    "react/jsx-uses-vars": 2,
    "react/no-danger": 2,
    "react/no-did-mount-set-state": [2, "allow-in-func"],
    "react/no-did-update-set-state": [2, "allow-in-func"],
    "react/no-direct-mutation-state": 2,
    "react/no-multi-comp": 2,
    "react/no-unknown-property": 2,
    "react/prop-types": 2,
    "react/require-extension": 2,
    "react/self-closing-comp": 2,
    "react/wrap-multilines": 2
  }
};

module.exports = {
  "extends": "justinlocsei/configurations/es6",
  "ecmaFeatures": {
    "jsx": true
  },
  "env": {
    "browser": true
  },
  "plugins": [
    "react"
  ],
  "rules": {
    "jsx-quotes": [2, "prefer-double"],
    "react/jsx-boolean-value": [2, "always"],
    "react/jsx-curly-spacing": [2, "never"],
    "react/jsx-handler-names": 2,
    "react/jsx-no-bind": 2,
    "react/jsx-no-duplicate-props": [2, {"ignoreCase": true}],
    "react/jsx-no-undef": 2,
    "react/jsx-pascal-case": 2,
    "react/jsx-uses-vars": 2,
    "react/no-danger": 2,
    "react/no-did-mount-set-state": 2,
    "react/no-did-update-set-state": 2,
    "react/no-direct-mutation-state": 2,
    "react/no-multi-comp": 2,
    "react/no-unknown-property": 2,
    "react/prop-types": 2,
    "react/require-extension": 2,
    "react/self-closing-comp": 2,
    "react/wrap-multilines": 2
  }
};

Update the React setState checks to avoid version-based syntax errors


//= require govuk_toolkit
//= require_tree .

jQuery(function($) {

  "use strict";
  GOVUK.primaryLinks.init('.primary-item');

  $('.js-collapsible-collection').each(function(){
    new GOVUK.CollapsibleCollection({$el:$(this)});
  })

  if (window.location.hash) {
    openSectionContainingAnchor($(window.location.hash));
  }

  $('.govspeak').on('click', 'a', function(event){
    if (window.location.pathname == event.target.pathname) {
      openSectionContainingAnchor($(window.location.hash));
    }
  })
});

function openSectionContainingAnchor($anchor) {
  if ($anchor.length != 0) {
    new GOVUK.Collapsible($anchor.closest('.js-openable')).open();
  }
}

//= require govuk_toolkit
//= require_tree .

jQuery(function($) {

  "use strict";
  GOVUK.primaryLinks.init('.primary-item');

  $('.js-collapsible-collection').each(function(){
    new GOVUK.CollapsibleCollection({$el:$(this)});
  })

  if (window.location.hash) {
    openSectionContainingAnchor($(window.location.hash));
  }

  $('.govspeak').on('click', 'a', function(event){
    if (window.location.pathname == event.target.pathname) {
      openSectionContainingAnchor($(event.currentTarget.hash));
    }
  })
});

function openSectionContainingAnchor($anchor) {
  if ($anchor.length != 0) {
    new GOVUK.Collapsible($anchor.closest('.js-openable')).open();
  }
}

Update anchor parameter to be derived from event


/**
 * Created by dungvn3000 on 4/4/14.
 */

Ext.define('sunerp.component.NhanVienCb', {
    extend: 'sunerp.component.Combobox',
    alias: 'widget.nhanviencb',
    gird: null,
    valueField: 'maNv',
    displayField: 'fullName',
    inject: ['userService'],
    config: {
        userService: null
    },
    initComponent: function () {
        var phongBanId = this.getUserService().getCurrentUser().phongBanId;
        this.store = Ext.create('sunerp.store.NhanVienStore');
        if(phongBanId) {
            this.store.filter('phongBanId', String(phongBanId));
        }
        this.store.load();
        this.callParent(arguments);
    },
    onItemClick: function (picker, record) {
        var me = this;
        me.callParent(arguments);
        if (me.gird && me.gird.getSelectionModel().hasSelection()) {
            var model = me.gird.getSelectionModel().getLastSelected();
            model.set('nhanVienId', record.getData().id);
        }
    }
});

/**
 * Created by dungvn3000 on 4/4/14.
 */

Ext.define('sunerp.component.NhanVienCb', {
    extend: 'sunerp.component.Combobox',
    alias: 'widget.nhanviencb',
    gird: null,
    valueField: 'maNv',
    displayField: 'fullName',
    inject: ['userService'],
    config: {
        userService: null
    },
    initComponent: function () {
        var phongBanId = this.getUserService().getCurrentUser().phongBanId;
        this.store = Ext.create('sunerp.store.NhanVienStore');
        if(phongBanId) {
            this.store.filter('phongBanId', String(phongBanId));
        }
        this.store.load();
        this.callParent(arguments);
    },
    onItemClick: function (picker, record) {
        var me = this;
        me.callParent(arguments);
        if (me.gird && me.gird.getSelectionModel().hasSelection()) {
            var model = me.gird.getSelectionModel().getLastSelected();
            model.set('nhanVienId', record.getData().id);
            model.set('nhanVien', record.getData());
        }
    }
});

Fix wrong display fullName in sophancong gird.


const test = require('tape');

// Load Array.prototype.customMap function
require('../exercises/map/map');
// Load Array.prototype.customFilter function
require('../exercises/filter/filter');
// Load Array.prototype.concatAll function.
require('../exercises/concatAll/concatAll');
// Load Array.prototype.concatMap function.
require('../exercises/concatMap/concatMap');

test('Practice the concept of unit testing with simple tape library', function(nest) {

    // TODO: Make unit test pass with actual and expected assertion.
    nest.test('Unit test the map function', assert => {
        assert.equal(actual, expected,
            `should render default message`);
        assert.end();
    });

    // TODO: Unit test filter function
    nest.test('Unit test the filter function', assert => {

    });

    // TODO: Unit test concatAll function

    // TODO: Unit test concatMap function
});

const test = require('tape');

// Load Array.prototype.customMap function
require('./exercises/map/map');
// Load Array.prototype.customFilter function
require('./exercises/filter/filter');
// Load Array.prototype.concatAll function.
require('./exercises/concatAll/concatAll');
// Load Array.prototype.concatMap function.
require('./exercises/concatMap/concatMap');

test('Practice the concept of unit testing with simple tape library', function(nest) {

    // TODO: Make unit test pass with actual and expected assertion.
    nest.test('Unit test the map function', assert => {
        assert.equal(actual, expected,
            `should render default message`);
        assert.end();
    });

    // TODO: Unit test filter function
    nest.test('Unit test the filter function', assert => {

    });

    // TODO: Unit test concatAll function

    // TODO: Unit test concatMap function
});

Add current Directory to repo.


'use strict';

var five = require('johnny-five');
var myBoard = new five.Board();

/**
 * The code for the project, that will be run when the board is ready
 *
 * This is a 'callback' function that will be run by johnny-five after it has
 * finished all the behind the scenes setup.
 *
 * johnny-five makes the board that this is a callback for available in the
 * 'this' parameter / variable.  All methods / properties of the specific
 * board are available as properties of 'this'.
 */
function myProjectCode() {
  /* jshint validthis:true */
  // Project code goes here
}

// This is where the program actully starts running.  It is kept at the end,
// after the callback function myProjectCode has been created, so that the
// jslint program does not complain about using something before it was defined.
// The way javascript works, it is not a technical requirement.  Just good
// practice.
myBoard.on('ready', myProjectCode);

'use strict';

var five = require('johnny-five');
var myBoard = new five.Board();

/**
 * The code for the project, that will be run when the board is ready
 *
 * This is a 'callback' function that will be run by johnny-five after it has
 * finished all the behind the scenes setup.
 *
 * johnny-five makes the board that this is a callback for available in the
 * 'this' parameter / variable.  All methods / properties of the specific
 * board are available as properties of 'this'.
 */
function boardIsReady() {
  /* jshint validthis:true */
  // Project code goes here
}

// This is where the program actully starts running.  It is kept at the end,
// after the callback function boardIsReady has been created, so that the
// jslint program does not complain about using something before it was defined.
// The way javascript works, it is not a technical requirement.  Just good
// practice.
myBoard.on('ready', boardIsReady);

Tweak function names in script template


/**
 * Book page
 */
define([
    "underscore",
    "backbone"
],
function(_, Backbone) {
    var BookPage = Backbone.View.extend({
        render: function() {
            // Fill out existing structure.
            var fieldsStandardText = ["title", "isbn", "publisher", "notesPublic", "notesPrivate"],
                authors;

            _.each(fieldsStandardText, function(field) {
                this.$("#book-" + field).html(this.model.get(field));
            }, this);

            // Show either author or authors rows.
            authors = this.model.get("authors");
            if (!_.isArray(authors) || authors.length === 0) {
                // Hide both.
                this.$(".author, .authors").hide();
            } else {
                // REFACTOR: use just one line, if simply using text for multiple authors.
                if (authors.length === 1) {
                    this.$(".authors").hide();
                    this.$(".author").show();
                    this.$(".author.ui-block-b div").html(authors[0]);
                } else {
                    this.$(".author").hide();
                    this.$(".authors").show();
                    this.$(".authors.ui-block-b div").html(authors.join(", "));
                }
            }

            // Private?
            this.$("#book-public").html(
                this.model.get("public") ? "Yes" : "No"
            );

            return this;
        }
    });

    return BookPage;
});

/**
 * Book page
 */
define([
    "underscore",
    "backbone"
],
function(_, Backbone) {
    var BookPage = Backbone.View.extend({
        render: function() {
            // Fill out existing structure.
            var fieldsStandardText = ["title", "isbn", "publisher", "notesPublic", "notesPrivate"],
                authors, fieldValue;

            _.each(fieldsStandardText, function(field) {
                // Use non-breaking space when field is null.
                if (this.model.has(field)) {
                    fieldValue = this.model.get(field);
                } else {
                    fieldValue = " ";
                }
                this.$("#book-" + field).html(fieldValue);
            }, this);

            // Show either author or authors rows.
            authors = this.model.get("authors");
            if (!_.isArray(authors) || authors.length === 0) {
                // Hide both.
                this.$(".author, .authors").hide();
            } else {
                // REFACTOR: use just one line, if simply using text for multiple authors.
                if (authors.length === 1) {
                    this.$(".authors").hide();
                    this.$(".author").show();
                    this.$(".author.ui-block-b div").html(authors[0]);
                } else {
                    this.$(".author").hide();
                    this.$(".authors").show();
                    this.$(".authors.ui-block-b div").html(authors.join(", "));
                }
            }

            // Private?
            this.$("#book-public").html(
                this.model.get("public") ? "Yes" : "No"
            );

            return this;
        }
    });

    return BookPage;
});

Use non-breaking space when book field is null.


var WebFont = require("webfont"),
    stripDomain = new RegExp("^(.*://[^/]*/)?(.*)$");

exports.locate = function(load) {
  return decodeURI(load.name.match(stripDomain)[2]);
}

exports.fetch = function(load) {
  return new Promise(function(resolve, reject) {
    var fontName = load.address.split(" ")[0],
        params = load.address.substr(fontName.length + 1).split(",").map(function(str) {
          return str.trim();
        }),
        font = {},
        config = {
          active: function() { resolve("") },
          inactive: function() { reject() }
        };

    config[fontName] = font

    switch (fontName) {
      case "fontdeck":
      case "typekit":
        font.id = params.join(",");
        break;
      case "google":
        font.families = params;
        break;
      case "monotype":
        font.projectId = params[0];
        font.version = params[1];
    }

    WebFont.load(config);
  });
}

var WebFont = require("webfont"),
    stripDomain = new RegExp("^(.*://[^/]*/)?(.*)$");
    //                     scheme^ domain^ font^

exports.locate = function(load) {
  return decodeURI(load.name.match(stripDomain)[2]);
}

exports.fetch = function(load) {
  return new Promise(function(resolve, reject) {
    var fontName = load.address.split(" ")[0],
        params = load.address.substr(fontName.length + 1).split(",").map(function(str) {
          return str.trim();
        }),
        font = {},
        config = {
          active: function() { resolve("") },
          inactive: function() { reject() }
        };

    config[fontName] = font

    switch (fontName) {
      case "fontdeck":
      case "typekit":
        font.id = params.join(",");
        break;
      case "google":
        font.families = params;
        break;
      case "monotype":
        font.projectId = params[0];
        font.version = params[1];
    }

    WebFont.load(config);
  });
}

Add comment to domain stripping regular experssion


/**
 * A script to generate Pull Request in Github
 */
let execSync = require("child_process").execSync;
let urlOfPR = ``;
execSync(`open ${urlOfPR}`);

/**
 * A script to generate Pull Request in Github
 */
let execSync = require("child_process").execSync;
let urlOfPR = `https://github.com/bvenkatr/common/compare/master...codingbranch?expand=1`;
execSync(`open ${urlOfPR}`);

Add static url to generate PR


'use strict';

let Telegram = require( 'node-telegram-bot-api' );
let config = require( '../config.js' );
let BotPlug = require( './BotPlug.js' );

class TelegramBotPlug extends BotPlug {
    constructor( bot ){
        super( bot );

        if( config.bot.plugins.indexOf( 'Telegram' ) > -1 ){
            this.telegramClient = new Telegram(
                config.telegram.apiKey,
                {
                    polling: true
                }
            );

            super.detectMessageToUser( this.onUserMessage );

            this.telegramClient.on( 'message', ( msg ) => {
                var chatId = msg.chat.id;

                this.telegramClient.sendMessage( chatId, 'Chat id: ' + chatId );
            });
        }
    }

    onUserMessage( users, from, message ){
        for( let i = 0; i < users.length; i = i + 1 ){
            if( config.users[ users[ i ] ] ){
                this.telegramClient.sendMessage( config.users[ users[ i ] ], '[' + from + '] ' + message );
                console.log( 'Telegram sent to ' + config.users[ users[ i ] ] );
            }
        }
    }
}

module.exports = TelegramBotPlug;

'use strict';

let Telegram = require( 'node-telegram-bot-api' );
let config = require( '../config.js' );
let BotPlug = require( './BotPlug.js' );

class TelegramBotPlug extends BotPlug {
    constructor( bot ){
        super( bot );

        if( config.bot.plugins.indexOf( 'Telegram' ) > -1 ){
            this.telegramClient = new Telegram(
                config.telegram.apiKey,
                {
                    polling: true
                }
            );

            super.detectMessageToUser( this.onUserMessage );

            this.telegramClient.on( 'message', ( msg ) => {
                var chatId = msg.chat.id;

                this.telegramClient.sendMessage( chatId, 'Chat id: ' + chatId );
            });
        }
    }

    onUserMessage( users, from, message ){
        for( let i = 0; i < users.length; i = i + 1 ){
            if( config.telegram.users[ users[ i ] ] ){
                this.telegramClient.sendMessage( config.telegram.users[ users[ i ] ], '[' + from + '] ' + message );
                console.log( 'Telegram sent to ' + config.telegram.users[ users[ i ] ] );
            }
        }
    }
}

module.exports = TelegramBotPlug;

Use the correct path for telegram config


#!/usr/bin/env node

const spawn = require('child_process').spawn;

spawn('node', ['node_modules/supervisor/lib/cli-wrapper.js', '-n', 'error', '-w', 'mocks', '-i', 'mocks/data,mocks/node_modules', '--', 'node_modules/mockizen/bin/mockizen', 'mocks/scenarios.json'], { stdio: 'inherit' })
  .on('close', (code) => process.exit(code));

#!/usr/bin/env node

const spawn = require('child_process').spawn;

process.on('exit', kill);
process.on('SIGINT', kill);
process.on('SIGTERM', kill);

const child = spawn('node', ['node_modules/supervisor/lib/cli-wrapper.js', '-n', 'error', '-w', 'mocks', '-i', 'mocks/data,mocks/node_modules', '--', 'node_modules/mockizen/bin/mockizen', 'mocks/scenarios.json'], { stdio: 'inherit' })
  .on('close', (code) => process.exit(code));

function kill() {
  child.kill('SIGINT');
}

Make sure the mock server’s process is stopped


(function() {
	var LiveApi = window['binary-live-api'].LiveApi;
	var api = new LiveApi();
	binary_visual.login = function login(token, callback){
		api.authorize(token).then(function(value){
			callback(value);
		}, function (reason){
			console.log('Error: ' + reason.message);
		});
	};

	binary_visual.startTrade = function startTrade(options, callback){
		/*api.events.on('tick', callback);
		api.subscribeToTicks(options.symbol).then(function(value){
			console.log('Subscribed to tick for symbol:', value);
		}, function(reason){
			console.log('Error: ' + reason.message);
		});*/
	};

	binary_visual.getPriceForProposal = function getPriceForProposal(options){
		api.subscribeToPriceForContractProposal(options).then(function(value){
			console.log('Proposal Accepted\nID:', value.proposal.id);
		}, function(reason){
			console.log('Error: ' + reason.message);
		});
	};
})();

(function() {
	var LiveApi = window['binary-live-api'].LiveApi;
	var api = new LiveApi();
	binary_visual.login = function login(token, callback){
		api.authorize(token).then(function(value){
			callback(value);
		}, function (reason){
			console.log('Error: ' + reason.message);
		});
	};

	binary_visual.startTrade = function startTrade(options, callback){
		/*api.events.on('tick', callback);
		api.subscribeToTicks(options.symbol).then(function(value){
			console.log('Subscribed to tick for symbol:', value);
		}, function(reason){
			console.log('Error: ' + reason.message);
		});*/
	};

	binary_visual.getPriceForProposal = function getPriceForProposal(options){
		api.subscribeToPriceForContractProposal(options).then(function(value){
			console.log('Proposal Accepted!\nID:', value.proposal.id);
		}, function(reason){
			console.log('Error: ' + reason.message);
		});
	};
})();

Add exclamation mark to the proposal console log


/**
 * @license
 * Copyright 2012 Google Inc. All Rights Reserved.
 *
 * 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.
 */
var fs = require('fs');
var vm = require('vm');
var path = require('path');

// Initializing FOAM_BOOT_DIR.
global.FOAM_BOOT_DIR = __dirname;

// Needed so that scripts run through runInThisContext can require other nodejs
// modules.
global.require = require;

var foamLoader = fs.readFileSync(
    path.join(global.FOAM_BOOT_DIR, 'foam_context_loader.js'));
vm.runInThisContext(foamLoader);

/**
 * @license
 * Copyright 2012 Google Inc. All Rights Reserved.
 *
 * 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.
 */
var fs = require('fs');
var vm = require('vm');
var path = require('path');

// Initializing FOAM_BOOT_DIR.
global.FOAM_BOOT_DIR = __dirname;

// Needed so that scripts run through runInThisContext can require other nodejs
// modules.
global.require = require;

var foamLoader = fs.readFileSync(
    path.join(global.FOAM_BOOT_DIR, 'FOAMContextLoader.js'));
vm.runInThisContext(foamLoader);

Fix bugs caused by renaming foam_context_loader.


(function() {
  'use strict';

  var app = angular.module('radar.validators');

  app.directive('equalToValidator', ['$parse', function($parse) {
    return {
      restrict: 'A',
      require: 'ngModel',
      scope: false,
      link: function(scope, element, attrs, ngModelCtrl) {
        ngModelCtrl.$parsers.push(function(thisValue) {
          var otherValue = $parse(attrs.equalToValidator)(scope);
          ngModelCtrl.$setValidity('equalTo', thisValue === otherValue);
          return thisValue;
        });
      }
    };
  }]);
})();

(function() {
  'use strict';

  var app = angular.module('radar.validators');

  app.directive('equalToValidator', ['$parse', function($parse) {
    return {
      restrict: 'A',
      require: 'ngModel',
      scope: false,
      link: function(scope, element, attrs, ngModelCtrl) {
        ngModelCtrl.$parsers.push(function(thisValue) {
          var otherValue = getOtherValue();
          validate(thisValue, otherValue);
          return thisValue;
        });

        scope.$watch(function() {
          return getOtherValue();
        }, function(otherValue) {
          var thisValue = getThisValue();
          validate(thisValue, otherValue);
        })

        function getThisValue() {
          return ngModelCtrl.$modelValue;
        }

        function getOtherValue() {
          return $parse(attrs.equalToValidator)(scope);
        }

        function validate(thisValue, otherValue) {
          var valid = thisValue === otherValue;
          ngModelCtrl.$setValidity('equalTo', valid);
          return valid;
        }
      }
    };
  }]);
})();

Check equality when referenced field changes


import React, { Component } from 'react';

class MembersPreview extends Component {

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

    return (

{displayName}

{intro}

    );
  }
}

MembersPreview.propTypes = {
  displayName: React.PropTypes.string.isRequired,
  image: React.PropTypes.shape({
    uri: React.PropTypes.string.isRequired,
    height: React.PropTypes.number,
    width: React.PropTypes.number,
  }),
  intro: React.PropTypes.string,
  slug: React.PropTypes.string.isRequired,
  usState: React.PropTypes.string,
};

export default MembersPreview;

import React, { Component } from 'react';

class MembersPreview extends Component {

  render() {
    const {displayName, image, intro, slug} = this.props;

    // TODO: remove inline styles and implement a system
    return (

            {displayName}

{intro}

    );
  }
}

MembersPreview.propTypes = {
  displayName: React.PropTypes.string.isRequired,
  image: React.PropTypes.shape({
    uri: React.PropTypes.string.isRequired,
    height: React.PropTypes.number,
    width: React.PropTypes.number,
  }),
  intro: React.PropTypes.string,
  slug: React.PropTypes.string.isRequired,
  usState: React.PropTypes.string,
};

export default MembersPreview;

Add more information to the member preview and add some temporary inline styles for mockup


const { GraphQLClient } = require("graphql-request");
const { writeFileSync, existsSync, mkdirSync } = require("fs");

async function fetchMembers(organisation) {
  const token = process.env.GH_TOKEN;

  if (!token) {
    console.error("'GH_TOKEN' not set. Could not fetch nteract members.");
    return [];
  }

  const client = new GraphQLClient("https://api.github.com/graphql", {
    headers: {
      Authorization: `Bearer ${token}`
    }
  });

  const query = `{
    organization(login: ${organisation}) {
      membersWithRole(first: 100) {
        totalCount
          nodes {
            name
            login
            websiteUrl
            avatarUrl
            url
          }
      }
    }
  }`;

  try {
    const data = await client.request(query);
    return data.organization.membersWithRole.nodes;
  } catch (e) {
    console.error(e);
    return [];
  }
}

async function main() {
  const members = await fetchMembers("nteract");
  if (!existsSync("generated")) mkdirSync("generated");
  writeFileSync("./generated/nteract-members.json", JSON.stringify(members));
}

main();

const { GraphQLClient } = require("graphql-request");
const { writeFileSync, existsSync, mkdirSync } = require("fs");

async function fetchMembers(organisation) {
  const token = process.env.GH_TOKEN;

  if (!token) {
    console.error("'GH_TOKEN' not set. Could not fetch nteract members.");
    return [];
  }

  const client = new GraphQLClient("https://api.github.com/graphql", {
    headers: {
      Authorization: `Bearer ${token}`
    }
  });

  const query = `{
    organization(login: "${organisation}") {
      membersWithRole(first: 100) {
        totalCount
          nodes {
            name
            login
            websiteUrl
            avatarUrl
            url
          }
      }
    }
  }`;

  try {
    const data = await client.request(query);
    return data.organization.membersWithRole.nodes;
  } catch (e) {
    console.error(e);
    return [];
  }
}

async function main() {
  const members = await fetchMembers("nteract");
  if (!existsSync("generated")) mkdirSync("generated");
  writeFileSync("./generated/nteract-members.json", JSON.stringify(members));
}

main();

Fix loading contributors on about page


export function isImageURL(url) {
    return (/^http.+(jpg|gif|png|svg)$/i).test(url || "");
}

export function checkStatus(response) {
    if (response.status >= 200 && response.status < 300) {
        return response;
    }
    const error = new Error(response.statusText);
    error.response = response;
    return response.json()
        .then((body) => { error.body = body; })
        .catch(() => {}) // Catch body parsing errors and continue
        .then(() => { throw error; });
}

export function fetchJSON(url, opts = {}) {
    const defaultOpts = { credentials: "same-origin" };
    return fetch(url, Object.assign({}, defaultOpts, opts))
        .then(checkStatus)
        .then((response) => response.json());
}

export function isImageURL(url) {
    return (/^http.+(jpg|gif|png|svg|jpeg)$/i).test(url || "");
}

export function checkStatus(response) {
    if (response.status >= 200 && response.status < 300) {
        return response;
    }
    const error = new Error(response.statusText);
    error.response = response;
    return response.json()
        .then((body) => { error.body = body; })
        .catch(() => {}) // Catch body parsing errors and continue
        .then(() => { throw error; });
}

export function fetchJSON(url, opts = {}) {
    const defaultOpts = { credentials: "same-origin" };
    return fetch(url, Object.assign({}, defaultOpts, opts))
        .then(checkStatus)
        .then((response) => response.json());
}

Make jpeg extension allowed for image component


import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import omit from 'lodash.omit';
import theme from './theme.css';

class StatusLabel extends Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
    className: PropTypes.string,
    mint: PropTypes.bool,
    teal: PropTypes.bool,
    violet: PropTypes.bool,
    ruby: PropTypes.bool,
    gold: PropTypes.bool,
    aqua: PropTypes.bool,
    small: PropTypes.bool,
  };

  getColor () {
    const colors = [
      'mint',
      'violet',
      'ruby',
      'gold',
      'aqua',
      'teal',
    ];

    for (var i = 0; i < colors.length; i++) {
      const color = colors[i];
      if (this.props[color]) {
        return color;
      }
    }
  }

  getSize () {
    return this.props.small ? 'small' : 'medium';
  }

  render () {
    const {
      children,
      className,
      ...others
    } = this.props;

    const color = this.getColor();
    const size = this.getSize();

    const classes = cx(
      theme.label,
      theme[color],
      theme[size],
      className,
    );

    const rest = omit(others, [
      'mint',
      'violet',
      'ruby',
      'gold',
      'aqua',
      'teal',
      'small',
    ]);

    return (
      <span className={classes} {...rest} data-teamleader-ui="status-label">
        {children}
      </span>
    );
  }
}

export default StatusLabel;

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import omit from 'lodash.omit';
import theme from './theme.css';

class StatusLabel extends Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
    className: PropTypes.string,
    mint: PropTypes.bool,
    teal: PropTypes.bool,
    violet: PropTypes.bool,
    ruby: PropTypes.bool,
    gold: PropTypes.bool,
    aqua: PropTypes.bool,
    small: PropTypes.bool,
  };

  getColor () {
    const colors = [
      'mint',
      'violet',
      'ruby',
      'gold',
      'aqua',
      'teal',
    ];

    const color = colors.filter(color => this.props.hasOwnProperty(color));
    return color[0];
  }

  getSize () {
    return this.props.small ? 'small' : 'medium';
  }

  render () {
    const {
      children,
      className,
      ...others
    } = this.props;

    const color = this.getColor();
    const size = this.getSize();

    const classes = cx(
      theme.label,
      theme[color],
      theme[size],
      className,
    );

    const rest = omit(others, [
      'mint',
      'violet',
      'ruby',
      'gold',
      'aqua',
      'teal',
      'small',
    ]);

    return (
      <span className={classes} {...rest} data-teamleader-ui="status-label">
        {children}
      </span>
    );
  }
}

export default StatusLabel;

Use filter instead of for loop


const path = require('path');

// These modules are already transpiled and should be excluded
const folioScopeBlacklist = [
  'react-githubish-mentions',
].map(segment => path.join('@folio', segment));

// We want to transpile files inside node_modules/@folio or outside
// any node_modules directory. And definitely not files in
// node_modules outside the @folio namespace even if some parent
// directory happens to be in @folio.
//
// fn is the path after all symlinks are resolved so we need to be
// wary of all the edge cases yarn link will find for us.
function babelLoaderTest(fileName) {
  const nodeModIdx = fileName.lastIndexOf('node_modules');
  if (fileName.endsWith('.js')
    && (nodeModIdx === -1 || fileName.lastIndexOf('@folio') > nodeModIdx)
    && (folioScopeBlacklist.findIndex(ignore => fileName.includes(ignore)) === -1)) {
    return true;
  }
  return false;
}

module.exports = {
  test: babelLoaderTest,
  loader: 'babel-loader',
  options: {
    cacheDirectory: true,
    presets: [
      [require.resolve('babel-preset-env'), { modules: false }],
      [require.resolve('babel-preset-stage-2')],
      [require.resolve('babel-preset-react')],
    ],
    plugins: [
      [require.resolve('babel-plugin-transform-decorators-legacy')],
      [require.resolve('react-hot-loader/babel')]
    ]
  },
};

const path = require('path');

// These modules are already transpiled and should be excluded
const folioScopeBlacklist = [
  'react-githubish-mentions',
  'react-big-calendar',
].map(segment => path.join('@folio', segment));

// We want to transpile files inside node_modules/@folio or outside
// any node_modules directory. And definitely not files in
// node_modules outside the @folio namespace even if some parent
// directory happens to be in @folio.
//
// fn is the path after all symlinks are resolved so we need to be
// wary of all the edge cases yarn link will find for us.
function babelLoaderTest(fileName) {
  const nodeModIdx = fileName.lastIndexOf('node_modules');
  if (fileName.endsWith('.js')
    && (nodeModIdx === -1 || fileName.lastIndexOf('@folio') > nodeModIdx)
    && (folioScopeBlacklist.findIndex(ignore => fileName.includes(ignore)) === -1)) {
    return true;
  }
  return false;
}

module.exports = {
  test: babelLoaderTest,
  loader: 'babel-loader',
  options: {
    cacheDirectory: true,
    presets: [
      [require.resolve('babel-preset-env'), { modules: false }],
      [require.resolve('babel-preset-stage-2')],
      [require.resolve('babel-preset-react')],
    ],
    plugins: [
      [require.resolve('babel-plugin-transform-decorators-legacy')],
      [require.resolve('react-hot-loader/babel')]
    ]
  },
};

Exclude folio/react-big-calendar from being transpiled during a platform build


var util = require('util');

// create custom Error object for better callback(err, ...) support
// accepts an JSON object from CouchDB's REST errors
function CouchError (err) {
	// ensure proper stack trace
	Error.call(this);
	Error.captureStackTrace(this, this.constructor);

	this.name = this.constructor.name;
	this.message = err.error + ': ' + err.reason;

	// add properties from CouchDB error response to Error object
	for (var k in err) {
		if (err.hasOwnProperty(k)) {
			this[k] = err[k];
		}
	}
}
// CouchError instanceof Error
util.inherits(CouchError, Error);

// export
this.CouchError = CouchError;

var util = require('util');

// create custom Error object for better callback(err, ...) support
// accepts an JSON object from CouchDB's REST errors
function CouchError (err) {
	// ensure proper stack trace
	Error.call(this);
	Error.captureStackTrace(this, this.constructor);

	this.name = this.constructor.name;
	this.message = err.error + ': ' + err.reason;

	// add properties from CouchDB error response to Error object
	for (var k in err) {
		if (err.hasOwnProperty(k)) {
			this[k] = err[k];
		}
	}
    this.headers = err.headers;
}
// CouchError instanceof Error
util.inherits(CouchError, Error);

// export
this.CouchError = CouchError;

Copy headers to error object explicitly. The way that cradle/response.extend works means the properties don't enumerate


'use strict';

// MODULES //

var exists = require( '@stdlib/fs/exists' );

// MAIN //

/**
* Filters out non-existing file paths.
*
* @private
* @param {StringArray} files - file paths
* @param {Callback} clbk - callback function
*/
function getExisting( files, clbk ) {
	var count = 0;
	var out = [];
	var i;

	for ( i = 0; i < files.length; i++ ) {
		exists( files[ i ], makeCallback( files[ i ] ) );
	}
	/**
	* Create a callback function with the correct file reference.
	*
	* @private
	* @param {string} file - full file path
	* @returns {Callback} callback function
	*/
	function makeCallback( file ) {
		/**
		* Appends path to output array in case the file exists. Once all checks have completed, the callback is invoked.
		*
		* @private
		* @param {(Error|null)} error - error object
		* @param {boolean} boolean indicating if file exists
		*/
		return function onDone( err, bool ) {
			if ( err ) {
				console.error( err );
			}
			if ( bool ) {
				out.push( file );
			}
			count += 1;
			if ( count === files.length ) {
				clbk( null, out );
			}
		}; // end FUNCTION onDone()
	} // end FUNCTION makeCallback()
} // end FUNCTION getExisting()

// EXPORTS //

module.exports = getExisting;

'use strict';

// MODULES //

var debug = require( 'debug' )( 'search-create:get-existing' );
var exists = require( '@stdlib/fs/exists' );

// MAIN //

/**
* Filters out non-existing file paths.
*
* @private
* @param {StringArray} files - file paths
* @param {Callback} clbk - callback function
*/
function getExisting( files, clbk ) {
	var out = [];
	var i = 0;

	exists( files[ i ], onDone );
	/**
	* Appends path to output array in case the file exists. Once all checks have completed, the callback is invoked.
	*
	* @private
	* @param {(Error|null)} error - error object
	* @param {boolean} boolean indicating if file exists
	*/
	function onDone( err, bool ) {
		if ( err ) {
			debug( err );
		}
		if ( bool ) {
			out.push( files[ i ] );
		}
		i += 1;
		if ( i === files.length ) {
			clbk( null, out );
		} else {
			exists( files[ i ], onDone );
		}
	} // end FUNCTION onDone()
} // end FUNCTION getExisting()

// EXPORTS //

module.exports = getExisting;

Use debug and process files sequentially


(function () {
    var cogClass = function () {};
    cogClass.prototype.exec = function (params, request, response) {
        var oops = this.utils.apiError;
        if (params.classid) {
            var db = this.sys.db;
            db.run('INSERT OR REPLACE INTO classes VALUES (?,?,?)',[params.classid,params.groupid,params.name],function(err){
                if (err) {return oops(response,err,'classes/addclass(1)')};
                sendClasses();
            })
        } else {
            var db = this.sys.db;
            db.run('INSERT INTO classes VALUES (NULL,?,?)',[params.groupid,params.name],function(err){
                if (err) {return oops(response,err,'classes/addclass(2)')};
                sendClasses();
            });
        }
        function sendClasses () {
            db.all('SELECT classID,classes.name,ruleGroupID,ruleGroups.name AS ruleGroupName FROM classes JOIN ruleGroups USING(ruleGroupID) ORDER BY classes.name;',function(err,rows){
                if (err||!rows) {return oops(response,err,'classes/addclass(3)')};
                response.writeHead(200, {'Content-Type': 'application/json'});
                response.end(JSON.stringify(rows));
            });
        }
    }
    exports.cogClass = cogClass;
})();

(function () {
    var cogClass = function () {};
    cogClass.prototype.exec = function (params, request, response) {
        var oops = this.utils.apiError;
        var sys = this.sys;
        if (params.classid) {
            sys.db.run('INSERT OR REPLACE INTO classes VALUES (?,?,?)',[params.classid,params.groupid,params.name],function(err){
                if (err) {return oops(response,err,'classes/addclass(1)')};
                sendClasses();
            })
        } else {
            var db = this.sys.db;
            sys.db.run('INSERT INTO classes VALUES (NULL,?,?)',[params.groupid,params.name],function(err){
                if (err) {return oops(response,err,'classes/addclass(2)')};
                sys.membershipKeys[this.lastID] = {};
                sendClasses();
            });
        }
        function sendClasses () {
            sys.db.all('SELECT classID,classes.name,ruleGroupID,ruleGroups.name AS ruleGroupName FROM classes JOIN ruleGroups USING(ruleGroupID) ORDER BY classes.name;',function(err,rows){
                if (err||!rows) {return oops(response,err,'classes/addclass(3)')};
                response.writeHead(200, {'Content-Type': 'application/json'});
                response.end(JSON.stringify(rows));
            });
        }
    }
    exports.cogClass = cogClass;
})();

Update memory object when adding a class


const assert = require('assert')

function createGL (opts) {
  assert(!opts || (typeof opts === 'object'), 'pex-gl: createGL requires opts argument to be null or an object')
  if (!opts) opts = {}

  let canvas = opts.canvas
  if (!canvas) {
    canvas = document.createElement('canvas')
    canvas.width = opts.width || window.innerWidth
    canvas.height = opts.height || window.innerHeight
    if (!opts.width && !opts.height) {
      // fullscreen
      document.body.style.margin = '0px'
    }
  }
  if (document.body) {
    document.body.appendChild(canvas)
  } else {
    // just in case our script is included above <body>
    document.addEventListener('DOMContentLoaded', () => {
      document.body.appendChild(canvas)
    })
  }
  const gl = canvas.getContext('webgl')
  return gl
}

module.exports = createGL

const assert = require('assert')

function createGL (opts) {
  assert(!opts || (typeof opts === 'object'), 'pex-gl: createGL requires opts argument to be null or an object')
  if (!opts) opts = {}

  let canvas = opts.canvas

  if (!canvas) {
    canvas = document.createElement('canvas')
    canvas.width = opts.width || window.innerWidth
    canvas.height = opts.height || window.innerHeight
    if (!opts.width && !opts.height) {
      // fullscreen
      document.body.style.margin = '0px'
    }
    if (document.body) {
      document.body.appendChild(canvas)
    } else {
      // just in case our script is included above <body>
      document.addEventListener('DOMContentLoaded', () => {
        document.body.appendChild(canvas)
      })
    }
  }
  const gl = canvas.getContext('webgl')
  return gl
}

module.exports = createGL

Append canvas to body only when creating new


import {
  FILTER_BY_TYPE_INJURY,
  FILTER_BY_TYPE_FATALITY,
  FILTER_BY_NO_INJURY_FATALITY,
} from '../constants/action_types';

const defaultState = {
  injury: {
    cyclist: false,
    motorist: false,
    pedestrian: false,
  },
  fatality: {
    cyclist: false,
    motorist: false,
    pedestrian: false,
  },
  noInjuryFatality: false
};

export default (state = defaultState, action) => {
  let { personType } = action;
  const { injury, fatality } = state;

  if (personType) {
    personType = personType.split(' ')[0];
  }

  switch (action.type) {
    case FILTER_BY_TYPE_INJURY:
      return {
        ...state,
        injury: {
          ...injury,
          [personType]: !injury[personType]
        }
      };
    case FILTER_BY_TYPE_FATALITY:
      return {
        ...state,
        fatality: {
          ...fatality,
          [personType]: !fatality[personType]
        }
      };
    case FILTER_BY_NO_INJURY_FATALITY:
      return {
        ...defaultState,
        noInjuryFatality: !state.noInjuryFatality
      };
    default:
      return state;
  }
};

import {
  FILTER_BY_TYPE_INJURY,
  FILTER_BY_TYPE_FATALITY,
  FILTER_BY_NO_INJURY_FATALITY,
} from '../constants/action_types';

const defaultState = {
  injury: {
    cyclist: false,
    motorist: false,
    pedestrian: false,
  },
  fatality: {
    cyclist: false,
    motorist: false,
    pedestrian: false,
  },
  noInjuryFatality: false
};

export default (state = defaultState, action) => {
  let { personType } = action;
  const { injury, fatality } = state;

  if (personType) {
    personType = personType.split(' ')[0];
  }

  switch (action.type) {
    case FILTER_BY_TYPE_INJURY:
      return {
        ...state,
        injury: {
          ...injury,
          [personType]: !injury[personType]
        },
        noInjuryFatality: false
      };
    case FILTER_BY_TYPE_FATALITY:
      return {
        ...state,
        fatality: {
          ...fatality,
          [personType]: !fatality[personType]
        },
        noInjuryFatality: false
      };
    case FILTER_BY_NO_INJURY_FATALITY:
      return {
        ...defaultState,
        noInjuryFatality: !state.noInjuryFatality
      };
    default:
      return state;
  }
};

Set filterType.noInjuryFatality to false when selecting another filter type


const axios = require('axios')

let params = {
  type: 'movie',
  tomatoes: 'true',
  title: 'la la land',
  year: '2016'
}
// params = Object.assign({title: 'jackie', year: '2016'}, params)
// If year is not specified, will pick the 2008 movie.
// params = Object.assign({title: 'passengers', year: '2016'}, params)

let url = 'http://omdbapi.com/'

axios.get(url, {params})
.then(res => {
  let data = res.data
  if (data.Error !== undefined) {
    console.log('Status: %s, Error: %s', res.status, data.Error)
    return
  }

  let movie = data
  // console.log(movie)
  console.log(movie.Title)
  console.log(movie.Year)
  console.log('Directed by', movie.Director)
  console.log('Metascore:', movie.Metascore)
  console.log('IMDB rating:', movie.imdbRating)
  console.log('Tomato rating:', movie.tomatoRating)
})

const axios = require('axios')

let params = {
  type: 'movie',
  tomatoes: 'true',
  plot: 'short',
  t: 'la la land',
  y: '2016',
}
params = Object.assign(params, {t: 'silence', y: '2016'})
// If year is not specified, will pick the 2008 movie.
// params = Object.assign(params, {t: 'passengers', y: '2016'})

let url = 'http://www.omdbapi.com/'

axios.get(url, {params})
.then(res => {
  let data = res.data
  if (data.Error !== undefined) {
    console.log('Status: %s, Error: %s', res.status, data.Error)
    return
  }

  let movie = data
  // console.log(movie)
  console.log(movie.Title)
  console.log(movie.Year)
  console.log('Directed by', movie.Director)
  console.log('Poster:', movie.Poster)
  console.log('Metascore:', movie.Metascore)
  console.log('IMDB rating:', movie.imdbRating)
  console.log('Tomato rating:', movie.tomatoRating)
})

Correct the order of arguments to Object.assign()


module.exports = {
  API_URL: 'https://api.import.io/store/data/3cf27c3b-c9e2-45c8-8a97-c4fc559ed74f/_query?_apikey=Xk6Emf7P1fSYy8lvBrvM0ygZdrQZytV5AAR4ykx5R%2FlwmgvPBYTH7XRwObZESjTduH6C0fsqr9N5y2LC9btu6g%3D%3D&_user=c5b82e89-e0b8-41f9-bdd5-f13f5925b0bb&input/webpage/url=',
  NHS_URL: 'http://www.nhs.uk/Service-Search/GP/England/Results/4/',
  EXTRA_NHS_PARAMS: '/4/0?distance=25&ResultsOnPageValue=30',
};

module.exports = {
  API_URL: 'https://api.import.io/store/data/3cf27c3b-c9e2-45c8-8a97-c4fc559ed74f/_query?_apikey=Xk6Emf7P1fSYy8lvBrvM0ygZdrQZytV5AAR4ykx5R%2FlwmgvPBYTH7XRwObZESjTduH6C0fsqr9N5y2LC9btu6g%3D%3D&_user=c5b82e89-e0b8-41f9-bdd5-f13f5925b0bb&input/webpage/url=',
  NHS_URL: 'http://www.nhs.uk/Service-Search/GP/England/Results/4/',
  EXTRA_NHS_PARAMS: '/4/0?distance=25&ResultsOnPageValue=30',
  GEOLOCATION_TIMEOUT: 5000,
  GEOLOCATION_MAXIMUM_AGE: 0
};

Add Geolocation options as constants


var config = require('./config')

module.exports = {
  site: {
    title: config.title,
    baseURL: config.baseURL
  }
}

var config = require('./config')

module.exports = {
  site: config
}

Change the templateData object to just include all config data until a blacklist is established.


/**
 * CustomEvent polyfill for IE & Edge
 * source: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
 */
(function () {

  if (typeof window.CustomEvent === 'function') {
    return false
  }

  function CustomEvent (event, params) {
    params = params || { bubbles: false, cancelable: false, detail: undefined }
    var evt = document.createEvent('CustomEvent')
    evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)
    return evt
  }

  CustomEvent.prototype = window.Event.prototype
  window.CustomEvent = CustomEvent
})()

Add a note re: CustomEvent polyfill


var uri = require('url');
var decisions = require('decisions');

function FileCredentialManager(file) {
  var settings = decisions.createSettings();
  settings.load(file);

  this._credentials = settings.toObject().credentials;
  console.log(this._credentials);
}

FileCredentialManager.prototype.get = function(options, cb) {
  if (options.url) {
    var url = uri.parse(options.url);

    options.scheme = url.protocol.slice(0, -1); // remove trailing colon
    options.authority = url.host;
    options.path = url.path;
  }

  var creds = this._credentials
    , cred, i, len;
  for (i = 0, len = creds.length; i < len; ++i) {
    cred = creds[i];

    if (options.authority != cred.authority) { continue; }
    if (options.path != cred.path) { continue; }
    return cb(null, cred.password);
  }

  return cb(new Error('No creds for: ' + options.authority));
}

module.exports = FileCredentialManager;

var uri = require('url');
var decisions = require('decisions');

function FileCredentialManager(file) {
  var settings = decisions.createSettings();
  settings.load(file);

  this._credentials = settings.toObject().credentials;
  console.log(this._credentials);
}

FileCredentialManager.prototype.get = function(options, cb) {
  console.log('GET CREDENTIALS!!!');
  console.log(options);
  //return;

  if (options.url) {
    var url = uri.parse(options.url);

    options.scheme = url.protocol.slice(0, -1); // remove trailing colon
    options.authority = url.host;
    options.path = url.path;
  }

  var creds = this._credentials
    , cred, i, len;
  for (i = 0, len = creds.length; i < len; ++i) {
    cred = creds[i];

    if (options.id && options.id == cred.id) {
      console.log('RETURN THE PASSWORD!');
      return cb(null, cred.password);
    }

    if (options.path) {
      if (options.authority != cred.authority) { continue; }
      if (options.path != cred.path) { continue; }
      return cb(null, cred.password);
    }
  }

  return cb(new Error('No creds for: ' + options.authority));
}

module.exports = FileCredentialManager;

Add find by id support.


//const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const COLLECTION_NAME = "User";

const schemaUser = new Schema({
    name: { type: String, required: true },
    email: { type: String, required: true },
    password: { type: String, required: true },
    id : {type: String, required: true },
    telephones: [{
        number: Number,
        ddd: Number
    }],
    createDate: { type: Date, default: Date },
    lastUpdate: { type: Date, default: Date }
});

let model = mongoose.model(COLLECTION_NAME, schemaUser);

module.exports = model;

Revert "teste ci broke code"


var namedTypes = {
  'NumberTypeAnnotation': 'number',
  'BooleanTypeAnnotation': 'boolean',
  'ObjectTypeAnnotation': 'Object',
  'StringTypeAnnotation': 'string'
};

var oneToOne = {
  'AnyTypeAnnotation': {
    type: 'AllLiteral'
  }
};

function flowDoctrine(type) {

  if (type.type in namedTypes) {
    return {
      type: 'NameExpression',
      name: namedTypes[type.type]
    };
  }

  if (type.type in oneToOne) {
    return oneToOne[type.type];
  }

  if (type.type === 'NullableTypeAnnotation') {
    return {
      type: 'OptionalType',
      expression: flowDoctrine(type.typeAnnotation)
    };
  }

  if (type.type === 'UnionTypeAnnotation') {
    return {
      type: 'UnionType',
      elements: type.types.map(flowDoctrine)
    };
  }

  if (type.type === 'GenericTypeAnnotation') {

    if (type.typeParameters) {
      return {
        type: 'TypeApplication',
        expression: {
          type: 'NameExpression',
          name: type.id.name
        },
        applications: type.typeParameters.params.map(flowDoctrine)
      };
    }

    return {
      type: 'NameExpression',
      name: type.id.name
    };
  }
}

module.exports = flowDoctrine;

var namedTypes = {
  'NumberTypeAnnotation': 'number',
  'BooleanTypeAnnotation': 'boolean',
  'ObjectTypeAnnotation': 'Object',
  'StringTypeAnnotation': 'string'
};

var oneToOne = {
  'AnyTypeAnnotation': {
    type: 'AllLiteral'
  }
};

var literalTypes = {
  'StringLiteralTypeAnnotation': 'StringLiteral',
  'NumberLiteralTypeAnnotation': 'NumberLiteral'
};

function flowDoctrine(type) {

  if (type.type in namedTypes) {
    return {
      type: 'NameExpression',
      name: namedTypes[type.type]
    };
  }

  if (type.type in oneToOne) {
    return oneToOne[type.type];
  }

  if (type.type === 'NullableTypeAnnotation') {
    return {
      type: 'OptionalType',
      expression: flowDoctrine(type.typeAnnotation)
    };
  }

  if (type.type === 'UnionTypeAnnotation') {
    return {
      type: 'UnionType',
      elements: type.types.map(flowDoctrine)
    };
  }

  if (type.type === 'GenericTypeAnnotation') {

    if (type.typeParameters) {
      return {
        type: 'TypeApplication',
        expression: {
          type: 'NameExpression',
          name: type.id.name
        },
        applications: type.typeParameters.params.map(flowDoctrine)
      };
    }

    return {
      type: 'NameExpression',
      name: type.id.name
    };
  }

  if (type.type in literalTypes) {
    return {
      type: literalTypes[type.type],
      name: type.value
    };
  }
}

module.exports = flowDoctrine;

Add support for Flow literal string/number types


const PythonShell = require('python-shell');

module.exports = stop => {
  return new Promise((resolve, reject) => {
    let options = {
      mode: 'json',
      scriptPath: './lib/scraper',
      args: [stop]
    };

    PythonShell.run('', options, (err, results) => {
      if (err) {
        reject(err);
      }

      if (!results[0]) {
        let err = new Error(`Can't get data for stop ${stop}.`);
        err.status = 400;
        reject(err);
      }

      resolve(results);
    });
  })
};

const PythonShell = require('python-shell');

module.exports = stop => {
  return new Promise((resolve, reject) => {
    let options = {
      mode: 'json',
      scriptPath: './lib/scraper',
      args: [stop]
    };

    PythonShell.run('', options, (err, results) => {
      let result = results[0];

      if (err) {
        reject(err);
      }

      if (!result) {
        let err = new Error(`Can't get data for stop ${stop}.`);
        err.status = 400;
        reject(err);
      }

      resolve(result);
    });
  })
};

Use first item in results array


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

router.get('/', function(req, res, next) {
  request('http://www.bikesharetoronto.com/stations/json', function(error, response, body) {
    if (!error & response.statusCode == 200) {
      data = JSON.parse(body);
    }
    console.log(data);
    res.render('map', {title: 'Map', bike_data: data});
  })
});

module.exports = router;

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

router.get('/', function(req, res, next) {
  request('http://www.bikesharetoronto.com/stations/json', function(error, response, body) {
    if (!error & response.statusCode == 200) {
      data = JSON.parse(body);
    }
    api_key = process.argv[2];
    res.render('map', {title: 'Map', api_key: api_key, bike_data: data});
  })
});

module.exports = router;

Add command line arg for Maps API key


"use strict";

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

const DHT = require('bittorrent-dht');

const redis = require("redis");
const client = redis.createClient(config.redis.port, config.redis.host, config.redis.options);

const bunyan = require("bunyan");
const logger = bunyan.createLogger({name: "crawler"});

const dht = new DHT();

dht.listen(6881, () => {
  logger.info('now listening');
  logger.info(dht.address());
});

dht.on('ready', () => {
  logger.info('now ready');
});

dht.on('announce', (peer, infoHash) => {
  logger.info(`announce : ${peer.host}:${peer.port} : ${infoHash.toString('hex')}`);
  dht.lookup(infoHash);
  client.rpush("DHTS", infoHash.toString('hex'));
});

dht.on('peer', (peer, infoHash, from) => {
  logger.info(`announce : ${peer.host}:${peer.port} : ${infoHash.toString('hex')}`);
});

dht.on('error', (err) => {
  logger.error(err);
  dht.destroy();
});

"use strict";

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

const DHT = require('bittorrent-dht');

const redis = require("redis");
const client = redis.createClient(config.redis.port, config.redis.host, config.redis.options);

const bunyan = require("bunyan");
const logger = bunyan.createLogger({name: "crawler"});

const dht = new DHT();

dht.listen(6881, () => {
  logger.info('now listening');
  logger.info(dht.address());
});

dht.on('ready', () => {
  logger.info('now ready');
});

dht.on('announce', (peer, infoHash) => {
  logger.info(`announce : ${peer.host}:${peer.port} : ${infoHash.toString('hex')}`);
  dht.lookup(infoHash);
  client.rpush("DHTS", infoHash.toString('hex'));
});

dht.on('peer', (peer, infoHash, from) => {
  logger.debug(`peer : ${peer.host}:${peer.port} : ${infoHash.toString('hex')}`);
});

dht.on('error', (err) => {
  logger.error(err);
  dht.destroy();
});

Update logging peer to debug