// ==UserScript==
// @name           Language switcher for Microsoft Docs
// @namespace      curipha
// @description    Add language menu
// @include        https://docs.microsoft.com/*
// @version        0.0.1
// @grant          none
// @noframes
// ==/UserScript==

(function() {
  'use strict';

  const nav = document.getElementById('affixed-left-container');
  if (nav) {
    const [tolang, label] = location.pathname.substring(0,7) === '/en-us/' ? ['ja-jp', '日本語'] : ['en-us', 'English'];

    const anchor = document.createElement('a');
    anchor.href = location.pathname.replace(/(?<=^\/)[A-Za-z0-9-]+(?=\/)/, tolang);
    anchor.className = 'button is-small is-text has-inner-focus has-margin-bottom-small has-border-top has-border-bottom';

    const icon = document.createElement('span');
    icon.className = 'icon is-size-8 has-text-subtle';

    const iconinner = document.createElement('span');
    iconinner.className = 'docon docon-locale-globe';

    const text = document.createElement('span');
    text.textContent = label;

    icon.appendChild(iconinner);
    anchor.appendChild(icon);
    anchor.appendChild(text);
    nav.appendChild(anchor);

    const makehref = function() { this.href += location.hash; };
    anchor.addEventListener('mousedown', makehref, false);
    anchor.addEventListener('keydown', makehref, false);
  }
})();

// ==UserScript==
// @name           Language switcher for Microsoft Docs
// @namespace      curipha
// @description    Add language menu
// @include        https://docs.microsoft.com/*
// @version        0.0.1
// @grant          none
// @noframes
// ==/UserScript==

(function() {
  'use strict';

  const nav = document.getElementById('affixed-left-container');
  if (nav) {
    const [tolang, label] = location.pathname.substring(0,7) === '/en-us/' ? ['ja-jp', '日本語'] : ['en-us', 'English'];

    const anchor = document.createElement('a');
    anchor.href = location.pathname.replace(/(?<=^\/)[A-Za-z0-9-]+(?=\/)/, tolang) + location.search;
    anchor.className = 'button is-small is-text has-inner-focus has-margin-bottom-small has-border-top has-border-bottom';

    const icon = document.createElement('span');
    icon.className = 'icon is-size-8 has-text-subtle';

    const iconinner = document.createElement('span');
    iconinner.className = 'docon docon-locale-globe';

    const text = document.createElement('span');
    text.textContent = label;

    icon.appendChild(iconinner);
    anchor.appendChild(icon);
    anchor.appendChild(text);
    nav.appendChild(anchor);

    const makehref = function() { this.href += location.hash; };
    anchor.addEventListener('mousedown', makehref, false);
    anchor.addEventListener('keydown', makehref, false);
  }
})();

Add query strings to the anchor


window.oncontextmenu = function() {return false;};

/**
 * Disables context menus, including those initiated by a right click.
 */
function disableRightClick() {
  window.addEventListener('oncontextmenu', function() {
    return false;
  }, true);
}

disableRightClick();

Add JSDoc and use addEventListener


define([
    'app/models/base',
    'app/validations/trade'
  ], function (BaseModel, validation) {
  return BaseModel.extend({
    defaults: {
      'executionOn': null,
      'isBtcSell': false,
      'isBtcBuy': false,
      'currencyIsoCode': 'usd',
      'btcPrice': 0.0,
      'btcAmount': 0.0,
      'xxxAmount': 0.0,
      'btcFee': 0.0,
      'xxxFee': 0.0,
      'isIgnored': false,
      'isDeleted': false,
      'serviceName': '',
      'serviceIdentifier': null,
      'tags': []
    },

    validation: validation
  });
});

define([
    'app/models/base',
    'app/validations/trade',
    'moment',
    'underscore'
  ], function (BaseModel, validation, moment, _) {
  return BaseModel.extend({
    validation: validation,
    defaults: {
      'executionOn': null,
      'isBtcSell': false,
      'isBtcBuy': false,
      'currencyIsoCode': 'usd',
      'btcPrice': 0.0,
      'btcAmount': 0.0,
      'xxxAmount': 0.0,
      'btcFee': 0.0,
      'xxxFee': 0.0,
      'isIgnored': false,
      'isDeleted': false,
      'serviceName': '',
      'serviceIdentifier': null,
      'tags': []
    },

    executionOn: function () {
      var setValue, getValue;

      if (arguments.length > 0) {
        // setter
        setValue = arguments[0];

        if (_.isNull(setValue))
          return this.set('executionOn', null);

        if (!_.isNull(setValue) && !moment.isMoment(setValue))
          throw new Error('No moment object provided!');

        return this.set('executionOn', newValue);
      } else {
        // getter
        getValue = this.get('executionOn');

        return moment(getValue);
      }
    }
  });
});

Add high level getter/setter for executionOn attr


import { ipcRenderer } from 'electron'
import rpc from 'pauls-electron-rpc'

// it would be better to import this from package.json
const BEAKER_VERSION = '0.0.1'

// method which will populate window.beaker with the APIs deemed appropriate for the protocol
export default function () {
  window.beaker = { version: BEAKER_VERSION }
  var webAPIs = ipcRenderer.sendSync('get-web-api-manifests', window.location.protocol)
  for (var k in webAPIs) {
    window[k] = rpc.importAPI(k, webAPIs[k], { timeout: false })
  }
}

import { ipcRenderer, webFrame } from 'electron'
import rpc from 'pauls-electron-rpc'

// it would be better to import this from package.json
const BEAKER_VERSION = '0.0.1'

// method which will populate window.beaker with the APIs deemed appropriate for the protocol
export default function () {

  // mark the safe protocol as 'secure' to enable all DOM APIs
  webFrame.registerURLSchemeAsSecure('safe');
  window.beaker = { version: BEAKER_VERSION }
  var webAPIs = ipcRenderer.sendSync('get-web-api-manifests', window.location.protocol)
  for (var k in webAPIs) {
    window[k] = rpc.importAPI(k, webAPIs[k], { timeout: false })
  }
}

Mark safe as a secure protocol


import { props, shadow, withUpdate } from 'skatejs';

class WithUpdate extends withUpdate() {
  static get props() {
    return {
      name: props.string
    };
  }
  updated() {
    return (shadow(this).innerHTML = `Hello, ${this.name}!`);
  }
}

customElements.define('with-update', WithUpdate);

import { props, shadow, withUpdate } from 'skatejs';

class WithUpdate extends withUpdate() {
  static get props() {
    return {
      name: props.string
    };
  }
  updated() {
    shadow(this).innerHTML = `Hello, ${this.name}!`;
  }
}

customElements.define('with-update', WithUpdate);

Remove return value from sample, it's not doing anything


/**
 * Event
 *
 * @author Rakume Hayashi<i@fake.moe>
 */

Faiash.ise.extend({
    on: function() {
        if (typeof arguments[0] === 'string') {
            for (var i = 0; i < this.length; i++) {
                this[i].addEventListener(arguments[0], arguments[1], arguments[2]);
            }
        } else {
            for (var i = 0; i < this.length; i++) {
                for (var event in this[i]) {
                    if (object.hasOwnProperty(event)) {
                        this[i].addEventListener(event, this[i][event]);
                    }
                }
            }
        }
    }
});

/**
 * Event
 *
 * @author Rakume Hayashi<i@fake.moe>
 */

Faiash.ise.extend({
    bind: function() {
        if (typeof arguments[0] === 'string') {
            for (var i = 0; i < this.length; i++) {
                this[i].addEventListener(arguments[0], arguments[1], arguments[2]);
            }
        } else {
            for (var i = 0; i < this.length; i++) {
                for (var event in this[i]) {
                    if (object.hasOwnProperty(event)) {
                        this[i].addEventListener(event, this[i][event]);
                    }
                }
            }
        }
    },

    unbind: function() {
        if (typeof arguments[0] === 'string') {
            for (var i = 0; i < this.length; i++) {
                this[i].removeEventListener(arguments[0], arguments[1], arguments[2]);
            }
        } else {
            for (var i = 0; i < this.length; i++) {
                for (var event in this[i]) {
                    if (object.hasOwnProperty(event)) {
                        this[i].removeEventListener(event, this[i][event]);
                    }
                }
            }
        }
    }
});

Rename on to bind, add unbind


import {Stream} from 'most'
import MulticastSource from './MulticastSource'

function multicast (stream) {
  const source = stream.source
  return source instanceof MulticastSource
    ? stream
    : new Stream(new MulticastSource(source))
}

export {multicast as default, MulticastSource}

import MulticastSource from './MulticastSource'

function multicast (stream) {
  const source = stream.source
  return source instanceof MulticastSource
    ? stream
    : new stream.constructor(new MulticastSource(source))
}

export {multicast as default, MulticastSource}

Break dep cycle, allow most to use mostjs/multicast


// Configuration
export {default as configure} from './configure';
export {default as configureRoutes} from './configureRoutes';

// Components
export {default as Card} from './components/Card/Card';
export {default as Span} from './components/Specimen/Span';

// Higher-order component for creating specimens
export {default as Specimen} from './components/Specimen/Specimen';

// Specimens
export {default as AudioSpecimen} from './specimens/Audio';
export {default as ButtonSpecimen} from './specimens/Button';
export {default as CodeSpecimen} from './specimens/Code';
export {default as ColorSpecimen} from './specimens/Color';
export {default as HtmlSpecimen} from './specimens/Html';
export {default as HintSpecimen} from './specimens/Hint';
export {default as ImageSpecimen} from './specimens/Image';
export {default as TypeSpecimen} from './specimens/Type';
export {default as ProjectSpecimen} from './specimens/Project/Project';
export {default as DownloadSpecimen} from './specimens/Download';
export {default as ReactSpecimen} from './specimens/ReactSpecimen/ReactSpecimen';
export {default as VideoSpecimen} from './specimens/Video';

// Configuration
export {default as render} from './render';
export {default as configure} from './configure';
export {default as configureRoutes} from './configureRoutes';

// Components
export {default as Card} from './components/Card/Card';
export {default as Span} from './components/Specimen/Span';

// Higher-order component for creating specimens
export {default as Specimen} from './components/Specimen/Specimen';

// Specimens
export {default as AudioSpecimen} from './specimens/Audio';
export {default as ButtonSpecimen} from './specimens/Button';
export {default as CodeSpecimen} from './specimens/Code';
export {default as ColorSpecimen} from './specimens/Color';
export {default as HtmlSpecimen} from './specimens/Html';
export {default as HintSpecimen} from './specimens/Hint';
export {default as ImageSpecimen} from './specimens/Image';
export {default as TypeSpecimen} from './specimens/Type';
export {default as ProjectSpecimen} from './specimens/Project/Project';
export {default as DownloadSpecimen} from './specimens/Download';
export {default as ReactSpecimen} from './specimens/ReactSpecimen/ReactSpecimen';
export {default as VideoSpecimen} from './specimens/Video';

Bring back `render` to module


import React from 'react'
import ReactDOM from 'react-dom'
import {Router, browserHistory} from 'react-router'
import configureStore from './store'
import {Provider} from 'react-redux'
import {syncHistoryWithStore} from 'react-router-redux'
import APIUtils from './utils/APIUtils'
import { AppContainer } from 'react-hot-loader'

import {makeRoutes} from './routes'

// styles are stored separately in production
if (__DEV__)
  require('../stylus/index.styl')
  // require('bootstrap/dist/css/bootstrap.css')

