var provision = function(abstraction, options) {
  var self = this; // eslint-disable-line no-unused-vars

  if (options.provider) {
    abstraction.setProvider(options.provider);
  }

  if (options.network_id) {
    abstraction.setNetwork(options.network_id);
  }

  if (options.network && options.networks) {
    abstraction.setNetworkType(options.networks[options.network].type);
  }

  if (options.ens) {
    abstraction.ens = options.ens;
  }

  ["from", "gas", "gasPrice"].forEach(function(key) {
    if (options[key]) {
      var obj = {};
      obj[key] = options[key];
      abstraction.defaults(obj);
    }
  });

  return abstraction;
};

module.exports = provision;

var provision = function(abstraction, options) {
  var self = this; // eslint-disable-line no-unused-vars

  if (options.provider) {
    abstraction.setProvider(options.provider);
  }

  if (options.network_id) {
    abstraction.setNetwork(options.network_id);
  }

  if (options.network && options.networks) {
    abstraction.setNetworkType(options.networks[options.network].type);
  }

  abstraction.ens = options.ens;

  ["from", "gas", "gasPrice"].forEach(function(key) {
    if (options[key]) {
      var obj = {};
      obj[key] = options[key];
      abstraction.defaults(obj);
    }
  });

  return abstraction;
};

module.exports = provision;

Add ens settings to the contract objects


/*
 * Copyright 2011 eBay Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';
var varNameRegExp = /^[A-Za-z_][A-Za-z0-9_\.]*$/;
function AssignNode(props) {
    AssignNode.$super.call(this);
    if (props) {
        this.setProperties(props);
    }
}
AssignNode.prototype = {
    doGenerateCode: function (template) {
        var varName = this.getProperty('var');
        var value = this.getProperty('value');
        if (!varName) {
            this.addError('"var" attribute is required');
        }
        if (!value) {
            this.addError('"value" attribute is required');
        }
        if (varName) {
            template.statement(varName + '=' + value + ';');
        }
    }
};

module.exports = AssignNode;

/*
 * Copyright 2011 eBay Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';
// var varNameRegExp = /^[A-Za-z_][A-Za-z0-9_\.]*$/;
function AssignNode(props) {
    AssignNode.$super.call(this);
    if (props) {
        this.setProperties(props);
    }
}
AssignNode.prototype = {
    doGenerateCode: function (template) {
        var varName = this.getProperty('var');
        var value = this.getProperty('value');
        if (!varName) {
            this.addError('"var" attribute is required');
        }
        if (!value) {
            this.addError('"value" attribute is required');
        }
        if (varName) {
            template.statement(varName + '=' + value + ';');
        }
    }
};

module.exports = AssignNode;

Remove varNameRegExp since it's never used;


'use strict';

function retrieveContact(conn, date, limit, offset, cb) {
  conn.sobject("Contact")
    .select('Id, IsDeleted, FirstName, LastName, Name, Phone, Fax, MobilePhone, MailingStreet, HomePhone, OtherPhone, AssistantPhone, Email, Title, Birthdate, PhotoUrl, CreatedDate, LastModifiedDate')
    .where('LastModifiedDate >= ' + date.toISOString())
    .orderby('LastModifiedDate', 'DESC')
    .limit(limit)
    .offset(offset)
    .execute(cb);
}

module.exports = function retrieveContacts(conn, cursor, limit, cb) {
  if(!cursor) {
    cursor = new Date(1970);
  }

  var counter = 0;
  var contacts = [];
  function retryRetrieve(cb) {
    retrieveContact(conn, cursor, limit, counter, function(err, results) {
      if(err) {
        return cb(err);
      }

      contacts = contacts.concat(results);
      counter += results.length;

      if(results.length !== limit) {
        return cb(null, new Date(), contacts);
      }
      else {
        return retryRetrieve(cb);
      }
    });
  }

  retryRetrieve(cb);
};

'use strict';

function retrieveContact(conn, date, limit, offset, cb) {
  conn.sobject("Contact")
    .select('Id, IsDeleted, FirstName, LastName, Name, Phone, Fax, MobilePhone, MailingStreet, HomePhone, OtherPhone, AssistantPhone, Email, Title, Birthdate, PhotoUrl, CreatedDate, LastModifiedDate')
    .where('LastModifiedDate >= ' + date.toISOString())
    .orderby('LastModifiedDate', 'DESC')
    .limit(limit)
    .offset(offset)
    .execute(cb);
}

module.exports = function retrieveContacts(conn, cursor, limit, cb) {
  if(!cursor) {
    cursor = new Date(1970);
  }

  var counter = 0;
  var contacts = [];
  function retryRetrieve(cb) {
    retrieveContact(conn, cursor, limit, counter, function(err, results) {
      if(err) {
        return cb(err);
      }

      contacts = contacts.concat(results);
      counter += results.length;

      // We can't have an offset greater than 2000
      // So we need to stop with counter > 2000
      if(results.length !== limit || counter > 2000) {
        return cb(null, new Date(), contacts);
      }
      else {
        return retryRetrieve(cb);
      }
    });
  }

  retryRetrieve(cb);
};

Stop retrieving contact with offset > 2000


var Q = require('Q'),
    childProcess = require('child_process');

function processPath(exec) {
  var exec = exec ||  Q.denodeify(childProcess.exec);
  var deferred = Q.defer();

  function handleDone(stdout, stderr) {
    var location = stdout[0].trim().replace(/\n$/, '');
    deferred.resolve(location);
  }

  function handleError(error) {
    deferred.reject(error);
  }

  exec('which mpd').done(handleDone, handleError);

  return deferred.promise;
}

function create(configFilepath, spawn) {
  var spawn = spawn || childProcess.spawn;
  var dfd = Q.defer();

  this.processPath().then(function (path) {
    var mpdProcess = spawn(path, [configFilepath, '--no-daemon']);

    mpdProcess.stdout.on('data', function (data) {
      dfd.resolve();
    });

    mpdProcess.on('error', function (error) {
      dfd.reject();
    });
  }, function() { dfd.reject(); });

  return dfd.promise;
}

module.exports = {
  processPath: processPath,
  create: create
};

var Q = require('Q'),
    childProcess = require('child_process');

function processPath(exec) {
  var exec = exec ||  Q.denodeify(childProcess.exec);
  var deferred = Q.defer();

  function handleDone(stdout, stderr) {
    var location = stdout[0].trim().replace(/\n$/, '');
    deferred.resolve(location);
  }

  function handleError(error) {
    deferred.reject(error);
  }

  exec('which mpd').done(handleDone, handleError);

  return deferred.promise;
}

function create(configFilepath, spawn) {
  var spawn = spawn || childProcess.spawn;
  var dfd = Q.defer();

  this.processPath().then(function (path) {
    var mpdProcess = spawn(path, [configFilepath, '--no-daemon']);

    mpdProcess.stdout.on('data', function (data) {
      dfd.resolve();
    });

    mpdProcess.on('error', function (error) {
      dfd.reject();
    });
  }, function() { dfd.reject('Could not find MPD binary'); });

  return dfd.promise;
}

module.exports = {
  processPath: processPath,
  create: create
};

Add failure message when MPD path is not found


module.exports = function(gulp, settings) {
    // Create the browserSync server.
    settings.dynamic.browserSync = require('browser-sync').create();

    /**
     * Initialize the browser sync server (static).
     */
    gulp.task('browser-sync-init', function() {
        settings.dynamic.browserSync.init({
            server: {
                baseDir: settings.testOutputPath
            }
        });
    });
};

module.exports = function(gulp, settings) {
    // Create the browserSync server.
    settings.dynamic.browserSync = require('browser-sync').create();

    /**
     * Initialize the browser sync server (static).
     */
    gulp.task('browser-sync-init', ['build-tests'], function(cb) {
        settings.dynamic.browserSync.init({
            server: {
                baseDir: settings.testOutputPath
            }
        });
        cb();
    });
};

Build tests before initializing BrowserSync


import Component from '@ember/component';
import layout from '../../../templates/components/nypr-accounts/membership-card/giving-history';
import { computed } from '@ember/object';

export default Component.extend({
  layout,
  init() {
    this._super(...arguments);
    this.set('orderDateSorting', ["orderDate:desc"]);
  },
  orderDateSorting: null,
  sortedPledges: computed.sort("pledges", "orderDateSorting"),
  sortedSustainingPledges: computed.filterBy(
    "sortedPledges",
    "orderType",
    "sustainer",
    "isPayment",
    true
  ),
  sortedOneTimePledges: computed.filterBy(
    "sortedPledges",
    "orderType",
    "onetime"
  ),
});

import Component from '@ember/component';
import layout from '../../../templates/components/nypr-accounts/membership-card/giving-history';
import { computed } from '@ember/object';

export default Component.extend({
  layout,
  init() {
    this._super(...arguments);
    this.set('orderDateSorting', ["orderDate:desc"]);
  },
  orderDateSorting: null,
  sortedPledges: computed.sort("pledges", "orderDateSorting"),
  sortedSustainingPledges: computed.filterBy(
    "sortedPledges",
    "orderType",
    "sustainer"
  ),
  sortedOneTimePledges: computed.filterBy(
    "sortedPledges",
    "orderType",
    "onetime"
  ),
});

Revert "Add additional filter to sustaining pledges for is-payment"


ManageIQ.angular.app.component('genericObjectTableComponent', {
  bindings: {
    keys: '=',
    values: '=',
    keyType: '@',
    tableHeaders: '=',
    valueOptions: '=',
    noOfRows: '=',
    angularForm: '=',
  },
  controllerAs: 'vm',
  controller: genericObjectTableController,
  templateUrl: '/static/generic_object/generic_object_table.html.haml',
});

genericObjectTableController.$inject = ['$timeout'];

function genericObjectTableController($timeout) {
  var vm = this;

  vm.$onInit = function() {
    vm.tableHeaders.push('', '');
  };

  vm.addRow = function(_currentRow, element) {
    vm.keys.push('');
    vm.noOfRows = _.size(vm.keys);

    $timeout(function() {
      angular.element('#' + element).focus();
    }, -1);
  };

  vm.deleteRow = function(currentRow) {
    _.pullAt(vm.keys, [currentRow]);

    if (vm.values) {
      _.pullAt(vm.values, [currentRow]);
    }
    vm.noOfRows = _.size(vm.keys);
  };
}

ManageIQ.angular.app.component('genericObjectTableComponent', {
  bindings: {
    keys: '=',
    values: '=',
    keyType: '@',
    tableHeaders: '=',
    valueOptions: '=',
    noOfRows: '=',
    angularForm: '=',
  },
  controllerAs: 'vm',
  controller: genericObjectTableController,
  templateUrl: '/static/generic_object/generic_object_table.html.haml',
});

genericObjectTableController.$inject = ['$timeout'];

function genericObjectTableController($timeout) {
  var vm = this;

  vm.$onInit = function() {
    vm.tableHeaders.push('', '');
  };

  vm.addRow = function(_currentRow, element, fromDelete) {
    vm.keys.push('');
    vm.noOfRows = _.size(vm.keys);

    if (!fromDelete) {
      $timeout(function () {
        angular.element('#' + element).focus();
      }, -1);
    }
  };

  vm.deleteRow = function(currentRow) {
    _.pullAt(vm.keys, [currentRow]);

    if (vm.values) {
      _.pullAt(vm.values, [currentRow]);
    }
    vm.noOfRows = _.size(vm.keys);

    if (vm.noOfRows === 0) {
      vm.addRow(0, vm.keyType + '0', true);
    }
  };
}

Add a new row when the last visible row is deleted


Package.describe({
    summary: "A flux implementation, packaged for meteor",
    version: "0.17.3",
    git: "https://github.com/froatsnook/meteor-alt.git",
    name: "froatsnook:alt",
});

Package.onUse(function(api) {
    api.versionsFrom("METEOR@0.9.0.1");
    api.use("react-runtime");
    api.addFiles("lib/00-alt.js", ["client"]);
    api.addFiles("lib/01-meteor-alt.js", ["client"]);
    api.export("Alt", ["client"]);
    api.export("alt", ["client"]);
});

