'use strict';

var chai = require('chai');
var expect = chai.expect;

var requireHelper = require('../../require_helper');
var Toggle = requireHelper('settings/Toggle');

describe("Toggle", function(){

	var toggle;

	beforeEach(function(){
	});

	describe("constructor", function(){

		it("should set defaults if parameters empty", function(){
			toggle = new Toggle();
			expect( toggle.isOn ).to.be.false;
			expect( toggle.storage ).to.be.undefined;
		});

		it("should set defaults from parameters", function(){
			var storage = {};
			toggle = new Toggle( true, storage );
			expect( toggle.isOn ).to.be.true;
			expect( toggle.storage ).to.equal( storage );
		});

	});

});

'use strict';

var chai = require('chai');
var expect = chai.expect;

var requireHelper = require('../../require_helper');
var Toggle = requireHelper('settings/Toggle');

describe("Toggle", function(){

	var toggle;

	describe("constructor", function(){

		it("should set defaults if parameters empty", function(){
			toggle = new Toggle();
			expect( toggle.isOn ).to.be.false;
			expect( toggle.storage ).to.be.undefined;
		});

		it("should set defaults from parameters", function(){
			var storage = {};
			toggle = new Toggle( true, storage );
			expect( toggle.isOn ).to.be.true;
			expect( toggle.storage ).to.equal( storage );
		});

	});

	describe("methods", function(){

		var storage = {};

		beforeEach(function(){
			toggle = new Toggle( true, storage );
		});

		it("should toggle state on toggle()", function(){
			expect( toggle.isOn ).to.be.true;
			toggle.toggle();
			expect( toggle.isOn ).to.be.false;
			toggle.toggle();
			expect( toggle.isOn ).to.be.true;
		});

		it("should call onchange on toggle", function(){
			var changed;
			toggle.onChange = function( newValue ){
				changed = newValue;
			}
			toggle.toggle();
			expect( changed ).to.be.false;
			toggle.toggle();
			expect( changed ).to.be.true;
		});

	});

});

Add toggle setting method tests


var Logger = require('./Logger'),
    inherits = require('inherits');

"use strict";

var ConsoleLogger = function () {
    this._console = window.console;
};

inherits(ConsoleLogger, Logger);

Logger.prototype.debug = function (data) {
    this._console.dir(data);
};

Logger.prototype.warning = function () {
    this._console.warn(data);
};

Logger.prototype.error = function (data) {
    this._console.error(data);
};

module.exports = ConsoleLogger;

var Logger = require('./Logger'),
    inherits = require('inherits');

"use strict";

var ConsoleLogger = function () {
    this._console = window.console;
};

inherits(ConsoleLogger, Logger);

ConsoleLogger.prototype.debug = function (data) {
    this._console.dir(data);
};

ConsoleLogger.prototype.warning = function () {
    this._console.warn(data);
};

ConsoleLogger.prototype.error = function (data) {
    this._console.error(data);
};

module.exports = ConsoleLogger;

Fix console logger prototype reference


'use strict';

module.exports = function(environment) {
  let ENV = {
    modulePrefix: 'dummy',
    environment,
    rootURL: '/',
    locationType: 'auto',
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. 'with-controller': true
      },
      EXTEND_PROTOTYPES: {
        // Prevent Ember Data from overriding Date.parse.
        Date: false
      }
    },

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

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

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

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

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

  if (environment === 'production') {
    // here you can enable a production-specific feature
  }

  return ENV;
};

'use strict';

module.exports = function(environment) {
  let ENV = {
    modulePrefix: 'dummy',
    environment,
    rootURL: '',
    locationType: 'hash',
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. 'with-controller': true
      },
      EXTEND_PROTOTYPES: {
        // Prevent Ember Data from overriding Date.parse.
        Date: false
      }
    },

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

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

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

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

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

  if (environment === 'production') {
    // here you can enable a production-specific feature
  }

  return ENV;
};

Make rootURL: '' and location: 'hash'


var _ = require('lodash'),
    Promise = require('bluebird'),
    util = require('../util'),
    log = util.logger();

function Campaign(marketo, connection) {
  this._marketo = marketo;
  this._connection = connection;
}

Campaign.prototype = {
  request: function(campaignId, leads, tokens, options) {
    if (!_.isArray(leads)) {
      var msg = 'leads needs to be an Array';
      log.error(msg);
      return Promise.reject(msg);
    }

    options = _.extend({}, options, {
      input: { leads: leads, tokens: tokens },
      _method: 'POST'
    });
    options = util.formatOptions(options);

    return this._connection.post(util.createPath('campaigns',campaignId,'trigger.json'),
	{data: JSON.stringify(options), headers: {'Content-Type': 'application/json'}});
  },
  getCampaigns: function(options) {
    var path = util.createPath( 'campaigns.json' );
    options = _.extend({}, options, {
      _method: 'GET'
    });
    return this._connection.get(path, {data: options});
  },

};

module.exports = Campaign;

var _ = require('lodash'),
    Promise = require('bluebird'),
    util = require('../util'),
    log = util.logger();

function Campaign(marketo, connection) {
  this._marketo = marketo;
  this._connection = connection;
}

Campaign.prototype = {
  request: function(campaignId, leads, tokens, options) {
    if (!_.isArray(leads)) {
      var msg = 'leads needs to be an Array';
      log.error(msg);
      return Promise.reject(msg);
    }

    options = _.extend({}, options, {
      input: { leads: leads, tokens: tokens },
      _method: 'POST'
    });
    options = util.formatOptions(options);

    return this._connection.post(util.createPath('campaigns',campaignId,'trigger.json'),
	{data: JSON.stringify(options), headers: {'Content-Type': 'application/json'}});
  },
  getCampaigns: function(options) {
    var path = util.createPath( 'campaigns.json' );
    options = _.extend({}, options, {
      _method: 'GET'
    });
    return this._connection.get(path, {data: options});
  },
  getSmartCampaigns: function(options) {
    var path = util.createAssetPath( 'smartCampaigns.json' );
    options = _.extend({}, options, {
      _method: 'GET'
    });
    return this._connection.get(path, {query: options});
  },
};

module.exports = Campaign;

Add support for new(er) smartCampaigns endpoints.


"use strict";

var _ = require('lodash'),
    iframePhone = require('iframe-phone'),
    EMBED_FLAG = 'itsi_embed',
    QUERY_SUFFIX = EMBED_FLAG + '=true';

var ItsiEmbed = function() {
    this.phone = new iframePhone.getIFrameEndpoint();

    this.url = window.location.href + '?' + QUERY_SUFFIX;

    this.setLearnerUrl = function(url) {
        if (url) {
            this.url = url + (url.indexOf('?') > 0 ? '&' : '?') + QUERY_SUFFIX;
        }

        this.phone.post('setLearnerUrl', this.url);
    };

    this.phone.addListener('getLearnerUrl', _.bind(this.setLearnerUrl, this));
    this.phone.initialize();
};

module.exports = {
    ItsiEmbed: ItsiEmbed
};

"use strict";

var _ = require('lodash'),
    iframePhone = require('iframe-phone'),
    EMBED_FLAG = 'itsi_embed',
    QUERY_SUFFIX = EMBED_FLAG + '=true';

var ItsiEmbed = function() {
    this.phone = new iframePhone.getIFrameEndpoint();

    this.url = window.location.href + '?' + QUERY_SUFFIX;

    this.interactiveState = { url: this.url };

    this.setLearnerUrl = function(url) {
        if (url) {
            this.url = url + (url.indexOf('?') > 0 ? '&' : '?') + QUERY_SUFFIX;
            this.interactiveState = { url: this.url };
        }

        this.phone.post('setLearnerUrl', this.url);
        this.phone.post('interactiveState', this.interactiveState);
    };

    this.phone.addListener('getLearnerUrl', _.bind(this.setLearnerUrl, this));
    this.phone.addListener('getInteractiveState', _.bind(this.setLearnerUrl, this));
    this.phone.initialize();
};

module.exports = {
    ItsiEmbed: ItsiEmbed
};

Save Interactive State in addition to URL


/*
 * @module fluent-react
 * @overview
 *

 * `fluent-react` provides React bindings for Fluent.  It takes advantage of
 * React's Components system and the virtual DOM.  Translations are exposed to
 * components via the provider pattern.
 *
 *     <LocalizationProvider bundles={…}>
 *         <Localized id="hello-world">
 *             <p>{'Hello, world!'}</p>
 *         </Localized>
 *     </LocalizationProvider>
 *
 * Consult the documentation of the `LocalizationProvider` and the `Localized`
 * components for more information.
 */

export { default as FluentContext } from "./context";
export { default as LocalizationProvider } from "./provider";
export { default as withLocalization } from "./with_localization";
export { default as Localized } from "./localized";

/*
 * @module fluent-react
 * @overview
 *

 * `fluent-react` provides React bindings for Fluent.  It takes advantage of
 * React's Components system and the virtual DOM.  Translations are exposed to
 * components via the provider pattern.
 *
 *     <LocalizationProvider bundles={…}>
 *         <Localized id="hello-world">
 *             <p>{'Hello, world!'}</p>
 *         </Localized>
 *     </LocalizationProvider>
 *
 * Consult the documentation of the `LocalizationProvider` and the `Localized`
 * components for more information.
 */

export { default as LocalizationProvider } from "./provider";
export { default as withLocalization } from "./with_localization";
export { default as Localized } from "./localized";

Revert "Expose FluentContext as public API"


import { mount } from '@vue/test-utils'
import AnnotationBar from '../../src/components/pages/playlists/AnnotationBar'

describe('AnnotationBar', () => {
  const wrapper = mount(AnnotationBar)
  test('should mount for testing', () => {
    expect(1).toEqual(1)
  })
})

import { mount } from '@vue/test-utils'
import AnnotationBar from '../../src/components/pages/playlists/AnnotationBar'

describe('AnnotationBar', () => {
  const wrapper = mount(AnnotationBar, {
    propsData: {
      annotations: [
        { time: 10 },
        { time: 20 },
      ],
      maxDurationRaw: 100,
      width: 100
    }
  })

  describe('Mount', () => {
    test('Ensure marks are there', () => {
      console.log('toto')
      const marks = wrapper.findAll('.annotation-mark')
      expect(marks.length).toEqual(2)
      expect(marks.at(0).element.style.left).toEqual('7px')
    })
  })

  describe('Methods', () => {
    test('getAnnotationPosition', () => {
      let position = wrapper.vm.getAnnotationPosition({ time: 10 })
      expect(position).toEqual(7)
      position = wrapper.vm.getAnnotationPosition({ time: 20 })
      expect(position).toEqual(17)
    })
  })
})

Add tests for annotation bar widget


/*******************************************************************************
 * @license
 * Copyright (c) 2012 VMware, Inc. All Rights Reserved.
 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
 * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
 * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
 * You can obtain a current copy of the Eclipse Public License from
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * Contributors:
 *     Kris De Volder - initial API and implementation
 ******************************************************************************/