class Root extends React.Component {
  render() {
    return (
      <Provider store={this.props.store}>
        <Router history={browserHistory}>
          {this.props.routes}
        </Router>
      </Provider>
    )
  }
}

const api = new APIUtils()
const store = configureStore(api)
const history = syncHistoryWithStore(browserHistory, store)
function render(routes) {
  console.log('render')
  ReactDOM.render(
    <AppContainer>
      <Provider store={store}>
        <Router history={history}>
          {routes}
        </Router>
      </Provider>
    </AppContainer>,
    document.getElementById('app')
  )
}

render(makeRoutes())
if (module.hot)
  module.hot.accept('./routes', () => render(makeRoutes()))

import React from 'react'
import ReactDOM from 'react-dom'
import {Router, browserHistory} from 'react-router'
import configureStore from './store'
import {Provider} from 'react-redux'
import {syncHistoryWithStore} from 'react-router-redux'
import APIUtils from './utils/APIUtils'
import { AppContainer } from 'react-hot-loader'

import {makeRoutes} from './routes'

import '../stylus/index.styl'

class Root extends React.Component {
  render() {
    return (
      <Provider store={this.props.store}>
        <Router history={browserHistory}>
          {this.props.routes}
        </Router>
      </Provider>
    )
  }
}

const api = new APIUtils()
const store = configureStore(api)
const history = syncHistoryWithStore(browserHistory, store)
function render(routes) {
  console.log('render')
  ReactDOM.render(
    <AppContainer>
      <Provider store={store}>
        <Router history={history}>
          {routes}
        </Router>
      </Provider>
    </AppContainer>,
    document.getElementById('app')
  )
}

render(makeRoutes())
if (module.hot)
  module.hot.accept('./routes', () => render(makeRoutes()))

Fix style loading in production.


import Component from './src/component';
import PureComponent from './src/pureComponent';

export default {
	Component,
	PureComponent,
};

import Component from './component';
import PureComponent from './pureComponent';

export default {
	Component,
	PureComponent,
};

Fix import path after file move.


"use strict";

var assert = require('assert');
var CryptoApi = require('../lib/crypto-api');
var hex = require('../lib/enc.hex');
var md2 = require('../lib/hasher.md2');
var md4 = require('../lib/hasher.md4');
var md5 = require('../lib/hasher.md5');
var sha0 = require('../lib/hasher.sha0');
var sha1 = require('../lib/hasher.sha1');
var sha256 = require('../lib/hasher.sha256');

var TestVectors = require('../test-vectors');

Object.keys(TestVectors).forEach(function(hash) {
    describe('Tests for hash ' + hash, function () {
        Object.keys(TestVectors[hash]).forEach(function(msg) {
            it(msg, function () {
                assert.equal(CryptoApi.hash(hash, TestVectors[hash][msg].message, {}).stringify('hex'), TestVectors[hash][msg].hash);
            });
        });
    });
});
describe('Test Error handling', function () {
    it("CryptoApi.hash('no-hasher')", function () {
        var error = '';
        try {
            CryptoApi.hash('no-hasher', '', {});
        } catch(e) {
            error = e;
        }
        assert.equal(error instanceof Error, true);
    });
    it("CryptoApi.hash('md2').stringify('no-encode')", function () {
        var error = '';
        try {
            CryptoApi.hash('md2', '', {}).stringify('no-encode');
        } catch(e) {
            error = e;
        }
        assert.equal(error instanceof Error, true);
    });
    it("CryptoApi.Hashers.add('undefined', undefined", function () {
        var error = '';
        try {
            CryptoApi.Hashers.add('undefined', undefined);
        } catch(e) {
            error = e;
        }
        assert.equal(error instanceof Error, true);
    });
    it("CryptoApi.Encodes.add('undefined', undefined)", function () {
        var error = '';
        try {
            CryptoApi.Encodes.add('undefined', undefined);
        } catch(e) {
            error = e;
        }
        assert.equal(error instanceof Error, true);
    });
});

Add tests for error handling


const Sequelize = require('sequelize');
const db = require('../db.js');

const beacon = db.define('beacon', {
  currentLocation: {
    type: Sequelize.ARRAY(Sequelize.FLOAT),
  },
})

module.exports = beacon;

const Sequelize = require('sequelize');
const db = require('../db.js');

const beacon = db.define('beacon', {
  currentLocation: {
    type: Sequelize.ARRAY(Sequelize.FLOAT),
  },
  OS: {
    type: Sequelize.STRING,
  },
  token: {
    type: Sequelize.STRING,
  },
  lastNotification: {
    type: Sequelize.DATE,
  },
  device: {
    type: Sequelize.STRING,
  }
})

module.exports = beacon;

Add device info to beacon


import Ember from 'ember';

export default Ember.Mixin.create({
  init: function() {
    this._super();
    if(!this.hasAnalytics()) {
      Ember.Logger.warn('Segment.io is not loaded yet (window.analytics)');
    }
  },
  hasAnalytics: function() {
    return !!(window.analytics && typeof window.analytics === "object");
  },

  log: function() {
    if(this.config && this.config.segment && this.config.segment.LOG_EVENT_TRACKING) {
      Ember.Logger.info('[Segment.io] ', arguments);
    }
  },

  trackPageView: function(page) {
    if(this.hasAnalytics()) {
      window.analytics.page(page);

      this.log('trackPageView', page);
    }
  },

  trackEvent: function(event, properties, options, callback) {
    if(this.hasAnalytics()) {
      window.analytics.track(event, properties, options, callback);
      this.log(event, properties, options);
    }
  },

  identifyUser: function(userId, traits, options, callback) {
    if(this.hasAnalytics()) {
      window.analytics.identify(userId, traits, options, callback);
      this.log('identifyUser', traits, options);
    }
  },

  aliasUser: function(userId, previousId, options, callback) {
    if(this.hasAnalytics()) {
      window.analytics.alias(userId, previousId, options, callback);
      this.log('aliasUser', previousId, options);
    }
  }
});

import Ember from 'ember';

export default Ember.Mixin.create({
  init: function() {
    this._super();
    if(!this.hasAnalytics()) {
      Ember.Logger.warn('Segment.io is not loaded yet (window.analytics)');
    }
  },
  hasAnalytics: function() {
    return !!(window.analytics && typeof window.analytics === "object");
  },

  log: function() {
    if(this.config && this.config.segment && this.config.segment.LOG_EVENT_TRACKING) {
      Ember.Logger.info('[Segment.io] ', arguments);
    }
  },

  trackPageView: function() {
    if(this.hasAnalytics()) {
      window.analytics.page.apply(this, arguments);

      this.log('trackPageView', arguments);
    }
  },

  trackEvent: function(event, properties, options, callback) {
    if(this.hasAnalytics()) {
      window.analytics.track(event, properties, options, callback);
      this.log(event, properties, options);
    }
  },

  identifyUser: function(userId, traits, options, callback) {
    if(this.hasAnalytics()) {
      window.analytics.identify(userId, traits, options, callback);
      this.log('identifyUser', traits, options);
    }
  },

  aliasUser: function(userId, previousId, options, callback) {
    if(this.hasAnalytics()) {
      window.analytics.alias(userId, previousId, options, callback);
      this.log('aliasUser', previousId, options);
    }
  }
});

Allow passing more params to trackPageView


/**
 * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You
 * may not use this file except in compliance with the License. A copy of
 * the License is located at
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */

var AWS = require('../core');

AWS.Route53 = AWS.Service.defineService('route53', ['2012-12-12'], {
  setupRequestListeners: function setupRequestListeners(request) {
    request.on('build', this.sanitizeUrl);
  },

  sanitizeUrl: function sanitizeUrl(request) {
    var path = request.httpRequest.path;
    request.httpRequest.path = path.replace(/\/%2F\w+%2F/, '/');
  },

  setEndpoint: function setEndpoint(endpoint) {
    if (endpoint) {
      AWS.Service.prototype.setEndpoint(endpoint);
    } else {
      var opts = {sslEnabled: true}; // SSL is always enabled for Route53
      this.endpoint = new AWS.Endpoint(this.api.globalEndpoint, opts);
    }
  }
});

module.exports = AWS.Route53;

/**
 * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You
 * may not use this file except in compliance with the License. A copy of
 * the License is located at
 *
 *     http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */

var AWS = require('../core');

AWS.Route53 = AWS.Service.defineService('route53', ['2012-12-12'], {
  /**
   * @api private
   */
  setupRequestListeners: function setupRequestListeners(request) {
    request.on('build', this.sanitizeUrl);
  },

  /**
   * @api private
   */
  sanitizeUrl: function sanitizeUrl(request) {
    var path = request.httpRequest.path;
    request.httpRequest.path = path.replace(/\/%2F\w+%2F/, '/');
  },

  /**
   * @api private
   */
  setEndpoint: function setEndpoint(endpoint) {
    if (endpoint) {
      AWS.Service.prototype.setEndpoint(endpoint);
    } else {
      var opts = {sslEnabled: true}; // SSL is always enabled for Route53
      this.endpoint = new AWS.Endpoint(this.api.globalEndpoint, opts);
    }
  }
});

module.exports = AWS.Route53;

Update documentation for Route53 service


'use strict'

const path = require('path')
const { config } = require(path.join(__dirname, '..', '..', 'main.config.js'))

module.exports = class MockHand {
  constructor (normalizedPosition) {
    this.normalizedPosition = [...normalizedPosition]
    this.target = [...normalizedPosition]
  }

  update (box) {
    this.normalizedPosition.forEach((_, index) => {
      const d = this.target[index] - this.normalizedPosition[index]
      this.normalizedPosition[index] += d * config.leap.mockHandEasing
    })

    return {
      x: this.normalizedPosition[0] * box[0],
      y: this.normalizedPosition[2] * box[1],
      z: this.normalizedPosition[1] * box[2]
    }
  }
}

'use strict'

const path = require('path')
const { config } = require(path.join(__dirname, '..', '..', 'main.config.js'))

module.exports = class MockHand {
  constructor (normalizedPosition) {
    this.normalizedPosition = [...normalizedPosition]
    this.target = [...normalizedPosition]
  }

  update (box) {
    this.normalizedPosition.forEach((_, index) => {
      const d = this.target[index] - this.normalizedPosition[index]
      this.normalizedPosition[index] += d * config.leap.mockHandEasing
    })

    return {
      isMockHand: true,
      x: this.normalizedPosition[0] * box[0],
      y: this.normalizedPosition[2] * box[1],
      z: this.normalizedPosition[1] * box[2]
    }
  }
}

Add method to determine if hand is mocked


var fs   = require('fs-extra');

exports.newer = function(src, dest) {
  var srcTime = 0;
  try {
    var srcTime  = fs.statSync(src).ctime.getTime();
  } catch (ex) {
    return false;
  }
  try {
    var destTime = fs.statSync(dest).ctime.getTime();
    return srcTime > destTime;
  } catch (ex) {
    return true;
  }
};

var fs   = require('fs');

exports.newer = function(src, dest) {
  var srcTime = 0;
  try {
    var srcTime  = fs.statSync(src).mtime.getTime();
  } catch (ex) {
    return false;
  }
  try {
    var destTime = fs.statSync(dest).mtime.getTime();
    return srcTime > destTime;
  } catch (ex) {
    return true;
  }
};

Use modified time instead of creation time when copying folders


