var esprima = require('esprima');
var esmangle = require('esmangle');
var escodegen = require('escodegen');

Blend.defineClass('Minify', {
    singleton: true,
    js: function (scripts) {
        var ast = esprima.parse(scripts.join(';'));
        var optimized = esmangle.optimize(ast, null);
        var result = esmangle.mangle(optimized);
        result = escodegen.generate(result, {
            format: {
                renumber: true,
                hexadecimal: true,
                escapeless: true,
                compact: true,
                semicolons: false,
                parentheses: false
            }
        });
        return result.toString();
    }
});

var esprima = require('esprima');
var esmangle = require('esmangle');
var escodegen = require('escodegen');

Blend.defineClass('Minify', {
    singleton: true,
    js: function (scripts) {
        var ast = esprima.parse(scripts.join(';'));
        var optimized = esmangle.optimize(ast, null);
        var result = esmangle.mangle(optimized);
        return escodegen.generate(result, {
            format: {
                renumber: true,
                hexadecimal: true,
                escapeless: true,
                compact: true,
                semicolons: false,
                parentheses: false
            }
        });
    }
});

Update to return the correct mangled string


var React = require('react-native');
var flattenStyle = require('flattenStyle');
var { requireNativeComponent, processColor, PropTypes, View } = React;

var LinearGradient = React.createClass({
  propTypes: {
    start: PropTypes.arrayOf(PropTypes.number),
    end: PropTypes.arrayOf(PropTypes.number),
    colors: PropTypes.arrayOf(PropTypes.string).isRequired,
    locations: PropTypes.arrayOf(PropTypes.number),
    ...View.propTypes,
  },

  render: function() {
    var { style, children, colors, locations, start, end, ...otherProps } = this.props;

    // inherit container borderRadius until this issue is resolved:
    // https://github.com/facebook/react-native/issues/3198
    var borderRadius = flattenStyle(style).borderRadius || 0;

    return (
      <View {...otherProps} style={style}>
        <NativeLinearGradient
          style={{position: 'absolute', top: 0, left: 0, bottom: 0, right: 0}}
          colors={colors.map(processColor)}
          start={start}
          end={end}
          locations={locations}
          borderRadius={borderRadius}
        />
        { children }
      </View>
    );
  }
})

 var NativeLinearGradient = requireNativeComponent('BVLinearGradient', null);

 module.exports = LinearGradient;

var React = require('react-native');
var flattenStyle = require('flattenStyle');
var { requireNativeComponent, processColor, PropTypes, View } = React;

var LinearGradient = React.createClass({
  propTypes: {
    start: PropTypes.arrayOf(PropTypes.number),
    end: PropTypes.arrayOf(PropTypes.number),
    colors: PropTypes.arrayOf(PropTypes.string).isRequired,
    locations: PropTypes.arrayOf(PropTypes.number),
    ...View.propTypes,
  },

  render: function() {
    var { style, children, colors, locations, start, end, ...otherProps } = this.props;

    // inherit container borderRadius until this issue is resolved:
    // https://github.com/facebook/react-native/issues/3198
    var borderRadius = style && flattenStyle(style).borderRadius || 0;

    return (
      <View {...otherProps} style={style}>
        <NativeLinearGradient
          style={{position: 'absolute', top: 0, left: 0, bottom: 0, right: 0}}
          colors={colors.map(processColor)}
          start={start}
          end={end}
          locations={locations}
          borderRadius={borderRadius}
        />
        { children }
      </View>
    );
  }
})

 var NativeLinearGradient = requireNativeComponent('BVLinearGradient', null);

 module.exports = LinearGradient;

Work on Android even if style is not passed in