/*global require define console module setTimeout XMLHttpRequest */
if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
define(function(require, exports, module) {

	var basePath = '/jsdepend';

	var makeServletStub = require('./stub-maker').makeServletStub;

	//TODO: This information is repeated between client and server code...
	// it shouldn't be.
	var signatures = {
		getDependencies: ['JSON', 'callback'],
		getTransitiveDependencies: ['JSON', 'callback'],
		getContents: ['JSON', 'callback', 'errback'],
		findFileNamesContaining: ['JSON', 'JSON', 'callback', 'errback'],
		getDGraph: ['JSON', 'callback']
	};

	var expectedSig = JSON.stringify(['JSON', 'callback', 'errback']);

	for (var functionName in signatures) {
		if (signatures.hasOwnProperty(functionName)) {
			exports[functionName] = makeServletStub(basePath+'/'+functionName, signatures[functionName]);
		}
	}
});

/*******************************************************************************
 * @license
 * Copyright (c) 2012 VMware, Inc. All Rights Reserved.
 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
 * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
 * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
 * You can obtain a current copy of the Eclipse Public License from
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * Contributors:
 *     Kris De Volder - initial API and implementation
 ******************************************************************************/

/*global require define console module setTimeout XMLHttpRequest */
if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
define(function(require, exports, module) {

	var basePath = '/jsdepend';

	var makeServletStub = require('./stub-maker').makeServletStub;

	//TODO: This information is repeated between client and server code...
	// it shouldn't be.
	var signatures = {
		getDependencies: ['JSON', 'callback'],
		getTransitiveDependencies: ['JSON', 'callback'],
		getContents: ['JSON', 'callback', 'errback'],
		findFileNamesContaining: ['JSON', 'JSON', 'callback', 'errback'],
		getDGraph: ['JSON', 'callback'],
		getConf: ['JSON', 'callback']
	};

	for (var functionName in signatures) {
		if (signatures.hasOwnProperty(functionName)) {
			exports[functionName] = makeServletStub(basePath+'/'+functionName, signatures[functionName]);
		}
	}
});

Add client side stub to call dot-scripted module in the server.


var helpers = require("../helpers")

describe('Security', function() {
    it("Initializes a (hopefully secret) cookie and navigates to the security test page", function(){
        browser.ignoreSynchronization = true;
        browser.get("http://localhost:9855/init")
        helpers.waitForEl("#confirm-cookie")

        browser.get("http://localhost:9856/src/e2e/security/security.html#auto-activate-fromjs")
        // browser.pause();
        return browser.driver.wait(function(){
           return browser.executeScript(function(){
               console.log("Waiting fo f__StringLiteral")
               return window.f__StringLiteral !== undefined
           }).then(function(r){
               return r
           })
       }).then(helpers.waitForEl("#security-done"))
        .then(function(){
            var getInnerHtml = function(){
                return "" + document.querySelector("#result").innerHTML
            }
            browser.executeScript(getInnerHtml).then(function (resultHtml) {
                expect(resultHtml.indexOf("FAILED")).toBe(-1)
            });
        })
        .catch(function(){
            console.log("FAIL")
        })
    })
});

var helpers = require("../helpers")

describe('Security', function() {
    it("Initializes a (hopefully secret) cookie and navigates to the security test page", function(){
        browser.ignoreSynchronization = true;
        browser.get("http://localhost:9855/init")
        helpers.waitForEl("#confirm-cookie")

        browser.get("http://localhost:9856/src/e2e/security/security.html#auto-activate-fromjs")
        // browser.pause();
        return browser.driver.wait(function(){
           return browser.executeScript(function(){
               console.log("Waiting fo f__StringLiteral")
               return window.f__StringLiteral !== undefined
           }).then(function(r){
               return r
           })
       }).then(helpers.waitForEl("#security-done"))
        .then(function(){
            var getInnerHtml = function(){
                return "" + document.querySelector("#result").innerHTML
            }
            browser.executeScript(getInnerHtml).then(function (resultHtml) {
                expect(resultHtml.indexOf("FAILED")).toBe(-1)
            });
        })
    })
});

Remove console log that never hits anyway.


/**
 * Archive
 * @return {Archive}
 */
function Archive() {

  if( !(this instanceof Archive) )
    return new Archive()

  // this.directory = new Zip.CentralDirectory()
  this.records = []

}

/**
 * Zip Archive File
 * @type {Function}
 */
Archive.File = require( './file' )

/**
 * Archive prototype
 * @type {Object}
 */
Archive.prototype = {

  constructor: Archive,

  get isEmpty() {},

  add: function( file ) {},
  extract: function( file, dest ) {},
  replace: function( oldFile, newFile ) {},
  remove: function( file ) {},
  partition: function( partMap ) {},

}

// Exports
module.exports = Archive

var Zip = require( '../zip' )

/**
 * Archive
 * @return {Archive}
 */
function Archive() {

  if( !(this instanceof Archive) )
    return new Archive()

  this.directory = new Zip.CentralDirectory()
  this.records = []

}

/**
 * Zip Archive File
 * @type {Function}
 */
Archive.File = require( './file' )

/**
 * Archive prototype
 * @type {Object}
 */
Archive.prototype = {

  constructor: Archive,

  get isEmpty() {},

  add: function( file ) {},
  extract: function( file, dest ) {},
  replace: function( oldFile, newFile ) {},
  remove: function( file ) {},
  partition: function( partMap ) {},

}

// Exports
module.exports = Archive

Update lib/archive: Enable central directory


const $ = require('cheerio');
const Promise = require('bluebird');
const drive = require('../drive');
const get = require('../get');
const textTemplate = require('../textTemplate');

const url = 'http://yle.fi/uutiset/osasto/news/';

const randomItem = ar => (ar[Math.floor(Math.random() * ar.length)]);

module.exports = {
  id: 'news',
  getText: () => Promise.all([
    get(url),
    drive.getContent('news', ['prefix']),
  ])
    .then((res) => {
      const doc = res[0];
      const randomPrefix = randomItem(res[1].prefix);
      const articles = $('section.recommends > article', doc);
      const randomArticle = randomItem(articles);
      const articleHeader = $('a > h1', randomArticle).text();
      const newsText = `${textTemplate(randomPrefix)} ${articleHeader}.`;

      return Promise.resolve(newsText);
    }),
};

const $ = require('cheerio');
const Promise = require('bluebird');
const drive = require('../drive');
const get = require('../get');
const textTemplate = require('../textTemplate');

const url = 'http://yle.fi/uutiset/osasto/news/';

const randomItem = ar => (ar[Math.floor(Math.random() * ar.length)]);

module.exports = {
  id: 'news',
  getText: () => Promise.all([
    get(url),
    drive.getContent('news', ['prefix']),
  ])
    .then((res) => {
      const doc = res[0];
      const randomPrefix = randomItem(res[1].prefix);
      const articles = $('section.recommends > article', doc);
      const randomArticle = randomItem(articles);
      const articleHeader = $('a > h1', randomArticle).text().trim();
      const newsText = `${textTemplate(randomPrefix)} ${articleHeader}.`;

      return Promise.resolve(newsText);
    }),
};

Trim for news headline newlines


/*global Uint8Array*/
var exifParser = require('exif-parser'),
    fs = require('fs');

module.exports = {
    name: 'unexpected-exif',
    installInto: function (expect) {
        expect.installPlugin(require('magicpen-media'));

        expect.addAssertion(['string', 'Buffer'], 'to have (exif|EXIF) data satisfying', function (expect, subject, value) {
            var title,
                subjectUrl;
            if (typeof subject === 'string') {
                var matchDataUrl = subject.match(/^data:[^;]*;base64,(.*)$/);
                if (matchDataUrl) {
                    subject = new Buffer(matchDataUrl[1], 'base64');
                } else {
                    title = subject;
                    subjectUrl = subject;
                    subject = fs.readFileSync(subject);
                }
            } else if (subject instanceof Uint8Array) {
                subject = new Buffer(subject);
            }

            this.subjectOutput = function () {
                this.image(subjectUrl || subject, { width: 10, height: 5, link: true, title: title });
            };

            return expect(exifParser.create(subject).parse(), 'to satisfy', value);
        });
    }
};

/*global Uint8Array*/
var exifParser = require('exif-parser'),
    fs = require('fs');

module.exports = {
    name: 'unexpected-exif',
    version: require('../package.json').version,
    installInto: function (expect) {
        expect.installPlugin(require('magicpen-media'));

        expect.addAssertion(['string', 'Buffer'], 'to have (exif|EXIF) data satisfying', function (expect, subject, value) {
            var title,
                subjectUrl;
            if (typeof subject === 'string') {
                var matchDataUrl = subject.match(/^data:[^;]*;base64,(.*)$/);
                if (matchDataUrl) {
                    subject = new Buffer(matchDataUrl[1], 'base64');
                } else {
                    title = subject;
                    subjectUrl = subject;
                    subject = fs.readFileSync(subject);
                }
            } else if (subject instanceof Uint8Array) {
                subject = new Buffer(subject);
            }

            this.subjectOutput = function () {
                this.image(subjectUrl || subject, { width: 10, height: 5, link: true, title: title });
            };

            return expect(exifParser.create(subject).parse(), 'to satisfy', value);
        });
    }
};

Include the version number in the plugin spec.


#ifndef __DOMAIN_MANAGER__
#define __DOMAIN_MANAGER__

#include "lib/common.js"
#include "data/suffix-list.js"

rndphrase.DomainManager = {
    get_reg_domain: function(rules, doms) {
        var node = rules[doms[0]];
        if(node == undefined) node = rules['*'];
        if(node == undefined || (node.L==1 && node['!'] == 1)) {
            return doms[0];
        } else if (node.L == 1) return node;
        var dom = this.get_reg_domain(node, doms.splice(1));
        if(dom != undefined)
            return dom + '.' + doms[0];
        return undefined;
    },
    get_host: function(domain) {
        var doms = domain.split('.').reverse();
        return this.get_reg_domain(SUFFIX_LIST, doms);
    }
};

#endif

#ifndef __DOMAIN_MANAGER__
#define __DOMAIN_MANAGER__

#include "lib/common.js"
#include "data/suffix-list.js"

rndphrase.DomainManager = {
    get_reg_domain: function(rules, doms) {
        var node = rules[doms[0]];
        if(node == undefined) node = rules['*'];
        if(node == undefined || (node.L==1 && node['!'] == 1)) {
            return doms[0];
        } else if (node.L == 1) return node;
        var dom = this.get_reg_domain(node, doms.splice(1));
        if(dom != undefined)
            return dom + '.' + doms[0];
        return undefined;
    },
    get_host: function(domain) {
        // Try to use Firefox' built in list
        var eTLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"]
                  .getService(Components.interfaces.nsIEffectiveTLDService);
        if(eTLDService) {
            dumpln("Using eTLDService.");
            return eTLDService.getBaseDomainFromHost(domain);
        }
        // Fall back to own list
        var doms = domain.split('.').reverse();
        return this.get_reg_domain(SUFFIX_LIST, doms);
    }
};

#endif

Use built in public suffix list in Firefox-based browsers


module.exports = {
  config: {
    fontSize: 13,
    fontFamily: '"Operator Mono", "Fira Code", Monoid, Menlo, "DejaVu Sans Mono", "Lucida Console", monospace',
    css: `
      header {
        box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.17);
      }

      .hyperterm_main {
        border-color: transparent !important;
      }
    `,
    termCSS: `
      x-row > span {
      }
    `,
    padding: '0'
  },

  plugins: [
    'hyperterm-adventurous',
    'hyperterm-title',
    'hyperterm-focus-reporting'
  ],

  // `~/.hyperterm_plugins/local/`
  localPlugins: []
};