Package.onTest(function(api) {
    api.use("tinytest");
    api.use("froatsnook:alt");

    api.addFiles("test/alt-tests.js", ["client"]);
});

Package.describe({
    summary: "A flux implementation, packaged for meteor",
    version: "0.17.3",
    git: "https://github.com/froatsnook/meteor-alt.git",
    name: "froatsnook:alt",
});

Package.onUse(function(api) {
    api.versionsFrom("METEOR@0.9.0.1");
    api.use("react-runtime@0.0.0");
    api.addFiles("lib/00-alt.js", ["client"]);
    api.addFiles("lib/01-meteor-alt.js", ["client"]);
    api.export("Alt", ["client"]);
    api.export("alt", ["client"]);
});

Package.onTest(function(api) {
    api.use("tinytest");
    api.use("froatsnook:alt");

    api.addFiles("test/alt-tests.js", ["client"]);
});

Allow 0.x.y versions of react-runtime.


import Ember from 'ember';

export default Ember.Controller.extend({
  queryParams: ['viewType', 'nodeId'],
  query: Ember.inject.service(),
  viewType: 'live',

  modelArrived: Ember.observer('model', function() {
    const nodeList = this.get('model.nodes');
    const nodeTuples = nodeList.map(node => {
      return [node.properties.id, node.properties];
    });
    const nodeMap = new Map(nodeTuples);
    this.set('nodeMap', nodeMap);
    this.set('nodeId', nodeList[0].properties.id);
  }),

  selectedNodeMeta: Ember.computed('nodeId', function() {
    const nodeMap = this.get('nodeMap');
    return nodeMap.get(this.get('nodeId'));
  }),

  actions: {
    onSelect(nodeId) {
      this.set('nodeId', nodeId);
    },
    download(params) {
      this.get('query').sensorDownload(params).then(resp => {
        this.transitionToRoute('datadump.download', resp.ticket, {queryParams: {data_type: 'csv'}});
      });
    }
  }
});

import Ember from 'ember';

export default Ember.Controller.extend({
  queryParams: ['viewType', 'nodeId'],
  query: Ember.inject.service(),
  viewType: 'live',

  modelArrived: Ember.observer('model', function() {
    const nodeList = this.get('model.nodes');
    const nodeTuples = nodeList.map(node => {
      return [node.properties.id, node.properties];
    });
    const nodeMap = new Map(nodeTuples);
    this.set('nodeMap', nodeMap);
    if (!this.get('nodeId')) {
      this.set('nodeId', nodeList[0].properties.id);
    }
  }),

  selectedNodeMeta: Ember.computed('nodeId', function() {
    const nodeMap = this.get('nodeMap');
    return nodeMap.get(this.get('nodeId'));
  }),

  actions: {
    onSelect(nodeId) {
      this.set('nodeId', nodeId);
    },
    download(params) {
      this.get('query').sensorDownload(params).then(resp => {
        this.transitionToRoute('datadump.download', resp.ticket, {queryParams: {data_type: 'csv'}});
      });
    }
  }
});

Fix urlparam for node id


var log = require('npmlog')
  , gcr = require('./gcr')
  , exec = require('child_process').exec
  , utils = exports

utils.genSSHKey = function(cb) {
  var cmd = 'ssh-keygen -t rsa -f ~/.ssh/gcr -N ""'
  exec(cmd, {
    env: process.env
  , cwd: process.cwd()
  }, function(err, stdout, stderr) {
    if (err) return cb && cb(err)
    return cb && cb(null, stdout)
  })
}

var log = require('npmlog')
  , gcr = require('./gcr')
  , exec = require('child_process').exec
  , path = require('path')
  , os = require('os')
  , isWin = os.platform() === 'win32'
  , utils = exports

utils.genSSHKey = function(cb) {
  var k = isWin
    ? 'ssh-keygen.exe'
    : 'ssh-keygen'
  var home = process.env.HOME || process.env.USERPROFILE
  var p = path.join(home, '.ssh', 'gcr')
  var cmd = k + ' -t rsa -f ' + p + ' -N ""'
  exec(cmd, {
    env: process.env
  , cwd: process.cwd()
  }, function(err, stdout, stderr) {
    if (err) return cb && cb(err)
    return cb && cb(null, stdout)
  })
}

Add support for ssh-keygen on windows


import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  status: DS.attr('contest-status'),
  goal: DS.attr('contest-goal'),
  qual_score: DS.attr('number'),
  year: DS.attr('number'),
  rounds: DS.attr('number'),
  session: DS.belongsTo('session', {async: true}),
  award: DS.belongsTo('award', {async: true}),
  contestants: DS.hasMany('contestant', {async: true}),
});

import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  status: DS.attr('contest-status'),
  goal: DS.attr('contest-goal'),
  qual_score: DS.attr('number'),
  year: DS.attr('number'),
  session: DS.belongsTo('session', {async: true}),
  award: DS.belongsTo('award', {async: true}),
  contestants: DS.hasMany('contestant', {async: true}),
});

Remove 'rounds' from Contest model


// @flow
/* global fetch */

import merge from 'lodash/merge'

type ResponseBody = Object | null | string

const fetchJSON = (url: string | Request | URL, options: Object = {}) => {
  const jsonOptions = merge(
    {
      headers: {
        'Content-Type': 'application/json'
      }
    },
    options
  )

  // $FlowIssue
  return fetch(url, jsonOptions)
    .then((response: Response) => {
      return getResponseBody(response).then(body => ({
        response,
        body
      }))
    })
    .then(checkStatus)
}

const getResponseBody = (response: Response): Promise<ResponseBody> => {
  const contentType = response.headers.get('content-type')
  return contentType && contentType.indexOf('json') >= 0
    ? response.text().then(tryParseJSON)
    : response.text()
}

const tryParseJSON = (json: string): Object | null => {
  if (!json) {
    return null
  }

  try {
    return JSON.parse(json)
  } catch (e) {
    throw new Error(`Failed to parse unexpected JSON response: ${json}`)
  }
}

function ResponseError (status: number, response: Response, body: ResponseBody) {
  this.name = 'ResponseError'
  this.status = status
  this.response = response
  this.body = body
}

// $FlowIssue
ResponseError.prototype = Error.prototype

const checkStatus = ({ response, body }) => {
  if (response.ok) {
    return { response, body }
  } else {
    throw new ResponseError(response.status, response, body)
  }
}

export default fetchJSON

// @flow
/* global fetch */

import merge from 'lodash/merge'

type ResponseBody = Object | null | string

const fetchJSON = (url: string | Request | URL, options: Object = {}) => {
  const jsonOptions = merge(
    {
      headers: {
        'Content-Type': 'application/json'
      }
    },
    options
  )

  return fetch(url, jsonOptions)
    .then((response: Response) => {
      return getResponseBody(response).then(body => ({
        response,
        body
      }))
    })
    .then(checkStatus)
}

const getResponseBody = (response: Response): Promise<ResponseBody> => {
  const contentType = response.headers.get('content-type')
  return contentType && contentType.indexOf('json') >= 0
    ? response.text().then(tryParseJSON)
    : response.text()
}

const tryParseJSON = (json: string): Object | null => {
  if (!json) {
    return null
  }

  try {
    return JSON.parse(json)
  } catch (e) {
    throw new Error(`Failed to parse unexpected JSON response: ${json}`)
  }
}

function ResponseError (status: number, response: Response, body: ResponseBody) {
  this.name = 'ResponseError'
  this.status = status
  this.response = response
  this.body = body
}

// $FlowIssue
ResponseError.prototype = Error.prototype

const checkStatus = ({ response, body }) => {
  if (response.ok) {
    return { response, body }
  } else {
    throw new ResponseError(response.status, response, body)
  }
}

export default fetchJSON

Remove unused flow suppression comment


/* global Promise */

export default (routesFetchersMap, path, query, options, store) => {
  const { ignoredPathsRegex, log } = options
  const decodedPath = decodeURI(path)

  if (ignoredPathsRegex && ignoredPathsRegex.test(decodedPath)) {
    return Promise.resolve(true)
  }

  log(
    `Pre-fetcher --> Decoded path: ${decodedPath}, query: ${JSON.stringify(
      query
    )}`
  )

  const promises = []

  for (let i = 0; i < routesFetchersMap.length; i++) {
    const { regex, name, func } = routesFetchersMap[i]

    const m = regex.exec(decodedPath)
    if (m !== null) {
      log(`Pre-fetcher --> Matched ${name}`)

      let actions = func(m, query)
      actions = actions instanceof Array ? actions : [actions]
      actions.forEach((action) => {
        promises.push(store.dispatch(action))
      })
    }
  }
  if (promises.length > 0) {
    return Promise.all(promises)
  }

  log(`Pre-fetcher --> No route matched, nothing to prefetch`)
  return Promise.resolve(true)
}

/* global Promise */

export default (routesFetchersMap, path, query, options, store) => {
  const { ignoredPathsRegex, log } = options
  const decodedPath = decodeURI(path)

  if (ignoredPathsRegex && ignoredPathsRegex.test(decodedPath)) {
    return Promise.resolve(true)
  }

  log(
    `Pre-fetcher --> Decoded path: ${decodedPath}, query: ${JSON.stringify(
      query
    )}`
  )

  const promises = []

  for (let i = 0; i < routesFetchersMap.length; i++) {
    const { regex, name, getActions } = routesFetchersMap[i]

    const m = regex.exec(decodedPath)
    if (m !== null) {
      log(`Pre-fetcher --> Matched ${name}`)

      let actions = getActions(m, query, decodedPath)
      actions = actions instanceof Array ? actions : [actions]
      actions.forEach((action) => {
        promises.push(store.dispatch(action))
      })
    }
  }
  if (promises.length > 0) {
    return Promise.all(promises)
  }

  log(`Pre-fetcher --> No route matched, nothing to prefetch`)
  return Promise.resolve(true)
}

Rename route function to getActions, now also pass the decodedPath


/*global js_beautify: true */
/*jshint node:true */

var SanityTest = require('./sanitytest'),
    Urlencoded = require('../lib/unpackers/urlencode_unpacker'),
    js_beautify = require('../lib/beautify').js_beautify,
    run_beautifier_tests = require('./beautify-tests').run_beautifier_tests;

function node_beautifier_tests() {
    var results = run_beautifier_tests(new SanityTest(), Urlencoded, js_beautify);
    console.log(results.results_raw());
    return results;
}

if (require.main === module) {
    process.exit(node_beautifier_tests().get_exitcode());
}

exports.node_beautifier_tests = node_beautifier_tests;

/*global js_beautify: true */
/*jshint node:true */

var SanityTest = require('./sanitytest'),
    Urlencoded = require('../lib/unpackers/urlencode_unpacker'),
    js_beautify = require('../index').js_beautify,
    run_beautifier_tests = require('./beautify-tests').run_beautifier_tests;

function node_beautifier_tests() {
    var results = run_beautifier_tests(new SanityTest(), Urlencoded, js_beautify);
    console.log(results.results_raw());
    return results;
}

if (require.main === module) {
    process.exit(node_beautifier_tests().get_exitcode());
}

exports.node_beautifier_tests = node_beautifier_tests;

Use index so testj will error if pathway is incorrect.


const initialState = {}

export default (state = initialState, action) => {
  return state
}

import { TAP_ASSERT_DONE } from '../actions'

const initialState = {
  assertions: []
}

export default (state = initialState, action) => {
  switch (action.type) {
    case TAP_ASSERT_DONE:
      return {
        ...state,
        assertions: [...state.assertions, action.payload]
      }

    default:
      return state
  }
}

Handle the tap-assert action in the reducer