Otherwise we get a "Cannot read property 'borderRadius' of undefined" since [flattenStyle() will return undefined](https://github.com/facebook/react-native/blob/62e8ddc20561a39c3c839ab9f83c95493df117c0/Libraries/StyleSheet/flattenStyle.js#L28) if style is undefined.


function makeClient() {
  const transport = new Thrift.Transport('/api');
  const protocol = new Thrift.Protocol(transport);
  return new ReadOnlySchedulerClient(protocol);
}

export default makeClient();

import { isNully } from 'utils/Common';

function getBaseUrl() {
  // Power feature: load a different Scheduler URL from local storage to test against live APIs.
  //
  // In your browser console:
  //    window.localStorage.apiUrl = 'http://myauroracluster.com';
  //
  // To remove the item:
  //    window.localStorage.removeItem('apiUrl')
  if (window && window.localStorage) {
    return isNully(window.localStorage.apiUrl) ? '' : window.localStorage.apiUrl;
  }
  return '';
}

function makeClient() {
  const transport = new Thrift.Transport(`${getBaseUrl()}/api`);
  const protocol = new Thrift.Protocol(transport);
  return new ReadOnlySchedulerClient(protocol);
}

export default makeClient();

Add support for controlling API url in UI without modifying code.

Reviewed at https://reviews.apache.org/r/63040/


// Decodes data received
function decode(content){
    var lsRegExp = /\%20/g;
    var lsRegExp2 = /\%2B/g;

    content = String(unescape(content)).replace(lsRegExp, " ");
    content = content.replace(lsRegExp2, "+")

    return content;
}

// Encodes data to be sent
function encode(content) {
    var lsRegExp = new RegExp(" ","gim");
    var lsRegExp2 = /\+/g;

    content = String(escape(content)).replace(lsRegExp, "%20");
    content = content.replace(lsRegExp2, "%2B");

    return content;
}

// Formats the data into a basic json format
function toJSON(content) {
    return'{"name":"' + "BeginToReason" + '","pkg":"User","project":"Teaching_Project","content":"' + content + '","parent":"undefined","type":"f"}';
}

// Decodes data received
function decode(content){
    var lsRegExp = /\%20/g;
    var lsRegExp2 = /\%2B/g;

    content = String(unescape(content)).replace(lsRegExp, " ");
    content = content.replace(lsRegExp2, "+")

    return content;
}

// Encodes data to be sent
function encode(content) {
    var lsRegExp = new RegExp(" ","gim");
    var lsRegExp2 = /\+/g;

    content = String(escape(content)).replace(lsRegExp, "%20");
    content = content.replace(lsRegExp2, "%2B");

    return content;
}

// Formats the data into a basic json format
function toJSON(content) {
    var jsonObj = new Object();

    jsonObj.name = "BeginToReason";
    jsonObj.pkg = "User";
    jsonObj.project = "Teaching_Project";
    jsonObj.content = content;
    jsonObj.parent = "undefined";
    jsonObj.type = "f";

    return JSON.stringify(jsonObj);
	// return '{"name":"' + "BeginToReason" + '","pkg":"User","project":"Teaching_Project","content":"' + content + '","parent":"undefined","type":"f"}';
}

Create json object rather than forming the strings ourselves


//= link_tree ../images

//= link refinery/refinery.js
//= link admin.js
//= link modernizr-min.js

//= link refinery/refinery.css
//= link refinery/formatting.css
//= link refinery/site_bar.css
//= link refinery/theme.css

//= link_tree ../images

//= link refinery/refinery.js
//= link refinery/sortable_list.js
//= link refinery/nestedsortables.js
//= link refinery/serializelist.js
//= link refinery/tree.js
//= link admin.js
//= link modernizr-min.js

//= link refinery/refinery.css
//= link refinery/formatting.css
//= link refinery/site_bar.css
//= link refinery/theme.css

Add missing js assets in core manifest

Add missing js assets in core manifest


(function (angular) {
    'use strict';

    angular.module('courseMaterial', [
        'courseMaterial.controllers',
        'courseMaterial.services',
        'courseMaterial.directives',
        'courseMaterial.filters',
        'django',
        'directive.markdowneditor',
        'directive.alertPopup',
        'directive.fixedBar'
    ]);

})(angular);

(function (angular) {
    'use strict';

    angular.module('courseMaterial', [
        'courseMaterial.controllers',
        'courseMaterial.services',
        'courseMaterial.directives',
        'courseMaterial.filters',
        'django',
        'directive.markdowneditor',
        'directive.alertPopup',
        'directive.fixedBar',
        'header',
    ]);

})(angular);

Solve issue with HeaderCtrl in course_material page admin


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

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

Make sure including the asset from the gem works.


var path = require('path');
var nunjucks = require('nunjucks');
var DoExtension = require('nunjucks-do')(nunjucks);

var TEMPLATES_FOLDER = require('../../constants/templatesFolder');

var Templating = require('../../templating');
var TemplateEngine = require('../../models/templateEngine');
var listSearchPaths = require('./listSearchPaths');

/**
    Directory for a theme with the templates
*/
function templateFolder(dir) {
    return path.join(dir, TEMPLATES_FOLDER);
}

/**
    Create templating engine to render themes

    @param {Output} output
    @param {String} currentFile
    @return {TemplateEngine}
*/
function createTemplateEngine(output, currentFile) {
    var searchPaths = listSearchPaths(output);

    // Search paths for templates
    var tplSearchPaths = searchPaths.map(templateFolder);

    var loader = new Templating.ThemesLoader(tplSearchPaths);

    return TemplateEngine.create({
        loader: loader,

        filters: {
            t: function(s) {
                return s;
            },
            resolveFile: function(s) {
                return s;
            },
            resolveAsset: function(s) {
                return s;
            },
            fileExists: function() {
                return false;
            },
            contentURL: function(s) {
                return s;
            },
            getArticleByPath: function(s) {
                return undefined;
            }
        },

        extensions: {
            'DoExtension': new DoExtension()
        }
    });
}

module.exports = createTemplateEngine;

var path = require('path');
var nunjucks = require('nunjucks');
var DoExtension = require('nunjucks-do')(nunjucks);

var TEMPLATES_FOLDER = require('../../constants/templatesFolder');

var Templating = require('../../templating');
var TemplateEngine = require('../../models/templateEngine');
var defaultFilters = require('../../constants/defaultFilters');
var listSearchPaths = require('./listSearchPaths');

/**
    Directory for a theme with the templates
*/
function templateFolder(dir) {
    return path.join(dir, TEMPLATES_FOLDER);
}

/**
    Create templating engine to render themes

    @param {Output} output
    @param {String} currentFile
    @return {TemplateEngine}
*/
function createTemplateEngine(output, currentFile) {
    var searchPaths = listSearchPaths(output);

    // Search paths for templates
    var tplSearchPaths = searchPaths.map(templateFolder);

    var loader = new Templating.ThemesLoader(tplSearchPaths);

    return TemplateEngine.create({
        loader: loader,

        filters: defaultFilters.merge({
            t: function(s) {
                return s;
            },
            resolveFile: function(s) {
                return s;
            },
            resolveAsset: function(s) {
                return s;
            },
            fileExists: function() {
                return false;
            },
            contentURL: function(s) {
                return s;
            },
            getArticleByPath: function(s) {
                return undefined;
            }
        }),

        extensions: {
            'DoExtension': new DoExtension()
        }
    });
}

module.exports = createTemplateEngine;

Add default filters to theme templating engine


/*global Promise:true*/
var Promise = require('bluebird');

var workQueue = {
    queue: [],
    drain: function () {
        this.queue.forEach(function (fn) {
            fn();
        });
        this.queue = [];
    }
};

var scheduler = Promise.setScheduler(function (fn) {
    workQueue.queue.push(fn);
    scheduler(function () {
        workQueue.drain();
    });
});

var _notifyUnhandledRejection = Promise.prototype._notifyUnhandledRejection;
Promise.prototype._notifyUnhandledRejection = function () {
    var that = this;
    var args = arguments;
    scheduler(function () {
        _notifyUnhandledRejection.apply(that, args);
    });
};

module.exports = workQueue;

/*global Promise:true*/
var Promise = require('bluebird');

var workQueue = {
    queue: [],
    drain: function () {
        this.queue.forEach(function (fn) {
            fn();
        });
        this.queue = [];
    }
};

var scheduler = Promise.setScheduler(function (fn) {
    workQueue.queue.push(fn);
    scheduler(function () {
        workQueue.drain();
    });
});

var _notifyUnhandledRejection = Promise.prototype._notifyUnhandledRejection;
Promise.prototype._notifyUnhandledRejection = function () {
    var that = this;
    var args = arguments;
    scheduler(function () {
        if (that._isRejectionUnhandled()) {
            throw that.reason();
        }
    });
};

module.exports = workQueue;

Make sure that unhandled rejections are thrown so that eg. mocha will pick them up and consider the test suite to have failed.


import React, { PropTypes } from 'react';

const styles = {
  wrapper: {
    width: 50,
    height: 50,
    border: '5px solid chocolate',
    backgroundColor: 'green',
    position: 'absolute',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
  },
  number: {
    color: 'orange',
  },
};

const Tile = ({
  id,
  number,
  left,
  top,
  onMouseDown,
  onMouseUp,
  onMouseMove
}) => ({
  render() {
    const compStyles = Object.assign({}, styles.wrapper, {
      left,
      top,
    });

    return (

        {number}

    );
  }
});

Tile.propTypes = {
  id: PropTypes.number.isRequired,
  number: PropTypes.number,
  left: PropTypes.number.isRequired,
  top: PropTypes.number.isRequired,
  onMouseDown: PropTypes.func.isRequired,
  onMouseUp: PropTypes.func.isRequired,
  onMouseMove: PropTypes.func.isRequired,
};

Tile.defaultProps = {
  number: 0,
};

export default Tile;

import React, { PropTypes } from 'react';

import './Tile.css';

const styles = {
  wrapper: {
    width: 50,
    height: 50,
    border: '5px solid chocolate',
    backgroundColor: 'green',
    position: 'absolute',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
  },
  number: {
    color: 'orange',
  },
};

const Tile = ({
  number,
  left,
  top,
  onClick,
}) => {
  const compStyles = Object.assign({}, styles.wrapper, {
    left,
    top,
  });

  return (

      {number}

  );
};

Tile.propTypes = {
  number: PropTypes.number,
  left: PropTypes.number.isRequired,
  top: PropTypes.number.isRequired,
  onClick: PropTypes.func.isRequired,
};

Tile.defaultProps = {
  number: 0,
};

export default Tile;

Fix stateless component. cc @catalinmiron


"use strict";

angular.module('arethusa.core').directive('rootToken', [
  'state',
  function(state) {
    return {
      restrict: 'A',
      scope: {},
      link: function(scope, element, attrs) {
        function apply(fn) {
          scope.$apply(fn());
        }

        element.bind('click', function() {
          apply(function() {
            state.handleChangeHead('0000', 'click');
            state.deselectAll();
          });
        });

        element.bind('mouseenter', function () {
          apply(function() {
            element.addClass('hovered');
          });
        });
        element.bind('mouseleave', function () {
          apply(function() {
            element.removeClass('hovered');
          });
        });
      }
    };
  }
]);

"use strict";

angular.module('arethusa.core').directive('rootToken', [
  'state',
  'depTree',
  function(state, depTree) {
    return {
      restrict: 'A',
      scope: {},
      link: function(scope, element, attrs) {
        function apply(fn) {
          scope.$apply(fn());
        }

        var changeHeads = depTree.mode === 'editor';

        element.bind('click', function() {
          apply(function() {
            if (changeHeads) {
              state.handleChangeHead('0000', 'click');
              state.deselectAll();
            }
          });
        });

        element.bind('mouseenter', function () {
          apply(function() {
            element.addClass('hovered');
          });
        });
        element.bind('mouseleave', function () {
          apply(function() {
            element.removeClass('hovered');
          });
        });
      }
    };
  }
]);

Disable root-token head changes when not editing


import childProcess from 'child_process'
import {promisify} from 'util'

const exec = promisify(childProcess.exec)

export default async function (projectDirectory, repoName, token) {
  await exec(
    `git remote add origin https://create-npm:${token}@github.com/${repoName}`,
    {
      cwd: projectDirectory
    }
  )
  await exec('git push -u origin master', {cwd: projectDirectory})
  await exec(`git remote set-url origin git@github.com:${repoName}.git`, {
    cwd: projectDirectory
  })
}

import childProcess from 'child_process'
import {promisify} from 'util'

const exec = promisify(childProcess.exec)

export default async function (projectDirectory, repoName, token) {
  const {stdout} = await exec('git branch --show-current', {
    cwd: projectDirectory
  })
  const branchName = stdout.trim()

  await exec(
    `git remote add origin https://create-npm:${token}@github.com/${repoName}`,
    {
      cwd: projectDirectory
    }
  )
  await exec(`git push -u origin ${branchName}`, {cwd: projectDirectory})
  await exec(`git remote set-url origin git@github.com:${repoName}.git`, {
    cwd: projectDirectory
  })
}

fix(create-npm): Allow for default branch names other than master


var table = function (table) {
  table.increments().primary();
  table.string('file_name').notNullable().unique();

  table.boolean('completed').notNullable();
  table.integer('transferred_bytes').notNullable();
  table.integer('transfer_time').notNullable();
  table.string('parsed_user_agent').notNullable();
  table.string('raw_user_agent').notNullable();
  table.string('country').notNullable();
  table.string('ip_address').notNullable();
  table.string('parsed_referrer').notNullable();
  table.string('raw_referrer').notNullable();
  table.string('mime_type').notNullable();
  table.timestamps();

  // defined by timestamps();
  table.index('created_at');
};

exports.up = function (knex, Promise) {
  return knex.schema.createTable('downloads', table)
  .then(function () {
    console.log('Downloads table is created!');
  });
};

exports.down = function (knex, Promise) {
  return knex.schema
  .dropTable('downloads', table)
  .then(function () {
    console.log('Downloads table was dropped!');
  });
};

var table = function (table) {
  table.increments().primary();
  table.string('file_name').notNullable().unique();

  table.enum('transfer_state', ['completed', 'partial', 'canceled']).notNullable();
  table.integer('transferred_bytes').notNullable();
  table.integer('transfer_time').notNullable();
  table.integer('response_code').notNullable();
  table.string('parsed_user_agent').notNullable();
  table.string('raw_user_agent').notNullable();
  table.string('country').notNullable();
  table.string('ip_address').notNullable();
  table.string('parsed_referrer').notNullable();
  table.string('raw_referrer').notNullable();
  table.string('mime_type').notNullable();
  table.timestamps();

  // defined by timestamps();
  table.index('created_at');
  table.index('transfer_state');
};

exports.up = function (knex, Promise) {
  return knex.schema.createTable('downloads', table)
  .then(function () {
    console.log('Downloads table is created!');
  });
};

exports.down = function (knex, Promise) {
  return knex.schema
  .dropTable('downloads', table)
  .then(function () {
    console.log('Downloads table was dropped!');
  });
};

Add additional columns and indexes

Add additional columns and indexes


import Ember from 'ember';
import InstanceItemComponent from "./instance-item";

const { computed } = Ember;

export default InstanceItemComponent.extend({
  itemType: 'method',
  routeName: 'klass.methods.method',
  parameterSentence: computed('item.params.@each', function(){
    return this.get('item.params').mapProperty('name').join(', ');
  })
});

import Ember from 'ember';
import InstanceItemComponent from "./instance-item";

const { computed } = Ember;

export default InstanceItemComponent.extend({
  itemType: 'method',
  routeName: 'klass.methods.method',

  parameterSentence: computed('item.params.[]', function(){
    return this.get('item.params').mapProperty('name').join(', ');
  })
});

Remove leaf node @each usage.

Remove leaf node @each usage.


Add "disabled" class binding to checkbox's div


import getComponents from '../utils/dynamoDB'

export async function handler (event, context, callback) {
  console.log('getComponents called')
  try {
    let comps = await getComponents()
    callback(null, JSON.stringify(comps, null, 2))
  } catch (error) {
    console.log('getComponents error', error)
    console.log(error.stack)
    callback(JSON.stringify({
      error: 'Exception occurred'
    }))
  }
}

import { getComponents } from '../utils/dynamoDB'

export async function handler (event, context, callback) {
  console.log('getComponents called')
  try {
    let comps = await getComponents()
    callback(null, JSON.stringify(comps))
  } catch (error) {
    console.log('getComponents error', error)
    console.log(error.stack)
    callback(JSON.stringify({
      error: 'Exception occurred'
    }))
  }
}

Remove space in response json

Remove space in response json


var UploadController = Ember.Controller.extend({
    acceptEncoding: 'image/*',
    actions: {
        confirmAccept: function () {
            var self = this;

            this.get('model').save().then(function (model) {
                self.notifications.showSuccess('Saved');
                return model;
            }).catch(this.notifications.showErrors);
        },

        confirmReject: function () {
            return false;
        }
    }
});

export default UploadController;

var UploadController = Ember.Controller.extend({
    acceptEncoding: 'image/*',
    actions: {
        confirmAccept: function () {
            var self = this;

            this.get('model').save().then(function (model) {
                self.notifications.showSuccess('Saved');
                return model;
            }).catch(function (err) {
                self.notifications.showErrors(err);
            });
        },

        confirmReject: function () {
            return false;
        }
    }
});

export default UploadController;

Update Users API to handle role objects or ids

Closes #3357
- API method User#edit now handles User objects that have either
  an array of Role ids or objects.
- Fixed error handler notification on upload modal controller.


/* eslint-disable no-console */
const fs = require('fs');
const path = require('path');
const shell = require('shelljs');

function getCommand(watch) {
  const tsc = path.join(__dirname, '..', 'node_modules', '.bin', 'tsc');

  const args = ['--outDir ./dist', '-d true', '--listEmittedFiles true', '--preserveSymlinks true'];

  if (watch) {
    args.push('-w');
  }

  return `${tsc} ${args.join(' ')}`;
}

function handleExit(code, errorCallback) {
  if (code !== 0) {
    if (errorCallback && typeof errorCallback === 'function') {
      errorCallback();
    }

    shell.exit(code);
  }
}

function tscfy(options = {}) {
  const { watch = false, silent = true, errorCallback } = options;
  const tsConfigFile = 'tsconfig.json';

  if (!fs.existsSync(tsConfigFile)) {
    if (!silent) console.log(`No ${tsConfigFile}`);
    return;
  }

  const content = fs.readFileSync(tsConfigFile);
  const tsConfig = JSON.parse(content);

  if (tsConfig && tsConfig.lerna && tsConfig.lerna.disabled === true) {
    if (!silent) console.log('Lerna disabled');
    return;
  }

  const command = getCommand(watch);
  const { code } = shell.exec(command, { silent });

  handleExit(code, errorCallback);
}

module.exports = {
  tscfy,
};

/* eslint-disable no-console */
const fs = require('fs');
const path = require('path');
const shell = require('shelljs');

function getCommand(watch) {
  const tsc = path.join(__dirname, '..', 'node_modules', '.bin', 'tsc');

  const args = ['--outDir ./dist', '-d true', '--listEmittedFiles true'];

  if (watch) {
    args.push('-w');
  }

  return `${tsc} ${args.join(' ')}`;
}

function handleExit(code, errorCallback) {
  if (code !== 0) {
    if (errorCallback && typeof errorCallback === 'function') {
      errorCallback();
    }

    shell.exit(code);
  }
}

function tscfy(options = {}) {
  const { watch = false, silent = true, errorCallback } = options;
  const tsConfigFile = 'tsconfig.json';

  if (!fs.existsSync(tsConfigFile)) {
    if (!silent) console.log(`No ${tsConfigFile}`);
    return;
  }

  const content = fs.readFileSync(tsConfigFile);
  const tsConfig = JSON.parse(content);

  if (tsConfig && tsConfig.lerna && tsConfig.lerna.disabled === true) {
    if (!silent) console.log('Lerna disabled');
    return;
  }

  const command = getCommand(watch);
  const { code } = shell.exec(command, { silent });

  handleExit(code, errorCallback);
}

module.exports = {
  tscfy,
};

Remove preserveSymlinks that didn't actually help


const express = require('express')
const ERRORS = require('../../errors')
const User = require('../../models/User')
const utils = require('../../utils')
const router = express.Router()

/*
 * Endpoint: [POST] /users
 * Header:
 *   <None>
 * Body: {username, password}
 * Response:
 *   201 (JSON) The created user with a valid auth token
 *   400 Bad Request: invalid parameters
 */
router.post('/', register)
function register(req, res, next) {
    const { body: { username, password } } = req
    if (!username || !password) {
        next(ERRORS.MISSING_PARAMETERS(['username', 'password']))
    } else {
        User.register(username, password)
            .then(user => ({
                id: user.id,
                username: user.username,
                token: utils.genToken(user.id),
                createdAt: user.createdAt
            }))
            .then(data => {
                res.status(201)
                res.json(data)
            })
            .catch(err => next(ERRORS.REGISTRATION_FAILED(err)))
    }
}

/*
 * Endpoint: [GET] /users/authenticate?username:username
 * Header:
 *   Authorization: password=<password>
 * Body: <None>
 * Response:
 *   200 (JSON) A valid auth token
 *   403 Unauthorized: Wrong credentials
 */
router.get('/authenticate', authenticate)
function authenticate(req, res) {
    res.json({ notImplemented: "yet" })
}

module.exports = router

const express = require('express')
const ERRORS = require('../../errors')
const User = require('../../models/User')
const utils = require('../../utils')
const router = express.Router()

/*
 * Endpoint: [POST] /users
 * Header:
 *   <None>
 * Body: {username, password}
 * Response:
 *   201 (JSON) The created user with a valid auth token
 *   400 Bad Request: invalid parameters
 */
router.post('/', register)
function register(req, res, next) {
    const { body: { username, password } } = req
    if (!username || !password) {
        next(ERRORS.MISSING_PARAMETERS(['username', 'password']))
    } else {
        User.register(username, password)
            .then(user => ({
                id: user.id,
                username: user.username,
                token: utils.genToken(user.id),
                createdAt: user.createdAt
            }))
            .then(data => {
                res.status(201)
                res.json(data)
            })
            .catch(err => next(ERRORS.REGISTRATION_FAILED(err)))
    }
}

/*
 * Endpoint: [GET] /users/authenticate?username:username
 * Header:
 *   Authorization: password=<password>
 * Body: <None>
 * Response:
 *   200 (JSON) A valid auth token
 *   403 Forbidden: Wrong credentials
 */
router.get('/authenticate', authenticate)
function authenticate(req, res) {
    res.json({ notImplemented: "yet" })
}

module.exports = router

Rectify meta-comment in user routes

Rectify meta-comment in user routes


import React from 'react'
import ReactDom from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import OfflinePluginRuntime from 'offline-plugin/runtime'
import App from './components/App'
import './styles/global.scss'

const render = (Component) => {
  ReactDom.render(
    <AppContainer>
      <Component />
    </AppContainer>,
  document.getElementById('app'))
}

render(App)

if (module.hot) {
  module.hot.accept('./components/App', () => { render(App) })
}

if (process.env.NODE_ENV === 'production') {
  OfflinePluginRuntime.install({
    onUpdateReady: () => OfflinePluginRuntime.applyUpdate(),
    onUpdated: () => location.reload(),
  })
}

import React from 'react'
import ReactDom from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import OfflinePluginRuntime from 'offline-plugin/runtime'
import App from './components/App'
import './styles/global.scss'

const render = (Component) => {
  ReactDom.render(
    <AppContainer>
      <Component />
    </AppContainer>,
  document.getElementById('app'))
}

render(App)

if (module.hot) {
  module.hot.accept('./components/App', () => { render(App) })
}

if (process.env.NODE_ENV === 'production') {
  OfflinePluginRuntime.install()
}

Use SW default behavior for installing/updating


import _ from 'lodash'
import axios from 'axios'
import * as task from './task'
import pipe from './pipe'
import pipes from './pipes'
import connections from './connections'

var base_url = 'https://www.flex.io/api/v1'

var cfg = {
  token: '',
  baseUrl: 'https://www.flex.io/api/v1',
  debug: false
}

export default {
  // see `../build/webpack.dist.js`
  version: VERSION,

  // allow all tasks exports from `./task/index.js`
  task,

  setup(token, params) {
    cfg = _.assign({}, { token }, params)
    this._createHttp()
    return this
  },

  getConfig() {
    return _.assign({}, cfg)
  },

  http() {
    if (!this._http)
      this._createHttp()

    return this._http
  },

  pipe()        { return pipe()        },
  pipes()       { return pipes()       },
  connections() { return connections() },

  _createHttp() {
    // axios instance with base url and auth token factored into it
    this._http = axios.create({
      baseURL: cfg.baseUrl,
      headers: { 'Authorization': 'Bearer ' + cfg.token }
    })
  }
}

import _ from 'lodash'
import axios from 'axios'
import * as task from './task'
import pipe from './pipe'
import pipes from './pipes'
import connections from './connections'

var base_url = 'https://www.flex.io/api/v1'

var cfg = {
  token: '',
  baseUrl: 'https://www.flex.io/api/v1',
  insecure: false,
  debug: false
}

export default {
  // see `../build/webpack.dist.js`
  version: VERSION,

  // allow all tasks exports from `./task/index.js`
  task,

  setup(token, params) {
    cfg = _.assign({}, { token }, params)
    this._createHttp()
    return this
  },

  getConfig() {
    return _.assign({}, cfg)
  },

  http() {
    if (!this._http)
      this._createHttp()

    return this._http
  },

  pipe()        { return pipe()        },
  pipes()       { return pipes()       },
  connections() { return connections() },

  _createHttp() {
    // axios instance options with base url and auth token
    var axios_opts = {
      baseURL: cfg.baseUrl,
      headers: { 'Authorization': 'Bearer ' + cfg.token }
    }

    // if the `insecure` flag is set, allow unauthorized HTTPS calls
    if (cfg.insecure === true)
    {
      _.assign(axios_opts, {
        httpsAgent: new https.Agent({
          rejectUnauthorized: false
        })
      })
    }

    this._http = axios.create(axios_opts)
  }
}

Allow `insecure` HTTPS calls if that flag is set.


'use strict';

var Q = require('q'),
    scorer = require('./scorer'),
    print = require('./board/print');

module.exports = {
    play: function(board, player_x, player_o) {
        var self = this;
        return Q.promise(function(resolve) {
            self
                .get_play(board, player_x, player_o)
                .then(function(choice) {
                    board.set(choice, scorer.turn(board));
                    if (scorer.is_over(board)) {
                        resolve();
                    } else {
                        resolve(self.play(board, player_x, player_o));
                    }
                });
        });
    },

    get_play: function(board, player_x, player_o) {
        var current_player;

        if (scorer.turn(board) === 'x') {
            current_player = player_x;
        } else {
            current_player = player_o;
        }

        if (current_player.type === 'human') {
            print.rows(board.horizontal_rows());
        }

        return current_player.play(board);
    }
};

'use strict';

var Q = require('q'),
    scorer = require('./scorer'),
    ui = require('./ui');

module.exports = {
    play: function(board, player_x, player_o) {
        var self = this;
        return Q.promise(function(resolve) {
            self
                .get_play(board, player_x, player_o)
                .then(function(choice) {
                    board.set(choice, scorer.turn(board));
                    if (!scorer.is_over(board)) {
                        resolve(self.play(board, player_x, player_o));
                    } else {
                        var ending_message = (scorer.is_tied(board)) ? 'Tied!' : scorer.winner(board) + ' wins!';
                        ui.ending(board, ending_message);
                        resolve();
                    }
                });
        });
    },

    get_play: function(board, player_x, player_o) {
        var current_player;

        if (scorer.turn(board) === 'x') {
            current_player = player_x;
        } else {
            current_player = player_o;
        }

        if (current_player.type === 'human') {
            ui.print_board(board);
        }

        return current_player.play(board);
    }
};

Clean up how UI is used

Clean up how UI is used


var Context = Packages.org.mozilla.javascript.Context;
var GeoScriptWrapFactory = Packages.org.geoscript.js.GeoScriptWrapFactory;

var cx = Context.getCurrentContext();
var wrapFactory = new GeoScriptWrapFactory();
wrapFactory.setJavaPrimitiveWrap(false);
cx.setWrapFactory(wrapFactory);

exports["test: geoscript"] = require("./test_geoscript");

if (require.main == module || require.main == module.id) {
    system.exit(require("test").run(exports));
}

Use wrap factory in tests.

Use wrap factory in tests.


angular.module('syncthing.core')
    .directive('modal', function () {
        return {
            restrict: 'E',
            templateUrl: 'modal.html',
            replace: true,
            transclude: true,
            scope: {
                heading: '@',
                status: '@',
                icon: '@',
                close: '@',
                large: '@'
            }
        };
    });

angular.module('syncthing.core')
    .directive('modal', function () {
        return {
            restrict: 'E',
            templateUrl: 'modal.html',
            replace: true,
            transclude: true,
            scope: {
                heading: '@',
                status: '@',
                icon: '@',
                close: '@',
                large: '@'
            },
            link: function (scope, element, attrs, tabsCtrl) {

                // before modal show animation
                $(element).on('show.bs.modal', function () {

                    // cycle through open modals, acertain modal with highest z-index
                    var largestZ = 1040;
                    $('.modal:visible').each(function (i) {
                        var thisZ = parseInt($(this).css('zIndex'));
                        if (thisZ > largestZ) {
                            largestZ = thisZ;
                        }
                    });

                    // set this modal's z-index to be 10 above the highest z
                    var aboveLargestZ = largestZ + 10;
                    $(element).css('zIndex', aboveLargestZ);

                    // set backdrop z-index. timeout used because element does not exist immediatly
                    setTimeout(function () {
                        $('.modal-backdrop:not(:last)').removeClass('in').addClass('out');
                        $('.modal-backdrop:last').attr('for-modal-id', $(element).attr('id')).css('zIndex', aboveLargestZ - 5);
                    }, 0);

                });

                // BEFORE modal hide animation
                $(element).on('hide.bs.modal', function () {

                    // find and unhide the next backdrop down in z order
                    var sel = false, largestZ = 0;
                    $('.modal-backdrop').each(function (i) {
                        console.log('sel each');
                        var thisZ = parseInt($(this).css('zIndex'));
                        if (thisZ > largestZ && $(this).attr('for-modal-id') !== $(element).attr('id')) {
                            largestZ = thisZ;
                            sel = i;
                        }
                    });
                    if (sel !== false) {
                        $('.modal-backdrop:eq(' + sel + ')').removeClass('out').addClass('in');
                    }
                });

                // AFTER modal hide animation
                $(element).on('hidden.bs.modal', function () {

                    // reset z-index of modal to normal
                    $(element).css('zIndex', 1040);

                    // fix scrolling by re-adding .modal-open to body
                    if ($('.modal:visible').length > 0) {
                        $('body').addClass('modal-open');
                    }

                });
            }
        };
    });

Add support for multiple stacked modals

gui: Add support for multiple stacked modals

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3288


/* See license.txt for terms of usage */

"use strict";

define(function(require, exports, module) {

// Dependencies
const React = require("react");
const { Reps } = require("reps/reps");
const { A, SPAN } = Reps.DOM;

/**
 * @template TODO docs
 */
const ObjectLink = React.createClass({
  displayName: "ObjectLink",
  render: function() {
    var className = this.props.className;
    var objectClassName = className ? " objectLink-" + className : "";
    var linkClassName = "objectLink" + objectClassName + " a11yFocus";

    return (
      SPAN({className: linkClassName, _repObject: this.props.object},
        this.props.children
      )
    )
  }
});

// Exports from this module
exports.ObjectLink = React.createFactory(ObjectLink);
});

/* See license.txt for terms of usage */

"use strict";

define(function(require, exports, module) {

// Dependencies
const React = require("react");
const { Reps } = require("reps/reps");
const { A, SPAN } = Reps.DOM;

/**
 * @template Generic link template. Used for all UI elements that
 * should behave as links and navigate the user thorough the UI.
 */
const ObjectLink = React.createClass(
/** @lends ObjectLink */
{
  displayName: "ObjectLink",

  render: function() {
    var className = this.props.className;
    var objectClassName = className ? " objectLink-" + className : "";
    var linkClassName = "objectLink" + objectClassName + " a11yFocus";

    return (
      SPAN({className: linkClassName, onClick: this.onClick},
        this.props.children
      )
    )
  },

  onClick: function(event) {
    if (!this.props.object) {
      return;
    }

    event.stopPropagation();
    event.preventDefault();

    // Fire generic event for UI navigation. E.g. clicking on
    // an element object navigates the user to the Inspector
    // panel.
    var customEvent = new CustomEvent("fbsdk:navigate", {
      detail: {
        repObject: this.props.object
      }
    });

    var target = event.target;
    target.dispatchEvent(customEvent);
  }
});

// Exports from this module
exports.ObjectLink = React.createFactory(ObjectLink);
});

Support for generic UI navigation

Support for generic UI navigation


import express from 'express';
import userController from '../controllers/userController';
// import documentController from '../controllers/documentController';
import auth from '../middleware/auth';
// import utils    from '../middlewares/utils';

const user = express.Router();

user.route('/api/user')
  .get(auth.verifyToken, auth.adminAccess, userController.getAllUsers)
  .post(userController.createUser);

user.route('/api/user/profile')
  .get(auth.verifyToken, userController.getProfile);

user.route('/api/user/admin')
  .get(auth.verifyToken, auth.adminAccess, userController.getAllAdmin)
  .post(auth.verifyToken, auth.adminAccess, userController.createUser);

user.route('/api/user/regular')
  .get(auth.verifyToken, userController.getAllRegular)
  .post(auth.verifyToken, userController.createUser);

user.route('/api/user/:id')
  .get(auth.verifyToken, userController.getUser)
  .put(auth.verifyToken, userController.updateUser)
  .delete(auth.verifyToken, userController.deleteUser);

// user.route('/api/user/:id/documents')
  // .all(auth.verifyToken)
//   .get(documentsController.getUserDocuments);

user.route('/api/user/login')
  .post(userController.login);

user.route('/api/user/logout')
  .post(auth.verifyToken, userController.logout);

module.exports = () => user;

import express from 'express';
import userController from '../controllers/userController';
// import documentController from '../controllers/documentController';
import auth from '../middleware/auth';
// import utils    from '../middlewares/utils';

const user = express.Router();

user.route('/api/user')
  .get(auth.verifyToken, auth.adminAccess, userController.getAllUsers)
  .post(userController.createUser);

user.route('/api/user/profile')
  .get(auth.verifyToken, userController.getProfile);

user.route('/api/user/admin')
  .get(auth.verifyToken, auth.adminAccess, userController.getAllAdmin);

user.route('/api/user/role')
  .get(auth.verifyToken, userController.getAllRole);

user.route('/api/user/:id')
  .get(auth.verifyToken, userController.getUser)
  .put(auth.verifyToken, userController.updateUser)
  .delete(auth.verifyToken, userController.deleteUser);

// user.route('/api/user/:id/documents')
  // .all(auth.verifyToken)
//   .get(documentsController.getUserDocuments);

user.route('/api/user/login')
  .post(userController.login);

user.route('/api/search/user')
  .get(auth.verifyToken, userController.searchUsers);

user.route('/api/user/logout')
  .post(auth.verifyToken, userController.logout);

module.exports = () => user;

Change search route remove multiple createuser routes change getAllRegular to getAll Role


import React from 'react';
import ReactDOM from 'react-dom';
import { connect, Provider } from 'react-redux';
import { createStore } from 'redux';
import store from './store';
import { Main } from './components';
import { increment, decrement } from './actions';

const rootNode = document.body.appendChild(document.createElement("div"));

function mapStateToProps(state) {
  return {
    value: state
  };
}

function mapDispatchToProps(dispatch) {
  return {
    onClickIncrement: () => {
      dispatch(increment)
    },
    onClickDecrement: () => {
      dispatch(decrement)
    }
  };
}

const MainContainer = connect(mapStateToProps, mapDispatchToProps)(Main);

function render() {
  ReactDOM.render(
    <Provider store={ createStore(store) }>
      <MainContainer />
    </Provider>,
    rootNode);
}

render();

import React from 'react';
import ReactDOM from 'react-dom';
import { connect, Provider } from 'react-redux';
import { createStore } from 'redux';
import store from './store';
import { Main } from './components';
import { increment, decrement } from './actions';

function mapStateToProps(state) {
  return {
    value: state
  };
}

function mapDispatchToProps(dispatch) {
  return {
    onClickIncrement: () => {
      dispatch(increment)
    },
    onClickDecrement: () => {
      dispatch(decrement)
    }
  };
}

const MainContainer = connect(mapStateToProps, mapDispatchToProps)(Main);

ReactDOM.render(
  <Provider store={ createStore(store) }>
    <MainContainer />
  </Provider>,
  document.body.appendChild(document.createElement("div")));

Simplify even more since we don't need a global reference to rootNode any more, either


module.exports = {
  PROTOCOL_WORKER: "MDPW02",
  PROTOCOL_CLIENT: "MDPC02",
  READY:      "\x01",
  REQUEST:    "\x02",
  REPLY:      "\x03",
  HEARTBEAT:  "\x04",
  DISCONNECT: "\x05",
  HEARTBEAT_INTERVAL_MS: 2500,
  HEARTBEAT_LIVENESS: 3,
  MSG_ATTRS: [
      'type', 'sender', 'correlationId', 'device', 'subDevice',
      'command', 'params'
  ]
};

module.exports = {
  PROTOCOL_WORKER: "MDPW02",
  PROTOCOL_CLIENT: "MDPC02",
  READY:      "\x01",
  REQUEST:    "\x02",
  REPLY:      "\x03",
  HEARTBEAT:  "\x04",
  DISCONNECT: "\x05",
  HEARTBEAT_INTERVAL_MS: 2500,
  HEARTBEAT_LIVENESS: 3,
  MSG_ATTRS: [
      'type', 'sender', 'correlationId', 'serviceType', 'serviceInstance',
      'command', 'params'
  ]
};

Fix keys for incoming worker message

Fix keys for incoming worker message


//
// ### function diffsplit (diff)
// #### @diff {array|string} Diff to split.
// Splits an unified diff into chunks.
//
module.exports = function diffsplit(diff) {
  var chunks = [],
      chunk;

  if (typeof diff === 'string') {
    diff = diff.split('\n');
  }

  diff.forEach(function (line) {
    var match = line.match(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@(.*)/);
    if (match) {
      if (chunk) {
        chunks.push(chunk);
      }

      chunk = {
        original: {
          start: +match[1],
          length: +match[2]
        },
        new: {
          start: +match[3],
          length: +match[4]
        },
        heading: match[5].substr(1),
        lines: []
      };
    }
    else {
      chunk.lines.push(line);
    }
  });

  if (chunk) {
    chunks.push(chunk);
  }

  return chunks;
};

//
// ### function diffsplit (diff)
// #### @diff {array|string} Diff to split.
// Splits an unified diff into chunks.
//
module.exports = function diffsplit(diff) {
  var chunks = [],
      chunk;

  if (typeof diff === 'string') {
    diff = diff.split('\n');
  }

  diff.forEach(function (line) {
    var match = line.match(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)/);
    if (match) {
      if (chunk) {
        chunks.push(chunk);
      }

      chunk = {
        original: {
          start: +match[1],
          length: typeof match[2] !== 'undefined' ? +match[2] : 1
        },
        new: {
          start: +match[3],
          length: typeof match[4] !== 'undefined' ? +match[4] : 1
        },
        heading: match[5].substr(1),
        lines: []
      };
    }
    else {
      chunk.lines.push(line);
    }
  });

  if (chunk) {
    chunks.push(chunk);
  }

  return chunks;
};