module.exports = {
  config: {
    fontSize: 12,
    fontFamily: '"Fira Code", Monoid, Menlo, "DejaVu Sans Mono", "Lucida Console", monospace, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',
    css: `
      header {
        box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.17);
      }

      .hyperterm_main {
        border-color: transparent !important;
      }
    `,
    termCSS: `
      x-row > span {
      }
    `,
    padding: '0'
  },

  plugins: [
    'hyperterm-adventurous',
    'hyperterm-title',
    'hyperterm-focus-reporting'
  ],

  // `~/.hyperterm_plugins/local/`
  localPlugins: []
};

Use Fira Code again in Hyper


/* global ftUtils, moment */
'use strict';

var app = angular.module('flowList', ['ui.grid']);

app.controller('flowListCtrl', function($scope, $http) {
    $http.get('/json/rawFlowsForLast/5/minutes')
        .success(function(data, status, headers, config) {

            var retList = [];
            data.hits.hits.forEach(function(element, index, array) {
                var flowRecord = {
                    Src_Address: ftUtils.inet_ntoa(element._source.ipv4_src_addr),
                    Dst_Address: ftUtils.inet_ntoa(element._source.ipv4_dst_addr),
                    Packets: element._source.in_pkts,
                    Bytes: element._source.in_bytes,
                    Time: moment(element._source.timestamp).format('YYYY-MM-DD HH:mm:ss')
                };
                retList.push(flowRecord);
            });
            $scope.flows = retList;
        })
        .error(function(data, status, headers) {
            console.warn('doh');
        });
});

/* global ftUtils, moment */

var app = angular.module('flowList', ['ui.grid']);

app.controller('flowListCtrl', function($scope, $http) {
    'use strict';
    $http.get('/json/rawFlowsForLast/5/minutes')
        .success(function(data, status, headers, config) {

            var retList = [];
            data.hits.hits.forEach(function(element, index, array) {
                var flowRecord = {
                    Src_Address: ftUtils.inet_ntoa(element._source.ipv4_src_addr),
                    Dst_Address: ftUtils.inet_ntoa(element._source.ipv4_dst_addr),
                    Packets: element._source.in_pkts,
                    Bytes: element._source.in_bytes,
                    Time: moment(element._source.timestamp).format('YYYY-MM-DD HH:mm:ss')
                };
                retList.push(flowRecord);
            });
            $scope.flows = retList;
        })
        .error(function(data, status, headers) {
            console.warn('doh');
        });
});

Move strict inside for browser use


'use strict';

var micromatch = require('micromatch');
var arrify = require('arrify');

var anymatch = function(criteria, value, returnIndex, startIndex, endIndex) {
  criteria = arrify(criteria);
  value = arrify(value);
  if (arguments.length === 1) {
    return criteria.length === 1 ?
      micromatch.matcher(criteria[0]) :
      anymatch.bind(null, criteria.map(function(criterion) {
        return micromatch.matcher(criterion);
      }));
  }
  startIndex = startIndex || 0;
  var string = value[0];
  var matchIndex = -1;
  function testCriteria (criterion, index) {
    var result;
    switch (toString.call(criterion)) {
    case '[object String]':
      result = string === criterion || micromatch.isMatch(string, criterion);
      break;
    case '[object RegExp]':
      result = criterion.test(string);
      break;
    case '[object Function]':
      result = criterion.apply(null, value);
      break;
    default:
      result = false;
    }
    if (result) { matchIndex = index + startIndex; }
    return result;
  }
  var matched = criteria.slice(startIndex, endIndex).some(testCriteria);
  return returnIndex === true ? matchIndex : matched;
};

module.exports = anymatch;

'use strict';

var micromatch = require('micromatch');
var arrify = require('arrify');

var anymatch = function(criteria, value, returnIndex, startIndex, endIndex) {
  criteria = arrify(criteria);
  value = arrify(value);
  if (arguments.length === 1) {
    return anymatch.bind(null, criteria.map(function(criterion) {
      return typeof criterion === 'string' ?
        micromatch.matcher(criterion) : criterion;
    }));
  }
  startIndex = startIndex || 0;
  var string = value[0];
  var matchIndex = -1;
  function testCriteria (criterion, index) {
    var result;
    switch (toString.call(criterion)) {
    case '[object String]':
      result = string === criterion || micromatch.isMatch(string, criterion);
      break;
    case '[object RegExp]':
      result = criterion.test(string);
      break;
    case '[object Function]':
      result = criterion.apply(null, value);
      break;
    default:
      result = false;
    }
    if (result) { matchIndex = index + startIndex; }
    return result;
  }
  var matched = criteria.slice(startIndex, endIndex).some(testCriteria);
  return returnIndex === true ? matchIndex : matched;
};

module.exports = anymatch;

Use micromatch.matcher on strings only


var mongoose = require('mongoose'),
	uuid = require('uuid/v1'),
	Cards = require('./CardsModel'),
	Schema = mongoose.Schema,
	PlayerSchema = new Schema({
		sessionId: {
			type: String,
			required: true,
			select: false
		},
		name: {
			type: String,
			required: true,
			trim: true
		},
		img: String,
		isActive: {
			type: Boolean,
			default: false
		},
		score: {
			type: Number,
			default: 0
		},
		cardsInHand: {
			type: [Schema.Types.ObjectId],
			ref: Cards.model,
			select: false
		},
		cardsUsed: {
			type: [Schema.Types.ObjectId],
			ref: Cards.model
		}
	}, {
		collection: 'players',
		timestamps: true
	});

const log = require('loggy');

PlayerSchema.set('toJSON', {
	transform: function(doc, ret, options) {
		delete ret._id;
		return ret;
	},
	virtuals: true
});

module.exports = {
	schema: PlayerSchema,
	model: mongoose.model('Player', PlayerSchema)
};

var mongoose = require('mongoose'),
	uuid = require('uuid/v1'),
	Card = require('./CardModel'),
	Schema = mongoose.Schema,
	PlayerSchema = new Schema({
		sessionId: {
			type: String,
			required: true,
			select: false
		},
		name: {
			type: String,
			required: true,
			trim: true
		},
		img: String,
		isActive: {
			type: Boolean,
			default: false
		},
		score: {
			type: Number,
			default: 0
		},
		cardsInHand: {
			type: [Schema.Types.ObjectId],
			ref: Card.model,
			select: false
		},
		cardsUsed: {
			type: [Schema.Types.ObjectId],
			ref: Card.model
		}
	}, {
		collection: 'players',
		timestamps: true
	});

const log = require('loggy');

PlayerSchema.set('toJSON', {
	transform: function(doc, ret, options) {
		delete ret._id;
		return ret;
	},
	virtuals: true
});

module.exports = {
	schema: PlayerSchema,
	model: mongoose.model('Player', PlayerSchema)
};

Update reference to CardModel after file was renamed


/*!
 * tweensy - Copyright (c) 2017 Jacob Buck
 * https://github.com/jacobbuck/tweensy
 * Licensed under the terms of the MIT license.
 */
import now from "performance-now";
import rafq from "rafq";

const queue = rafq();

const defaultOptions = {
  duration: 0,
  easing: t => t,
  from: 0,
  onComplete: () => {},
  onProgress: () => {},
  to: 1,
};

const tween = instanceOptions => {
  const options = {
    ...defaultOptions,
    ...instanceOptions,
  };
  const fromToMultiplier = options.to - options.from + options.from;
  let isFinished = false;
  let startTime = null;

  const tick = () => {
    const time = now();

    if (!startTime) {
      startTime = time;
    }

    var progress = isFinished
      ? 1
      : Math.min((time - startTime) / options.duration, 1);

    options.onProgress(options.easing(progress) * fromToMultiplier);

    if (progress === 1) {
      options.onComplete(time);
    } else {
      queue.add(tick);
    }
  };

  const stop = finish => {
    isFinished = true;

    if (!finish) {
      queue.remove(tick);
    }
  };

  tick();

  return stop;
};

/*!
 * tweensy - Copyright (c) 2017 Jacob Buck
 * https://github.com/jacobbuck/tweensy
 * Licensed under the terms of the MIT license.
 */
import now from "performance-now";
import rafq from "rafq";

const queue = rafq();

const defaultOptions = {
  duration: 0,
  easing: t => t,
  from: 0,
  onComplete: () => {},
  onProgress: () => {},
  to: 1,
};

const tween = instanceOptions => {
  const options = {
    ...defaultOptions,
    ...instanceOptions,
  };
  let isFinished = false;
  let startTime = null;

  const tick = () => {
    const time = now();

    if (!startTime) {
      startTime = time;
    }

    var progress = isFinished
      ? 1
      : Math.min((time - startTime) / options.duration, 1);

    options.onProgress(
      options.easing(progress) * (options.to - options.from) + options.from
    );

    if (progress === 1) {
      options.onComplete(time);
    } else {
      queue.add(tick);
    }
  };

  const stop = finish => {
    isFinished = true;

    if (!finish) {
      queue.remove(tick);
    }
  };

  tick();

  return stop;
};

Remove fromToMultiplier and fix up lerp logic


'use strict';

/**
 * Dependencies.
 */

var phonetics;

phonetics = require('soundex-code');

/**
 * Change handler
 *
 * @this {WordNode}
 */

function onchange() {
    var data,
        value;

    data = this.data;
    value = this.toString();

    data.phonetics = value ? phonetics(value, Infinity) : null;

    if ('stem' in data) {
        data.stemmedPhonetics = value ? phonetics(data.stem, Infinity) : null;
    }
}

/**
 * Define `soundex`.
 *
 * @param {Retext} retext
 */

function soundex(retext) {
    var WordNode;

    WordNode = retext.TextOM.WordNode;

    WordNode.on('changetextinside', onchange);
    WordNode.on('removeinside', onchange);
    WordNode.on('insertinside', onchange);
}

/**
 * Expose `soundex`.
 */

module.exports = soundex;

'use strict';

/**
 * Dependencies.
 */

var phonetics;

phonetics = require('soundex-code');

/**
 * Change handler
 *
 * @this {WordNode}
 */

function onchange() {
    var data,
        value;

    data = this.data;
    value = this.toString();

    data.phonetics = value ? phonetics(value, Infinity) : null;

    if ('stem' in data) {
        data.stemmedPhonetics = value ? phonetics(data.stem, Infinity) : null;
    }
}

/**
 * Define `soundex`.
 *
 * @param {Retext} retext
 */

function soundex(retext) {
    retext.TextOM.WordNode.on('changeinside', onchange);
}

/**
 * Expose `soundex`.
 */

module.exports = soundex;

Refactor to use generic `changeinside` in new retext


'use strict';

var dir = './lib';
if (process.env.COVERAGE){
  dir = './lib-cov';
}

var M = require(dir);

if (typeof window !== 'undefined') {
    var _M = window.M;
    window.M = M;
    M.noConflict = function () {
        window.M = _M;
        return M;
    };
}
if (typeof module !== 'undefined') {
    module.exports = M;
}

'use strict';

var M = require('./lib');
if (process.env.COVERAGE){
  var dir = './lib-cov';
  M = require(dir);
}