(function (module) {
    module.controller('projectListProcess', projectListProcess);
    projectListProcess.$inject = ["processes", "project", "$state", "mcmodal", "$filter"];

    function projectListProcess(processes, project, $state, mcmodal, $filter) {
        console.log('projectListProcess');
        var ctrl = this;

        ctrl.viewProcess = viewProcess;
        ctrl.chooseTemplate = chooseTemplate;

        ctrl.processes = processes;
        ctrl.project = project;
        if (ctrl.processes.length !== 0) {
            console.log('  ctrl.processes.length !== 0');
            ctrl.processes = $filter('orderBy')(ctrl.processes, 'name');
            ctrl.current = ctrl.processes[0];
            //$state.go('projects.project.processes.list.view', {process_id: ctrl.current.id});
        }

        ///////////////////////////////////

        function viewProcess(process) {
            ctrl.current = process;
            $state.go('projects.project.processes.list.view', {process_id: ctrl.current.id});
        }

        function chooseTemplate() {
            mcmodal.chooseTemplate(ctrl.project);
        }
    }
}(angular.module('materialscommons')));

(function (module) {
    module.controller('projectListProcess', projectListProcess);
    projectListProcess.$inject = ["processes", "project", "$state", "mcmodal", "$filter"];

    function projectListProcess(processes, project, $state, mcmodal, $filter) {
        var ctrl = this;

        ctrl.viewProcess = viewProcess;
        ctrl.chooseTemplate = chooseTemplate;

        ctrl.processes = processes;
        ctrl.project = project;
        if (ctrl.processes.length !== 0) {
            ctrl.processes = $filter('orderBy')(ctrl.processes, 'name');
            ctrl.current = ctrl.processes[0];
            $state.go('projects.project.processes.list.view', {process_id: ctrl.current.id});
        }

        ///////////////////////////////////

        function viewProcess(process) {
            ctrl.current = process;
            $state.go('projects.project.processes.list.view', {process_id: ctrl.current.id});
        }

        function chooseTemplate() {
            mcmodal.chooseTemplate(ctrl.project);
        }
    }
}(angular.module('materialscommons')));

Remove debug of ui router state changes.


import Input from "@hig/input";
import React from "react";
import { withInfo } from "@storybook/addon-info";
import { storiesOf } from "@storybook/react";

import getKnobs from "./getKnobs";
import Label from "../index";
import infoOptions from "./infoOptions";
import withThemeProvider from "./withThemeProvider";

const storybook = storiesOf("Theming|Themable Label", module);

storybook.add(
  "default",
  withInfo(infoOptions)(() => {
    const props = {
      children: "Email"
    };
    const { children, theme, ...otherProps } = getKnobs(props);

    return withThemeProvider(<Label {...otherProps}>{children}</Label>);
  })
);

storybook.add(
  "with reference to form element",
  withInfo(infoOptions)(() => {
    const props = {
      children: "Input Field"
    };
    const { children, theme, ...otherProps } = getKnobs(props);

    return withThemeProvider(
      <form id="a_form">
        <Label form="a_form" htmlFor="an_input" {...otherProps}>
          {children}
        </Label>
        <Input id="an_input" variant="line" />
      </form>
    );
  })
);

Add storybook for Label that references a form field


import {terminal as term} from "terminal-kit";

export default function terminalRender(store) {
  // term.fullscreen();
  term.alternateScreenBuffer();

  store.subscribe(() => {
    const {title, status, entries, categories} = store.getState().terminal;
    term.clear();

    term.moveTo(1, term.height);
    entries.forEach((entry) => {
      const cat = categories[entry.category];
      term.colorRgb(...cat.color)(`${cat.name} `);
      term.colorRgb(255, 255, 255)(`${entry.text}\n`);
    });

    term.saveCursor();
    // Set up top variables
    const titleText = ` ${title.text} `;
    const statusText = ` ${status.text} `;
    const neededSpacing = term.width - titleText.length - statusText.length;
    let spacing = "";
    while (spacing.length < neededSpacing) {
      spacing += " ";
    }

    // Print top bar
    term.moveTo(1, 1);
    term.underline.colorRgb(...title.color)(titleText);
    term.underline.colorRgb(255, 255, 255)(spacing);
    term.underline.colorRgb(...status.color)(statusText);

    term.restoreCursor();
  });
}

import {terminal as term} from "terminal-kit";

const hasPrinted = new Set();

export default function terminalRender(store) {
  // term.fullscreen();
  // term.alternateScreenBuffer();

  store.subscribe(() => {
    const {title, status, entries, categories} = store.getState().terminal;
    // term.clear();

    term.eraseDisplayBelow();

    // term.moveTo(1, term.height);
    entries.forEach((entry) => {
      if (hasPrinted.has(entry)) {
        return;
      }
      hasPrinted.add(entry);
      const cat = categories[entry.category];
      term.colorRgb(...cat.color)(`${cat.name} `);
      term.colorRgb(255, 255, 255)(`${entry.text}\n`);
    });

    // term.saveCursor();
    // Set up top variables
    const titleText = ` ${title.text} `;
    const statusText = ` ${status.text} `;
    const neededSpacing = term.width - titleText.length - statusText.length;
    let spacing = "";
    while (spacing.length < neededSpacing) {
      spacing += " ";
    }
    term("\n");
    term.up(1);

    term.down(1);
    term.underline.colorRgb(...title.color)(titleText);
    term.underline.colorRgb(255, 255, 255)(spacing);
    term.underline.colorRgb(...status.color)(statusText);
    term.up(1);
    term.column(1);
    term.styleReset();

    // // Print top bar

    // term.restoreCursor();
  });
}

Move terminal status bar to the bottom


/*
 * Author: CM
 */
(function($) {
	$.event.special.clickConfirmed = {
		bindType: "click",
		delegateType: "click",

		settings: {
			message: 'Please Confirm'
		},

		handle: function(event) {
			var $this = $(this);
			var deactivateTimeout = null;

			var activateButton = function() {
				$this.addClass('confirmClick');
				$this.attr('title', $.event.special.clickConfirmed.settings.message).tooltip({trigger: 'manual'}).tooltip('show');
				deactivateTimeout = setTimeout(function() {
					deactivateButton();
				}, 5000);
				setTimeout(function() {
					$(document).one('click.clickConfirmed', function(e) {
						if (!$this.length || e.target !== $this[0] && !$.contains($this[0], e.target)) {
							deactivateButton();
						}
					});
				}, 0);
			};

			var deactivateButton = function() {
				$this.removeClass('confirmClick');
				$this.removeAttr('title').tooltip('hide');
				clearTimeout(deactivateTimeout);
				$(document).off('click.clickConfirmed');
			};

			if ($this.hasClass('confirmClick')) {
				deactivateButton();
				return event.handleObj.handler.call(this, event);
			}
			activateButton();

			return false;
		}
	};
})(jQuery);

/*
 * Author: CM
 */
(function($) {
	$.event.special.clickConfirmed = {
		bindType: "click",
		delegateType: "click",

		settings: {
			message: 'Please Confirm'
		},

		handle: function(event) {
			var $this = $(this);

			var activateButton = function() {
				$this.addClass('confirmClick');
				$this.attr('title', $.event.special.clickConfirmed.settings.message).tooltip({trigger: 'manual'}).tooltip('show');

				var deactivateButton = function() {
					$this.removeClass('confirmClick');
					$this.removeAttr('title').tooltip('hide');
					$this.removeData('clickConfirmed.deactivate');
					clearTimeout(deactivateTimeout);
					$(document).off('click.clickConfirmed', documentClickHandler);
				};

				$this.data('clickConfirmed.deactivate', deactivateButton);

				var deactivateTimeout = setTimeout(function() {
					deactivateButton();
				}, 5000);

				var documentClickHandler = function(e) {
					if (!$this.length || e.target !== $this[0] && !$.contains($this[0], e.target)) {
						deactivateButton();
					}
				};

				setTimeout(function() {
					$(document).on('click.clickConfirmed', documentClickHandler);
				}, 0);
			};

			if ($this.hasClass('confirmClick')) {
				$this.data('clickConfirmed.deactivate')();
				return event.handleObj.handler.call(this, event);
			} else {
				activateButton();
				return false;
			}
		}
	};
})(jQuery);

Store deactivation callback on button-data


/**
 * @externs
 * @fileoverview Symbols needed to compile webcomponents
 * @license
 * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */
var require;
var global;
var ES6Promise;
var process;
var define;
var module;
var exports;

var ShadyDOM;
var WebComponents;

/** @type {!Function} */
Promise.cast;

/** @type {function()} */
HTMLTemplateElement.bootstrap;

/**
 * @externs
 * @fileoverview Symbols needed to compile webcomponents
 * @license
 * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */
var ShadyDOM;
var WebComponents;

/** @type {!Function} */
Promise.cast;

/** @type {function()} */
HTMLTemplateElement.bootstrap;

Remove externs that aren't used internally.


var utilPath = require('../../../lib/file/path');
var getRealPkgSrc = require('../../../lib/file/get-real-pkg-src');
var expect = require('expect');

var fs = require('fs');

describe('Get real paths of the package\'s files', function () {

  var optG = {src: './runtime'};
  var root = fs.realpathSync(optG.src) + '/';

  function T(pkg, files) {
    var ret = utilPath(optG, pkg);
    expect(ret).toEqual(files.map(function (file) {
      return root + file;
    }));
    if (ret.length) {
      expect(pkg.realSrc).toBe(getRealPkgSrc(optG, pkg));
    }
  }

  it('Empty', function () {
    T({}, []);
    T({files: []}, []);
  });

  it('Normal use, and that src override name', function () {
    T({
      name: 'a',
      src: '.',
      files: [
        'a.js',
        'b/a.js'
      ]
    }, [
      'a.js',
      'b/a.js'
    ]);
  });

  it('Wildcard', function () {
    T({
      name: 'b',
      files: [
        '**/*.js',
        'c/*.css'
      ]
    }, [
      'b/a.js',
      'b/b.js',
      'b/c/a.js',
      'b/c/a.css'
    ]);
  });

});

var utilPath = require('../../../lib/file/path');
var getRealPkgSrc = require('../../../lib/file/get-real-pkg-src');
var expect = require('expect');

var runtimePath = require('../../util').runtimePath;

describe('Get real paths of the package\'s files', function () {

  var optG = {src: runtimePath};

  function T(pkg, files) {
    var ret = utilPath(optG, pkg);
    expect(ret).toEqual(files.map(function (file) {
      return runtimePath + file;
    }));
    if (ret.length) {
      expect(pkg.realSrc).toBe(getRealPkgSrc(optG, pkg));
    }
  }

  it('Empty', function () {
    T({}, []);
    T({files: []}, []);
  });

  it('Normal use, and that src override name', function () {
    T({
      name: 'a',
      src: '.',
      files: [
        'a.js',
        'b/a.js'
      ]
    }, [
      'a.js',
      'b/a.js'
    ]);
  });

  it('Wildcard', function () {
    T({
      name: 'b',
      files: [
        '**/*.js',
        'c/*.css'
      ]
    }, [
      'b/a.js',
      'b/b.js',
      'b/c/a.js',
      'b/c/a.css'
    ]);
  });

});

Update tests: replace fs with util


import require, { has } from 'require';

/**
  ⚠ This file exists ONLY for DEV ergonomics to ensure
  JS import autocompletion works and flags can be toggled.

  In production, The actual flag states are ALWAYS determined
  at build-time and off-branches stripped from the output.

  This determination is done in `src/debug-macros.js`

  The file itself is stripped from production builds.
*/

function dataFlagState(flagName) {
  let value;
  if (has('@ember-data/canary-features')) {
    value = require('@ember-data/canary-features')[flagName];
  }
  return value || false;
}

function m3FlagState(flagName) {
  return window.M3ENV?.FEATURES?.[flagName];
}

export const CUSTOM_MODEL_CLASS = dataFlagState('CUSTOM_MODEL_CLASS');
export const PROXY_MODEL_CLASS = m3FlagState('PROXY_MODEL_CLASS');

import require, { has } from 'require';

/**
  ⚠ This file exists ONLY for DEV ergonomics to ensure
  JS import autocompletion works and flags can be toggled.

  In production, The actual flag states are ALWAYS determined
  at build-time and off-branches stripped from the output.

  This determination is done in `src/debug-macros.js`

  The file itself is stripped from production builds.
*/

function dataFlagState(flagName) {
  let value;
  if (has('@ember-data/canary-features')) {
    value = require('@ember-data/canary-features')[flagName];
  }
  return value || false;
}