var fs = require('fs'),
    _ = require('lodash'),
    yaml = require('js-yaml'),
    bundles = yaml.safeLoad(fs.readFileSync('bundles.yml', 'utf8')),
    settings = require('./config');

function getTag(key, asset) {
    if (key.indexOf('_js') > -1) {
        return '<script type="text/javascript" src="' + asset + '"></script>';
    } else {
        return '<link rel="stylesheet" type="text/css" href="' + asset + '" />';
    }
}

function production(value, key) {
    return [key, getTag(key, value.dest)];
}

function development(value, key) {
    var tags = value.src.map(function(asset) {
        return getTag(key, asset);
    });

    return [key, tags.join('')];
}

var map = settings.env === 'production' ? production : development;

module.exports = _.object(_.map(bundles, map));

var fs = require('fs'),
    _ = require('lodash'),
    yaml = require('js-yaml'),
    bundles = yaml.safeLoad(fs.readFileSync('bundles.yml', 'utf8')),
    settings = require('./config');

function getTag(key, asset) {
    if (key.indexOf('_js') > -1) {
        return '<script type="text/javascript" src="' + asset + '"></script>';
    } else {
        return '<link rel="stylesheet" type="text/css" href="' + asset + '" />';
    }
}

function production(value, key) {
    return [key, getTag(key, value.dest)];
}

function development(value, key) {
    var tags = value.src.map(function(asset) {
        if (asset.indexOf('socket.io.js') > -1) {
            asset ='socket.io/socket.io.js';
        }
        return getTag(key, asset);
    });

    return [key, tags.join('')];
}

var map = settings.env === 'production' ? production : development;

module.exports = _.object(_.map(bundles, map));

Fix loading of socket.io.js when in development mode


import React from 'react';
import ReactDOM from 'react-dom';
import { setComponentsNames, globalizeComponents, promoteInlineExamples, flattenChildren } from './utils/utils';
import StyleGuide from 'rsg-components/StyleGuide';

import 'highlight.js/styles/tomorrow.css';
import './styles.css';

global.React = React;

if (module.hot) {
	module.hot.accept();
}

// Load style guide
let { config, components, sections } = require('styleguide!');

function processComponents(cs) {
	cs = flattenChildren(cs);
	cs = promoteInlineExamples(cs);
	cs = setComponentsNames(cs);
	globalizeComponents(cs);

	return cs;
}

function processSections(ss) {
	return ss.map(section => {
		section.components = processComponents(section.components || []);
		section.sections = processSections(section.sections || []);

		return section;
	});
}

// Components are required unless sections are provided
if (sections) {
	sections = processSections(sections)
	components = []
} else {
	components = processComponents(components)
	sections = []
}
components = components ? processComponents(components) : [];
sections = sections ? processSections(sections) : [];

ReactDOM.render(<StyleGuide config={config} components={components} sections={sections} />, document.getElementById('app'));

import React from 'react';
import ReactDOM from 'react-dom';
import { setComponentsNames, globalizeComponents, promoteInlineExamples, flattenChildren } from './utils/utils';
import StyleGuide from 'rsg-components/StyleGuide';

import 'highlight.js/styles/tomorrow.css';
import './styles.css';

global.React = React;

if (module.hot) {
	module.hot.accept();
}

// Load style guide
let { config, components, sections } = require('styleguide!');

function processComponents(cs) {
	cs = flattenChildren(cs);
	cs = promoteInlineExamples(cs);
	cs = setComponentsNames(cs);
	globalizeComponents(cs);

	return cs;
}

function processSections(ss) {
	return ss.map(section => {
		section.components = processComponents(section.components || []);
		section.sections = processSections(section.sections || []);

		return section;
	});
}

// Components are required unless sections are provided
if (sections) {
	sections = processSections(sections);
	components = [];
}
else {
	components = processComponents(components);
	sections = [];
}

ReactDOM.render(<StyleGuide config={config} components={components} sections={sections} />, document.getElementById('app'));

Fix linting issues and duplicate check for components and sections


import functionalText from "functional-text";

window.addEventListener("DOMContentLoaded", function () {
    let inputNode = document.querySelector("#input");
    let outputHtmlNode = document.querySelector("#output-html");

    let str = `Sample Text for parsing`.trim();

    inputNode.value = str;
    inputNode.style.height = '200px';
    inputNode.style.width = '100%';

    function runParser() {
        let parsedHtml = functionalText(inputNode.value);
        outputHtmlNode.innerHTML = parsedHtml.replace(/</g, "<").replace(/>/g, ">");
    }

    inputNode.addEventListener("input", runParser, 200);
    try {
        runParser();
    } catch (err) {
        console.error(err);
    }
});

import functionalText from "functional-text";

window.addEventListener("DOMContentLoaded", function () {
    let inputNode = document.querySelector("#input");
    let outputHtmlNode = document.querySelector("#output-html");

    let str = `Sample Text for parsing`.trim();

    inputNode.value = str;
    inputNode.style.height = '200px';
    inputNode.style.width = '100%';

    function runParser() {
        try {
            let parsedHtml = functionalText(inputNode.value);
            outputHtmlNode.style.borderColor = "black";
            outputHtmlNode.innerHTML = parsedHtml.replace(/</g, "<").replace(/>/g, ">");
        } catch (error) {
            outputHtmlNode.style.borderColor = "red";
            outputHtmlNode.innerHTML = error;
        }
    }

    inputNode.addEventListener("input", runParser, 200);
    runParser();
});

Move try-catch into the parsing logic, and display errors into the output.


import React from 'react';
import { render } from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';

import App from './components/app';

import rootReducer from './reducers'

const store = createStore(rootReducer);

render(
	<Provider store={store}>
		<App />
	</Provider>, document.getElementById('app'));

import React from 'react';
import { render } from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';

import App from './components/app';

import rootReducer from './reducers'

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);

render(
	<Provider store={createStoreWithMiddleware(rootReducer)}>
		<App />
	</Provider>, document.getElementById('app'));

Update React app entry point: Add middleware to the project Use redux-thunk lib Applies middleware and use it as store


import React from 'react';
import App from './app/App';

React.render(<App />, document.body);

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app/App';

const appRoot = document.createElement('div');

appRoot.id = 'app';
document.body.appendChild(appRoot);
ReactDOM.render(<App />, appRoot);

Update App rendering to comply with React 0.14


import glob from 'glob'
import path from 'path'
import Dns from './dns'
import { name as packageName } from '../package.json'

export default () => {
  const dns = new Dns()

  // Load Plugins
  glob(
    `./node_modules/${packageName}-plugin-*`,
    ( err, files ) => {
        files
          .forEach(
            ( plugin ) => {
              plugin = path.basename( plugin )

              const instance = eval('require')( plugin )

              if ( instance && instance.default )
                new instance.default( dns )
              else if ( instance ) {
                new instance( dns )
              }
            }
          )

        // Finally start the DNS daemon
        dns.start()
    }
  )
}

import { exec } from 'child_process'
import glob from 'glob'
import path from 'path'
import Dns from './dns'
import { name as packageName } from '../package.json'

const dns = new Dns()

function getNodeModulesPath( isGlobal ) {
  return new Promise (
    ( resolve, reject ) => {
      if ( isGlobal )
        exec(
          `npm config get prefix -g`,
          ( err, stdout, stderr ) => {
            if ( err ) reject( err )
            else if ( stderr ) reject ( stderr )
            else resolve( stdout )
          }
        )
      else
        resolve(
          `${path.resolve()}/node_modules`
        )
    }
  )
}

function loadPlugins( pluginPath ) {
  return new Promise (
    ( resolve, reject ) => {
      // Load Plugins
      glob(
        `${pluginPath}/${packageName}-plugin-*`,
        ( err, files ) => {
            if ( err ) reject( err )
            else {
              files
                .forEach(
                  ( plugin ) => {
                    plugin = path.basename( plugin )

                    const instance = eval('require')( plugin )

                    if ( instance && instance.default )
                      new instance.default( dns )
                    else if ( instance ) {
                      new instance( dns )
                    }
                  }
                )

              // Finally resolve
              resolve()
            }
        }
      )
    }
  )
}

export default () => {
  Promise.resolve()
    .catch( err => console.log( err ) )
    // Load global plugins
    .then( () => getNodeModulesPath( true ) )
    .then( path => loadPlugins( path ) )
    // Load local plugins
    .then( () => getNodeModulesPath() )
    .then( path => loadPlugins( path ) )
    // Start the DNS
    .then( () => dns.start() )
}

Allow loading of local and global plugins


import R from 'ramda';
import And from './and';
import Or from './or';
import Conjunction from './conjunction';

/**
 * Check if the given object is an object-like `And` conjunction.
 * @param {Object} obj
 * @param {String} obj.type
 * @returns {Boolean}
 */
const objectIsAndConjunction = R.compose(
  R.equals(And.type()),
  R.prop('type')
);

/**
 * Check if the given object is an object-like `Or` conjunction.
 * @param {Object} obj
 * @param {String} obj.type
 * @returns {Boolean}
 */
const objectIsOrConjunction = R.compose(
  R.equals(Or.type()),
  R.prop('type')
);

const create = obj => {
  if (objectIsOrConjunction(obj)) {
    return new Or(obj.mappings);
  } else if (objectIsAndConjunction(obj)) {
    return new And(obj.mappings);
  } else {
    var message = 'Cannot create conjunction based on ' + obj;
    throw new Error(message);
  }
}

export default {
  create,
  And,
  Or,
  Conjunction
};

import R from 'ramda';
import And from './and';
import Or from './or';
import Conjunction from './conjunction';

/**
 * Check if the given object is an object-like `And` conjunction.
 * @param {Object} obj
 * @param {String} obj.type
 * @returns {Boolean}
 */
const objectIsAndConjunction = R.compose(
  R.equals(And.type()),
  R.prop('type')
);

/**
 * Check if the given object is an object-like `Or` conjunction.
 * @param {Object} obj
 * @param {String} obj.type
 * @returns {Boolean}
 */
const objectIsOrConjunction = R.compose(
  R.equals(Or.type()),
  R.prop('type')
);

const create = obj => {
  if (objectIsOrConjunction(obj)) {
    return new Or(obj.mappings);
  } else if (objectIsAndConjunction(obj)) {
    return new And(obj.mappings);
  } else {
    var message = 'Cannot create conjunction based on ' + obj;
    throw new Error(message);
  }
}

module.exports = {
  create,
  And,
  Or,
  Conjunction
};

export default module.exports

Add support to old module.exports (webpack has issue with it)


import { currentURL, visit } from '@ember/test-helpers';
import { module, test } from 'qunit';
import setupAuthentication from 'ilios/tests/helpers/setup-authentication';
import { percySnapshot } from 'ember-percy';

import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { getElementText, getText } from 'ilios/tests/helpers/custom-helpers';

module('Acceptance: assign students', function(hooks) {
  setupApplicationTest(hooks);
  setupMirage(hooks);
  hooks.beforeEach(async function () {
    const school = this.server.create('school');
    await setupAuthentication({ school, administeredSchools: [this.school] });
    this.server.create('school');
  });

  test('visiting /admin/assignstudents', async function(assert) {
    await visit('/admin/assignstudents');

    assert.equal(await getElementText('.schoolsfilter'), getText('school 0'));

    assert.equal(currentURL(), '/admin/assignstudents');
    percySnapshot(assert);
  });
});