if (typeof window !== 'undefined') {
    var _M = window.M;
    window.M = M;
    M.noConflict = function () {
        window.M = _M;
        return M;
    };
}
if (typeof module !== 'undefined') {
    module.exports = M;
}

Fix lib-cov require when using browserify


'use strict'

const crypto = require('crypto')

// Delimeter to separate object items form each other
// when stringifying
const DELIM = '|'

/**
 * Stringifies a JSON object (not any randon JS object).
 *
 * It should be noted that JS objects can have members of
 * specific type (e.g. function), that are not supported
 * by JSON.
 *
 * @param {Object} obj JSON object
 * @returns {String} stringified JSON object.
 */
function stringify (obj) {
  if (Array.isArray(obj)) {
    return JSON.stringify(obj.map(i => stringify(i)))
  } else if (typeof obj === 'object' && obj !== null) {
    return Object.keys(obj)
      .sort()
      .map(k => `${k}:${stringify(obj[k])}`)
      .join(DELIM)
  }

  return obj
}

/**
 * Creates hash of given JSON object.
 *
 * @param {Object} obj JSON object
 * @param {String} hashAlgorithm hash algorithm (e.g. SHA256)
 * @param {String} encoding hash encoding (e.g. base64) or none for buffer
 * @see #stringify
 */
function digest (obj, hashAlgorithm, encoding) {
  let hash = crypto.createHash(hashAlgorithm)
  return hash.update(stringify(obj)).digest(encoding)
}

module.exports = {
  stringify: stringify,
  digest: digest
}

'use strict'

const crypto = require('crypto')

// Delimeter to separate object items form each other
// when stringifying
const DELIM = '|'

/**
 * Stringifies a JSON object (not any randon JS object).
 *
 * It should be noted that JS objects can have members of
 * specific type (e.g. function), that are not supported
 * by JSON.
 *
 * @param {Object} obj JSON object
 * @returns {String} stringified JSON object.
 */
function stringify (obj) {
  if (Array.isArray(obj)) {
    let stringifiedArr = []
    for (let i = 0; i < obj.length; i++) {
      stringifiedArr[i] = stringify(obj[i])
    }

    return JSON.stringify(stringifiedArr)
  } else if (typeof obj === 'object' && obj !== null) {
    let acc = []
    let sortedKeys = Object.keys(obj).sort()

    for (let i = 0; i < sortedKeys.length; i++) {
      let k = sortedKeys[i]
      acc[i] = `${k}:${stringify(obj[k])}`
    }

    return acc.join(DELIM)
  }

  return obj
}

/**
 * Creates hash of given JSON object.
 *
 * @param {Object} obj JSON object
 * @param {String} hashAlgorithm hash algorithm (e.g. SHA256)
 * @param {String} encoding hash encoding (e.g. base64) or none for buffer
 * @see #stringify
 */
function digest (obj, hashAlgorithm, encoding) {
  let hash = crypto.createHash(hashAlgorithm)
  return hash.update(stringify(obj)).digest(encoding)
}

module.exports = {
  stringify: stringify,
  digest: digest
}

Replace maps with fors to improve performance.


import React from 'react';
import AutocompleteProvider from './AutocompleteProvider';
import Q from 'q';
import {emojioneList, shortnameToImage, shortnameToUnicode} from 'emojione';
import Fuse from 'fuse.js';

const EMOJI_REGEX = /:\w*:?/g;
const EMOJI_SHORTNAMES = Object.keys(emojioneList);

let instance = null;

export default class EmojiProvider extends AutocompleteProvider {
    constructor() {
        super(EMOJI_REGEX);
        this.fuse = new Fuse(EMOJI_SHORTNAMES);
    }

    getCompletions(query: string, selection: {start: number, end: number}) {
        let completions = [];
        let {command, range} = this.getCurrentCommand(query, selection);
        if (command) {
            completions = this.fuse.search(command[0]).map(result => {
                let shortname = EMOJI_SHORTNAMES[result];
                let imageHTML = shortnameToImage(shortname);
                return {
                    completion: shortnameToUnicode(shortname),
                    component: (

                             {shortname}

                    ),
                    range,
                };
            }).slice(0, 4);
        }
        return Q.when(completions);
    }

    getName() {
        return 'Emoji';
    }

    static getInstance() {
        if (instance == null)
            instance = new EmojiProvider();
        return instance;
    }
}

Add max-width to emoji completions.


var lint = require('./lint');
var clean = require('./clean');
var copy = require('./copy');

var runSequence = require('run-sequence');

exports.config = function(gulp, debugTask, releaseTask) {
	lint.config(gulp);
	clean.config(gulp);
	copy.config(gulp);

	gulp.task('build', ['build.debug']);

	gulp.task('build.debug', function(done) {
		runSequence('lint',
					'clean.debug',
					debugTask,
					'copy.debug',
					done);
	});

	gulp.task('build.release', function(done) {
		runSequence('lint',
					'clean.release',
					releaseTask,
					'copy.release',
					done);
	});
};

var lint = require('./lint');
var clean = require('./clean');
var copy = require('./copy');

var runSequence = require('run-sequence');

exports.config = function(gulp, debugTask, releaseTask, useLint) {
	lint.config(gulp);
	clean.config(gulp);
	copy.config(gulp);

	gulp.task('build', ['build.debug']);

	gulp.task('build.debug', function(done) {
		if (useLint) {
			runSequence('lint',
						'clean.debug',
						debugTask,
						'copy.debug',
						done);
		} else {
			runSequence('clean.debug',
						debugTask,
						'copy.debug',
						done);
		}
	});

	gulp.task('build.release', function(done) {
		if (useLint) {
			runSequence('lint',
						'clean.release',
						releaseTask,
						'copy.release',
						done);
		} else {
			runSequence('clean.release',
						releaseTask,
						'copy.release',
						done);
		}
	});
};

Allow lint to be disabled since it does not yet support ES6 modules.


/**
 * ASCII book generator methods, for implementing gpub.book.Gen
 * interface.
 */
gpub.book.ascii.generator = {
  generate: function(spec) {
    var view = this.options().bookOptions;
    var content = [];
    this.forEachSgf(spec, function(mt, flattened) {

    });
  },

  defaultTemplate: function() {
    return gpub.book.ascii._defaultTemplate;
  },

  defaultOptions: function(opts) {
    return {
      diagramType: gpub.diagrams.diagramType.ASCII
    }
  }
};

/**
 * ASCII book generator methods, for implementing gpub.book.Gen
 * interface.
 */
gpub.book.ascii.generator = {
  generate: function(spec) {
    var view = this.options().bookOptions;
    var content = [];
    this.forEachSgf(spec, function(mt, flattened) {

    });
  },

  defaultTemplate: function() {
    return gpub.book.ascii._defaultTemplate;
  },

  defaultOptions: function(opts) {
    return {
      diagramType: gpub.diagrams.diagramType.SENSEIS_ASCII;
    }
  }
};

Change default diagramType for ASCII to SENSEIS_ASCII


/**
 * @file Selection Colormaker
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @private
 */

import { Color } from "../../lib/three.es6.js";

import Selection from "../selection.js";
import Colormaker from "./colormaker.js";

class SelectionColormaker extends Colormaker{

    constructor( params ){

        super( params );

        this.pairList = params.pairList || [];

        this.colorList = [];
        this.selectionList = [];

        this.pairList.forEach( pair => {
            this.colorList.push( new Color( pair[ 0 ] ).getHex() );
            this.selectionList.push( new Selection( pair[ 1 ] ) );
        } );

    }

    atomColor( a ){
        for( var i = 0, n = this.pairList.length; i < n; ++i ){
            if( this.selectionList[ i ].test( a ) ){
                return this.colorList[ i ];
            }
        }
        return 0xFFFFFF;
    }

}

export default SelectionColormaker;

/**
 * @file Selection Colormaker
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @private
 */

import { Color } from "../../lib/three.es6.js";

import Selection from "../selection.js";
import Colormaker from "./colormaker.js";
import { ColormakerRegistry } from "../globals.js";

class SelectionColormaker extends Colormaker{

    constructor( params ){

        super( params );

        this.pairList = params.pairList || [];

        this.colorList = [];
        this.selectionList = [];

        this.schemesList = ColormakerRegistry.getSchemes();

        this.pairList.forEach( pair => {
            let schemeProperties = ( this.schemesList.hasOwnProperty( pair[ 0 ] ) )?
                {
                    scheme: this.schemesList[ pair[ 0 ] ],
                    structure: this.structure,
                    value: 0x909090
                }
                :
                {
                    scheme: 'uniform',
                    value: new Color( pair[ 0 ] ).getHex()
                };

            let param = pair[2] || {};
            Object.assign( schemeProperties, param )

            this.colorList.push( ColormakerRegistry.getScheme( schemeProperties ) );

            this.selectionList.push( new Selection( pair[ 1 ] ) );
        } );

    }

    atomColor( a ){

        for( var i = 0, n = this.pairList.length; i < n; ++i ){
            if( this.selectionList[ i ].test( a ) ){
                return this.colorList[ i ].atomColor( a );
            }
        }
        return 0xFFFFFF;
    }

}

export default SelectionColormaker;

Add color schemes to color selection options


'use strict';

module.exports = function (actions, context) {
  return input => {
    const promise = new Promise(resolve => resolve(input));

    return decoratePromise(promise, actions);
  }
};

function decoratePromise(promise, actions) {
  Object.keys(actions).forEach(name => {
    promise[name] = function () {
      const args = [].slice.call(arguments);

      const newPromise = new Promise((resolve, reject) => {
        promise.then(output => {
          args.unshift(output);

          const result = actions[name].apply(null, args);

          if (result instanceof Promise) {
            result.then(resolve, reject);
          } else {
            resolve(result);
          }
        })
        .catch(reject);
      });

      return decoratePromise(newPromise, actions);
    };
  });

  return promise;
};

'use strict';

module.exports = function (actions, options) {
  options = Object.assign({ Promise: Promise }, options);

  return input => {
    const promise = new options.Promise(resolve => resolve(input));

    return decoratePromise(promise, actions, options);
  }
};

function decoratePromise(promise, actions, options) {
  Object.keys(actions).forEach(name => {
    promise[name] = function () {
      const args = [].slice.call(arguments);

      const newPromise = new options.Promise((resolve, reject) => {
        promise.then(output => {
          args.unshift(output);

          const result = actions[name].apply(null, args);

          if (isPromise(result)) {
            result.then(resolve, reject);
          } else {
            resolve(result);
          }
        })
        .catch(reject);
      });

      return decoratePromise(newPromise, actions, options);
    };
  });

  return promise;
};

function isPromise(obj) {
  return typeof obj.then === 'function';
}

Support third party Promise library


'use strict';

var knexConfig = require('./knex-config.js');
var knex = require('knex')(knexConfig[process.env.HAL_ENV]);
var bookshelf = require('bookshelf')(knex);

console.log('Top of bookshelf.js');
console.log('  env: ' + process.env.HAL_ENV);

/*
 * For the unittest environment we perform a schema migration + loading
 * of the seed data. Each unit test can create additional data if it
 * wishes. However, the seed data should not be molested with too much
 * as most unit tests will rely on it.
 */
if (process.env.HAL_ENV === 'unittest') {

    console.log('Bootstrapping database...');

    global.unittestDataSeeded = false;
    knex.migrate.latest()
        .then(function() {
            knex.seed.run().then(function() {
                global.unittestDataSeeded = true;
            });
            //global.unittestDataSeeded = true;
        }, function(err) {
            console.log(err);
        });
}