Use default value for diff length

[fix] Use default value for diff length


var buildMoldsSelector = require('./build-molds-selector');

module.exports = function fillMold(raw, fillers, alias) {

	var filled;
	var moldsSelector = buildMoldsSelector(alias);
	var moldSelected;

	while(moldSelected = moldsSelector.exec(raw)) {
		filled = raw.replace(moldSelected[0], fillers[moldSelected[1]]);
	}
	if(!filled) return raw;
	return filled;

};

var buildMoldsSelector = require('./build-molds-selector');

module.exports = function fillMold(raw, fillers, alias) {

	var moldsSelector = buildMoldsSelector(alias);
	var moldSelected;

	while(moldSelected = moldsSelector.exec(raw)) {
		raw = raw.replace(
			new RegExp(moldSelected[0], 'g'),
			fillers[moldSelected[1]]
		);
	}
	return raw;

};

Add support of multiple molds per raw

Add support of multiple molds per raw


module.exports = function (stackName, id) {
	if (typeof id === 'string') {
		id = this.idByFront(stackName, id)
	}
	this.stacks[stackName][id].right += 1
}

var copy = require('../copy.js')
module.exports = function (stack, id) {
	var newStack = copy(stack)
	if (typeof id === 'undefined') {
		// stack is not a stack - it's just a card, so update the card's right key
		newStack.right += 1
	}
	else {
		newStack[id].right += 1
	}
	return newStack
}