function m3FlagState(flagName) {
  if (window && window.M3ENV && window.M3ENV.FEATURES) {
    return window.M3ENV.FEATURES[flagName];
  }
}

export const CUSTOM_MODEL_CLASS = dataFlagState('CUSTOM_MODEL_CLASS');
export const PROXY_MODEL_CLASS = m3FlagState('PROXY_MODEL_CLASS');

Fix feature flag infra code for node


// @flow

import { red } from 'chalk';
import R from 'ramda';

type Clog = typeof console.log;
type GraphQLError = { message: string };

// FIXME: Improve naming
export function exitError(clog: Clog, ...errors: Array<string | Error | GraphQLError>): number {
  R.compose(R.forEach(clog), R.map(err => (err.stack ? red(err.stack) : red(err))))(errors);
  return 1;
}

export function exitNoConfig(clog: Clog): number {
  return exitError(clog, '.amazeeio.yml config file not found.');
}

export function exitGraphQLError(clog: Clog, errors: Array<GraphQLError>): number {
  return exitError(clog, 'Oops! The server returned errors:', ...errors);
}

// @flow

import { red } from 'chalk';
import R from 'ramda';

type Clog = typeof console.log;
type GraphQLError = { message: string };

// FIXME: Improve naming
export function exitError(clog: Clog, ...errors: Array<string | Error | GraphQLError>): number {
  R.compose(R.forEach(clog), R.map(err => (err.stack ? red(err.stack) : red(err))))(errors);
  return 1;
}

export function exitNoConfig(clog: Clog): number {
  return exitError(clog, '.amazeeio.yml config file not found.');
}

export function exitGraphQLError(clog: Clog, errors: Array<GraphQLError>): number {
  const prettyErrors = R.map(error => JSON.stringify(error, null, 2), errors);
  const errorMessage =
    R.length(errors) === 1
      ? 'Oops! The server returned an error:'
      : 'Oops! The server returned errors:';
  return exitError(clog, errorMessage, ...prettyErrors);
}

Print full pretty GraphQL errors


async function sqlite_sql(args) {
/*
description("`sqlite db driver")
base_component_id("sqlite_server")
load_once_from_file(true)
only_run_on_server(true)
*/
   let tables =  [{name: "server_fdfd"},{name: "fdfdsffdsd"},
                  {name: "fdssdfdffd"},{name: "fff"},{name: "fgg"}]
  return  tables
}

async function sqlite_sql(args) {
/*
description("`sqlite db driver")
base_component_id("sqlite_server")
load_once_from_file(true)
only_run_on_server(true)
*/
  let dbsearch = new sqlite3.Database("/Users/faroukzquraishi/Yazz/node.visi");
  dbsearch.run("PRAGMA journal_mode=WAL;")
console.log(1)
  var promise = new Promise(async function(returnFn) {
    dbsearch.serialize(
        function() {
            var stmt = dbsearch.all(
                "SELECT  *  FROM   system_code",
                []
                ,

                function(err, results)
                {
                  console.log(2)
                    if (results) {
                        if (results.length > 0) {
                            var codeId = results[0].id
                                dbsearch.all(
                                    "SELECT dependency_name FROM app_dependencies where code_id = ?; ",
                                    codeId,

                                    function(err, results2)
                                    {
                                        results[0].libs = results2
                                        console.log(3)
                                        returnFn(results2)
                                    })
                        }

                    }

                })
    }, sqlite3.OPEN_READONLY)
  })
  console.log(4)
  var ret = await promise
  //console.log("ret: "  +  JSON.stringify(ret,null,2))
   let tables =  [{name: "server_fdfd"},{name: "fdfdsffdsd"},
                  {name: "fdssdfdffd"},{name: "fff"},{name: "fgg"}]
    console.log(5)
  return  tables
}

Allow Sqlite driver to call out to sqlite


const test = require('tape')
const BorrowState = require('borrow-state')

const sleep50ms = (something) => new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve(something)
  }, 50)
})

;[true, false].forEach((unsafe) => {
  test(`read-only-parallel (${unsafe ? 'un' : ''}safe)`, (t) => {
    t.plan(6)
    t.timeoutAfter(100)
    let myState = new BorrowState()
    ;[1, 2, 3].forEach(() => {
      myState.block('r')
        .then(sleep50ms)
        .then((state) => {
          t.ok(true)
          state.unblock()
        })
    })
  })
})

const test = require('tape')
const BorrowState = require('borrow-state')

const sleep50ms = (something) => new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve(something)
  }, 50)
})

;[true, false].forEach((unsafe) => {
  test(`read-only-parallel (${unsafe ? 'un' : ''}safe)`, (t) => {
    t.plan(3)
    t.timeoutAfter(100)
    let myState = new BorrowState()
    ;[1, 2, 3].forEach(() => {
      myState.block('r')
        .then(sleep50ms)
        .then((state) => {
          t.ok(true)
          state.unblock()
        })
    })
  })
})

Correct the expected number of tests


angular.module('services')
       .service('userService',['$q','config','storageService','$http',userService]);

function userService($q,config,storageService,$http) {

  var service = {};
  service.get = get;
  service.one = one;
  return service;

  function one(userId) {
    var deferred = $q.defer();
    $http.get(config.apiEndPoint + '/users/' + userId).then(function(response) {
      deferred.resolve(response.data);
    },function(){
      deferred.resolve({});
    });
    return deferred.promise;
  }

  function get(userId) {

    var deferred = $q.defer(),
        query = config.apiEndPoint + '/users';

    if(userId) {
      query += '?filter=' + userId;
    }

    $http.get(query).then(function(response) {
      deferred.resolve(response.data);
    },function(){
      deferred.resolve({});
    });
    return deferred.promise;
  }

};

angular.module('services')
       .service('userService',['$q','config','storageService','$http',userService]);

function userService($q,config,storageService,$http) {

  var service = {};
  service.get = get;
  service.one = one;
  service.update = update;
  return service;

  function one(userId) {
    var deferred = $q.defer();
    $http.get(config.apiEndPoint + '/users/' + userId).then(function(response) {
      deferred.resolve(response.data);
    },function(){
      deferred.resolve({});
    });
    return deferred.promise;
  }

  function get(userId) {

    var deferred = $q.defer(),
        query = config.apiEndPoint + '/users';

    if(userId) {
      query += '?filter=' + userId;
    }

    $http.get(query).then(function(response) {
      deferred.resolve(response.data);
    },function(){
      deferred.resolve({});
    });

    return deferred.promise;
  }

  function update(user) {

    var deferred = $q.defer(),
        query = config.apiEndPoint + '/users/' + user._id;

    $http.put(query,user).then(function(data){
      deferred.resolve(data);
    },function(err){
      deferred.reject(err)
    });

    return deferred.promise;
  }

};

Edit user initial commit for userService


(function(global) {
  'use strict';
  var GOVUK = global.GOVUK || {};
  var $ = global.jQuery;

  GOVUK.autoSubmitForm = {
    attach: function () {
        var destinationLink = document.getElementById("saml-response-form");
        ga("govuk_shared.linker:decorate", destinationLink);
        $('form.js-auto-submit').submit();
    }
  };

  global.GOVUK = GOVUK;
})(window);

(function(global) {
  'use strict';
  var GOVUK = global.GOVUK || {};
  var $ = global.jQuery;

  GOVUK.autoSubmitForm = {
    attach: function () {
        var destinationLink = $('#saml-response-form')[0];
        ga("govuk_shared.linker:decorate", destinationLink);
        $('form.js-auto-submit').submit();
    }
  };

  global.GOVUK = GOVUK;
})(window);

Implement cross domain Google Analytics tracking for Verify


"use strict";

angular.module('arethusa').service('treebankRetriever', function($http) {
  // tokens should always be loaded synchronous - the app should
  // not start anything without knowing an initial state

  var xmlToState = function(token) {
    // One could formalize this to real rules that are configurable...
    //
    // Remember that attributes of the converted xml are prefixed with underscore
    return {
      id: arethusaUtil.formatNumber(token._id, 4),
      string: token._form,
      morphology: {
        lemma: token._lemma,
        postag: token._postag
      },
      relation: {
        label: token._relation
      },
      head: {
        id: token._head
      }
    };
  };

  var parseXml = function(data) {
    var tokens = {};
    var xml = arethusaUtil.xml2json(data);
    var words = xml.treebank.sentence.word;
    angular.forEach(words, function(xmlToken, i) {
      var token = xmlToState(xmlToken);
      tokens[token.id] = token;
    });
    return tokens;
  };

  return {
    getData: function(url, callback) {
      $http.get(url).then(function(res) {
        callback(parseXml(res.data));
      });
    }
  };
});

"use strict";

angular.module('arethusa').service('treebankRetriever', function($http) {
  // tokens should always be loaded synchronous - the app should
  // not start anything without knowing an initial state

  var formatId = function(id) {
    return arethusaUtil.formatNumber(id, 4);
  };

  var xmlToState = function(token) {
    // One could formalize this to real rules that are configurable...
    //
    // Remember that attributes of the converted xml are prefixed with underscore
    return {
      id: formatId(token._id),
      string: token._form,
      morphology: {
        lemma: token._lemma,
        postag: token._postag
      },
      relation: {
        label: token._relation
      },
      head: {
        id: formatId(token._head)
      }
    };
  };

  var parseXml = function(data) {
    var tokens = {};
    var xml = arethusaUtil.xml2json(data);
    var words = xml.treebank.sentence.word;
    angular.forEach(words, function(xmlToken, i) {
      var token = xmlToState(xmlToken);
      tokens[token.id] = token;
    });
    return tokens;
  };

  return {
    getData: function(url, callback) {
      $http.get(url).then(function(res) {
        callback(parseXml(res.data));
      });
    }
  };
});

Fix head id in treebank retriever


#!/usr/bin/env node

var azure = require('./lib/azure_wrapper.js');
var kube = require('./lib/deployment_logic/kubernetes.js');

azure.create_config('kubernetes', { 'etcd': 3, 'kube': 4 });

azure.run_task_queue([
  azure.queue_default_network(),
  azure.queue_machines('etcd', 'stable',
    kube.create_etcd_cloud_config),
  azure.queue_machines('kube', 'stable',
    kube.create_node_cloud_config),
]);

#!/usr/bin/env node

var azure = require('./lib/azure_wrapper.js');
var kube = require('./lib/deployment_logic/kubernetes.js');

azure.create_config('kubernetes', { 'etcd': 3, 'kube': 3 });

azure.run_task_queue([
  azure.queue_default_network(),
  azure.queue_machines('etcd', 'stable',
    kube.create_etcd_cloud_config),
  azure.queue_machines('kube', 'stable',
    kube.create_node_cloud_config),
]);

Create two minions initially, to save some cores in trial package


define('scribe-plugin-image-inserter', [
  'eventsWithPromises',
  'rangy-core',
  'rangy-selectionsaverestore',
  'filter-event'
],
function (eventsWithPromises, rangy, rangySelectionSaveRestore, filterEvent) {
  'use strict';

  /**
   * This plugin adds a command for editing/creating links via LinkEditor/LinkInserter
   */
  return function (context) {
    return function (scribe) {
      var insertImageCommand = new scribe.api.Command('insertHTML');

      insertImageCommand.nodeName = 'IMG';

      insertImageCommand.execute = function () {
        return true;
      };

      insertImageCommand.queryState = function () {
        return false;
      };

      insertImageCommand.queryEnabled = function() {
        return true;
      };

      insertImageCommand.insert = function (url) {
        scribe.api.SimpleCommand.prototype.execute.call(this, '<img src="'+ url +'">');
      };

      insertImageCommand.handleInsertPublished = function(eventData) {
        if(!eventData.val) return;
        this.insert(eventData.val);
      };

      insertImageCommand.setupEvents = function() {
        eventsWithPromises.subscribe('insertmanager:insert-published',
          filterEvent(this.handleInsertPublished.bind(this), context)
        );
      };

      insertImageCommand.init = function() {
        this.setupEvents();
      };

      insertImageCommand.init();

      scribe.commands.insertImage = insertImageCommand;
    };
  };

});