import { currentURL, visit } from '@ember/test-helpers';
import { module, test } from 'qunit';
import setupAuthentication from 'ilios/tests/helpers/setup-authentication';
import { percySnapshot } from 'ember-percy';

import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { getElementText, getText } from 'ilios/tests/helpers/custom-helpers';

module('Acceptance: assign students', function(hooks) {
  setupApplicationTest(hooks);
  setupMirage(hooks);
  hooks.beforeEach(async function () {
    const school = this.server.create('school');
    await setupAuthentication({ school, administeredSchools: [school] });
    this.server.create('school');
  });

  test('visiting /admin/assignstudents', async function(assert) {
    await visit('/admin/assignstudents');

    assert.equal(await getElementText('.schoolsfilter'), getText('school 0'));

    assert.equal(currentURL(), '/admin/assignstudents');
    percySnapshot(assert);
  });
});

Fix test to pass model not nothing


import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';
import App from './App';
import Board from './Board';
import './styles/index.css';

ReactDOM.render(
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <Route path="boards/:abbreviation/" component={Board}>
        {/*<Route path="boards/:abbreviation/" component={ThreadList} />*/}
        <Route path=":thread/" />
      </Route>
    </Route>
  </Router>,
  document.getElementById('root')
);

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';
import App from './App';
import Board from './Board';
import './styles/index.css';

ReactDOM.render(
  <Router history={browserHistory}>
    <Route path="/" component={App}>
      <Route path="boards/:abbreviation/" component={Board}>
        <Route path=":threadId" />
      </Route>
    </Route>
  </Router>,
  document.getElementById('root')
);

Fix bug with Board not realizing it's in a thread view


export default {
  name: 'Apollo Starter Kit',
  logging: {
    level: 'info',
    debugSQL: false,
    apolloLogging: ['production'].indexOf(process.env.NODE_ENV) < 0
  },
  // Check here for Windows and Mac OS X: https://code.visualstudio.com/docs/editor/command-line#_opening-vs-code-with-urls
  // Use this protocol handler for Linux: https://github.com/sysgears/vscode-handler
  stackFragmentFormat: 'vscode://file/{0}:{1}:{2}'
};

export default {
  name: 'Apollo Starter Kit',
  logging: {
    level: ['production'].indexOf(process.env.NODE_ENV) < 0 ? 'debug' : 'info',
    debugSQL: false,
    apolloLogging: ['production'].indexOf(process.env.NODE_ENV) < 0
  },
  // Check here for Windows and Mac OS X: https://code.visualstudio.com/docs/editor/command-line#_opening-vs-code-with-urls
  // Use this protocol handler for Linux: https://github.com/sysgears/vscode-handler
  stackFragmentFormat: 'vscode://file/{0}:{1}:{2}'
};

Set log level to info only in production


var extend = require('extend')

var bv, createClient

module.exports.mock = function (mocks) {
  var boxview = 'box-view'
  bv = require(boxview)
  createClient = bv.createClient
  bv.createClient = function (token) {
    if (token === 'your api token') {
      throw new Error('(HINT) remember to replace "your api token" with your Box View token!')
    }
    var client = createClient(token)
      , mock = extend(true, {}, client, mocks)
    mock.documents.__ = client.documents
    mock.sessions.__ = client.sessions
    return mock
  }
}

module.exports.restore = function () {
  if (bv) {
    bv.createClient = createClient
  }
}

var extend = require('extend')

var bv, createClient

module.exports.mock = function (mocks, creator) {
  var boxview = 'box-view'
  bv = require(boxview)
  createClient = bv.createClient
  bv.createClient = function (token) {
    if (token === 'your api token') {
      throw new Error('(HINT) remember to replace "your api token" with your Box View token!')
    }
    var client = createClient(token)
      , mock = extend(true, {}, client, mocks)

    mock.documents.__ = client.documents
    mock.sessions.__ = client.sessions
    client.token = token
    mock.documents.__client = client
    mock.sessions.__client = client

    return creator(mock, token)
  }
}

module.exports.restore = function () {
  if (bv) {
    bv.createClient = createClient
  }
}

Add token and client reference to box-view mock


var Trie = require('../app/trie');

describe('Trie', function() {
  var trie;

  beforeEach(function() {
    trie = new Trie();
  });

  it('should be an object', function() {
    expect(trie).to.be.ok;
  });

  it('should have add method', function() {
    expect(trie.add).to.be.an.instanceof(Function);
  });

  it('should have search method', function() {
    expect(trie.search).to.be.an.instanceof(Function);
  });

  it('should have find method', function() {
    expect(trie.find).to.be.an.instanceof(Function);
  });
});

var Trie = require('../app/trie');

describe('Trie', function() {
  var trie;

  beforeEach(function() {
    trie = new Trie();
  });

  it('should be an object', function() {
    expect(trie).to.be.ok;
  });

  it('should have a root', function() {
    expect(trie.root).to.be.ok;
  });

  it('should have add method', function() {
    expect(trie.add).to.be.an.instanceof(Function);
  });

  it('should have search method', function() {
    expect(trie.search).to.be.an.instanceof(Function);
  });

  it('should have find method', function() {
    expect(trie.find).to.be.an.instanceof(Function);
  });
});

Add check for root variable in Trie


export function extractAttributes(el) {
  const map = el.hasAttributes() ? el.attributes : []
  const attrs = {}
  for (let i = 0; i < map.length; i++) {
    const attr = map[i]
    if (attr.value) {
      attrs[attr.name] = attr.value === '' ? true : attr.value
    }
  }
  let klass, style
  if (attrs.class) {
    klass = attrs.class
    delete attrs.class
  }
  if (attrs.style) {
    style = attrs.style
    delete attrs.style
  }
  const data = {
    attrs,
    class: klass,
    style,
  }
  return data
}

export function freeze(item) {
  if (Array.isArray(item) || typeof item === 'object') {
    return Object.freeze(item)
  }
  return item
}

export function combinePassengers(transports, slotProps = {}) {
  return transports.reduce((passengers, transport) => {
    let newPassengers = transport.passengers[0]
    newPassengers =
      typeof newPassengers === 'function'
        ? newPassengers(slotProps)
        : newPassengers
    return passengers.concat(newPassengers)
  }, [])
}

export function extractAttributes(el) {
  const map = el.hasAttributes() ? el.attributes : []
  const attrs = {}
  for (let i = 0; i < map.length; i++) {
    const attr = map[i]
    if (attr.value) {
      attrs[attr.name] = attr.value === '' ? true : attr.value
    }
  }
  let klass, style
  if (attrs.class) {
    klass = attrs.class
    delete attrs.class
  }
  if (attrs.style) {
    style = attrs.style
    delete attrs.style
  }
  const data = {
    attrs,
    class: klass,
    style,
  }
  return data
}

export function freeze(item) {
  if (Array.isArray(item) || typeof item === 'object') {
    return Object.freeze(item)
  }
  return item
}

export function combinePassengers(transports, slotProps = {}) {
  return transports.reduce((passengers, transport) => {
    let newPassengers = transport.passengers[0]
    newPassengers =
      typeof newPassengers === 'function'
        ? newPassengers(slotProps)
        : transport.passengers
    return passengers.concat(newPassengers)
  }, [])
}

Fix bug wher only one element was returned


/*
 Copyright, 2013, by Tomas Korcak. <korczis@gmail.com>

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */

(function (global) {
    require
    (
        ["ember", "app"], function (Ember, App) {

            App.ApplicationRoute = Ember.Route.extend({
                title: "Microscratch",

                model: function() {
                },

                setupController: function(controller, model) {
                }
            });

            App.ApplicationController = Ember.Controller.extend({
            });

            App.ApplicationView = Ember.View.extend({
                classNames: ['app-view'],
                templateName: "application",

                /**
                 * Called when inserted to DOM.
                 * @memberof Application.ApplicationView
                 * @instance
                 */
                didInsertElement: function () {
                    console.log("App.ApplicationView.didInsertElement()");
                }
            });
        }
    );
})(this);

/*
 Copyright, 2013, by Tomas Korcak. <korczis@gmail.com>

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */

(function (global) {
    require
    (
        ["ember", "app"], function (Ember, App) {

            App.ApplicationView = Ember.View.extend({
                classNames: ['app-view'],
                templateName: "application",

                /**
                 * Called when inserted to DOM.
                 * @memberof Application.ApplicationView
                 * @instance
                 */
                didInsertElement: function () {
                    console.log("App.ApplicationView.didInsertElement()");
                }
            });
        }
    );
})(this);

Remove empty route and controller


'use strict';
var express = require('express');

module.exports = function buildAdminRouter(mediator) {
  var router = express.Router();

  // TODO: Remove this endpoint when not needed
  if (process.env.NODE_ENV !== 'production') {
    /**
     * Asks for data to be reset to the default list of users
     * This is intended only for demonstration/debugging purposes
     * and by default only runs on NODE_ENV === 'development'
     */
    require('./addResetEndpoint')(router, mediator);
  }

  return router;
};

'use strict';
var express = require('express');

module.exports = function buildAdminRouter(mediator) {
  var router = express.Router();

  /**
   * Asks for data to be reset to the default list of users
   * This is intended only for demonstration/debugging purposes.
   * TODO: Remove this endpoint in production or when not needed
   */
  require('./addResetEndpoint')(router, mediator);

  return router;
};

Remove check for environment to add data reset endpoint


global.assert = require('assert');
global.chai = require("chai");
global.chaiAsPromised = require("chai-as-promised");
global.jsf = require('json-schema-faker');
global.should = require('should');
global.sinon = require('sinon');

// Load schemas
global.mocks = require('./mocks');

// Run the tests
require('./unit');

global.assert = require('assert');
global.chai = require("chai");
global.chaiAsPromised = require("chai-as-promised");
global.jsf = require('json-schema-faker');
global.should = require('should');
global.sinon = require('sinon');
global._ = require('lodash');

// Load schemas
global.mocks = require('./mocks');

// Run the tests
require('./unit');

Add lodash access in global scope


function clearAndHideResultTable() {
  var header = $('table.matching-term .header');
  $('table.matching-term').html(header);
  $('table.matching-term').hide();
}

function hideNoResults() {
  $('.no-results').hide();
}

function showNoResults() {
  $('.no-results').show();
}

function showResultTable() {
  hideNoResults();
  $('table.matching-term').show();
}

function searchResults(query) {
  clearAndHideResultTable();
  var found = $('[data-search*=' + query).parent('tr');
  return found;
}

function addToResultTable(result){
  showResultTable();
  var table = $('.matching-term');
  var lastChild = table.find('tr:last');
  if(lastChild.length == 0) {
    table.html(result);
  }
  else {
    lastChild.after(result);
  }
}

$(document).on('ready', function(){
  $('input[name=search]').keyup(function(event){
    var searchTerm = event.target.value;
    if(searchTerm.length > 0) {
      hideNoResults();
      var results = searchResults(searchTerm.toLowerCase());
      if (results.length > 0) {
        $.each(results, function(index, value){
          addToResultTable($(value).clone());
        });
      }
      else {
        showNoResults();
      }
    }
    else {
      hideNoResults();
      clearAndHideResultTable();
    }
  });
});

DomElements = {
  matchingTerm: 'table.matching-term'
};

function clearAndHideResultTable() {
  var header = $('table.matching-term .header');
  $(DomElements.matchingTerm).html(header);
  $(DomElements.matchingTerm).hide();
}