Make f.gotRight() work with actual arrays


import _ from 'lodash'
const unique = Symbol('lacona-unique-key')

export default unique

function getUniqueValue (result) {
  if (!_.isObject(result)) {
    return result
  } else if (result[unique] != null) {
    if (_.isFunction(result[unique])) {
      return result[unique](result)
    } else {
      return result[unique]
    }
  } else {
    return result
  }
}

export function checkAgainstUniqueList(result, uniqueList) {
  if (result == null) return true

  const value = getUniqueValue(result)

  if (_.isObject(value)) {
    return !_.some(uniqueList, _.partial(_.isEqual, _, value))
  } else {
    return !_.includes(uniqueList, value)
  }
}

export function checkAgainstResultList(result, resultList) {
  if (result == null) return true

  const value = getUniqueValue(result)

  if (_.isObject(value)) {
    return !_.some(resultList, compareResult => _.isEqual(getUniqueValue(compareResult), value))
  } else {
    return !_.some(resultList, compareResult => getUniqueValue(compareResult) === value)
  }
}

export function addToUniqueList(result, uniqueList) {
  const value = getUniqueValue(result)

  if (result != null) {
    uniqueList.splice(uniqueList.length, 0, value)
  }
}

import _ from 'lodash'
const unique = Symbol.for('lacona-unique-key')