define('scribe-plugin-image-inserter', [
  'eventsWithPromises',
  'rangy-core',
  'rangy-selectionsaverestore',
  'filter-event'
],
function (eventsWithPromises, rangy, rangySelectionSaveRestore, filterEvent) {
  'use strict';

  /**
   * This plugin adds a command for editing/creating links via LinkEditor/LinkInserter
   */
  return function (context) {
    return function (scribe) {
      var insertImageCommand = new scribe.api.Command('insertHTML');

      insertImageCommand.nodeName = 'P';
      insertImageCommand.validNodes = ['P','LI','A'];

      insertImageCommand.execute = function () {
        return true;
      };

      insertImageCommand.queryState = function () {
        return false;
      };

      insertImageCommand.queryEnabled = function() {
        var selection = new scribe.api.Selection();
        return selection.getContaining(function (node) {
          return insertImageCommand.validNodes.indexOf(node.nodeName) !== -1;
        });
      };

      insertImageCommand.insert = function (url) {
        scribe.api.SimpleCommand.prototype.execute.call(this, '<img src="'+ url +'">');
      };

      insertImageCommand.handleInsertPublished = function(eventData) {
        if(!eventData.val) return;
        this.insert(eventData.val);
      };

      insertImageCommand.setupEvents = function() {
        eventsWithPromises.subscribe('insertmanager:insert-published',
          filterEvent(this.handleInsertPublished.bind(this), context)
        );
      };

      insertImageCommand.init = function() {
        this.setupEvents();
      };

      insertImageCommand.init();

      scribe.commands.insertImage = insertImageCommand;
    };
  };

});

Enable toolbar buttons only within certain tags


'use strict';

var _ = require('lodash');

var prompts = [
  {
    type: 'input',
    name: 'projectName',
    message: 'Machine-name of your project?',
    // Name of the parent directory.
    default: _.last(process.cwd().split('/')),
    validate: function (input) {
      return (input.search(' ') === -1) ? true : 'No spaces allowed.';
    }
  },
  {
    type: 'list',
    name: 'webserver',
    message: 'Choose your webserver:',
    choices: [
      'apache',
      'custom'
    ],
    default: 'apache'
  },
  {
    name: 'webImage',
    message: 'Specify your webserver Docker image:',
    default: 'phase2/apache24php55',
    when: function(answers) {
      return answers.webserver == 'custom';
    },
    validate: function(input) {
      if (_.isString(input)) {
        return true;
      }

      return 'A validate docker image identifier is required.';
    }
  },
  {
    type: 'list',
    name: 'cacheInternal',
    message: 'Choose a cache backend:',
    default: 'memcache',
    choices: [
      'memcache',
      'database'
    ]
  }
];

module.exports = prompts;

'use strict';

var _ = require('lodash');

var prompts = [
  {
    type: 'input',
    name: 'projectName',
    message: 'Machine-name of your project?',
    // Name of the parent directory.
    default: _.last(process.cwd().split('/')),
    validate: function (input) {
      return (input.search(' ') === -1) ? true : 'No spaces allowed.';
    }
  },
  {
    type: 'list',
    name: 'webserver',
    message: 'Choose your webserver:',
    choices: [
      'apache',
      'custom'
    ],
    default: 'apache'
  },
  {
    name: 'webImage',
    message: 'Specify your webserver Docker image:',
    default: 'phase2/apache24php55',
    when: function(answers) {
      return answers.webserver == 'custom';
    },
    validate: function(input) {
      if (_.isString(input)) {
        return true;
      }

      return 'A validate docker image identifier is required.';
    }
  },
  {
    type: 'list',
    name: 'cacheInternal',
    message: 'Choose a cache backend:',
    default: 'memcache',
    choices: [
      'memcache',
      'database'
    ]
  },
  {
    type: 'checkbox',
    name: 'environments',
    message: 'Select default standing environments:',
    default: [
      'dev',
      'qa',
      'ms'
    ],
    choices: [
      {
        value: 'dev',
        name: 'Development - Automatically updates when PRs are merged.',
        short: 'Development'
      },
      {
        value: 'qa',
        name: 'QA - Regularly scheduled deployments for manual Phase2 testing.',
        short: 'QA'
      },
      {
        value: 'ms',
        name: 'Review - Milestone review sandbox for client use.',
        short: 'Review'
      }
    ]
  }
];

module.exports = prompts;

Add out-of-box support for QA, Dev, and Review sites.


jQuery(document).ready(function($) {
    function update_chars_left() {
        var max_len = 140;
        var textarea = $('#new_tweet')[0];
        var tweet_len = textarea.value.length;
        if (tweet_len >= max_len) {
            textarea.value = textarea.value.substring(0, max_len); // truncate
            $('#chars_left').html("0");
        } else {
            $('#chars_left').html(max_len - tweet_len);
        }
    }
    $('#new_tweet').keyup(function() {
        update_chars_left();
    });
    update_chars_left();
    $('#new_tweet').focus();
});

jQuery(document).ready(function($) {
    if ($('#new_tweet').length) {
      function update_chars_left() {
          var max_len = 140;
          var textarea = $('#new_tweet')[0];
          var tweet_len = textarea.value.length;
          if (tweet_len >= max_len) {
              textarea.value = textarea.value.substring(0, max_len); // truncate
              $('#chars_left').html("0");
          } else {
              $('#chars_left').html(max_len - tweet_len);
          }
      }
      $('#new_tweet').keyup(function() {
          update_chars_left();
      });
      update_chars_left();
      $('#new_tweet').focus();
    }
});

Fix js error on touite input when not authenticated


function randomValue () {
    const value = [];
    const lengthOfTheArray = 30*24*12;
    for (var i=0; i <= lengthOfTheArray ; i++) {
        value.push((Math.random() * 10).toFixed(1))
    }
    return value.join(",");
}

Meteor.startup(() => {
    if (
        process.env.ENVIRONMENT !== "production" &&
        SiteMonthReadingsAggregates.find().count() === 0
    ) {
        SiteMonthReadingsAggregates.insert({
            podId: "podId",
            month: "2015-10",
            readings: {
                "energia attiva": randomValue(),
                "enregia reattiva": randomValue(),
                "potenza massima": randomValue(),
                "temperature": randomValue(),
                "humidity": randomValue(),
                "illuminance": randomValue(),
                "co2": randomValue()
            }
        });
    }
});

function randomValue () {
    const value = [];
    const lengthOfTheArray = 30*24*12;
    for (var i=0; i <= lengthOfTheArray ; i++) {
        value.push((Math.random() * 10).toFixed(1))
    }
    return value.join(",");
}

Meteor.startup(() => {
    if (
        process.env.ENVIRONMENT !== "production" &&
        SiteMonthReadingsAggregates.find().count() === 0
    ) {
        SiteMonthReadingsAggregates.insert({
            podId: "podId",
            month: moment().format("YYYY-MM"),
            readings: {
                "energia attiva": randomValue(),
                "enregia reattiva": randomValue(),
                "potenza massima": randomValue(),
                "temperature": randomValue(),
                "humidity": randomValue(),
                "illuminance": randomValue(),
                "co2": randomValue()
            }
        });
    }
});

Insert dynamic data of the actual month


"use strict";

/**
 * This class will hold API keys etc. when it gets smarter
 */
class StackOverflowSearcher {
  getUrlForRelevantAnswer(errorMessage) {
    return `http://stackoverflow.com/search?q=${errorMessage}`;
  }
}

module.exports = StackOverflowSearcher;

"use strict";

/**
 * This class will hold API keys etc. when it gets smarter
 */
class StackOverflowSearcher {
  getUrlForRelevantAnswer(errorMessage) {
    return encodeURI(`http://stackoverflow.com/search?q=${errorMessage}`);
  }
}

module.exports = StackOverflowSearcher;

Change StackOverflow url so that it is URI encoded


import React from 'react';

const Glitch = () => (

Uh oh, there was a problem.

There might be something not-quite-right with the content
    you're trying to view. Sorry, machines make mistakes too

You might be able to get to it later.

);

Glitch.displayName = 'Glitch';

export default Glitch;

import React from 'react';

const Glitch = () => (

Uh oh, there was a problem.

There might be something not-quite-right with the content
    you're trying to view. Sorry, machines make mistakes too.

You might be able to get to it later.

);

Glitch.displayName = 'Glitch';

export default Glitch;

Fix grammar in <Glitch /> component


(function($) {
  $('.call-to-action .btn').click(function() {
    $('#geotagging-map').slideToggle('slow');
  });

  $('.save-coordinates .btn').click(function() {
    if(map.getStreetView().getVisible()){
      console.log(map.getStreetView().getPosition().lat());
      console.log(map.getStreetView().getPosition().lng());
      console.log(map.getStreetView().getPov());
    }
    else{
      console.log(marker.getPosition().lat());
      console.log(marker.getPosition().lng());
    }

  });
})(jQuery);

var map;
var marker;
function initMap() {
  var myLatlng = new google.maps.LatLng(55.6776555,	12.5691513);
  map = new google.maps.Map(document.getElementById('geotagging-map'), {
    center: myLatlng,
    zoom: 12
  });

  // Place a draggable marker on the map
  marker = new google.maps.Marker({
      position: myLatlng,
      map: map,
      draggable:true
  });
}

(function($) {
  $('.call-to-action .btn').click(function() {
    $('#geotagging-map').slideToggle('slow');
  });

  $('.save-coordinates .btn').click(function() {
    var data = {};
    if(map.getStreetView().getVisible()){
      data.latitude = map.getStreetView().getPosition().lat();
      data.longitude = map.getStreetView().getPosition().lng();
      data.pov = map.getStreetView().getPov();
    } else{
      data.latitude = marker.getPosition().lat();
      data.longitude = marker.getPosition().lng();
    }
    var $item = $('.item');
    var catalogAlias = $item.data('catalog-alias');
    var itemId = $item.data('item-id');
    console.log('Saving geo-tag', catalogAlias, itemId, data);
    var url = '/' + catalogAlias + '/' + itemId + '/save-geotag';
    $.post(url, data, function(response) {
      console.log(response);
    });
  });
})(jQuery);

var map;
var marker;
function initMap() {
  var myLatlng = new google.maps.LatLng(55.6776555,	12.5691513);
  map = new google.maps.Map(document.getElementById('geotagging-map'), {
    center: myLatlng,
    zoom: 12
  });

  // Place a draggable marker on the map
  marker = new google.maps.Marker({
      position: myLatlng,
      map: map,
      draggable:true
  });
}

Send a request when clicking the save button.


/**
 * @ngdoc     overview
 * @name      alquimia
 * @author    Mauro Constantinescu <mauro.constantinescu@gmail.com>
 * @copyright © 2015 White, Red & Green Digital S.r.l.
 *
 * @description
 * The `alquimia` module provides utility objects for using the Alquimia framework as efficiently as possible.
 * The main goal of this module is to help developers handling `$location`'s **HTML5 mode** and communicating
 * with the Wordpress' **WP REST API** plugin and specifically with the Alquimia Wordpress plugin for the API.
 */
angular.module( 'alquimia', ['restangular'] )
/*
Uncomment this directive if you want to use $location's html5Mode. You should keep it
into your project only while developing. For more information, see the readme file.
 */
// .directive( 'a', ['$location', require( './d-a' )] )
.provider( 'WPApi', require( './p-wp-api' ) );

/**
 * @ngdoc     overview
 * @name      alquimia
 * @author    Mauro Constantinescu <mauro.constantinescu@gmail.com>
 * @copyright © 2015 White, Red & Green Digital S.r.l.
 *
 * @description
 * The `alquimia` module provides utility objects for using the Alquimia framework as efficiently as possible.
 * The main goal of this module is to help developers handling `$location`'s **HTML5 mode** and communicating
 * with the Wordpress' **WP REST API** plugin and specifically with the Alquimia Wordpress plugin for the API.
 */
var module = angular.module( 'alquimia', ['restangular'] )

if ( window.location && window.location.hostname === 'localhost' ) {
  module.directive( 'a', ['$location', require( './d-a' )] )
}