module.exports = bookshelf;

'use strict';

var knexConfig = require('./knex-config.js');
var knex = require('knex')(knexConfig[process.env.HAL_ENV]);
var bookshelf = require('bookshelf')(knex);

/*
 * For the unittest environment we perform a schema migration + loading
 * of the seed data. Each unit test can create additional data if it
 * wishes. However, the seed data should not be molested with too much
 * as most unit tests will rely on it.
 */
if (process.env.HAL_ENV === 'unittest') {
    global.unittestDataSeeded = false;
    knex.migrate.latest()
        .then(function() {
            knex.seed.run().then(function() {
                global.unittestDataSeeded = true;
            });
        });
}

module.exports = bookshelf;

Remove a bit of console output junk


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

import Control from './Control';

class Select extends Control {
  static propTypes = {
    className: PropTypes.string,
    id: PropTypes.string,
    name: PropTypes.string.isRequired,
    options: PropTypes.arrayOf(
      PropTypes.shape({
        name: PropTypes.string.isRequired,
        value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
      }),
    ).isRequired,
    style: PropTypes.string,
    initialValue: PropTypes.string,
    placeholder: PropTypes.string,
  };

  componentDidMount() {
    if (this.props.initialValue) {
      this._onChange(this.props.initialValue);
    }
  }

  render() {
    const {className, id, name, style, value, placeholder} = this.props;

    const options = this.props.options.map(option => (
      <option key={option.value} value={option.value}>
        {option.name}
      </option>
    ));

    if (placeholder) {
      options.unshift(
        <option key={placeholder} value="" disabled>
          {placeholder}
        </option>,
      );
    }

    return (
      <select
        id={id}
        name={name}
        value={this._getValue() || ""}
        className={className}
        style={style}
        onChange={e => this._onChange(e.target.value)}
      >
        {options}
      </select>
    );
  }
}

export default Select;

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import {updateValue} from '../actions/controls';
import {connect} from '../store';

class Select extends Component {
  static propTypes = {
    className: PropTypes.string,
    id: PropTypes.string,
    name: PropTypes.string.isRequired,
    options: PropTypes.arrayOf(
      PropTypes.shape({
        name: PropTypes.string.isRequired,
        value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
      }),
    ).isRequired,
    style: PropTypes.string,
    initialValue: PropTypes.string,
    placeholder: PropTypes.string,
  };

  componentDidMount() {
    const {initialValue, name} = this.props;

    if (initialValue) {
      // this.props.updateValue(name, initialValue); TODO
    }
  }

  render() {
    const {className, id, name, style, placeholder} = this.props;

    const options = this.props.options.map(option => (
      <option key={option.value} value={option.value}>
        {option.name}
      </option>
    ));

    if (placeholder) {
      options.unshift(
        <option key={placeholder} value="" disabled>
          {placeholder}
        </option>,
      );
    }

    return (
      <select
        id={id}
        name={name}
        value={this.props.value || ""}
        className={className}
        style={style}
        onChange={e => this.props.updateValue(name, e.target.value)}
      >
        {options}
      </select>
    );
  }
}

const mapStateToProps = ({controls}, props) => ({
  value: controls.get(props.name),
});

const mapDispatchToProps = {
  updateValue,
};

export default connect(mapStateToProps, mapDispatchToProps)(Select);

Create select with hook up to store


/* eslint-disable no-console */
import chalk from 'chalk';

export function logConfig(caption, config) {
  console.log(chalk.cyan(caption));
  console.log(JSON.stringify(config, null, 2));
}

/* eslint-disable no-console */
import chalk from 'chalk';

export function logConfig(caption, config) {
  console.log(chalk.cyan(caption));
  console.dir(config, { depth: null });
}

Use console.dir instead of console.log


"use strict";

/*global nodeca, _*/

var me_in_fields = [
  '_uname',
  'locale'
];

// fetch current user info
// fired before each controllers
nodeca.filters.before('', { weight: -70 }, function load_current_user(params, next) {
  var env = this;

  //
  // fill in default (guest) values
  //

  env.user = null;
  env.runtime.user_name = '';
  env.runtime.is_member = false;
  env.runtime.is_guest  = true;

  //
  // if there's no session or session has no user_id, user is guest - skip
  //

  if (!env.session || !env.session.user_id) {
    next();
    return;
  }

  nodeca.models.users.User
    .findOne({ '_id': env.session.user_id })
    .select(me_in_fields.join(' '))
    .setOptions({ lean: true })
    .exec(function(err, user){
      if (err) {
        next(err);
        return;
      }

      // user in session, but db does not know this user
      if (!user) {
        next();
        return;
      }

      env.user = user;
      env.runtime.user_name = user._uname;
      env.runtime.is_guest  = false;
      env.runtime.is_member = true;

      next();
    });
});

"use strict";

/*global nodeca, _*/

var me_in_fields = [
  '_uname',
  'locale'
];

// fetch current user info
// fired before each controllers
nodeca.filters.before('', { weight: -70 }, function load_current_user(params, next) {
  var env = this;

  //
  // fill in default (guest) values
  //

  env.current_user = null;
  env.runtime.user_name = '';
  env.runtime.is_member = false;
  env.runtime.is_guest  = true;

  //
  // if there's no session or session has no user_id, user is guest - skip
  //

  if (!env.session || !env.session.user_id) {
    next();
    return;
  }

  nodeca.models.users.User
    .findOne({ '_id': env.session.user_id })
    .select(me_in_fields.join(' '))
    .setOptions({ lean: true })
    .exec(function(err, user){
      if (err) {
        next(err);
        return;
      }

      // user in session, but db does not know this user
      if (!user) {
        next();
        return;
      }

      env.current_user = user;
      env.runtime.user_name = user._uname;
      env.runtime.is_guest  = false;
      env.runtime.is_member = true;

      // set user's locale
      env.session.locale = user.locale || env.session.locale;

      next();
    });
});

Rename env.data -> env.current_user; Set locale.


// Shortcuts for common image kinds

export const BINARY = 'BINARY';
export const GREYA = 'GREYA';
export const RGBA = 'RGBA';
export const RGB = 'RGB';
export const GREY = 'GREY';

// Shortcuts for common image kinds

export const BINARY = 'BINARY';
export const GREY = 'GREY';
export const GREYA = 'GREYA';
export const RGB = 'RGB';
export const RGBA = 'RGBA';
export const CMYK = 'CMYK';
export const CMYKA = 'CMYKA';

Add CMYK and CMYKA kinds


/**
 * Translate keys like laravel helper method trans
 *
 * @param  {String} key         the translation key to translate
 * @param  {Object} [params={}] the params to include in the translation
 * @return {String}             the translated string
 */
export function trans(key, params = {}) {
    if (typeof Polyglot === 'undefined') {
        throw new Error('Polyglot is missing.');
    }

    let trans = Polyglot;

    key.split('.').forEach(item => trans = ((typeof trans[item] !== 'undefined') ? trans[item] : key));

    for (let param in params) {
        let pattern = `:${param}`;
        let regex = new RegExp(pattern, "g");
        trans = trans.replace(regex, params[param]);
    }

    return trans;
}

window.trans = trans;

/**
 * Translate keys like laravel helper method trans
 *
 * @param  {String} key         the translation key to translate
 * @param  {Object} [params={}] the params to include in the translation
 * @return {String}             the translated string
 */
var trans = function(key, params = {}) {
    if (typeof Polyglot === 'undefined') {
        throw new Error('Polyglot is missing.');
    }

    let trans = Polyglot;

    key.split('.').forEach(item => trans = ((typeof trans[item] !== 'undefined') ? trans[item] : key));

    for (let param in params) {
        let pattern = `:${param}`;
        let regex = new RegExp(pattern, "g");
        trans = trans.replace(regex, params[param]);
    }

    return trans;
}

export { trans };

Fix exporting issue, removed the glorious window ref.


"use strict";

var requestHelper = require('./request-helper');

var jsonSchema = require('jsonschema');

/**
 * Returns an express middleware function that validates the request body
 * or the request's field if provided against the given JSON schema.
 */

var validateJson = function(schema, field) {
  return function(req, res, next) {
    if (!field) {
      field = 'body';
    }

    if (field === 'body' && !requestHelper.isContentType(req, 'application/json')) {
      res.sendInvalidRequest("Invalid content type: " + req.get('Content-Type'));
      return;
    }

    var result = jsonSchema.validate(req[field], schema);

    if (result.errors.length > 0) {
      res.sendInvalidRequest(result.toString());
      return;
    }

    next();
  };
};

module.exports = validateJson;

"use strict";

var requestHelper = require('./request-helper');

var jsonSchema = require('jsonschema');

/**
 * Returns an express middleware function that validates the request body
 * or the request's field if provided against the given JSON schema.
 *
 * schemas is either an array of object or a single object
 */

var validateJson = function(schemas, field) {
  return function(req, res, next) {
    if (!field) {
      field = 'body';
    }

    if (field === 'body' && !requestHelper.isContentType(req, 'application/json')) {
      res.sendInvalidRequest("Invalid content type: " + req.get('Content-Type'));
      return;
    }

    if (!Array.isArray(schemas)) {
      schemas = [schemas];
    }

    var errors = [];
    schemas.forEach(function (schema) {
      var result = jsonSchema.validate(req[field], schema);

      if (result.errors.length > 0) {
        errors.push(result.toString());
      }
    });

    if (errors.length === schemas.length && errors.length > 0) {
      var errorMessage = '';

      errors.forEach(function(err) {
        errorMessage += err;
      });

      return res.sendInvalidRequest(errorMessage);
    }
    next();
  };
};

module.exports = validateJson;

Add support for multiple schemas


module.exports = {
  safe: function (thing, path, otherwise) {
    thing = (typeof thing === 'object' && thing != null) ? thing : {};
    var props = path.split('.');
    if (props.length === 1) {
      return typeof thing[props[0]] === 'undefined' ? otherwise : thing[props.shift()];
    } else {
      var prop = props.shift();
      return (typeof thing[prop] === 'object' && thing != null) ? this.safe(thing[prop], props.join('.'), otherwise) : otherwise || undefined;
    }
  },

  expand: function (obj, path, thing) {
    obj = (typeof obj === 'object' && obj != null) ? obj : {};
    var props = path.split('.');
    if (props.length === 1) {
      obj[props.shift()] = thing;
    } else {
      var prop = props.shift();
      if (!obj[prop]) {
        obj[prop] = {};
      }
      this.expand(obj[prop], props.join('.'), thing);
    }
  }
};

module.exports = {
  safe: function (thing, path, otherwise) {
    thing = (typeof thing === 'object' && thing != null) ? thing : {};
    var props = path.split('.');
    if (props.length === 1) {
      return typeof thing[props[0]] === 'undefined' ? otherwise : thing[props.shift()];
    } else {
      var prop = props.shift();
      return (typeof thing[prop] === 'object' && thing != null) ? this.safe(thing[prop], props.join('.'), otherwise) : otherwise;
    }
  },

  expand: function (obj, path, thing) {
    obj = (typeof obj === 'object' && obj != null) ? obj : {};
    var props = path.split('.');
    if (props.length === 1) {
      obj[props.shift()] = thing;
    } else {
      var prop = props.shift();
      if (!obj[prop]) {
        obj[prop] = {};
      }
      this.expand(obj[prop], props.join('.'), thing);
    }
  }
};