function hideNoResults() {
  $('.no-results').hide();
}

function showNoResults() {
  $('.no-results').show();
}

function showResultTable() {
  hideNoResults();
  $(DomElements.matchingTerm).show();
}

function searchResults(query) {
  clearAndHideResultTable();
  var found = $('[data-search*=' + query).parent('tr');
  return found;
}

function addToResultTable(result){
  showResultTable();
  var table = $('.matching-term');
  var lastChild = table.find('tr:last');
  if(lastChild.length == 0) {
    table.html(result);
  }
  else {
    lastChild.after(result);
  }
}

$(document).on('ready', function(){
  $('input[name=search]').keyup(function(event){
    var searchTerm = event.target.value;
    if(searchTerm.length > 0) {
      hideNoResults();
      var results = searchResults(searchTerm.toLowerCase());
      if (results.length > 0) {
        $.each(results, function(index, value){
          addToResultTable($(value).clone());
        });
      }
      else {
        showNoResults();
      }
    }
    else {
      hideNoResults();
      clearAndHideResultTable();
    }
  });
});

Add JS lookup to object


const parseVariations = require('../variations');
const createValidator = require('./validator');
const validate = createValidator({
    variations: {type: 'array', minLen: 1},
    // There can be a user of Mendel who does not want variation but faster build.
    allVariationDirs: {type: 'array', minLen: 0},
    allDirs: {type: 'array', minLen: 1},
});

function VariationConfig(config) {
    const variations = parseVariations(config);
    const allVariationDirs = getAllDirs(variations);

    const baseVariation = {
        id: config.baseConfig.id,
        chain: [config.baseConfig.dir],
    };
    variations.push(baseVariation);

    const allDirs = getAllDirs(variations);
    const variationConfig = {
        variations,
        baseVariation,
        allDirs,
        allVariationDirs,
    };

    validate(variationConfig);

    return variationConfig;
}

function getAllDirs(variationArray) {
    return variationArray.reduce((allDirs, variation) => {
        variation.chain.forEach(dir => {
            if (!allDirs.includes(dir)) allDirs.push(dir);
        });
        return allDirs;
    }, []);
}

module.exports = VariationConfig;

const parseVariations = require('../variations');
const createValidator = require('./validator');
const validate = createValidator({
    variations: {type: 'array', minLen: 1},
    // There can be a user of Mendel who does not want variation but faster build.
    allVariationDirs: {type: 'array', minLen: 0},
    allDirs: {type: 'array', minLen: 1},
});

function VariationConfig(config) {
    const variations = parseVariations(config);
    const allVariationDirs = getAllDirs(variations);

    const baseVariation = {
        id: config.baseConfig.id,
        chain: [config.baseConfig.dir],
    };
    // base variation must come first in order to variationMatches to work
    variations.unshift(baseVariation);

    const allDirs = getAllDirs(variations);
    const variationConfig = {
        variations,
        baseVariation,
        allDirs,
        allVariationDirs,
    };

    validate(variationConfig);

    return variationConfig;
}

function getAllDirs(variationArray) {
    return variationArray.reduce((allDirs, variation) => {
        variation.chain.forEach(dir => {
            if (!allDirs.includes(dir)) allDirs.push(dir);
        });
        return allDirs;
    }, []);
}

module.exports = VariationConfig;

Fix base files identified as wrong variation


jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;
jQuery.unique = Sizzle.uniqueSort;
jQuery.getText = getText;
jQuery.isXMLDoc = isXML;
jQuery.contains = contains;

Make sure that we're not trying to pull in things that don't exist, durr.


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

moduleForAcceptance('Acceptance | create new object');

test('visiting /create-new-object', function(assert) {
  visit('/collectionobject/new');

  andThen(function() {
    assert.equal(currentURL(), '/collectionobject/new');
  });
});

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

moduleForAcceptance('Acceptance | create new object');

test('visiting /create-new-object', function(assert) {
  /*visit('/collectionobject/new');

  andThen(function() {
    assert.equal(currentURL(), '/collectionobject/new');
  });*/

  assert.equal('', '');
});

Update acceptance test to dummy test


KB.onClick('.js-autocomplete-email', function (e) {
    var email = KB.dom(e.target).data('email');
    var emailField = KB.find('.js-mail-form input[type="email"]');

    if (email && emailField) {
        emailField.build().value = email;
    }

    _KB.controllers['Dropdown'].close();
});

KB.onClick('.js-autocomplete-subject', function (e) {
    var subject = KB.dom(e.target).data('subject');
    var subjectField = KB.find('.js-mail-form input[name="subject"]');

    if (subject && subjectField) {
        subjectField.build().value = subject;
    }

    _KB.controllers['Dropdown'].close();
});

KB.onClick('.js-autocomplete-email', function (e) {
    var email = KB.dom(e.target).data('email');
    var emailField = KB.find('.js-mail-form input[type="email"]');

    if (email && emailField) {
        emailField.build().value = email;
    }

    _KB.controllers.Dropdown.close();
});

KB.onClick('.js-autocomplete-subject', function (e) {
    var subject = KB.dom(e.target).data('subject');
    var subjectField = KB.find('.js-mail-form input[name="subject"]');

    if (subject && subjectField) {
        subjectField.build().value = subject;
    }

    _KB.controllers.Dropdown.close();
});

Use dot notation in Javascript component


Package.describe({
  name: 'easysearch:elasticsearch',
  summary: "Elasticsearch Engine for EasySearch",
  version: "2.1.1",
  git: "https://github.com/matteodem/meteor-easy-search.git",
  documentation: 'README.md'
});

Npm.depends({
  'elasticsearch': '8.2.0'
});

Package.onUse(function(api) {
  api.versionsFrom('1.4.2');

  // Dependencies
  api.use(['check', 'ecmascript']);
  api.use(['easysearch:core@2.1.0', 'erasaur:meteor-lodash@4.0.0']);

  api.addFiles([
    'lib/data-syncer.js',
    'lib/engine.js',
  ]);

  api.export('EasySearch');
  api.mainModule('./lib/main.js');
});

Package.onTest(function(api) {
  api.use(['tinytest', 'ecmascript']);
  api.use('easysearch:elasticsearch');

  api.addFiles(['tests/engine-tests.js']);
});

Package.describe({
  name: 'easysearch:elasticsearch',
  summary: "Elasticsearch Engine for EasySearch",
  version: "2.1.1",
  git: "https://github.com/matteodem/meteor-easy-search.git",
  documentation: 'README.md'
});

Npm.depends({
  'elasticsearch': '13.0.0'
});

Package.onUse(function(api) {
  api.versionsFrom('1.4.2');

  // Dependencies
  api.use(['check', 'ecmascript']);
  api.use(['easysearch:core@2.1.0', 'erasaur:meteor-lodash@4.0.0']);

  api.addFiles([
    'lib/data-syncer.js',
    'lib/engine.js',
  ]);

  api.export('EasySearch');
  api.mainModule('./lib/main.js');
});

Package.onTest(function(api) {
  api.use(['tinytest', 'ecmascript']);
  api.use('easysearch:elasticsearch');

  api.addFiles(['tests/engine-tests.js']);
});

Update ES client to support ES 5.x


import Adapter from './adapter';
import { inspect } from 'ember-metal';

/**
  This class implements the methods defined by Ember.Test.Adapter for the
  QUnit testing framework.

  @class QUnitAdapter
  @namespace Ember.Test
  @extends Ember.Test.Adapter
  @public
*/
export default Adapter.extend({
  asyncStart() {
    QUnit.stop();
  },
  asyncEnd() {
    QUnit.start();
  },
  exception(error) {
    ok(false, inspect(error));
  }
});

import { inspect } from 'ember-utils';
import Adapter from './adapter';

/**
  This class implements the methods defined by Ember.Test.Adapter for the
  QUnit testing framework.

  @class QUnitAdapter
  @namespace Ember.Test
  @extends Ember.Test.Adapter
  @public
*/
export default Adapter.extend({
  asyncStart() {
    QUnit.stop();
  },
  asyncEnd() {
    QUnit.start();
  },
  exception(error) {
    ok(false, inspect(error));
  }
});

Refactor ember-utils imports in ember-testing package.


const API_URL = process.env.API_URL

export default {
  GET_TOP_GAMES  : () => `${API_URL}/gamess`,
  GET_PRICES     : appIds => `${API_URL}/games/prices?appIds=${appIds}`,
  GET_SUGGESTIONS: name => `${API_URL}/games/suggestions?name=${name}`,
  SEARCH_GAMES   : name => `${API_URL}/games/search?name=${name}`,
  GET_RATES      : () => `${API_URL}/rates`
}

const API_URL = process.env.API_URL

export default {
  GET_TOP_GAMES  : () => `${API_URL}/games`,
  GET_PRICES     : appIds => `${API_URL}/games/prices?appIds=${appIds}`,
  GET_SUGGESTIONS: name => `${API_URL}/games/suggestions?name=${name}`,
  SEARCH_GAMES   : name => `${API_URL}/games/search?name=${name}`,
  GET_RATES      : () => `${API_URL}/rates`
}

Fix wrong api for games list


module("Text Descendant", {
});

test("Find text descendants in an iframe.", function() {
    // Setup fixture
    var fixture = document.getElementById('qunit-fixture');

    var iframe = document.createElement('iframe');
    var html = '
bar
';
    fixture.appendChild(iframe);
    iframe.contentWindow.document.open();
    iframe.contentWindow.document.write(html);
    iframe.contentWindow.document.close();

    var foo = iframe.contentDocument.getElementById("foo");

    equal(axs.properties.hasDirectTextDescendant(foo), true);
});

module("findTextAlternatives", {
  setup: function () {
    this.fixture_ = document.getElementById('qunit-fixture');
  }
});
test("returns the selector text for a nested object with a class attribute", function() {
  var targetNode = document.createElement('select');
  this.fixture_.appendChild(targetNode);

  try {
    equal(axs.properties.findTextAlternatives(targetNode, {}, true), "");
    return ok(true);
  } catch( e ) {
    return ok(false, "Threw exception");
  }
});

Test that findTextAlternatives does not raise errors


import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import 'reflect-metadata'; // here location matters: has to be before import of AppModule

import { AppModule } from './imports/components/app.module';

import 'zone.js'; // here location matters: has to be after import of AppModule
                  // Note: this import loads 'zone.js' itself but also 'long-stack-trace-zone'

platformBrowserDynamic().bootstrapModule(AppModule)
.then((ref) => console.log("App is running"))
.catch((err) => console.error(err));

import 'reflect-metadata'; // here location matters: has to be before import of AppModule
                           // and even before other imports under Windows

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './imports/components/app.module';

import 'zone.js'; // here location matters: has to be after import of AppModule
                  // Note: this import loads 'zone.js' itself but also 'long-stack-trace-zone'

platformBrowserDynamic().bootstrapModule(AppModule)
.then((ref) => console.log("App is running"))
.catch((err) => console.error(err));

Move import 'reflect-metadata' before other ones.


"use strict";

var loki = require('lokijs');
var _ = require('lodash');
var Q = require('q');

//  variable to hold the singleton instance, if used in that manner
var userDAOInstance = undefined;

//
// User Data Access Object
//

// Constructor
function UserDAO(dbName) {
	// Define database name
	dbName = (dbName != '') ? dbName : 'janux.people.db';
	// Create db
	this._db = new loki(dbName);
	// Add users collection
	this._users = this._db.addCollection('users');
}