module.provider( 'WPApi', require( './p-wp-api' ) );

Set alquimia "a" directive to be executed only on localhost


// @flow

import React from 'react';
import {
    StyleSheet,
    Platform,
    View,
    Button,
} from 'react-native';

import Icon from 'react-native-vector-icons/MaterialIcons';
const {ToolbarAndroid} = Icon;

const ToolbarIos = (props) => (
    <View {...props} style={{backgroundColor:'blue', paddingTop: 20}}>
        {
            (props.navigation.state
                ? (
                    <Button color="white" title="Back" onPress={() => props.navigation.goBack()}
                        />
                )
                : null)
        }
    </View>
)

const Toolbar = (props) => {
    const Comp = (Platform.OS === 'android'
        ? ToolbarAndroid
        : ToolbarIos);
    return (
        <Comp
            titleColor="white"
            {...props}
            style={[styles.toolbar, props.style]} />
    )
};

const styles = StyleSheet.create({
    toolbar: {
        height: 56,
        backgroundColor: '#651FFF',
        elevation: 5,
    }
});

export default Toolbar;

// @flow

import React from 'react';
import {
    StyleSheet,
    Platform,
    View,
    Button,
} from 'react-native';

import Icon from 'react-native-vector-icons/MaterialIcons';
const {ToolbarAndroid} = Icon;

const ToolbarIos = (props) => {
    return (
        <View {...props} style={{ backgroundColor: 'blue', paddingTop: 20 }}>
            {
                (props.navigation.state.routeName !== 'PhotoGrid'
                    ? (
                        <Button color="white" title="Back" onPress={() => props.navigation.goBack()}
                        />
                    )
                    : null)
            }
        </View>
    )
}

const Toolbar = (props) => {
    const Comp = (Platform.OS === 'android'
        ? ToolbarAndroid
        : ToolbarIos);
    return (
        <Comp
            titleColor="white"
            {...props}
            style={[styles.toolbar, props.style]} />
    )
};

const styles = StyleSheet.create({
    toolbar: {
        height: 56,
        backgroundColor: '#651FFF',
        elevation: 5,
    }
});

export default Toolbar;

Hide iOS toolbar when on PhotoGrid


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

module.exports = function render(input, context) {
    var widgetsContext = raptorWidgets.getWidgetsContext(context);

    if (context.featureLastFlush === false) {
        // If the rendering context doesn't support the ability to know when all of the asynchronous fragmnents
        // have completed then we won't be able to know which widgets were rendered so we will
        // need to scan the DOM to find the widgets
        raptorWidgets.writeInitWidgetsCode(widgetsContext, context, {scanDOM: true});
    } else {
        var asyncContext = context.beginAsync({ last: true });
        context.on('last', function() {
            if (!widgetsContext.hasWidgets()) {
                return asyncContext.end();
            }

            raptorWidgets.writeInitWidgetsCode(widgetsContext, asyncContext);
            asyncContext.end();
        });
    }

};

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

module.exports = function render(input, context) {
    var widgetsContext = raptorWidgets.getWidgetsContext(context);

    if (context.featureLastFlush === false) {
        // If the rendering context doesn't support the ability to know when all of the asynchronous fragmnents
        // have completed then we won't be able to know which widgets were rendered so we will
        // need to scan the DOM to find the widgets
        raptorWidgets.writeInitWidgetsCode(widgetsContext, context, {scanDOM: true});
    } else {
        var asyncContext = context.beginAsync({ last: true, timeout: -1 });
        context.on('last', function() {
            if (!widgetsContext.hasWidgets()) {
                return asyncContext.end();
            }

            raptorWidgets.writeInitWidgetsCode(widgetsContext, asyncContext);
            asyncContext.end();
        });
    }
};

Set timeout to infinity for init-widgets tag


/**
 * Created by gwennael.buchet on 01/01/17.
 */
"use strict";

/**
 * HOW-TO :
 * - rename this file into "secretKeys.js"
 * - replace values with your own
 */

//ThingSpeak API keys
const THINGSPEAK_CHANNEL_NUMBER = 0;
const THINGSPEAK_WRITE_API_KEY = "";
const THINGSPEAK_READ_API_KEY = "";

//Shiftr.io tokens
const SHIFTR_NAMESPACE = "/xxx";
const SHIFTR_DEVICE_LOGIN = "";
const SHIFTR_DEVICE_PWD = "";

/**
 * Created by gwennael.buchet on 01/01/17.
 */
"use strict";

/**
 * HOW-TO :
 * - rename this file into "secretKeys.js"
 * - replace values with your own
 */

module.exports = Object.freeze(
	{
		//ThingSpeak API keys
		THINGSPEAK_CHANNEL_NUMBER: 0,
		THINGSPEAK_WRITE_API_KEY: "",
		THINGSPEAK_READ_API_KEY: "",

		//Shiftr.io tokens
		SHIFTR_NAMESPACE: "/xxxx",
		SHIFTR_DEVICE_LOGIN: "",
		SHIFTR_DEVICE_PWD: ""
	}
);

Use module system for secret keys


var gulp = require('gulp');
var browserify = require('browserify');
var vinyl = require('vinyl-source-stream');
var tsify = require('tsify');
var watchify = require('watchify');

const JS_OUTPUT = 'bundle.js';
const DIST_DIR = './dist';

function compile() {
  return browserify({
    basedir: '.',
    debug: true,
    entries: ['src/main.ts'],
    cache: {},
    packageCache: {},
  }).plugin(tsify);
}

// Compile TypeScript and bundle everything in a single bundle.js file.
function build() {
  return compile()
    .bundle()
    .pipe(vinyl(JS_OUTPUT))
    .pipe(gulp.dest(DIST_DIR));
}

// Recompile TypeScript on file change.
function watch() {
  var task = watchify(compile());

  task.on('update', build);

  return task
    .bundle()
    .pipe(vinyl(JS_OUTPUT))
    .pipe(gulp.dest(DIST_DIR));
}

gulp.task('default', watch);
gulp.task('build', build);

var gulp = require('gulp');
var browserify = require('browserify');
var vinyl = require('vinyl-source-stream');
var tsify = require('tsify');
var watchify = require('watchify');

const JS_OUTPUT = 'bundle.js';
const DIST_DIR = './dist';

function compile() {
  return browserify({
    basedir: '.',
    debug: true,
    entries: ['src/main.ts'],
    cache: {},
    packageCache: {},
  }).plugin(tsify);
}

// Compile TypeScript and bundle everything in a single bundle.js file.
function build() {
  return compile()
    .bundle()
    .pipe(vinyl(JS_OUTPUT))
    .pipe(gulp.dest(DIST_DIR));
}

// Watch the source code and recompile on modifications
var watchedBrowserify = watchify(compile());
watchedBrowserify.on("update", watch);

function watch() {
  return watchedBrowserify
    .bundle()
    .pipe(vinyl(JS_OUTPUT))
    .pipe(gulp.dest(DIST_DIR));
}

gulp.task('default', watch);
gulp.task('build', build);

Fix a bug where `watch` task was not working.


const flatten = require('flatten')
const Set     = require('es6-set')

function normalizeRoot(root) {
	if(!root) return document
	if(typeof(root) == 'string') return $(root)
	return root
}

function $(selector, root) {
	root = normalizeRoot(root)
	return wrapNode(root.querySelector(selector))
}

$.all = function $$(selector, root) {
	root = normalizeRoot(root)
	return [].slice.call(root.querySelectorAll(selector)).map(function(node) {
		return wrapNode(node)
	})
}

$.wrap = function(node) {
	if(typeof(node.length) == 'number') {
		return [].slice.call(node).map(function(node) {
			return wrapNode(node)
		})
	} else {
		return wrapNode(node)
	}
}

function wrapNode(node) {
	node.find = function(sel) {
		return $(sel, node)
	}
	node.findAll = function(sel) {
		return $.all(sel, node)
	}
	return node
}

module.exports = $

window.$ = $

const flatten = require('flatten')
const Set     = require('es6-set')

function normalizeRoot(root) {
	if(!root) return document
	if(typeof(root) == 'string') return $(root)
	return root
}

function $(selector, root) {
	root = normalizeRoot(root)
	return wrapNode(root.querySelector(selector))
}

$.all = function $$(selector, root) {
	root = normalizeRoot(root)
	return [].slice.call(root.querySelectorAll(selector)).map(function(node) {
		return wrapNode(node)
	})
}

$.wrap = function(node) {
	if(typeof(node.length) == 'number') {
		return [].slice.call(node).map(function(node) {
			return wrapNode(node)
		})
	} else {
		return wrapNode(node)
	}
}

function wrapNode(node) {
	if(!node) return null

	node.find = function(sel) {
		return $(sel, node)
	}
	node.findAll = function(sel) {
		return $.all(sel, node)
	}
	return node
}

module.exports = $

window.$ = $

Fix $.wrap for null This also fixes $ for when no element is found


import { resolve } from 'path';
import { load as grpcLoad } from 'grpc';

// The proto files are copied as part of the build script (see package.json) to a '/protos'
// folder under the root of the project
const root = resolve(__dirname, '../../protos');

/**
 * Common function for loading a protobuf file. Returns the proto object.
 */
export function load(file) {
  return grpcLoad({ root, file });
};

export default load;

import { resolve } from 'path';
import { load as grpcLoad } from 'grpc';

// The proto files are copied as part of the build script (see package.json) to a '/protos'
// folder under the root of the project
const root = resolve(__dirname, '../../protos');

/**
 * Common function for loading a protobuf file. Returns the proto object.
 */
export function load(file) {
  return grpcLoad({ root, file }, 'proto', { convertFieldsToCamelCase: true });
};

export default load;

Load should convert fields to camel case


/*jshint node:true*/
module.exports = {
  scenarios: [
    {
      name: 'default',
      dependencies: { }
    },
    {
      name: 'ember-release',
      dependencies: {
        'ember': 'components/ember#release'
      },
      resolutions: {
        'ember': 'release'
      }
    },
    {
      name: 'ember-beta',
      dependencies: {
        'ember': 'components/ember#beta'
      },
      resolutions: {
        'ember': 'beta'
      }
    },
    {
      name: 'ember-canary',
      dependencies: {
        'ember': 'components/ember#canary'
      },
      resolutions: {
        'ember': 'canary'
      }
    }
  ]
};

/*jshint node:true*/
module.exports = {
  scenarios: [
    {
      name: 'default',
      dependencies: { }
    },
    {
      name: 'ember-1.12',
      dependencies: {
        'ember': '1.12'
      }
    },
    {
      name: 'ember-1.13',
      dependencies: {
        'ember': '1.13'
      }
    },
    {
      name: 'ember-release',
      dependencies: {
        'ember': 'components/ember#release'
      },
      resolutions: {
        'ember': 'release'
      }
    },
    {
      name: 'ember-beta',
      dependencies: {
        'ember': 'components/ember#beta'
      },
      resolutions: {
        'ember': 'beta'
      }
    },
    {
      name: 'ember-canary',
      dependencies: {
        'ember': 'components/ember#canary'
      },
      resolutions: {
        'ember': 'canary'
      }
    }
  ]
};