export default unique

function getUniqueValue (result) {
  if (!_.isObject(result)) {
    return result
  } else if (result[unique] != null) {
    if (_.isFunction(result[unique])) {
      return result[unique](result)
    } else {
      return result[unique]
    }
  } else {
    return result
  }
}

export function checkAgainstUniqueList(result, uniqueList) {
  if (result == null) return true

  const value = getUniqueValue(result)

  if (_.isObject(value)) {
    return !_.some(uniqueList, _.partial(_.isEqual, _, value))
  } else {
    return !_.includes(uniqueList, value)
  }
}

export function checkAgainstResultList(result, resultList) {
  if (result == null) return true

  const value = getUniqueValue(result)

  if (_.isObject(value)) {
    return !_.some(resultList, compareResult => _.isEqual(getUniqueValue(compareResult), value))
  } else {
    return !_.some(resultList, compareResult => getUniqueValue(compareResult) === value)
  }
}

export function addToUniqueList(result, uniqueList) {
  const value = getUniqueValue(result)

  if (result != null) {
    uniqueList.splice(uniqueList.length, 0, value)
  }
}

Use symbol.for for node environments with potentially multiple loads


window.OpenBudget = {"data":{"meta":{
    "hierarchy": ["Funding Source", "Department", "Expense Type", "Subcategory"],
    "page_title": "City of Philadelphia Budget",
    "description": "",
    "h1": "City of Philadelphia",
    "h2": "Operating Budget",
    "data_link": "https://github.com/CityOfPhiladelphia/open-budget-data-transformer/blob/master/data/FY2014-actual.csv",
    "data_title": "Download Data",
    "uservoice": "",
    "base_headline": "Funding Sources",
    "gross_cost_label": "Expenses",
    "revenue_label": "Revenues",
    "currency_prefix": "$",
    "overview_label": "Overview",
    "deficit_label": "Deficit",
    "surplus_label": "Surplus",
    "data_url": "data/phl/data.json",
    "cache_url": "data/phl/cache.json",
    "value": {
        "label": "FY 2016",
        "type": "accounts",
        "year": "2016"
    },
    "value2": {
        "label": "FY 2015",
        "type": "accounts",
        "year": "2015"
    }
}}};