// Get User Object by id
UserDAO.prototype.getUserById = function (userId, callback) {
	return Q.when( this._users.findOne( { userId:userId } ) );
};

// Get User Object by username
UserDAO.prototype.getUserByName = function (userName) {
	return Q.when( this._users.findOne( { username:userName } ) );
};

// Add new User Object
UserDAO.prototype.addUser = function (aUserObj) {
	this._users.insert(aUserObj);
};

exports.createInstance = function() {
	return new UserDAO();
};

exports.singleton = function() {
	// if the singleton has not yet been instantiated, do so
	if ( !_.isObject(userDAOInstance) ) {
		userDAOInstance = new UserDAO();
	}

	return userDAOInstance;
};

"use strict";

var loki = require('lokijs');
var _ = require('lodash');
var Promise  = require('bluebird');

//  variable to hold the singleton instance, if used in that manner
var userDAOInstance = undefined;

//
// User Data Access Object
//

// Constructor
function UserDAO(dbName) {
	// Define database name
	dbName = (dbName != '') ? dbName : 'janux.people.db';
	// Create db
	this._db = new loki(dbName);
	// Add users collection
	this._users = this._db.addCollection('users');
}

// Get User Object by id
UserDAO.prototype.findUserById = function (userId, callback) {

	var users = this._users.findOne( { userId:userId });
	return new Promise(function(resolve){
		resolve( users );
	}).asCallback(callback);
};

// Get User Object by username
UserDAO.prototype.findUserByName = function (userName, callback) {

	var users = this._users.findOne( { username:userName } );
	return new Promise(function(resolve){
		resolve( users );
	}).asCallback(callback);
};

// Add new User Object
UserDAO.prototype.addUser = function (aUserObj) {
	this._users.insert(aUserObj);
};

exports.createInstance = function() {
	return new UserDAO();
};

exports.singleton = function() {
	// if the singleton has not yet been instantiated, do so
	if ( !_.isObject(userDAOInstance) ) {
		userDAOInstance = new UserDAO();
	}

	return userDAOInstance;
};

Implement bluebird instead of Q inside demo userDAO


/* global document */
function setCookie(name, value, options = {}) {
  let cookieString = `${name}=${value}; path=/`;

  if (options.days) {
    const date = new Date();
    date.setTime(date.getTime() + (options.days * 24 * 60 * 60 * 1000));
    cookieString = `${cookieString}; expires=${date.toGMTString()}`;
  }

  if (document.location.protocol === 'https:') {
    cookieString = `${cookieString}; Secure`;
  }

  document.cookie = cookieString;
}

function getCookie(name) {
  const nameEQ = `${name}=`;
  const cookies = document.cookie.split(';');

  for (let i = 0, len = cookies.length; i < len; i++) {
    let cookie = cookies[i];

    while (cookie.charAt(0) === ' ') {
      cookie = cookie.substring(1, cookie.length);
    }

    if (cookie.indexOf(nameEQ) === 0) {
      return decodeURIComponent(cookie.substring(nameEQ.length));
    }
  }

  return null;
}

$(function() {
  const banner = document.getElementById('global-cookies-banner');

  if (banner && getCookie('nhsuk_seen_cookie_message') === null) {
    banner.style.display = 'block';
    setCookie('nhsuk_seen_cookie_message', 'yes', { days: 28 });
  }
});

(function(global) {
  'use strict'
  var $ = global.jQuery;
  var document = global.document;

  function setCookie(name, value, options) {
    options = options || {};
    var cookieString = name + '=' + value + '; path=/';

    if (options.days) {
      var date = new Date();
      date.setTime(date.getTime() + (options.days * 24 * 60 * 60 * 1000));
      cookieString = cookieString + '; expires=' + date.toGMTString();
    }

    if (document.location.protocol === 'https:') {
      cookieString = cookieString + '; Secure';
    }

    document.cookie = cookieString;
  }

  function getCookie(name) {
    var nameEQ = name + '=';
    var cookies = document.cookie.split(';');

    for (var i = 0, len = cookies.length; i < len; i++) {
      var cookie = cookies[i];

      while (cookie.charAt(0) === ' ') {
        cookie = cookie.substring(1, cookie.length);
      }

      if (cookie.indexOf(nameEQ) === 0) {
        return decodeURIComponent(cookie.substring(nameEQ.length));
      }
    }

    return null;
  }

  $(function() {
    var banner = document.getElementById('global-cookies-banner');

    if (banner && getCookie('nhsuk_seen_cookie_message') === null) {
      banner.style.display = 'block';
      setCookie('nhsuk_seen_cookie_message', 'yes', { days: 28 });
    }
  });
})(window);

Update script to be IE7+ compatible


/* global describe, it, expect */
import { filterByKeys, transform } from '../src/transform'
import * as mocks from './mocks'

describe('Transform suite', () => {
  it('should filter by keys two objects', () => {
    const keys = Object.keys(mocks.defs.simple)
    expect(filterByKeys(keys, mocks.defs.complex)).toEqual(mocks.defs.simple)
  })

  it('should transform a definition into a fulfilled object', () => {
    expect(transform(mocks.defs.simple, mocks.fulfilled)).toEqual(mocks.fulfilled)
  })

  it('should transform a definition using mutators', () => {
    expect(transform(mocks.defs.simple, mocks.fulfilled, mocks.mutators)).toMatchSnapshot()
  })

  it('should be able to define agent mutators', () => {
    transform.mutators = { foo: 'bar' }
    expect(transform(mocks.defs.simple, mocks.fulfilled)).toMatchSnapshot()
  })
})

/* global describe, it, expect */
import { filterByKeys, transform } from '../src/transform'
import * as mocks from './mocks'

describe('Transform suite', () => {
  const keys = Object.keys(mocks.defs.simple)

  it('should filter by keys two objects', () => {
    expect(filterByKeys(keys, mocks.defs.complex)).toEqual(mocks.defs.simple)
  })

  it('should transform a definition into a fulfilled object', () => {
    expect(transform(mocks.defs.simple, mocks.fulfilled)).toEqual(mocks.fulfilled)
  })

  it('should transform a definition using mutators', () => {
    expect(transform(mocks.defs.simple, mocks.fulfilled, mocks.mutators)).toMatchSnapshot()
  })

  it('should be able to define agent mutators', () => {
    const mutator = { foo: 'bar' }
    transform.mutators = mutator

    expect(transform(mocks.defs.simple, mocks.fulfilled)).toMatchSnapshot()
    expect(transform.mutators).toEqual(mutator)
  })

  it('should be able to define keys declaratively', () => {
    transform.keys = keys
    expect(transform.keys).toEqual(keys)
  })
})

Check transform definitions are well set


var app = require('app');
var BrowserWindow = require('browser-window');
var mainWindow = null;

app.on('window-all-closed', function() {
    app.quit();
});