Allow falsy values to be passed as defaults


import React from 'react'
import Chronodex from './src/Chronodex.jsx'

let events = [
  [9, 10, 'Email'],
  [10, 12, 'Meeting'],
  [12, 13, 'Lunch'],
  [13, 15, 'Meeting'],
  [15, 16, 'Coffee'],
  [16, 17, 'Email'],
  [17, 18, 'Commute,Reading,Music'],
  [18, 19, 'Exercise'],
  [19, 20, 'Dinner,Netflix']
]

React.render(<Chronodex
                title='Chronodex'
                size={256}
                center={128}
                radius={64}
                events={events}
              />, document.querySelector('#chronodex'))

import React from 'react'
import Chronodex from './src/Chronodex.jsx'

let events = [
  [9, 10, 'Email'],
  [10, 12, 'Meeting'],
  [12, 13, 'Lunch'],
  [13, 15, 'Meeting'],
  [15, 16, 'Coffee'],
  [16, 17, 'Email'],
  [17, 18, 'Commute,Reading,Music'],
  [18, 19, 'Exercise'],
  [19, 20, 'Dinner,Netflix'],
  [20, 21, 'Walk Dog']
]

React.render(<Chronodex
                title='Chronodex'
                size={256}
                center={128}
                radius={64}
                events={events}
              />, document.querySelector('#chronodex'))

Add last event of the day


var os = require('os');
var io = require('socket.io-client');

// The Castle address is loaded dynamically and passed to this script as an argument
var socket = io.connect('http://'+process.argv[2]+':8888');

if(!process.stdin.isTTY) {
    var image = Buffer.alloc(0);

    // Data is read in chunks of up to 64K (65356 bytes)
    // These need to be assembled into JPEG before being sent to castle
    process.stdin.on('data', function(chunk) {
    	image = Buffer.concat([image, chunk]);
    	if(chunk[chunk.length-2].toString(16) == 'ff' && chunk[chunk.length-1].toString(16) == 'd9') {
    	    console.log('Sending image to Castle '+image.length);
    	    socket.emit('watchman', {id: os.hostname(), image: image});
    	    image = Buffer.alloc(0);
    	}
    });
}

var os = require('os');
var io = require('socket.io-client');

// The Castle address is loaded dynamically and passed to this script as an argument
var socket = io.connect('http://'+process.argv[2]+':8888');

if(!process.stdin.isTTY) {
    var image = Buffer.alloc(0);

    // Data is read in chunks of up to 64K (65356 bytes)
    // These need to be assembled into JPEG before being sent to castle
    process.stdin.on('data', function(chunk) {
        if(chunk != undefined) {
            try {
            	image = Buffer.concat([image, chunk]);
            	if(chunk[chunk.length-2].toString(16) == 'ff' && chunk[chunk.length-1].toString(16) == 'd9') {
            	    console.log('Sending image to Castle '+image.length);
            	    socket.emit('watchman', {id: os.hostname(), image: image});
            	    image = Buffer.alloc(0);
            	}
            }
            catch(error) {
                console.log(error);
            }
        }
    });
}

Handle an error where data chunks from camera could be undefined


/*
 * Appcelerator Titanium Mobile
 * Copyright (c) 2011-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */

// start customization here
var suites = [
	{name: "tizen/media_content"},
	{name: "tizen/lbs"},
	{name: "tizen/call"},
	{name: "tizen/tizen_application"}
];

/*
these lines must be present and should not be modified.  "suites" argument to setSuites is
expected to be an array (should be an empty array at the very least in cases where population of
the suites argument is based on platform type and may result in no valid suites being added to the
argument)
*/
var init = require("init");
init.setSuites(suites);
init.start();

/*
 * Appcelerator Titanium Mobile
 * Copyright (c) 2011-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */

// start customization here
var suites = [
	{name: "tizen/messaging"},
	{name: "tizen/media_content"},
	{name: "tizen/lbs"},
	{name: "tizen/call"},
	{name: "tizen/tizen_application"}
];

/*
these lines must be present and should not be modified.  "suites" argument to setSuites is
expected to be an array (should be an empty array at the very least in cases where population of
the suites argument is based on platform type and may result in no valid suites being added to the
argument)
*/
var init = require("init");
init.setSuites(suites);
init.start();

Add messaging suite to Anvil config.


import {
  RepeatWrapping,
  NearestFilter,
  LinearMipMapLinearFilter,
  TextureLoader,
  Vector2
} from 'three';

const loader = new TextureLoader();

export class TextureModule {
  static load(url) {
    return new TextureModule({url}).texture;
  }

  textures = [];

  constructor(...textures) {
    textures.forEach(({url, type = 'map', offset = new Vector2(0, 0), repeat = new Vector2(1, 1)}) => {
      const texture = loader.load(url);

      texture.wrapS = texture.wrapT = RepeatWrapping;

      texture.offset.copy(offset);
      texture.repeat.copy(repeat);

      texture.magFilter = NearestFilter;
      texture.minFilter = LinearMipMapLinearFilter;

      this.textures.push([type, texture]);
    });
  }

  bridge = {
    material(material, self) {
      self.textures.forEach(texture => {
        material[texture[0]] = texture[1];
      });

      return material;
    }
  }
}

import {
  RepeatWrapping,
  UVMapping,
  NearestFilter,
  LinearMipMapLinearFilter,
  TextureLoader,
  Vector2
} from 'three';

const loader = new TextureLoader();

export class TextureModule {
  static load(url) {
    return new TextureModule({url}).texture;
  }

  textures = [];

  constructor(...textures) {
    textures.forEach(({
      url,
      type = 'map',
      offset = new Vector2(0, 0),
      repeat = new Vector2(1, 1),
      wrap = RepeatWrapping,
      mapping = UVMapping
    }) => {
      const texture = loader.load(url);

      if (wrap.length > 0) {
        texture.wrapS = wrap[0];
        texture.wrapT = wrap[1];
      } else
        texture.wrapS = texture.wrapT = wrap;

      texture.mapping = mapping;

      texture.offset.copy(offset);
      texture.repeat.copy(repeat);

      texture.magFilter = NearestFilter;
      texture.minFilter = LinearMipMapLinearFilter;

      this.textures.push([type, texture]);
    });
  }

  bridge = {
    material(material, self) {
      self.textures.forEach(texture => {
        material[texture[0]] = texture[1];
      });

      return material;
    }
  }
}

Add ability to use wrap and mapping


import createReducer from 'borex-reducers/createReducer';
import actionCreator from 'borex-actions/actionCreator';
import setMetaStatic from 'borex-actions/setMetaStatic';

import initialState from 'vclub/redux/initialClubState';

export const toggleModal = actionCreator(
  setMetaStatic('remote', true),
  setMetaStatic('broadcast', true)
);
export const like = actionCreator(
  setMetaStatic('remote', true),
  setMetaStatic('broadcast', true)
);

export const dislike = actionCreator(
  setMetaStatic('remote', true),
  setMetaStatic('broadcast', true)
);

export default createReducer((on) => {
  on(toggleModal, (state) => {
    if (state.showModalVote === true) return initialState.vote;
    return {
      ...state,
      showModalVote: !state.showModalVote,
    };
  });
  on(like, (state, action) => ({ ...state, pros: [...state.pros, action.payload] }));
  on(dislike, (state, action) => ({ ...state, cons: [...state.cons, action.payload] }));
});

import createReducer from 'borex-reducers/createReducer';
import actionCreator from 'borex-actions/actionCreator';
import setMetaStatic from 'borex-actions/setMetaStatic';
import appendIn from 'borex-reducers/appendIn';

import initialState from 'vclub/redux/initialClubState';

export const toggleModal = actionCreator(
  setMetaStatic('remote', true),
  setMetaStatic('broadcast', true)
);
export const like = actionCreator(
  setMetaStatic('remote', true),
  setMetaStatic('broadcast', true)
);

export const dislike = actionCreator(
  setMetaStatic('remote', true),
  setMetaStatic('broadcast', true)
);

export default createReducer((on) => {
  on(toggleModal, (state) => {
    if (state.showModalVote === true) return initialState.vote;
    return {
      ...state,
      showModalVote: !state.showModalVote,
    };
  });
  on(like, appendIn('pros'));
  on(dislike, appendIn('cons'));
});

Fix redusers like & dislike


#! /usr/bin/env node

/*
 * gog-scraper
 * Copyright (c) 2016 Jeff Minnear
 * Licensed under the MIT license.
 */

'use strict';

var program = require('commander');
var request = require('request');
var cheerio = require('cheerio');
const chalk = require('chalk');
var colorLegend = "Prices in " + chalk.green("green") + " are current sale prices, shown next to their normal price in " + chalk.gray("gray") + ".";

program
    .version('0.0.1')
    .option('-t, --title <string>', 'the title of the game you want to price-check', String)
    .option('-l, --limit <n>', 'the number of results you want to see (default is 1)', Number)
    .parse(process.argv);

var gogSearchUrl = 'http://www.gog.com/games/ajax/filtered?limit=' + program.limit + '&search=';
var gameSearchUrl = gogSearchUrl + encodeURIComponent(program.title);
console.log(colorLegend);

request(gameSearchUrl, function(error, response, body){
    if (!error) {
        var json = JSON.parse(body);

        console.log(json.products);
    }
});

#! /usr/bin/env node

/*
 * gog-scraper
 * Copyright (c) 2016 Jeff Minnear
 * Licensed under the MIT license.
 */

'use strict';

var program = require('commander');
var request = require('request');
var cheerio = require('cheerio');
const chalk = require('chalk');
var colorLegend = "Prices in " + chalk.green("green") + " are current sale prices, shown next to their normal price in " + chalk.gray("gray") + ".";

program
    .version('0.0.1')
    .option('-t, --title <string>', 'the title of the game you want to price-check', String)
    .option('-l, --limit <n>', 'the number of results you want to see (default is 1)', Number)
    .parse(process.argv);

var gogSearchUrl = 'http://www.gog.com/games/ajax/filtered?limit=' + program.limit + '&search=';
var gameSearchUrl = gogSearchUrl + encodeURIComponent(program.title);
console.log(colorLegend);

request(gameSearchUrl, function(error, response, body){
    if (!error) {
        var json = JSON.parse(body);
        var products = json.products;
        var title, price, normalPrice;

        for (var i = 0; i < products.length; i++) {
            normalPrice = undefined;
            title = products[i].title;
            price = products[i].price.amount;
            if (products[i].price.isDiscounted) {
                normalPrice = products[i].price.baseAmount;
            }

            if (normalPrice) {
                console.log(title + ": " + chalk.gray(normalPrice) + "  " + chalk.green(price));
            } else {
                console.log(title + ": " + price);
            }
        }
    }
});

Return title and color-coded price


var http = require('http');
var cheerio = require('cheerio');