window.OpenBudget = {"data":{"meta":{
    "hierarchy": ["Funding Source", "Department", "Expense Type", "Expense Subtype"],
    "page_title": "City of Philadelphia Budget",
    "description": "",
    "h1": "City of Philadelphia",
    "h2": "Operating Budget",
    "data_link": "https://github.com/CityOfPhiladelphia/open-budget-data-transformer/blob/master/data/FY2014-actual.csv",
    "data_title": "Download Data",
    "uservoice": "",
    "base_headline": "Funding Sources",
    "gross_cost_label": "Expenses",
    "revenue_label": "Revenues",
    "currency_prefix": "$",
    "overview_label": "Overview",
    "deficit_label": "Deficit",
    "surplus_label": "Surplus",
    "data_url": "data/phl/data.json",
    "cache_url": "data/phl/cache.json",
    "value": {
        "label": "FY 2016",
        "type": "accounts",
        "year": "2016"
    },
    "value2": {
        "label": "FY 2015",
        "type": "accounts",
        "year": "2015"
    }
}}};

Add dimension for expense subtype

Add dimension for expense subtype


var npmWhich = require('npm-which')(process.cwd())

module.exports = function findBin (binName, paths, config, cb) {
    var binPath = 'npm'
    var args = ['run', '-s', binName, '--'].concat(paths)
    /*
    * If package.json has script with binName defined
    * we want it to be executed first
    */
    if (config.scripts[binName] !== undefined) {
        // Support for scripts from package.json
        cb.call(this, null, binPath, args)
    } else {
        /*
        *  If binName wasn't found in package.json scripts
        *  we'll try to locate the binary in node_modules/.bin
        *  This is useful for shorter configs like:
        *
        *  "lint-staged": {
        *    "*.js": "eslint"
        *  }
        *
        *  without adding
        *
        *  "scripts" {
        *    "eslint": "eslint"
        *  }
        */
        npmWhich(binName, function (err, bin) {
            if (err) {
                /*
                * If we could not locate a binary than the config is invald
                * and we should warn about it...
                */
                cb.call(this, err, null)
            }
            cb.call(this, null, bin, ['--'].concat(paths))
        })
    }
}