app.on('ready', function() {
  mainWindow = new BrowserWindow({
    "width": 225,
    "height": 225,
    "transparent": true,
    "frame": false,
    "always-on-top": true,
    "resizable": false
  });
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

var {app} = require('electron');
var {BrowserWindow} = require('electron');
var mainWindow = null;

app.on('window-all-closed', function() {
    app.quit();
});

app.on('ready', function() {
  mainWindow = new BrowserWindow({
    "width": 225,
    "height": 225,
    "transparent": true,
    "frame": false,
    "always-on-top": true,
    "resizable": false
  });
  mainWindow.loadURL('file://' + __dirname + '/index.html');
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

Fix problems on the latest electron


angular
    .module('app')
    .controller('changelogController', [
        '$rootScope',
        '$scope',
        'apiService',
        function($rootScope, $scope, api) {

            api.changelog.then(function(response) {
                $scope.changelog = response.data;
            });

        }
    ]);

angular
    .module('app')
    .controller('changelogController', [
        '$rootScope',
        '$scope',
        'apiService',
        function($rootScope, $scope, api) {

            api.changelog().then(function(response) {
                $scope.changelog = response.data;
            });

        }
    ]);

Fix for change log error


// Thests for the open method for fs module. This opens a file for reading only.
//
var fs=newFS();
var fileName="hello.txt";
var content="hello";
function testOpen(){
	try{
		f=fs.open(fileName);
		message=f.read();
    if(message!=content){
      throw "expected "+content+" got "+message;
    }
		f.close();
	}catch(e){
		throw e;
	}
}
testOpen();

// Thests for the open method for fs module. This opens a file for reading only.
//
var fs=newFS();
var fileName="hello.txt";
var content="hello";
function testOpen(){
  console.log("-- Testing fs.open");
	try{
		f=fs.open(fileName);
		message=f.read();
    if(message!=content){
      throw "expected "+content+" got "+message;
    }
		f.close();
	}catch(e){
		throw e;
	}
}
testOpen();

Add logging information to a test script


'use strict'

const mapResult = result => {
  return {
    name: result.contract.name,
    consumer: result.contract.consumer,
    status: result.err ? 'Fail' : 'Pass',
    error: result.err
  }
}

module.exports = mapResult

'use strict'

const Joi = require('joi')

const mapResult = result => {
  return {
    name: result.contract.name,
    consumer: result.contract.consumer,
    status: result.err ? 'Fail' : 'Pass',
    error: result.err ? result.err.toString() : null
  }
}

module.exports = mapResult

Tweak to result mapper. Fixed example contract to use new syntax


function cleanupPlugins(resolve, reject) {
  'use strict';
  if (!axe._audit) {
    throw new Error('No audit configured');
  }

  var q = axe.utils.queue();
  // If a plugin fails it's cleanup, we still want the others to run
  var cleanupErrors = [];

  Object.keys(axe.plugins).forEach(function (key) {
    q.defer(function (res) {
      var rej = function (err) {
        cleanupErrors.push(err);
        res();
      };
      try {
        axe.plugins[key].cleanup(res, rej);
      } catch(err) {
        rej(err);
      }
    });
  });

  var flattenedTree = axe.utils.getFlattenedTree(document.body)

  axe.utils.querySelectorAll(flattenedTree, 'iframe, frame').forEach(function (node) {
    q.defer(function (res, rej) {
      return axe.utils.sendCommandToFrame(node.actualNode, {
        command: 'cleanup-plugin'
      }, res, rej);
    });
  });

  q.then(function (results) {
    if (cleanupErrors.length === 0) {
      resolve(results);
    } else {
      reject(cleanupErrors);
    }
  })
  .catch(reject);
}
axe.cleanup = cleanupPlugins;

function cleanupPlugins(resolve, reject) {
  'use strict';
  if (!axe._audit) {
    throw new Error('No audit configured');
  }

  var q = axe.utils.queue();
  // If a plugin fails it's cleanup, we still want the others to run
  var cleanupErrors = [];

  Object.keys(axe.plugins).forEach(function (key) {
    q.defer(function (res) {
      var rej = function (err) {
        cleanupErrors.push(err);
        res();
      };
      try {
        axe.plugins[key].cleanup(res, rej);
      } catch(err) {
        rej(err);
      }
    });
  });

  var flattenedTree = axe.utils.getFlattenedTree(document.body);

  axe.utils.querySelectorAll(flattenedTree, 'iframe, frame').forEach(function (node) {
    q.defer(function (res, rej) {
      return axe.utils.sendCommandToFrame(node.actualNode, {
        command: 'cleanup-plugin'
      }, res, rej);
    });
  });

  q.then(function (results) {
    if (cleanupErrors.length === 0) {
      resolve(results);
    } else {
      reject(cleanupErrors);
    }
  })
  .catch(reject);
}
axe.cleanup = cleanupPlugins;

Fix lint problem in cleanup-plugin


"use strict";
// DO NOT EDIT THIS FILE, EDIT THE GRUNT TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE
angular.module('publisherApp')

.constant('ENV', 'dev')

.constant('VERSION', '1.2.1-SNAPSHOT')

;

"use strict";
// DO NOT EDIT THIS FILE, EDIT THE GRUNT TASK NGCONSTANT SETTINGS INSTEAD WHICH GENERATES THIS FILE
angular.module('publisherApp')

.constant('ENV', 'dev')

.constant('VERSION', '1.2.2-SNAPSHOT')

;

Update ngconstant version after releasing


import Ember from 'ember';
import Application from '../../app';
import config from '../../config/environment';

export default function startApp(attrs) {
  let application;

  let attributes = Ember.assign({}, config.APP);
  attributes = Ember.assign(attributes, attrs); // use defaults, but you can override;

  Ember.run(() => {
    application = Application.create(attributes);
    application.setupForTesting();
    application.injectTestHelpers();
  });

  return application;
}

import Ember from 'ember';
import Application from '../../app';
import config from '../../config/environment';

export default function startApp(attrs) {
  let application;

  let attributes = (Ember.assign || Ember.merge)({}, config.APP);
  attributes = (Ember.assign || Ember.merge)(attributes, attrs); // use defaults, but you can override;

  Ember.run(() => {
    application = Application.create(attributes);
    application.setupForTesting();
    application.injectTestHelpers();
  });

  return application;
}

Allow for versions of ember that don't have Ember.assign yet


var nijs = require('nijs');

exports.pkg = function(args) {
  return args.stdenv().mkDerivation({
    name : "node-0.10.26",
    src : args.fetchurl()({
      url : new nijs.NixURL("http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gz"),
      sha256 : "1ahx9cf2irp8injh826sk417wd528awi4l1mh7vxg7k8yak4wppg"
    }),

    configureFlags : [ "--shared-openssl", "--shared-zlib" ],

    buildInputs : [
      args.python(),
      args.openssl(),
      args.zlib(),
      args.utillinux()
    ],

    setupHook : new nijs.NixFile({
      value : "setup-hook.sh",
      module : module
    }),

    meta : {
      homepage : new nijs.NixURL("http://nodejs.org"),
      description : "Platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications"
    }
  });
};

var nijs = require('nijs');

exports.pkg = function(args) {
  return args.stdenv().mkDerivation({
    name : "node-0.10.26",
    src : args.fetchurl()({
      url : new nijs.NixURL("http://nodejs.org/dist/v0.10.26/node-v0.10.26.tar.gz"),
      sha256 : "1ahx9cf2irp8injh826sk417wd528awi4l1mh7vxg7k8yak4wppg"
    }),

    preConfigure : 'sed -i -e "s|#!/usr/bin/env python|#! $(type -p python)|" configure',

    configureFlags : [ "--shared-openssl", "--shared-zlib" ],

    buildInputs : [
      args.python(),
      args.openssl(),
      args.zlib(),
      args.utillinux()
    ],

    setupHook : new nijs.NixFile({
      value : "setup-hook.sh",
      module : module
    }),

    meta : {
      homepage : new nijs.NixURL("http://nodejs.org"),
      description : "Platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications"
    }
  });
};

Fix path to python interpreter to make it work with chroot builds


import React from 'react'
import injectSheet from 'react-jss'

import styles from './styles'

const GenResults = ({ classes, newLine, results, stats }) => {
  let joinedResults = Array.prototype.join.call(results, `${newLine ? '\n' : ' '}`).trim()
  let words = stats.words
  let maxWords = stats.maxWords
  let filtered = stats.filtered

  const statsText = () => {
    if (filtered > 0) {
      return `words: ${words} (${filtered} filtered out); maximum different words: ${maxWords}`
    } else {
      return `words: ${words}; maximum different words: ${maxWords}`
    }
  }

  return (

          {joinedResults}

          {statsText()}

  )
}

export default injectSheet(styles)(GenResults)

import React from 'react'
import injectSheet from 'react-jss'

import styles from './styles'

const GenResults = ({ classes, newLine, results, stats }) => {
  let joinedResults = Array.prototype.join.call(results, `${newLine ? '\n' : ' '}`).trim()
  let words = stats.words
  let maxWords = stats.maxWords
  let filtered = stats.filtered

  const statsText = () => {
    if (filtered > 0) {
      return `words: ${words.toLocaleString()} (${filtered.toLocaleString()} filtered out); maximum different words: ${maxWords.toLocaleString()}`
    } else {
      return `words: ${words.toLocaleString()}; maximum different words: ${maxWords.toLocaleString()}`
    }
  }

  return (

          {joinedResults}

          {statsText()}

  )
}

export default injectSheet(styles)(GenResults)

Add locale formatting to stats numbers


var configuration = require('../../config/configuration.json')
var utility = require('../../public/method/utility')

module.exports = {
  getSubcampaignModel: function (redisClient, subcampaignHashID, callback) {
    var tableName = configuration.TableMASubcampaignModel + subcampaignHashID
    redisClient.hmget(tableName,
      configuration.ConstantSCMMinBudget,
      configuration.ConstantSCMSubcampaignName,
      configuration.ConstantSCMSubcampaignStyle,
      configuration.ConstantSCMSubcampaignPlan,
      configuration.ConstantSCMSubcampaignPrice,
      configuration.ConstantSCMFileURL,
      function (err, replies) {
        if (err) {
          callback(err, null)
          return
        }
        callback(null, replies)
      }
    )
  },
}

var configuration = require('../../config/configuration.json')
var utility = require('../../public/method/utility')

module.exports = {
  getSubcampaignModel: function (redisClient, subcampaignHashID, callback) {
    var tableName = configuration.TableMASubcampaignModel + subcampaignHashID
    redisClient.hmget(tableName,
      configuration.ConstantSCMMinBudget,
      configuration.ConstantSCMSubcampaignName,
      configuration.ConstantSCMSubcampaignStyle,
      configuration.ConstantSCMSubcampaignPlan,
      configuration.ConstantSCMSubcampaignPrice,
      configuration.ConstantSCMFileURL,
      function (err, replies) {
        if (err) {
          callback(err, null)
          return
        }
        callback(null, replies)
      }
    )
  },

  getSubcampaignList: function (redisClient, campiagnHashID, filter, callback) {
    var filterKeys = Object.keys(filter)
    if (filterKeys.length == 0) {
      var tableName = configuration.TableMSCampaignModelSubcampaignModel + accountHashID
      redisClient.zrange(tableName, '0', '-1', 'WITHSCORES', function (err, replies) {
        if (err) {
          callback(err, null)
          return
        }
        callback(null, replies)
      })
    }
    else {
      var destinationTableName = configuration.TableMACampaignModel + configuration.TableTemporary + utility.generateUniqueHashID()
      var result
      var args = []
      args.push(destinationTableName)
      args.push(filterKeys.length)
      for (var i = 0; i < filterKeys.length; i++) {
        var key = configuration.campaignEnum[filterKeys[i]]
        var table = configuration.TableName.general.SubcampaignModel + accountHashID
        utility.stringReplace(table, '@', key)
        args.push(table)
      }
      args.push('AGGREGATE')
      args.push('MAX')
      redisClient.zinterstore(args, function (err, replies) {
        if (err) {
          callback(err, null)
          return
        }
        redisClient.zrange(destinationTableName, '0', '-1', 'WITHSCORES', function (err, replies) {
          if (err) {
            callback(err, null)
            return
          }
          result = replies
          redisClient.zremrangebyrank(destinationTableName, '0', '-1', function (err, replies) {
            if (err) {
              callback(err, null)
              return
            }
            callback(null, result)
          })
        })
      })
    }
  },
}

Implement Get List of Subcampaign HashIDs (By Filter)


var config = {}
module.exports = config;

config.listen = {}
config.listen.address = '0.0.0.0'
config.listen.port = 3080;

// Margan is used to be logger, visit here to get more info:
// https://github.com/expressjs/morgan
config.logType = 'combined';

config.trust_proxy = 'loopback, 163.13.128.112';

var config = {}
module.exports = config;

config.listen = {}
config.listen.address = '0.0.0.0'
config.listen.port = 3080;

// Margan is used to be logger, visit here to get more info:
// https://github.com/expressjs/morgan
config.logType = 'combined';

config.trust_proxy = 'loopback, uniquelocal';

Edit trust_proxy setting of express.


import _ from 'lodash'
import mergeDefaults from 'merge-defaults'
_.mergeDefaults = mergeDefaults

class ConfigManager {
	constructor() {
		this.Riak = {
			nodes: ["localhost:8098"]
		}

		this.GremlinServer = {
			port: 8182,
			host: "localhost",
			options: {}
		}
	}

	setRiakCluster(nodes) {
		if(arguments.length === 1 && nodes instanceof Array)
			this.Riak.nodes = nodes
		else
			this.Riak.nodes = [].slice.call(arguments)
	}
	setGremlinClientConfig(port, host, options) {
		this.GremlinServer = _.mergeDefaults({
			port: port,
			host: host,
			options: options
		} || {}, this.GremlinServer)
	}
}
export default new ConfigManager()

import _ from 'lodash'
import mergeDefaults from 'merge-defaults'
import is from 'is_js'
_.mergeDefaults = mergeDefaults

class ConfigManager {
	constructor() {
		this.Riak = {
			nodes: ["localhost:8098"]
		}

		this.GremlinServer = {
			port: 8182,
			host: "localhost",
			options: {}
		}
	}

	setRiakCluster(nodes) {
		if(arguments.length === 1 && is.array(nodes))
			this.Riak.nodes = nodes
		else
			this.Riak.nodes = [].slice.call(arguments)
	}
	setGremlinClientConfig(port, host, options) {
		this.GremlinServer = _.mergeDefaults({
			port: port,
			host: host,
			options: options
		} || {}, this.GremlinServer)
	}
}
export default new ConfigManager()

Use is instead of instanceof to determine if it is an array


const webpack = require('webpack');
const merge = require('webpack-merge');
const webpackConfig = require('./webpack.base.conf');
const config = require('./index');

const HtmlWebpackPlugin = require('html-webpack-plugin');

// so that everything is absolute
webpackConfig.output.publicPath = `${config.domain}:${config.port}/`;

// add hot-reload related code to entry chunks
Object.keys(webpackConfig.entry).forEach((name) => {
  webpackConfig.entry[name] = [
    `webpack-dev-server/client?${webpackConfig.output.publicPath}`,
    'webpack/hot/dev-server',
  ].concat(webpackConfig.entry[name]);
});

module.exports = merge(webpackConfig, {
  devtool: '#eval-source-map',

  devServer: {
    outputPath: 'dist/',
    inline: true,
  },

  module: {
    rules: [
      {
        test: /\.s[ac]ss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ],
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env': { NODE_ENV: '"development"' },
    }),

    new webpack.HotModuleReplacementPlugin(),

    new webpack.NoEmitOnErrorsPlugin(),

    new HtmlWebpackPlugin({
      excludeChunks: ['static'],
      filename: '../layout/theme.liquid',
      template: './layout/theme.liquid',
      inject: true,
    }),
  ],
});

const webpack = require('webpack');
const merge = require('webpack-merge');
const webpackConfig = require('./webpack.base.conf');
const config = require('./index');

const HtmlWebpackPlugin = require('html-webpack-plugin');

// so that everything is absolute
webpackConfig.output.publicPath = `${config.domain}:${config.port}/`;

// add hot-reload related code to entry chunks
Object.keys(webpackConfig.entry).forEach((name) => {
  webpackConfig.entry[name] = [
    `webpack-dev-server/client?${webpackConfig.output.publicPath}`,
    'webpack/hot/dev-server',
  ].concat(webpackConfig.entry[name]);
});

module.exports = merge(webpackConfig, {
  devtool: '#eval-source-map',

  devServer: {
    outputPath: 'dist/',
    inline: true,
  },

  module: {
    rules: [
      {
        test: /\.s[ac]ss$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader', options: { sourceMap: true } },
          { loader: 'sass-loader', options: { sourceMap: true } },
        ],
      },
    ],
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env': { NODE_ENV: '"development"' },
    }),

    new webpack.HotModuleReplacementPlugin(),

    new webpack.NoEmitOnErrorsPlugin(),

    new HtmlWebpackPlugin({
      excludeChunks: ['static'],
      filename: '../layout/theme.liquid',
      template: './layout/theme.liquid',
      inject: true,
    }),
  ],
});