Add Ember 1.12 and 1.13 to tests


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

	grunt.registerMultiTask('typedoc', 'Generate TypeScript docs', function () {
		var options = this.options({});

		var args = [];
		for (var key in options) {
			if (options.hasOwnProperty(key)) {
				args.push('--' + key);
				if (!!options[key]) {
					args.push(options[key]);
				}
			}
		}
		for (var i = 0; i < this.filesSrc.length; i++) {
			args.push(this.filesSrc[i]);
		}

		// lazy init
		var path = require('path');
		var child_process = require('child_process');

		var winExt = /^win/.test(process.platform) ? '.cmd' : '';

		var done = this.async();
		var executable = path.resolve(require.resolve('typedoc/package.json'), '..', '..', '.bin', 'typedoc' + winExt);

		var child = child_process.spawn(executable, args, {
			stdio: 'inherit',
			env: process.env
		}).on('exit', function (code) {
			if (code !== 0) {
				done(false);
			}
			if (child) {
				child.kill();
			}
			done();
		});
	});
};

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

	grunt.registerMultiTask('typedoc', 'Generate TypeScript docs', function () {
		var options = this.options({});

		var args = [];
		for (var key in options) {
			if (options.hasOwnProperty(key) && (typeof options[key] !== "boolean" || options[key])) {
				args.push('--' + key);
				if (typeof options[key] !== "boolean" && !!options[key]) {
					args.push(options[key]);
				}
			}
		}
		for (var i = 0; i < this.filesSrc.length; i++) {
			args.push(this.filesSrc[i]);
		}

		// lazy init
		var path = require('path');
		var child_process = require('child_process');
		var typedoc;

		try {
			typedoc = require.resolve('../../typedoc/package.json');
		} catch(e) {
			typedoc = require.resolve('typedoc/package.json')
		}

		var winExt = /^win/.test(process.platform) ? '.cmd' : '';

		var done = this.async();
		var executable = path.resolve(typedoc, '..', '..', '.bin', 'typedoc' + winExt);

		var child = child_process.spawn(executable, args, {
			stdio: 'inherit',
			env: process.env
		}).on('exit', function (code) {
			if (code !== 0) {
				done(false);
			}
			if (child) {
				child.kill();
			}
			done();
		});
	});
};

Implement boolean option flags and change TypeDoc path strategy


Meteor.publish('ItemSets.id', function (id) {
  check(id, String);
  this.unblock();
  return ItemSets.find(new Meteor.Collection.ObjectID(id));
});
Meteor.publish('ItemSets.last', function () {
  this.unblock();
  return ItemSets.find({}, { sort: { patchVersion : -1, generationDate: -1 }, limit: 1 });
});

Meteor.publish('Downloads', function () {
  this.unblock();
  return Downloads.find();
});

Meteor.publish('Versions', function () {
  this.unblock();
  return Versions.find();
});

Meteor.publish('GuestbookEntries', function () {
  this.unblock();
  return GuestbookEntries.find({ approved: true });
});

Meteor.publish('TwitterAnnouncements.last', function () {
  this.unblock();
  return TwitterAnnouncements.find({}, { sort: { creationDate: -1 }, limit: 1 });
});

Meteor.publish('ItemSets.id', function (id) {
  check(id, String);
  this.unblock();
  return ItemSets.find(new Meteor.Collection.ObjectID(id), { reactive: false });
});
Meteor.publish('ItemSets.last', function () {
  this.unblock();
  return ItemSets.find({}, { sort: { patchVersion : -1, generationDate: -1 }, limit: 1 }, { reactive: false });
});

Meteor.publish('Downloads', function () {
  this.unblock();
  return Downloads.find();
});

Meteor.publish('Versions', function () {
  this.unblock();
  return Versions.find();
});

Meteor.publish('GuestbookEntries', function () {
  this.unblock();
  return GuestbookEntries.find({ approved: true });
});

Meteor.publish('TwitterAnnouncements.last', function () {
  this.unblock();
  return TwitterAnnouncements.find({}, { sort: { creationDate: -1 }, limit: 1 });
});

Disable reactivity of item sets publications.


var Promise = require('../')
  , Domain = require('domain')
  , assert = require('assert');

var next = 'function' == typeof setImmediate
  ? setImmediate
  : process.nextTick;

describe("domains", function () {
  it("exceptions should not breakout of domain bounderies", function (done) {
    var d = Domain.create();
    d.on('error', function (err) {
      assert.equal(err.message, 'gaga');
      done()
    });

    var p = new Promise();

    d.run(function () {
      p.then(function () {

      }).then(function () {
          throw new Error('gaga');
        }).end();
    });

    next(function () {
      p.fulfill();
    })
  });
});

var Promise = require('../')
  , Domain = require('domain')
  , assert = require('assert');

var next = 'function' == typeof setImmediate
  ? setImmediate
  : process.nextTick;

describe("domains", function () {
  it("exceptions should not breakout of domain bounderies", function (done) {
    if (process.version.indexOf('v0.8') == 0) return done();
    var d = Domain.create();
    d.once('error', function (err) {
      assert.equal(err.message, 'gaga');
      done()
    });

    var p = new Promise();

    d.run(function () {
      p.then(function () {

      }).then(function () {
          throw new Error('gaga');
        }).end();
    });

    next(function () {
      p.fulfill();
    })
  });
});

Fix works only for v0.10.x


'use strict';

var path = require('path');
var assert = require('yeoman-generator').assert;
var helpers = require('yeoman-generator').test;
var os = require('os');

describe('ironhide-webapp:app', function () {
  before(function (done) {
    helpers.run(path.join(__dirname, '../app'))
      .withOptions({ skipInstall: true })
      .withPrompts({ someOption: true })
      .on('end', done);
  });

  it('creates files', function () {
    assert.file([
      'bower.json',
      'package.json',
      '.editorconfig',
      '.jshintrc'
    ]);
  });
});

'use strict';

var path = require('path');
var assert = require('yeoman-generator').assert;
var helpers = require('yeoman-generator').test;
var os = require('os');

describe('ironhide-webapp:app', function () {
  before(function (done) {
    helpers.run(path.join(__dirname, '../app'))
      .withOptions({ skipInstall: true })
      .withPrompts({ appname: 'ironhide-webapp-test-app' })
      .on('end', done);
  });

  it('Should create files', function () {
    assert.file([
      'app',
      'tasks',
      'tests',
      'bower.json',
      'Gemfile',
      'Gemfile.lock',
      'gulpfile.js',
      'license.md',
      'package.json',
      'package.json',
      'readme.md',
      'travis.yml',
      '.bowerrc',
      '.compassrc',
      '.editorconfig',
      '.gitattributes',
      '.jshintignore',
      '.jshintrc',
      '.karmarc',
      '.ruby-gemset',
      '.ruby-version',
      '.scsslintrc'
    ]);
  });
});

Update tests to reflect new files.


(function () {
	'use strict';

	if (location.hostname === 'todomvc.com') {
		var _gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
	}
})();

(function () {
	'use strict';

	if (location.hostname === 'todomvc.com') {
		var _gaq=[['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
	}

	function appendSourceLink() {
		var sourceLink = document.createElement('a');
		var paragraph = document.createElement('p');
		var footer = document.getElementById('info');
		var urlBase = 'https://github.com/addyosmani/todomvc/tree/gh-pages';

		if (footer) {
			sourceLink.href = urlBase + location.pathName;
			sourceLink.appendChild(document.createTextNode('Check out the source'));
			paragraph.appendChild(sourceLink);
			footer.appendChild(paragraph);
		}
	}

	appendSourceLink();
})();

Add link to source to footer of every example


import createDebug from 'debug';

import { onLoad } from './util';

const debug = createDebug('ms:api');
const partitionArray = (array, size) => array.map((e, i) => (i % size === 0) ?
  array.slice(i, i + size) : null).filter(e => e);

onLoad(() => {
  $('#create_filter').on('click', () => {
    const checkboxes = $('input[type=checkbox]');
    const bits = new Array(checkboxes.length);

    $.each(checkboxes, (index, item) => {
      const $item = $(item);
      const arrayIndex = $item.data('index');
      if ($item.is(':checked')) {
        bits[arrayIndex] = 1;
        debug($item, arrayIndex);
      } else {
        bits[arrayIndex] = 0;
      }
    });

    const bytes = partitionArray(bits, 8);
    debug(bits.join(''));
    debug(bytes.map(x => x.join('')).join(' '));
    debug(bytes.map(x => parseInt(x.join(''), 2)).join('        '));

    let unsafeFilter = '';
    for (let i = 0; i < bytes.length; i++) {
      const nextByte = bytes[i].join('');
      const charCode = parseInt(nextByte.toString(), 2);
      unsafeFilter += String.fromCharCode(charCode);
      debug(nextByte, charCode, unsafeFilter);
    }

    const filter = btoa(unsafeFilter);
    debug(filter);
    window.prompt('Your filter:', filter);
  });
});

import createDebug from 'debug';

import { onLoad } from './util';

const debug = createDebug('ms:api');
const partitionArray = (array, size) => array.map((e, i) => (i % size === 0) ?
  array.slice(i, i + size) : null).filter(e => e);

onLoad(() => {
  $('#create_filter').on('click', () => {
    const bits = Array.from($('input[type=checkbox]')).reduce((arr, el) => {
      const $el = $(el);
      arr[$el.data('index')] = Number($el.is(':checked'));
      return arr;
    }, []);

    const bytes = partitionArray(bits, 8);
    debug(bits.join(''));
    debug(bytes.map(x => x.join('')).join(' '));
    debug(bytes.map(x => parseInt(x.join(''), 2)).join('        '));

    let unsafeFilter = '';
    for (let i = 0; i < bytes.length; i++) {
      const nextByte = bytes[i].join('');
      const charCode = parseInt(nextByte.toString(), 2);
      unsafeFilter += String.fromCharCode(charCode);
      debug(nextByte, charCode, unsafeFilter);
    }

    const filter = btoa(unsafeFilter);
    debug(filter);
    window.prompt('Your filter:', filter);
  });
});

Refactor to more functional style


const gulp = require('gulp');
const tsc = require('gulp-typescript');
const Server = require('karma').Server;
const tsProject = tsc.createProject('src/tsconfig.json');
const tsProjectSpec = tsc.createProject('spec/tsconfig.json');

gulp.task('default', ['build']);
gulp.task('build', () => {
  return tsProject.src()
    .pipe(tsc(tsProject))
    .pipe(gulp.dest('build'));
});
gulp.task('test', ['test-build:spec', 'test-build:src'], () => {
  new Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true,
    plugins:[
      'karma-spec-reporter',
      'karma-coverage',
      'karma-coveralls'
    ]
  }).start();
});
gulp.task('test-build:spec', (done) => {
  tsProjectSpec.src()
    .pipe(tsc(tsProjectSpec))
    .pipe(gulp.dest('test-build'))
    .on('end', done);
});
gulp.task('test-build:src', (done) => {
  tsProject.src()
    .pipe(tsc(tsProject))
    .pipe(gulp.dest('test-build/src'))
    .on('end', done);
});

const gulp = require('gulp');
const tsc = require('gulp-typescript');
const Server = require('karma').Server;
const tsProject = tsc.createProject('src/tsconfig.json');
const tsProjectSpec = tsc.createProject('spec/tsconfig.json');

gulp.task('default', ['build']);
gulp.task('build', () => {
  return tsProject.src()
    .pipe(tsc(tsProject))
    .pipe(gulp.dest('build'));
});
gulp.task('test', ['test-build:spec', 'test-build:src'], () => {
  new Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true,
    plugins: [
      'karma-jasmine',
      'karma-spec-reporter',
      'karma-coverage',
      'karma-coveralls'
    ]
  }).start();
});
gulp.task('test-build:spec', (done) => {
  tsProjectSpec.src()
    .pipe(tsc(tsProjectSpec))
    .pipe(gulp.dest('test-build'))
    .on('end', done);
});
gulp.task('test-build:src', (done) => {
  tsProject.src()
    .pipe(tsc(tsProject))
    .pipe(gulp.dest('test-build/src'))
    .on('end', done);
});

Add karma-jasmine to the plugins


// PiscoBot Script

var commandDescription = {
  name: 'GitHub Mention',
  author: 'Daniel Gallegos [@that_taco_guy]',
  trigger: '[none]',
  version: 1.0,
  description: 'Have the bot reply to new commits on GitHub.',
  module: 'Core'
};

global.botHelp.push(commandDescription);

var _ = require('underscore');

global.piscobot.hears(['PiscoBot.*new commits by', 'PiscoBot.*new commit by'], ['bot_message'],
  function(bot, message) {
    var emoji = [
      'thinking_face',
      'open_mouth',
      'face_with_rolling_eyes',
      'sweat_smile'
    ];
    bot.api.reactions.add({
      timestamp: message.ts,
      channel: message.channel,
      name: _.sample(emoji)
    }, function(err) {
      if(err) {
        bot.botkit.log('Failed to add emoji reaction :(', err);
      }
    });
  }
);