exports.translate = function(text, lang, trans, cb){
  http.get('http://tyda.se/search/'+text+'?lang%5B0%5D='+lang+'&lang%5B1%5D='+trans, function(res){
      var body = '';

      res.on('data', function(d){
        body+= d;
      });

      res.on('end', function(e){
        var c = cheerio.load(body.toString());

        var lastLang = '';
        var translations = { };
        c('.list-translations').children('li:not(.item-title)').find('a').each(function(i, obj){

          var item = c(this);
          var translatedText = item.text().replace(/^\s+/,'').replace(/\s+/,'').replace(/\n/g, '');

          var lang = item.parent().parent().find('.item-title').text().replace(/(^\s+|\s+$|\n)/,'').replace(/\s+$/,'').replace(/\n/g,'');
          if(lastLang != lang){
            if(lang.length > 0){
              translations[lang] = [];
              lastLang = lang;
            }
          }

          if(translatedText.length > 0){
            translations[lang].push(translatedText);
          }
        });

        cb(null, translations);

      });

      res.on('error', function(err){
        return cb(err);
      });
  }).on('error', function(err){
    return cb(err);
  });
};

var http = require('http');
var cheerio = require('cheerio');

exports.translate = function(text, lang, trans, cb){
  http.get('http://tyda.se/search/'+text+'?lang%5B0%5D='+lang+'&lang%5B1%5D='+trans, function(res){
      var body = '';

      res.on('data', function(d){
        body+= d;
      });

      res.on('end', function(e){
        var c = cheerio.load(body.toString());

        var lastLang = '';
        var translations = { };
        c('.list-translations').children('li:not(.item-title)').find('a').each(function(i, obj){

          var item = c(this);
          var translatedText = item.text().replace(/(^\s+|\s+$|\n)/,'');

          var lang = item.parent().parent().find('.item-title').text().replace(/(^\s+|\s+$|\n)/,'');
          if(lastLang != lang){
            if(lang.length > 0){
              translations[lang] = [];
              lastLang = lang;
            }
          }

          if(translatedText.length > 0){
            translations[lang].push(translatedText);
          }
        });

        cb(null, translations);

      });

      res.on('error', function(err){
        return cb(err);
      });
  }).on('error', function(err){
    return cb(err);
  });
};

Use one regex instead of 3


var React = require('react'),
    StateMixin = require('../mixins/app-StateMixin'),
    SearchBox = require('../components/app-SearchBox'),
    TaskList = require('../components/app-TaskList');

var MainCard = React.createClass({
    mixins: [StateMixin],
    render: function () {
        "use strict";
        return (

                                Pick Your Tasks

                    <SearchBox items={this.state.filteredResult}/>

                        <TaskList items={this.state.activeItems} activities={this.state.activities} customFields={this.state.settings.customFields}/>

        );
    }
});

module.exports = MainCard;

Fix issue where task list appears above search result


'use strict'

module.exports = require('./abstract/test')

if (!module.parent) {
  var test = require('tape')
  var packager = require('./')
  var leveldown = require('leveldown')
  module.exports(test, packager(leveldown))
}

'use strict'

var test = require('tape')
var packager = require('.')

test('Level constructor relays .destroy if it exists', function (t) {
  t.plan(2)
  function Down () {}
  Down.destroy = function (location, cb) {
    t.is(location, 'location', 'location is correct')
    t.is(typeof cb, 'function', 'cb is set')
  }
  packager(Down).destroy('location')
})

test('Level constructor relays .repair if it exists', function (t) {
  t.plan(2)
  function Down () {}
  Down.repair = function (location, cb) {
    t.is(location, 'location', 'location is correct')
    t.is(typeof cb, 'function', 'cb is set')
  }
  packager(Down).repair('location')
})

test('Level constructor, default options', function (t) {
  t.plan(3)
  function Down (location) {
    t.is(location, 'location', 'location is correct')
    return {
      open: function (opts, cb) {}
    }
  }
  var levelup = packager(Down)('location')
  t.is(levelup.options.keyEncoding, 'utf8')
  t.is(levelup.options.valueEncoding, 'utf8')
})

test('Level constructor, custom options', function (t) {
  t.plan(3)
  var Down = function (location) {
    t.is(location, 'location', 'location is correct')
    return {
      open: function (opts, cb) {}
    }
  }
  var levelup = packager(Down)('location', {
    keyEncoding: 'binary',
    valueEncoding: 'binary'
  })
  t.is(levelup.options.keyEncoding, 'binary')
  t.is(levelup.options.valueEncoding, 'binary')
})

Test packager functionality using generic Down


window.addEventListener("load", function(e) {
  var run = function() {
    var document = content.document;
    var reGist = /^https?\:\/\/gist\.github\.com\/(\d*)/i,
        reRel = /^\/?(\d+)$/,
        gist = reGist.test(document.location.href),
        anchors = document.querySelectorAll("a[href]"),
        anchor,
        image,
        imageURL = "chrome://bl.ocks.org/content/bl.ocks.png",
        i = -1,
        n = anchors.length,
        href,
        match;
    while (++i < n) {
      match = (href = (anchor = anchors[i]).getAttribute("href")).match(reGist);
      if (gist && !(match && match[1])) match = href.match(reRel);
      if (match && match[1]) {
        anchor = anchor.parentNode.insertBefore(document.createElement("a"), anchor.nextSibling);
        anchor.setAttribute("href", "http://bl.ocks.org/" + match[1]);
        anchor.setAttribute("title", "View bl.ock #" + match[1] + ".");
        anchor.style.marginLeft = "2px";
        image = anchor.appendChild(document.createElement("img"));
        image.setAttribute("src", imageURL);
        image.style.width = "16px";
      }
    }
  };
  var appcontent = document.getElementById("appcontent");
  if (appcontent) {
    appcontent.addEventListener("DOMContentLoaded", run, true);
  }
}, false);

window.addEventListener("load", function load() {
  window.removeEventListener("load", load, false);
  gBrowser.addEventListener("DOMContentLoaded", function(e) {
    var document = e.originalTarget,
        reGist = /^https?\:\/\/gist\.github\.com\/(\d*)/i,
        reRel = /^\/?(\d+)$/,
        gist = reGist.test(document.location.href),
        anchors = document.querySelectorAll("a[href]"),
        anchor,
        image,
        imageURL = "chrome://bl.ocks.org/content/bl.ocks.png",
        i = -1,
        n = anchors.length,
        href,
        match;
    while (++i < n) {
      match = (href = (anchor = anchors[i]).getAttribute("href")).match(reGist);
      if (gist && !(match && match[1])) match = href.match(reRel);
      if (match && match[1] && !anchor.matched) {
        anchor.matched = true; // avoid duplicate linking on iframes
        anchor = anchor.parentNode.insertBefore(document.createElement("a"), anchor.nextSibling);
        anchor.setAttribute("href", "http://bl.ocks.org/" + match[1]);
        anchor.setAttribute("title", "View bl.ock #" + match[1] + ".");
        anchor.style.marginLeft = "2px";
        image = anchor.appendChild(document.createElement("img"));
        image.setAttribute("src", imageURL);
        image.style.width = "16px";
      }
    }
  }, false);
}, false);

Fix duplicate linking with iframes.


/* eslint-disable */
'use strict';

module.exports = {
  name: 'ember-flatpickr',
  included: function(app) {
    let cssPath = 'themes/';
    if(app.options && app.options.flatpickr && app.options.flatpickr.theme) {
      cssPath += app.options.flatpickr.theme;
    }
    else {
      cssPath += 'dark';
    }
    cssPath += '.css';
    this.theme = cssPath;

    this._super.included.apply(this, arguments);
  },
  options: {
    nodeAssets: {
      flatpickr: function() {
        if (!process.env.EMBER_CLI_FASTBOOT) {
          return {
            srcDir: 'dist',
            import: [
              'flatpickr.js',
              this.theme
            ]
          };
        }
      }
    }
  }
};

/* eslint-disable */
'use strict';

module.exports = {
  name: 'ember-flatpickr',
  included: function(app) {
    let cssPath = 'themes/';
    if (app.options && app.options.flatpickr && app.options.flatpickr.theme) {
      cssPath += app.options.flatpickr.theme;
    }
    else {
      cssPath += 'dark';
    }
    cssPath += '.css';
    this.theme = cssPath;

    this._super.included.apply(this, arguments);
  },
  options: {
    nodeAssets: {
      flatpickr: function() {
        return {
          enabled: !process.env.EMBER_CLI_FASTBOOT,
          srcDir: 'dist',
          import: [
            'flatpickr.js',
            this.theme
          ]
        };
      }
    }
  }
};

Fix node assets with fastboot


var debug       = require( 'debug' )( 'wpcom-vip' );
var request     = require( './lib/util/request' );

// Modules

function WPCOM_VIP( token ) {
    this.req = new Request( this );
}

WPCOM_VIP.prototype.API_VERSION = '1';
WPCOM_VIP.prototype.API_TIMEOUT = 10000;

WPCOM_VIP.prototype.req = new Request();

WPCOM_VIP.prototype.get = function() {
    return this.req.get.apply( arguments );
};

WPCOM_VIP.prototype.post = function() {
    return this.req.post.apply( arguments );
};

WPCOM_VIP.prototype.put = function() {
    return this.req.get.apply( arguments );
};

WPCOM_VIP.prototype.delete = function() {
    return this.req.delete.apply( arguments );
};

module.exports = WPCOM_VIP;

var debug       = require( 'debug' )( 'wpcom-vip' );
var request     = require( './lib/util/request' );

// Modules

function WPCOM_VIP( token ) {
    this.req = new Request( this );

    this.auth = {};
}

WPCOM_VIP.prototype.API_VERSION = '1';
WPCOM_VIP.prototype.API_TIMEOUT = 10000;

WPCOM_VIP.prototype.req = new Request();

WPCOM_VIP.prototype.get = function() {
    return this.req.get.apply( arguments );
};

WPCOM_VIP.prototype.post = function() {
    return this.req.post.apply( arguments );
};

WPCOM_VIP.prototype.put = function() {
    return this.req.get.apply( arguments );
};

WPCOM_VIP.prototype.delete = function() {
    return this.req.delete.apply( arguments );
};

module.exports = WPCOM_VIP;

Add placeholder 'auth' property to the main object


module.exports = function cu(fn) {
  'use strict';
  var args = [].slice.call(arguments);

  if ('function' !== typeof fn) throw new Error('auto-curry: Invalid parameter. First parameter should be a function.');
  if ('function' === typeof fn && !fn.length) return fn;
  if (args.length - 1 >= fn.length) return fn.apply(this, args.slice(1));
  return function() {
    var tempArgs = args.concat([].slice.call(arguments));
    return cu.apply(this, tempArgs);
  };
};

module.exports = function cu(fn) {
  'use strict'

  var args = [].slice.call(arguments)
  var typeOfFn = typeof fn

  if ('function' !== typeOfFn) throw new Error('auto-curry: Invalid parameter. Expected function, received ' + typeOfFn)
  if (fn.length <= 1) return fn
  if (args.length - 1 >= fn.length) return fn.apply(this, args.slice(1))

  return function() {
    return cu.apply(this, args.concat([].slice.call(arguments)))
  };
};

Return unary fn as is and remove redundant checks


const Hapi = require('@hapi/hapi');
const routes = require('./routes');
const auth = require('./auth');