'use strict'

const npmWhich = require('npm-which')(process.cwd())

module.exports = function findBin (binName, paths, config, cb) {
    const binPath = 'npm'
    const args = ['run', '-s', binName, '--'].concat(paths)
    /*
    * If package.json has script with binName defined
    * we want it to be executed first
    */
    if (config.scripts[binName] !== undefined) {
        // Support for scripts from package.json
        cb.call(this, null, binPath, args)
    } else {
        /*
        *  If binName wasn't found in package.json scripts
        *  we'll try to locate the binary in node_modules/.bin
        *  This is useful for shorter configs like:
        *
        *  "lint-staged": {
        *    "*.js": "eslint"
        *  }
        *
        *  without adding
        *
        *  "scripts" {
        *    "eslint": "eslint"
        *  }
        */
        npmWhich(binName, function (err, bin) {
            if (err) {
                /*
                * If we could not locate a binary than the config is invald
                * and we should warn about it...
                */
                cb.call(this, err, null)
            }
            cb.call(this, null, bin, ['--'].concat(paths))
        })
    }
}

Use ES2015 + strict mode

Use ES2015 + strict mode


import { until, By, WebElement } from 'selenium-webdriver';

export default (elementOrLocator, driver) => {
    if (elementOrLocator instanceof WebElement) {
        return elementOrLocator;
    }

    let locator = elementOrLocator;

    if (typeof elementOrLocator === 'string') {
        locator = By.css(elementOrLocator);
    }

    return driver
        .wait(until.elementLocated(locator))
        .then(() => driver.findElement(locator));
};

import { until, By, WebElement } from 'selenium-webdriver';

export default (elementOrLocator, driver) => {
    if (elementOrLocator instanceof WebElement) {
        return Promise.resolve(elementOrLocator);
    }

    let locator = elementOrLocator;

    if (typeof elementOrLocator === 'string') {
        locator = By.css(elementOrLocator);
    }

    return driver
        .wait(until.elementLocated(locator))
        .then(() => driver.findElement(locator));
};

[RFR] Fix wrapped conditions when passing a web element