Add sass sourcemaps to dev env


'use strict';

if ($ === undefined) {
  throw 'Gelato requires jQuery as a dependency.'
} else {
  window.jQuery = window.$ = $;
}

if (_ === undefined) {
  throw 'Gelato requires Lodash as a dependency.'
} else {
  window._ = _;
}

if (Backbone === undefined) {
  throw 'Gelato requires Backbone as a dependency.'
} else {
  window.Backbone = Backbone;
}

var Gelato = {};

Gelato._BUILD = '{!date!}';

Gelato._VERSION = '{!version!}';

Gelato.isLocalhost = function() {
  return location.hostname === 'localhost';
};

Gelato.isWebsite = function() {
  return _.includes(location.protocol, 'http');
};

'use strict';

if ($ === undefined) {
  throw 'Gelato requires jQuery as a dependency.'
} else {
  window.jQuery = window.$ = $;
}

if (_ === undefined) {
  throw 'Gelato requires Lodash as a dependency.'
} else {
  window._ = _;
}

if (Backbone === undefined) {
  throw 'Gelato requires Backbone as a dependency.'
} else {
  window.Backbone = Backbone;
}

var Gelato = {};

Gelato._BUILD = '{!date!}';

Gelato._VERSION = '{!version!}';

Gelato.isCordova = function() {
  return window.cordova !== undefined;
};

Gelato.isLocalhost = function() {
  return location.hostname === 'localhost';
};

Gelato.isWebsite = function() {
  return _.includes(location.protocol, 'http');
};

Add method for checking if cordova is being used


'use strict';

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

module.exports = {
  'name': 'placeholder-in-extend',
  'defaults': {},
  'detect': function (ast, parser) {
    var result = [];

    ast.traverseByType('atkeyword', function (keyword, i, parent) {
      keyword.forEach(function (item) {
        if (item.content === 'extend') {

          parent.forEach('simpleSelector', function (selector) {
            var placeholder = false;

            selector.content.forEach(function (selectorPiece) {
              if (selectorPiece.type === 'placeholder') {
                placeholder = true;
              }
            });

            if (!placeholder) {
              result = helpers.addUnique(result, {
                'ruleId': parser.rule.name,
                'line': selector.start.line,
                'column': selector.start.column,
                'message': '@extend must be used with a %placeholder',
                'severity': parser.severity
              });
            }
          });
        }
      });
    });

    return result;
  }
};

'use strict';

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

module.exports = {
  'name': 'placeholder-in-extend',
  'defaults': {},
  'detect': function (ast, parser) {
    var result = [];

    ast.traverseByType('atkeyword', function (keyword, i, parent) {
      keyword.forEach(function (item) {
        if (item.content === 'extend') {

          parent.forEach('selector', function (selector) {
            var placeholder = false;

            selector.content.forEach(function (selectorPiece) {
              if (selectorPiece.type === 'placeholder') {
                placeholder = true;
              }
            });

            if (!placeholder) {
              result = helpers.addUnique(result, {
                'ruleId': parser.rule.name,
                'line': selector.start.line,
                'column': selector.start.column,
                'message': '@extend must be used with a %placeholder',
                'severity': parser.severity
              });
            }
          });
        }
      });
    });

    return result;
  }
};

Replace deprecated node type simpleSelector with selector


import fetch from 'isomorphic-fetch';

export function invalidateReddit({ reddit }) {}

export function requestPosts({ reddit }) {}

export function receivePosts({ reddit, json }) {
  return {
    reddit,
    posts: json.data.children.map(child => child.data),
    receivedAt: Date.now()
  };
}

function fetchPosts({ reddit }, { currentActionSet }) {
  currentActionSet.requestPosts({ reddit });

  fetch(`http://www.reddit.com/r/${reddit}.json`)
    .then(response => response.json())
    .then(json => currentActionSet.receivePosts({ reddit, json }))
  ;
}

export const introspection = {
  shouldFetchPosts({ reddit }) {}
}

export function fetchPostsIfNeeded({ reddit }, { currentActionSet, getConsensus }) {
  if (currentActionSet.getConsensus.shouldFetchPosts({ reddit }).some()) {
    fetchPosts({ reddit }, { currentActionSet });
  }
}

import fetch from 'isomorphic-fetch';

export function invalidateReddit({ reddit }) {}

export function requestPosts({ reddit }) {}

export function receivePosts({ reddit, json }) {
  return {
    reddit,
    posts: json.data.children.map(child => child.data),
    receivedAt: Date.now()
  };
}

function fetchPosts({ reddit }, { currentActionSet }) {
  currentActionSet.requestPosts({ reddit });

  fetch(`http://www.reddit.com/r/${reddit}.json`)
    .then(response => response.json())
    .then(json => currentActionSet.receivePosts({ reddit, json }))
  ;
}

export const introspection = {
  shouldFetchPosts({ reddit }) {}
}

export function fetchPostsIfNeeded({ reddit }, { currentActionSet }) {
  if (currentActionSet.consensus.shouldFetchPosts({ reddit }).some()) {
    fetchPosts({ reddit }, { currentActionSet });
  }
}

Update async-redux example to getConsensus -> consensus


var Promise = require('ember-cli/lib/ext/promise');

var chalk  = require('chalk');
var yellow = chalk.yellow;
var blue   = chalk.blue;

function applyDefaultConfigIfNecessary(config, prop, defaultConfig, ui){
  if (!config[prop]) {
    var value = defaultConfig[prop];
    config[prop] = value;
    ui.write(blue('|    '));
    ui.writeLine(yellow('- Missing config: `' + prop + '`, using default: `' + value + '`'));
  }
}

module.exports = function(ui, config) {
  ui.write(blue('|    '));
  ui.writeLine(blue('- validating config'));

  var defaultConfig = {
    filePattern: '**/*.{js,css,png,gif,jpg,map,xml,txt}'
  };
  applyDefaultConfigIfNecessary(config, 'filePattern', defaultConfig, ui);

  return Promise.resolve();
}

var Promise = require('ember-cli/lib/ext/promise');

var chalk  = require('chalk');
var yellow = chalk.yellow;
var blue   = chalk.blue;

function applyDefaultConfigIfNecessary(config, prop, defaultConfig, ui){
  if (!config[prop]) {
    var value = defaultConfig[prop];
    config[prop] = value;
    ui.write(blue('|    '));
    ui.writeLine(yellow('- Missing config: `' + prop + '`, using default: `' + value + '`'));
  }
}

module.exports = function(ui, config) {
  ui.write(blue('|    '));
  ui.writeLine(blue('- validating config'));

  var defaultConfig = {
    filePattern: '**/*.{js,css,png,gif,jpg,map,xml,txt,svg,eot,ttf,woff,woff2}'
  };
  applyDefaultConfigIfNecessary(config, 'filePattern', defaultConfig, ui);

  return Promise.resolve();
}

Include webfont extensions in default filePatterns


export default class GameModelService {
	constructor($log, $http, $localStorage, _, websocket) {
		'ngInject';

		this.$log = $log;
		this.$http = $http;
		this.$localStorage = $localStorage;

		this._ = _;
		this.ws = websocket;

		this.model = {
			game: null
		};
	}

	update(data) {
		this.model.game = data;
	}
}

export default class GameModelService {
	constructor($log, $http, $localStorage, _, websocket) {
		'ngInject';

		this.$log = $log;
		this.$http = $http;
		this.$localStorage = $localStorage;

		this._ = _;
		this.ws = websocket;

		this.model = {
			game: {}
		};
	}

	isGameStarted() {
		return !this._.isEmpty(this.model.game);
	}

	update(data) {
		data.isGameStarted = true;
		this.model.isGameStarted = true;

		Object.assign(this.model.game, data);
	}
}

Add 'isGameStarted' property to GameModelService


function testFeature(feature) {
  if (feature.annotations.ignore) {
    describe.skip(`Feature: ${feature.title}`, () => {});
  } else {
    describe(`Feature: ${feature.title}`, function() {
      feature.scenarios.forEach(function(scenario) {
        if (scenario.annotations.ignore) {
          describe.skip(`Scenario: ${scenario.title}`, () => {});
        } else {
          describe(`Scenario: ${scenario.title}`, function() {
            before(function() {
              this.application = startApp();
            });

            after(function() {
              destroyApp(this.application);
            });

            let context = { ctx: {} };
            let failed = false;
            scenario.steps.forEach(function(step) {
              it(step, function() {
                if (failed === true) {
                  this.test.pending = true;
                  this.skip();
                } else {
                  let self = this;
                  let promise = new Ember.RSVP.Promise(function(resolve) {
                    yadda.Yadda(library.default(), self).yadda(step, context, function next(err, result) {
                      if (err) {
                        failed = true;
                        throw err;
                      }

                      return result;
                    });
                  });

                  return promise;
                }
              });
            });
          });
        }
      });
    });
  }
}

function testFeature(feature) {
  if (feature.annotations.ignore) {
    describe.skip(`Feature: ${feature.title}`, () => {});
  } else {
    describe(`Feature: ${feature.title}`, function() {
      feature.scenarios.forEach(function(scenario) {
        if (scenario.annotations.ignore) {
          describe.skip(`Scenario: ${scenario.title}`, () => {});
        } else {
          describe(`Scenario: ${scenario.title}`, function() {
            before(function() {
              this.application = startApp();
            });

            after(function() {
              destroyApp(this.application);
            });

            let context = { ctx: {} };
            let failed = false;
            scenario.steps.forEach(function(step) {
              it(step, function() {
                if (failed === true) {
                  this.test.pending = true;
                  this.skip();
                } else {
                  let self = this;
                  let promise = new Ember.RSVP.Promise(function(resolve) {
                    yadda.Yadda(library.default(), self).yadda(step, context, function next(err, result) {
                      if (err) {
                        failed = true;
                        throw err;
                      }

                      resolve(result);
                    });
                  });

                  return promise;
                }
              });
            });
          });
        }
      });
    });
  }
}

Fix hanging promise in mocha