module.exports = async (elastic, config, cb) => {
  const server = new Hapi.Server({ port: config.port, routes: { cors: { origin: "ignore" }, log: { collect: true } } });

  server.route(routes(elastic, config));

  if (config.auth) {
    server.route(auth());
    await server.register(require('hapi-auth-jwt2'));
    await server.register(require('./auth/authentication'));
  }

  try {
    await server.register([
      {
        plugin: require('good'),
        options: {
          reporters: {
            console: [{ module: 'good-console' }, 'stdout']
          }
        }
      },
      require('inert'),
      require('vision'),
      require('h2o2'),
      {
        plugin: require('./routes/plugins/error'),
        options: {
          config: config
        }
      }
    ]);
  } catch (err) {
    return cb(err);
  }

  server.views({
    engines: { html: { module: require('handlebars'), compileMode: 'sync' } },
    relativeTo: __dirname,
    path: './templates/pages',
    layout: 'default',
    layoutPath: './templates/layouts',
    partialsPath: './templates/partials',
    helpersPath: './templates/helpers'
  });

  cb(null, { server, elastic });
};

const Hapi = require('@hapi/hapi');
const routes = require('./routes');
const auth = require('./auth');

module.exports = async (elastic, config, cb) => {
  const server = new Hapi.Server({ port: config.port, routes: { cors: { origin: 'ignore' }, log: { collect: true } } });

  server.route(routes(elastic, config));

  if (config.auth) {
    server.route(auth());
    await server.register(require('hapi-auth-jwt2'));
    await server.register(require('./auth/authentication'));
  }

  try {
    await server.register([
      {
        plugin: require('good'),
        options: {
          reporters: {
            console: [{ module: 'good-console' }, 'stdout']
          }
        }
      },
      require('inert'),
      require('vision'),
      require('h2o2'),
      {
        plugin: require('./routes/plugins/error'),
        options: {
          config: config
        }
      }
    ]);
  } catch (err) {
    return cb(err);
  }

  server.views({
    engines: { html: { module: require('handlebars'), compileMode: 'sync' } },
    relativeTo: __dirname,
    path: './templates/pages',
    layout: 'default',
    layoutPath: './templates/layouts',
    partialsPath: './templates/partials',
    helpersPath: './templates/helpers'
  });

  cb(null, { server, elastic });
};

Enable CORS ignore orgin header


import { readdirSync, lstatSync } from 'fs';
import { resolve } from 'path';
import { init } from './server/init';
import { replaceInjectedVars } from './server/lib/replace_injected_vars';

export default function (kibana) {
  return new kibana.Plugin({
    id: 'notification_center',
    configPrefix: 'notification_center',
    require: ['elasticsearch'],
    name: 'notification_center',
    uiExports: {

      chromeNavControls: [
        'plugins/notification_center/nav_control'
      ],

      injectDefaultVars(server) {
        return {
          notificationCenter: {
            supportDarkTheme: server.config().get('notification_center.supportDarkTheme')
          }
        };
      },

      replaceInjectedVars

    },

    config(Joi) {
      return Joi.object({
        enabled: Joi.boolean().default(true),
        index: Joi.string().default('notification-%{+YYYY.MM.DD}'),
        template: Joi.object({
          name: Joi.string().default('notification_center_template'),
          overwrite: Joi.boolean().default(false)
        }).default(),
        api: Joi.object({
          enabled: Joi.boolean().default(true),
          pull: Joi.object({
            maxSize: Joi.number().default(100)
          }).default()
        }).default(),
        supportDarkTheme: Joi.boolean().default(true)
      }).default();
    },

    init

  });
};

import { resolve } from 'path';
import { init } from './server/init';
import { replaceInjectedVars } from './server/lib/replace_injected_vars';

export default function (kibana) {
  return new kibana.Plugin({
    id: 'notification_center',
    configPrefix: 'notification_center',
    require: ['elasticsearch'],
    name: 'notification_center',
    publicDir: resolve(__dirname, 'public'),
    uiExports: {

      chromeNavControls: [
        'plugins/notification_center/nav_control'
      ],

      injectDefaultVars(server) {
        return {
          notificationCenter: {
            supportDarkTheme: server.config().get('notification_center.supportDarkTheme')
          }
        };
      },

      replaceInjectedVars

    },

    config(Joi) {
      return Joi.object({
        enabled: Joi.boolean().default(true),
        index: Joi.string().default('notification-%{+YYYY.MM.DD}'),
        template: Joi.object({
          name: Joi.string().default('notification_center_template'),
          overwrite: Joi.boolean().default(false)
        }).default(),
        api: Joi.object({
          enabled: Joi.boolean().default(true),
          pull: Joi.object({
            maxSize: Joi.number().default(100)
          }).default()
        }).default(),
        supportDarkTheme: Joi.boolean().default(true)
      }).default();
    },

    init

  });
};

Add `publicDir` option to plugin options


'use strict';

var express = require('express');
var routes = require('./app/routes/index.js');
var mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');
var bodyParser = require('body-parser')

var app = express();
require('dotenv').load();
require('./app/config/passport')(passport);

mongoose.connect(process.env.MONGO_URI);
mongoose.Promise = global.Promise;

// Configure server to parse JSON for us
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.use('/controllers', express.static(process.cwd() + '/app/controllers'));
app.use('/public', express.static(process.cwd() + '/public'));

app.use(session({
	secret: 'secretJcsgithubNightlifeapp',
	resave: false,
	saveUninitialized: true
}));

app.use(passport.initialize());
app.use(passport.session());

routes(app, passport);

var port = process.env.PORT || 8080;
app.listen(port,  function () {
	console.log('Node.js listening on port ' + port + '...');
});

'use strict';

var express = require('express');
var routes = require('./app/routes/index.js');
var mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');
var bodyParser = require('body-parser')

var app = express();
// require('dotenv').load();
require('./app/config/passport')(passport);

mongoose.connect(process.env.MONGO_URI);
mongoose.Promise = global.Promise;

// Configure server to parse JSON for us
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.use('/controllers', express.static(process.cwd() + '/app/controllers'));
app.use('/public', express.static(process.cwd() + '/public'));

app.use(session({
	secret: 'secretJcsgithubNightlifeapp',
	resave: false,
	saveUninitialized: true
}));

app.use(passport.initialize());
app.use(passport.session());

routes(app, passport);

var port = process.env.PORT || 8080;
app.listen(port,  function () {
	console.log('Node.js listening on port ' + port + '...');
});

Comment out dotenv for heroku deployment


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

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

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

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

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

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

Revert "Revert "debugging the ios directory issue""


var express = require('express'),
    app = express();

app.use( express.static( __dirname + '/public' ) );

var server = app.listen(3000, function() {
    console.log('Listening on port %d', server.address().port);
});

var express = require('express'),
    app = express();

app.use( express.static( __dirname + '/public' ) );

var server = app.listen(3000, function() {
    console.log('Listening on port %d', server.address().port);

    require('opn')('http://localhost:3000');
});

Use opn to open demo site in a browser on start.


/* eslint-disable no-console */
/**
 * Setup and run the development server for Hot-Module-Replacement
 * https://webpack.github.io/docs/hot-module-replacement-with-webpack.html
 * @flow
 */

import express from 'express';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import { spawn } from 'child_process';

import config from './webpack.config.development';

const app = express();
const compiler = webpack(config);
const PORT = process.env.PORT || 3000;

const wdm = webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath,
  stats: {
    colors: true
  }
});

app.use(wdm);

app.use(webpackHotMiddleware(compiler));

const server = app.listen(PORT, 'localhost', serverError => {
  if (serverError) {
    return console.error(serverError);
  }

  spawn('npm', ['run', 'start-hot'], { stdio: 'inherit' })
    .on('close', code => process.exit(code))
    .on('error', spawnError => console.error(spawnError));

  console.log(`Listening at http://localhost:${PORT}`);
});

process.on('SIGTERM', () => {
  console.log('Stopping dev server');
  wdm.close();
  server.close(() => {
    process.exit(0);
  });
});

/* eslint-disable no-console */
/**
 * Setup and run the development server for Hot-Module-Replacement
 * https://webpack.github.io/docs/hot-module-replacement-with-webpack.html
 * @flow
 */

import express from 'express';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
import { spawn } from 'child_process';

import config from './webpack.config.development';

const argv = require('minimist')(process.argv.slice(2));

const app = express();
const compiler = webpack(config);
const PORT = process.env.PORT || 3000;

const wdm = webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath,
  stats: {
    colors: true
  }
});

app.use(wdm);

app.use(webpackHotMiddleware(compiler));

const server = app.listen(PORT, 'localhost', serverError => {
  if (serverError) {
    return console.error(serverError);
  }

  if (argv['start-hot']) {
    spawn('npm', ['run', 'start-hot'], { env: process.env, stdio: 'inherit' })
      .on('close', code => process.exit(code))
      .on('error', spawnError => console.error(spawnError));
  }

  console.log(`Listening at http://localhost:${PORT}`);
});

process.on('SIGTERM', () => {
  console.log('Stopping dev server');
  wdm.close();
  server.close(() => {
    process.exit(0);
  });
});

Add flag option `start-hot` and apply env


const path = require('path');
const express = require('express');
const logger = require('winston');
const passport = require('passport');
const bodyParser = require('body-parser');
const bearerAuth = require('./auth/bearer');
const httpHelper = require('sharemyscreen-http-helper');

const user = require('./route/user');
const organization = require('./route/organization/index');

var apiApp = null;
var apiRouter = null;

function getApp () {
  logger.info('Initializing api app ...');
  apiApp = express();
  apiApp.use(bodyParser.json());
  apiApp.use(passport.initialize());

  apiRouter = express.Router();

  bearerAuth.init();
  apiRouter.use(passport.authenticate('bearer', { session: false }));

  // Register all routes
  user.registerRoute(apiRouter);
  organization.registerRoute(apiRouter);

  apiApp.use('/v1', apiRouter);
  apiApp.use('/doc', express.static(path.join(__dirname, '/doc'), {dotfiles: 'allow'}));

  // Error handler
  apiApp.use(function (err, req, res, next) {
    logger.error(err);
    httpHelper.sendReply(res, httpHelper.error.internalServerError(err));
  });

  logger.info('Api app initialized');

  return apiApp;
}

module.exports.getApp = getApp;

const path = require('path');
const express = require('express');
const logger = require('winston');
const passport = require('passport');
const bodyParser = require('body-parser');
const bearerAuth = require('./auth/bearer');
const httpHelper = require('sharemyscreen-http-helper');

const user = require('./route/user');
const organization = require('./route/organization/index');

var apiApp = null;
var apiRouter = null;

function getApp () {
  logger.info('Initializing api app ...');
  apiApp = express();
  apiApp.use(bodyParser.json());
  apiApp.use(passport.initialize());

  apiRouter = express.Router();

  bearerAuth.init();
  apiRouter.use(passport.authenticate('bearer', { session: false }));

  apiApp.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
    next();
  });

  // Register all routes
  user.registerRoute(apiRouter);
  organization.registerRoute(apiRouter);

  apiApp.use('/v1', apiRouter);
  apiApp.use('/doc', express.static(path.join(__dirname, '/doc'), {dotfiles: 'allow'}));

  // Error handler
  apiApp.use(function (err, req, res, next) {
    logger.error(err);
    httpHelper.sendReply(res, httpHelper.error.internalServerError(err));
  });

  logger.info('Api app initialized');

  return apiApp;
}

module.exports.getApp = getApp;

Allow CROS (via adding headers)