// PiscoBot Script

var commandDescription = {
  name: 'GitHub Mention',
  author: 'Daniel Gallegos [@that_taco_guy]',
  trigger: '[none]',
  version: 1.0,
  description: 'Have the bot reply to new commits on GitHub.',
  module: 'Core'
};

var _ = require('underscore');

global.piscobot.hears(['PiscoBot.*new commits by', 'PiscoBot.*new commit by'], ['bot_message'],
  function(bot, message) {
    var emoji = [
      'thinking_face',
      'open_mouth',
      'face_with_rolling_eyes',
      'sweat_smile'
    ];
    bot.api.reactions.add({
      timestamp: message.ts,
      channel: message.channel,
      name: _.sample(emoji)
    }, function(err) {
      if(err) {
        bot.botkit.log('Failed to add emoji reaction :(', err);
      }
    });
  }
);

Remove GitHub from the help scripts


const fs = require('fs')
const file = require('file')
const path = require('path')
const toml = require('toml')

const parsers = {
    '.toml': toml.parse,
    '.json': JSON.parse
}

function readGraphObjects(objectsPath) {
    let result = []
    file.walkSync(objectsPath, (dirPath, dirs, filePaths) => {
        result = result.concat(
            filePaths
                .filter(filePath => !!parsers[path.extname(filePath)])
                .map(filePath => {
                    const absoluteFilePath =  path.resolve(dirPath, filePath)
                    const fileContent = fs.readFileSync(absoluteFilePath, { encoding: 'utf8' })

                    const parser = parsers[path.extname(filePath)]
                    const content = parser(fileContent)

                    return {
                        absoluteFilePath,
                        content
                    }
                })
        )
    })
    return result
}

module.exports = function readGraph(graphPath) {
    return {
        nodeLabels:        readGraphObjects(path.resolve(graphPath, 'nodeLabels')),
        nodes:             readGraphObjects(path.resolve(graphPath, 'nodes')),
        relationships:     readGraphObjects(path.resolve(graphPath, 'relationships')),
        relationshipTypes: readGraphObjects(path.resolve(graphPath, 'relationshipTypes')),
    }

}

const fs = require('fs')
const file = require('file')
const path = require('path')
const toml = require('toml')

const parsers = {
    '.toml': toml.parse,
    '.json': JSON.parse
}

function readGraphObjects(objectsPath, mapResult) {
    let result = []
    file.walkSync(objectsPath, (dirPath, dirs, filePaths) => {
        result = result.concat(
            filePaths
                .filter(filePath => !!parsers[path.extname(filePath)])
                .map(filePath => {
                    const absoluteFilePath =  path.resolve(dirPath, filePath)
                    const fileContent = fs.readFileSync(absoluteFilePath, { encoding: 'utf8' })

                    const parser = parsers[path.extname(filePath)]
                    const content = parser(fileContent)

                    return mapResult({
                        absoluteFilePath,
                        content
                    })
                })
        )
    })
    return result
}

module.exports = function readGraph(graphPath, mapResult = i => i) {
    return {
        nodeLabels:        readGraphObjects(path.resolve(graphPath, 'nodeLabels'), mapResult),
        nodes:             readGraphObjects(path.resolve(graphPath, 'nodes'), mapResult),
        relationships:     readGraphObjects(path.resolve(graphPath, 'relationships'), mapResult),
        relationshipTypes: readGraphObjects(path.resolve(graphPath, 'relationshipTypes'), mapResult),
    }

}

Allow custom mapping function when reading graph.


const twitchIO = require('socket.io');
const twitchClient = require('./tmiClient');
// const Rx = require('rx');
const eventEmitter = require('./eventEmitter');
const messageController = require('../db/messageController');

// const messageSource = Rx.Observable.fromEvent(twitchClient, 'chat', () => {
//   let args = [].slice.call(arguments);
//   return {
//     user: args[1].username,
//     message: args[2]
//   };
// });

// const messageSubscription = messageSource.subscribe(msgObj => {
//   eventEmitter.emit('chatMessage', msgObj);
// });

twitchClient.on('chat', (channel, user, msg, self) => {
  const messageBody = {
    channel,
    user,
    msg,
  };

  messageController.saveMessage(messageBody);

  eventEmitter.emit('chatMessage', {
    user: user.username,
    message: msg,
  });
});

module.exports = server => {
  const io = twitchIO.listen(server);

  io.sockets.on('connection', socket => {
    // socket.send('hello world');

    eventEmitter.on('chatMessage', message => {
      io.emit('message', message);
    });
  });

  return io;
};

const twitchIO = require('socket.io');
const twitchClient = require('./tmiClient');
const Rx = require('rx');
const eventEmitter = require('./eventEmitter');
const messageController = require('../db/messageController');

const messageSource = Rx.Observable.fromEvent(twitchClient, 'chat', (channel, user, msg) => {
  return { channel, user, msg };
});

const messageSubscription = messageSource.subscribe((msgObj) => {
  eventEmitter.emit('chatMessage', msgObj);
  messageController.saveMessage(msgObj);
});

module.exports = server => {
  const io = twitchIO.listen(server);

  io.sockets.on('connection', socket => {

    eventEmitter.on('chatMessage', message => {
      io.emit('message', message);
    });

  });

  return io;
};

Simplify message emitting and incorporate RxJS


"use strict";

describe("deselector", function() {
  var element;
  var state;
  var configurator = { provideResource: function() {} };

  beforeEach(module("arethusa.core", function($provide) {
    $provide.value('configurator', configurator);
  }));

  beforeEach(inject(function($compile, $rootScope, _state_) {
    element = angular.element("<span deselector/>");
    $compile(element)($rootScope);
    state = _state_;
  }));

  describe("on click", function() {
    it('deselects all tokens', function() {
      state.selectToken('01', 'ctrl-click');
      state.selectToken('02', 'ctrl-click');
      expect(state.hasSelections()).toBeTruthy();

      element.triggerHandler('click');
      expect(state.hasSelections()).toBeFalsy();
    });
  });
});

"use strict";

describe("deselector", function() {
  var element;
  var state;
  var configurator = {
    provideResource: function() {},
    configurationFor: function() {}
  };

  beforeEach(module("arethusa.core", function($provide) {
    $provide.value('configurator', configurator);
  }));

  beforeEach(inject(function($compile, $rootScope, _state_) {
    element = angular.element("<span deselector/>");
    $compile(element)($rootScope);
    state = _state_;
  }));

  describe("on click", function() {
    it('deselects all tokens', function() {
      state.selectToken('01', 'ctrl-click');
      state.selectToken('02', 'ctrl-click');
      expect(state.hasSelections()).toBeTruthy();

      element.triggerHandler('click');
      expect(state.hasSelections()).toBeFalsy();
    });
  });
});

Update configurator mock in deselector spec


'use strict';

angular.module('polestar')
  .directive('jsonInput', function() {
    return {
      restrict: 'A',
      require: 'ngModel',
      scope: {},
      link: function(scope, element, attrs, modelCtrl) {
        var format = function(inputValue) {
          return JSON.stringify(inputValue, null, '  ', 80);
        };
        modelCtrl.$formatters.push(format);
      }
    };
  });

'use strict';

angular.module('polestar')
  .directive('jsonInput', function(JSON3) {
    return {
      restrict: 'A',
      require: 'ngModel',
      scope: {},
      link: function(scope, element, attrs, modelCtrl) {
        var format = function(inputValue) {
          return JSON3.stringify(inputValue, null, '  ', 80);
        };
        modelCtrl.$formatters.push(format);
      }
    };
  });

Use JSON3 with no conflict


define([
	'../../Promise'
], function (Promise) {
	'use strict';

	var resolve = Promise.resolve.bind(Promise),
		arrayProto = Array.prototype,
		slice = arrayProto.slice,
		iteratorMethods = [ 'forEach', 'map', 'filter' ];

	/**
	 * Decorates a promise with a method derived from the Array.prototype wrapped in a promise that resolves when the
	 * promise is resolved
	 * @param  {Promise} promise The promise that is to be decorated
	 * @param  {String}  method  The name of the function from the Array prototype that should be decorated
	 */
	function decorate(promise, method) {
		promise[method] = function () {
			var args = slice.call(arguments);
			return promise.then(function (results) {
				return arrayProto[method].apply(results, args);
			});
		};
	}

	/**
	 * Takes results from a store query, wraps them in a promise if none provided, decorates with promise iterators and
	 * a total.
	 * @param  {Promise|Array} results The results that are to be wrapped and decorated
	 * @return {Promise}               The resulting promise that has been decorated.
	 */
	return function queryResults(results) {
		var resultsPromise = resolve(results);
		iteratorMethods.forEach(function (method) {
			decorate(resultsPromise, method);
		});
		resultsPromise.total = results.total || resultsPromise.then(function (results) {
			return results.length;
		});
		return resultsPromise;
	};
});

define([
	'../../Promise'
], function (Promise) {
	'use strict';

	var resolve = Promise.resolve.bind(Promise),
		arrayProto = Array.prototype,
		slice = arrayProto.slice,
		iteratorMethods = [ 'forEach', 'map', 'filter', 'every', 'some', 'reduce', 'reduceRight' ];

	/**
	 * Decorates a promise with a method derived from the Array.prototype wrapped in a promise that resolves when the
	 * promise is resolved
	 * @param  {Promise} promise The promise that is to be decorated
	 * @param  {String}  method  The name of the function from the Array prototype that should be decorated
	 */
	function decorate(promise, method) {
		promise[method] = function () {
			var args = slice.call(arguments);
			return promise.then(function (results) {
				return arrayProto[method].apply(results, args);
			});
		};
	}

	/**
	 * Takes results from a store query, wraps them in a promise if none provided, decorates with promise iterators and
	 * a total.
	 * @param  {Promise|Array} results The results that are to be wrapped and decorated
	 * @return {Promise}               The resulting promise that has been decorated.
	 */
	return function queryResults(results) {
		var resultsPromise = resolve(results);
		iteratorMethods.forEach(function (method) {
			decorate(resultsPromise, method);
		});
		resultsPromise.total = results.total || resultsPromise.then(function (results) {
			return results.length;
		});
		return resultsPromise;
	};
});

Add more iterator methods to query results.


import { remote } from 'electron';
import fs from 'fs';
import path from 'path';

window.addEventListener('load', () => {
  if (window.$ && Settings.get('welcomed') === remote.app.getVersion() && $('#welcome').length) {
    $('[data-app-changes]').html(fs.readFileSync(path.resolve(`${__dirname}/../../../../MR_CHANGELOG.html`), 'utf8')); // eslint-disable-line

    $('#welcome').openModal({
      dismissible: false,
      complete: () => {
        Emitter.fire('welcomed', remote.app.getVersion());
      },
    });
  }
  if (window.$) {
    const modal = $('#about');
    $('[data-app-version]').text(remote.app.getVersion());
    $('[data-app-name]').text(remote.app.getName());
    $('[data-app-dev-mode]').text(remote.getGlobal('DEV_MODE') ? 'Running in Development Mode' : '');
    Emitter.on('about', () => {
      modal.openModal({
        dismissable: true,
      });
    });
  }
});

import { remote } from 'electron';
import fs from 'fs';
import path from 'path';

window.addEventListener('load', () => {
  if (window.$ && Settings.get('welcomed') !== remote.app.getVersion() && $('#welcome').length) {
    $('[data-app-changes]').html(fs.readFileSync(path.resolve(`${__dirname}/../../../../MR_CHANGELOG.html`), 'utf8')); // eslint-disable-line

    $('#welcome').openModal({
      dismissible: false,
      complete: () => {
        Emitter.fire('welcomed', remote.app.getVersion());
      },
    });
  }
  if (window.$) {
    const modal = $('#about');
    $('[data-app-version]').text(remote.app.getVersion());
    $('[data-app-name]').text(remote.app.getName());
    $('[data-app-dev-mode]').text(remote.getGlobal('DEV_MODE') ? 'Running in Development Mode' : '');
    Emitter.on('about', () => {
      modal.openModal({
        dismissable: true,
      });
    });
  }
});

Undo change made for debugging