var User        = require('./controllers/user.server.controller'),
    Upload      = require('./controllers/upload.server.controller'),
    Video       = require('./controllers/video.server.controller'),
    View        = require('./controllers/view.server.controller'),
    token       = require('../config/token');

module.exports = function(app) {
  app.get('/api', token.ensureAuthenticated,  User.welcome);

  app.post('/api/login',    User.authenticate);
  app.post('/api/register', User.registerUser);

  app.post('/api/upload', token.ensureAuthenticated, Upload.uploadVideo);
  app.post('/api/view/increment', View.increment);
  app.get('/api/view/:public_id', View.retrieveEachView);

  app.post('/api/videos/create', token.ensureAuthenticated, Video.create);
  app.put('/api/video/:public_id', token.ensureAuthenticated, Video.updateVideoDetails);
  app.get('/api/videos', token.ensureAuthenticated, Video.retrieveAll);
  app.get('/api/video/:public_id', token.ensureAuthenticated, Video.retrieveEachVideoDetails);
  app.delete('/api/video/:public_id', token.ensureAuthenticated, Video.deleteVideo);

  app.get('/api/me', token.ensureAuthenticated, User.getLoggedInUserDetail);
  app.put('/api/me', token.ensureAuthenticated, User.updateLoggedInUserDetail);
};

var User        = require('./controllers/user.server.controller'),
    Upload      = require('./controllers/upload.server.controller'),
    Video       = require('./controllers/video.server.controller'),
    View        = require('./controllers/view.server.controller'),
    token       = require('../config/token');

module.exports = function(app) {
  app.get('/api', token.ensureAuthenticated,  User.welcome);

  app.post('/api/login',    User.authenticate);
  app.post('/api/register', User.registerUser);

  app.post('/api/upload', token.ensureAuthenticated, Upload.uploadVideo);
  app.post('/api/view/increment', View.increment);
  app.get('/api/view/:public_id', View.retrieveEachView);

  app.post('/api/videos/create', token.ensureAuthenticated, Video.create);
  app.put('/api/video/:public_id', token.ensureAuthenticated, Video.updateVideoDetails);
  app.get('/api/videos', Video.retrieveAll);
  app.get('/api/video/:public_id', token.ensureAuthenticated, Video.retrieveEachVideoDetails);
  app.delete('/api/video/:public_id', token.ensureAuthenticated, Video.deleteVideo);

  app.get('/api/me', token.ensureAuthenticated, User.getLoggedInUserDetail);
  app.put('/api/me', token.ensureAuthenticated, User.updateLoggedInUserDetail);
};

Remove middleware preventing videos from loading on the homepage


Package.describe({
  git: 'https://github.com/zimme/meteor-collection-behaviours',
  name: 'zimme:collection-behaviours',
  summary: 'Define and attach behaviours on collections',
  version: '1.0.2'
});

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

  api.use([
    'coffeescript',
    'mongo',
    'underscore'
  ]);

  api.addFiles([
    'collection-behaviour.coffee',
    'mongo.coffee'
  ]);

  api.export('CollectionBehaviours');
});

Package.describe({
  git: 'https://github.com/zimme/meteor-collection-behaviours.git',
  name: 'zimme:collection-behaviours',
  summary: 'Define and attach behaviours on collections',
  version: '1.0.2'
});

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

  api.use([
    'coffeescript',
    'mongo',
    'underscore'
  ]);

  api.addFiles([
    'collection-behaviour.coffee',
    'mongo.coffee'
  ]);

  api.export('CollectionBehaviours');
});

Add .git to git url


Package.describe({
  name: 'kriegslustig:simulatency',
  version: '0.0.0',
  description: 'Adds a lag to all connections you make to the server',
  repository: 'https://github.com/Kriegslustig/meteor-lag.git',
  debugOnly: true
})

Package.onUse(function (api) {
  api.versionsFrom('METEOR@1.2')
  api.use([
    'ecmascript',
    'ddp',
    'webapp',
    'underscore',
    'templating',
    'spacebars'
  ])
  api.addFiles([
    'server/lib/utils.js',
    'server/simulatency.js'
  ], 'server')
  api.addFiles([
    'client/simulatency.js',
    'client/lagPicker/lagPicker.css',
    'client/lagPicker/lagPicker.html',
    'client/lagPicker/lagPicker.js'
  ], 'client')
  api.export('simulatency')
})

Package.describe({
  name: 'kriegslustig:simulatency',
  version: '0.0.0',
  description: 'Adds a lag to all connections you make to the server',
  repository: 'https://github.com/Kriegslustig/meteor-lag.git',
  debugOnly: true
})

Package.onUse(function (api) {
  api.versionsFrom('METEOR@1.2')
  api.use([
    'ecmascript',
    'ddp',
    'webapp',
    'underscore',
    'templating',
    'spacebars'
  ])
  api.addFiles([
    'server/lib/utils.js',
    'server/simulatency.js'
  ], 'server')
  api.addFiles([
    'client/simulatency.js',
  ], 'client')
  api.export('simulatency')
})

Delete some deps used for testing


'use strict';

/* http://docs.angularjs.org/guide/dev_guide.e2e-testing */

describe('my app', function() {

  beforeEach(function() {
    browser().navigateTo('../../app/index.html');
  });

  it('should automatically redirect to /jargon when location hash/fragment is empty', function() {
    expect(browser().location().url()).toBe("/jargon");
  });
});

'use strict';

/* http://docs.angularjs.org/guide/dev_guide.e2e-testing */

describe('my app', function() {

  beforeEach(function() {
    browser().navigateTo('../app/index.html');
  });

  it('should automatically redirect to /jargon when location hash/fragment is empty', function() {
    expect(browser().location().url()).toBe("/jargon");
  });
});

Change order of karma tests


var mistigri = require("../mistigri.js");
var fs = require("fs");

// Some generic setup

mistigri.options.escapeFunction = String;

function readFile(name, options) {
    return new Promise(function fsReadFile(fulfill, reject) {
        var fsCallback = function fsCallback(error, data) {
            if (error) reject(error);
            else fulfill(data);
        }
        fs.readFile(name, (options === undefined) ? "utf8" : options, fsCallback);
    });
}

// This is the filter function

function uppercaseFilter(args) {
    var toUpper = function toUpper(text) {
        return text.toLocaleUpperCase();
    }

    if ('$invertBlock' in args) // we are inside a block
    {
        return mistigri.prrcess(args.$template, args.$model).then(toUpper);
    }
    else
    {
        return toUpper(args.text);
    }
}

// Render the template using the filter

readFile("filter.mi").then(function(template) {
    return mistigri.prrcess(template, {
        CAPS: uppercaseFilter
    });
}).then(console.log);

var mistigri = require("../mistigri.js");
var fs = require("fs");

// Some generic setup

mistigri.options.escapeFunction = String;

function readFile(name, options) {
    return new Promise(function fsReadFile(fulfill, reject) {
        var fsCallback = function fsCallback(error, data) {
            if (error) reject(error);
            else fulfill(data);
        }
        fs.readFile(name, (options === undefined) ? "utf8" : options, fsCallback);
    });
}

// This is the filter function

function uppercaseFilter(args) {
    var toUpper = function toUpper(text) {
        return text.toLocaleUpperCase();
    }

    if ('$invertBlock' in args) // we are inside a block
    {
        return mistigri.prrcess(args.$template, args.$model).then(toUpper);
    }
    else
    {
        return toUpper(args.text);
    }
}

// Render the template using the filter

var model = {CAPS: uppercaseFilter};

readFile("filter.mi").then(function(template) {
    return mistigri.prrcess(template, model);
}).then(console.log);

Save model in a separate variable.


module.exports = {
  parser: "@typescript-eslint/parser",
  plugins: ["react-hooks"],
  extends: [
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint", // Disables rules from @typescript-eslint that would conflict with Prettier
    "plugin:prettier/recommended" // Make sure this always the last config to be loaded.
  ],
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: "module",
    ecmaFeatures: {
      jsx: true
    }
  },
  rules: {
    camelcase: "off",
    "@typescript-eslint/camelcase": "off",
    "@typescript-eslint/no-inferrable-types": "off",
    "@typescript-eslint/no-explicit-any": "off",

    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  },
  settings: {
    react: {
      version: "detect"
    }
  }
};

module.exports = {
  parser: "@typescript-eslint/parser",
  plugins: ["react-hooks"],
  extends: [
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint", // Disables rules from @typescript-eslint that would conflict with Prettier
    "plugin:prettier/recommended" // Make sure this always the last config to be loaded.
  ],
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: "module",
    ecmaFeatures: {
      jsx: true
    }
  },
  rules: {
    camelcase: "off",
    "@typescript-eslint/camelcase": "off",
    "@typescript-eslint/no-inferrable-types": "off",
    "@typescript-eslint/no-explicit-any": "off",

    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",

    "arrow-body-style": "always"
  },
  settings: {
    react: {
      version: "detect"
    }
  }
};

Add rule requiring curly brackets for arrow functions


(function (enyo, scope) {
	/**
	* {@link moon.Divider} is a simply styled component that may be used as a separator
	* between groups of components.
	*
	* @class moon.Divider
	* @mixes moon.MarqueeSupport
	* @mixes moon.MarqueeItem
	* @ui
	* @public
	*/
	enyo.kind(
		/** @lends moon.Divider.prototype */ {

		/**
		* @private
		*/
		name: 'moon.Divider',

		/**
		* @private
		*/
		classes: 'moon-divider moon-divider-text',

		/**
		* @private
		*/
		mixins: ['moon.MarqueeSupport', 'moon.MarqueeItem'],

		/**
		* @private
		*/
		marqueeOnSpotlight: false,

		/**
		* @private
		*/
		marqueeOnRender: true,

		/**
		* @private
		*/
		contentChanged: function () {
			this.set('content', this.content.split(' ').map(enyo.cap).join(' '));
		}
	});

})(enyo, this);

(function (enyo, scope) {
	/**
	* {@link moon.Divider} is a simply styled component that may be used as a separator
	* between groups of components.
	*
	* @class moon.Divider
	* @mixes moon.MarqueeSupport
	* @mixes moon.MarqueeItem
	* @ui
	* @public
	*/
	enyo.kind(
		/** @lends moon.Divider.prototype */ {

		/**
		* @private
		*/
		name: 'moon.Divider',

		/**
		* @private
		*/
		classes: 'moon-divider moon-divider-text',

		/**
		* @private
		*/
		mixins: ['moon.MarqueeSupport', 'moon.MarqueeItem'],

		/**
		* @private
		*/
		marqueeOnSpotlight: false,

		/**
		* @private
		*/
		marqueeOnRender: true,

		/**
		* @private
		*/
		contentChanged: function () {
			this.inherited(arguments);
			this.content = this.content.split(' ').map(enyo.cap).join(' ');
		}
	});

})(enyo, this);

Call the super and set the content property directly.


/*global describe, it */

"use strict";

var opencpu = require("../lib/opencpu"),
    config = require("./opencpu-config"),
    assert = require("assert");

describe("Packages test:", function () {

    describe("MASS getInfo", function () {
        it("should find Information word", function (done) {
            opencpu.packages.getInfo("MASS", function (err, data) {
                if (!err) {
                    assert.equal(4, /Information/.exec(data).index);
                } else {
                    throw err;
                }
                done();
            }, "/library/", config.getOptions());
        });
    });

    describe("MASS getExportedObjects", function () {
        it("should find addterm object", function (done) {
            opencpu.packages.getExportedObjects("MASS", function (err, data) {
                if (!err) {
                    assert.equal(18, /addterm/.exec(data).index);
                } else {
                    throw err;
                }
                done();
            }, "/library/", config.getOptions());
        });
    });

});

/*global describe, it */

"use strict";

var opencpu = require("../lib/opencpu"),
    config = require("./opencpu-config"),
    assert = require("assert");

describe("Packages test:", function () {

    describe("MASS getInfo", function () {
        it("should find Information word", function (done) {
            opencpu.packages.getInfo("MASS", function (err, data) {
                if (!err) {
                    assert.ok(/Information/.test(data));
                } else {
                    throw err;
                }
                done();
            }, "/library/", config.getOptions());
        });
    });

    describe("MASS getExportedObjects", function () {
        it("should find addterm object", function (done) {
            opencpu.packages.getExportedObjects("MASS", function (err, data) {
                if (!err) {
                    assert.ok(/addterm/.test(data));
                } else {
                    throw err;
                }
                done();
            }, "/library/", config.getOptions());
        });
    });

});

Fix packages test for CI env.


describe( 'csscomb', function () {
  var expand = require( 'glob-expand' );
  var path = require( 'path' );

  var exec = require( '../lib/exec' );
  var read = function ( file ) {
    return require( 'fs' ).readFileSync( file, {
      encoding: 'utf8'
    } );
  };
  //var write = require( 'write' ).sync;

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

  fs.removeSync( './tmp' );
  fs.copySync( './resources', './tmp' );

  var files = expand( 'tmp/fixtures/**/*.less' );
  files.forEach( function ( file ) {

    var basename = path.basename( file );

    it( 'should format the file ' + basename + ' and match the expected result', function ( done ) {
      exec( './bin/cli.js --no-use-cache ' + file, {
        stdio: 'ignore'
      } ).then( function () {

        var expected = read( path.join( 'tmp/expected/', basename ) );
        var result = read( file );
        //console.log('here >> task complete, result', result, expected);

        expect( result ).to.equal( expected );

        done();
      } ).catch( function ( err ) {

        done( err );
      } );
    } );
  } );

  after( function () { //eslint-disable-line
    //fs.removeSync( './tmp' );
  } );

} );

describe( 'csscomb', function () {
  var expand = require( 'glob-expand' );
  var path = require( 'path' );

  var exec = require( '../lib/exec' );
  var read = function ( file ) {
    return require( 'fs' ).readFileSync( file, {
      encoding: 'utf8'
    } );
  };
  //var write = require( 'write' ).sync;

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

  fs.removeSync( './tmp' );
  fs.copySync( './resources', './tmp' );

  var files = expand( 'tmp/fixtures/**/*.less' );
  files.forEach( function ( file ) {

    var basename = path.basename( file );

    it( 'should format the file ' + basename + ' and match the expected result', function ( done ) {
      exec( './bin/cli.js --no-use-cache ' + file, {
        stdio: 'ignore'
      } ).then( function () {

        var expected = read( path.join( 'tmp/expected/', basename ) );
        var result = read( file );
        //console.log('here >> task complete, result', result, expected);

        expect( result ).to.equal( expected );

        done();
      } ).catch( function ( err ) {

        done( err );
      } );
    } );
  } );

  after( function () { //eslint-disable-line
    fs.removeSync( './tmp' );
  } );

} );

Remove test resources created during tests


var code = null;
if (/([^\/].)?oglobo\.globo\.com/.test(document.location.host))
    code = 'paywallAtivo = false;';

else if (/www\.economist\.com/.test(document.location.host))
    code = 'document.cookie = "ec_limit=allow";';

else if (/foreignpolicy\.com/.test(document.location.host)) {
    code = 'window.FPMarketingSettings.__meta.disable_paywall = true;';
    code += 'window.Drupal.settings.ec_wallpage.ec_wallpage_paywall_name = ' +
        '"article paywall registered"';
}

if (code !== null) {
    code = 'console.log("Burlando paywall com Burlesco");' + code;
    var script = document.createElement('script');
    script.textContent = code;
    (document.head||document.documentElement).appendChild(script);
    script.parentNode.removeChild(script);
}

var code = null;
if (/([^\/].)?oglobo\.globo\.com/.test(document.location.host))
    code = 'paywallAtivo = false;';

else if (/www\.economist\.com/.test(document.location.host))
    code = 'document.cookie = "ec_limit=allow";';

else if (/foreignpolicy\.com/.test(document.location.host)) {
    code = 'window.FPMarketingSettings.__meta.disable_paywall = true;';
    code += 'window.Drupal.settings.ec_wallpage.ec_wallpage_paywall_name = ' +
        '"article paywall registered"';
}

if (code !== null) {
    var script = document.createElement('script');
    script.textContent = code;
    (document.head||document.documentElement).appendChild(script);
    script.parentNode.removeChild(script);
}

Remove debug log devido à reclamação da Mozilla


module.exports = (req, res, next) => {
  req.app.settings.nunjucksEnv
    .addGlobal('req', req)
    .addGlobal('res', res);

  next();
}

module.exports = (req, res, next) => {
  res.locals.req = req;
  res.locals.res = res;
  next();
}

Add req/res to res.locals not global nunjucks instance


/**
 * requires rcmApi from core
 */
angular.module('rcmAdminApi', [])
    .factory(
    'rcmAdminApiUrlService',
    [
        function () {

            /**
             * url map for APIs - These are parsed using the rcmApi service (core)
             * NOTE: these are named like {leastSpecific}{moreSpecific}{mostSpecific} for consistency and order
             *
             * @type {object}
             */
            var urlMap = {
                countries: '/api/admin/country',
                languages: '/api/admin/language',
                pageTypes: '/api/admin/pagetypes',
                /* Current site */
                siteCurrent: '/api/admin/manage-sites/current',
                /* Default site configuration */
                siteDefault: '/api/admin/manage-sites/default',
                sites: '/api/admin/manage-sites?page_size=-1',
                site: '/api/admin/manage-sites/{siteId}',
                siteCopy: '/api/admin/site-copy',
                sitePages: '/api/admin/sites/{siteId}/pages',
                sitePage: '/api/admin/sites/{siteId}/pages/{pageId}',
                sitePageCopy: '/api/admin/sites/{siteId}/page-copy/{pageId}',

                themes: '/api/admin/theme'
            };

            return urlMap;
        }
    ]
);

rcm.addAngularModule('rcmAdminApi');

/**
 * requires rcmApi from core
 */
angular.module('rcmAdminApi', [])
    .factory(
    'rcmAdminApiUrlService',
    [
        function () {

            /**
             * url map for APIs - These are parsed using the rcmApi service (core)
             * NOTE: these are named like {leastSpecific}{moreSpecific}{mostSpecific} for consistency and order
             *
             * @type {object}
             */
            var urlMap = {
                countries: '/api/admin/country',
                languages: '/api/admin/language',
                pageTypes: '/api/admin/pagetypes',
                /* Current site */
                siteCurrent: '/api/admin/manage-sites/current',
                /* Default site configuration */
                siteDefault: '/api/admin/manage-sites/default',
                sites: '/api/admin/manage-sites',
                site: '/api/admin/manage-sites/{siteId}',
                siteCopy: '/api/admin/site-copy',
                sitePages: '/api/admin/sites/{siteId}/pages',
                sitePage: '/api/admin/sites/{siteId}/pages/{pageId}',
                sitePageCopy: '/api/admin/sites/{siteId}/page-copy/{pageId}',

                themes: '/api/admin/theme'
            };

            return urlMap;
        }
    ]
);

rcm.addAngularModule('rcmAdminApi');

Fix error route no match


import shallowEqual from 'is-equal-shallow';
import { bindActionCreators } from 'redux';

export const observeStore = (store, currState, select, onChange) => {
  if (typeof onChange !== 'function') return null;
  let currentState = currState || {};

  function handleChange() {
    const nextState = select(store.getState());
    if (!shallowEqual(currentState, nextState)) {
      const previousState = currentState;
      currentState = nextState;
      onChange(currentState, previousState);
    }
  }

  const unsubscribe = store.subscribe(handleChange);
  handleChange();
  return unsubscribe;
};

export const wrapActionCreators = (actionCreators) =>
  dispatch => bindActionCreators(actionCreators, dispatch);

import { bindActionCreators } from 'redux';

export function shallowEqual(objA, objB) {
  if (objA === objB) return true;

  const keysA = Object.keys(objA);
  const keysB = Object.keys(objB);

  if (keysA.length !== keysB.length) return false;

  // Test for A's keys different from B.
  const hasOwn = Object.prototype.hasOwnProperty;
  for (let i = 0; i < keysA.length; i++) {
    if (!hasOwn.call(objB, keysA[i]) ||
        objA[keysA[i]] !== objB[keysA[i]]) {
      return false;
    }
  }

  return true;
}

export function observeStore(store, currState, select, onChange) {
  if (typeof onChange !== 'function') return null;
  let currentState = currState || {};

  function handleChange() {
    const nextState = select(store.getState());
    if (!shallowEqual(currentState, nextState)) {
      const previousState = currentState;
      currentState = nextState;
      onChange(currentState, previousState);
    }
  }

  const unsubscribe = store.subscribe(handleChange);
  handleChange();
  return unsubscribe;
}

export const wrapActionCreators = (actionCreators) =>
  dispatch => bindActionCreators(actionCreators, dispatch);

Use gaeron's shallowEqual algo instead


"use strict";

const jsdoc2md = require('jsdoc-to-markdown');
const fs = require('fs');

jsdoc2md({src: './node_modules/kittik-animation-*/**/*.js'}).pipe(fs.createWriteStream('./doc/api/Animation.md'));
jsdoc2md({src: './node_modules/kittik-shape-*/**/*.js'}).pipe(fs.createWriteStream('./doc/api/Shape.md'));
jsdoc2md({src: './node_modules/kittik-cursor/**/*.js'}).pipe(fs.createWriteStream('./doc/api/Cursor.md'));
jsdoc2md({src: './src/**/*.js'}).pipe(fs.createWriteStream('./doc/api/Kittik.md'));

"use strict";

const jsdoc2md = require('jsdoc-to-markdown');
const fs = require('fs');

jsdoc2md({src: './node_modules/kittik-animation-*/**/*.js'}).pipe(fs.createWriteStream('./doc/api/Animation.md'));
jsdoc2md({src: './node_modules/kittik-shape-*/**/*.js'}).pipe(fs.createWriteStream('./doc/api/Shape.md'));
jsdoc2md({src: './node_modules/kittik-cursor/**/*.js'}).pipe(fs.createWriteStream('./doc/api/Cursor.md'));
jsdoc2md({src: './lib/**/*.js'}).pipe(fs.createWriteStream('./doc/api/Kittik.md'));

Fix issue with generating doc for src instead of lib


class MyClock extends React.Component {
	constructor(props) {
		super(props);
		this.state = {date: new Date()};
	}

	render() {
		return (

 CLOCK TIME: {this.state.date.toLocaleTimeString()}

			);
	}

	componentDidMount() {
		setInterval (
			() => {this.tick()},
			1000);
	}

	tick() {
	    this.setState (
		    {
	    	  date: new Date()
	    	}
    	);
  	}

}

var MyHelloTag = () => {
	return(

Hello Clock

			<MyClock/>

		);
};

ReactDOM.render(
	<MyHelloTag/>,
	document.getElementById('root')
);

//Written using a function
var MyActionHandler = () => {

    //Function to handle the click event
	const handleClick = (e) => {
    	e.preventDefault();
    	alert('The link was clicked.');
    };

	return (
		Click Me
	);
};

//Written using a class. Note the this.handleClick call
class MyActionHandlerClass extends React.Component {

	handleClick(e) {
    	e.preventDefault();
    	console.log('The link CLICK ME HERE was clicked.');
    }

    render() {
		return (
			Click Me Here
		);
    }
}

class MyClock extends React.Component {
	constructor(props) {
		super(props);
		this.state = {date: new Date()};
	}

	render() {
		return (

 CLOCK TIME: {this.state.date.toLocaleTimeString()}

			);
	}

	componentDidMount() {
		setInterval (
			() => {this.tick()},
			1000);
	}

	tick() {
	    this.setState (
		    {
	    	  date: new Date()
	    	}
    	);
  	}

}

var MyHelloTag = () => {
	return(

Hello Clock

			<MyClock/>
			<MyActionHandler/>

			<MyActionHandlerClass/>

		);
};

ReactDOM.render(
	<MyHelloTag/>,
	document.getElementById('root')
);

Handle an event using react class, or using a function


'use strict';

const childProcess = require('child_process');

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

module.exports = function(ci) {
  console.log('Installing apm');
  childProcess.execFileSync(
    CONFIG.getNpmBinPath(),
    ['--global-style', '--loglevel=error', ci ? 'ci' : 'install'],
    { env: process.env, cwd: CONFIG.apmRootPath }
  );
};

'use strict';

const childProcess = require('child_process');

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

module.exports = function(ci) {
  console.log('Installing apm');
  // npm ci leaves apm with a bunch of unmet dependencies
  childProcess.execFileSync(
    CONFIG.getNpmBinPath(),
    ['--global-style', '--loglevel=error', 'install'],
    { env: process.env, cwd: CONFIG.apmRootPath }
  );
};

Revert "Install apm using ci"


import React from 'react';

export default class App extends React.Component {
  render() {
    return (

hello admin

    )
  }
}

import React from 'react';

export default class App extends React.Component {
  render() {
    return (

hello admin !!

    )
  }
}

Test case for dev reloader


(function () {
    angular
            .module('auth')
            .controller('LoginController', LoginController);

    LoginController.$inject = [
        'AuthService',
        'Notification',
        '$scope',
        '$location'
    ];

    function LoginController(AuthService, Notification, $scope, $location) {
        var vm = this;

        vm.STATUS_WAITING = 0;
        vm.STATUS_LOADING = 1;

        vm.user = {
            username: "",
            password: ""
        };

        vm.submit = submit;

        activate();

        function activate() {
            vm.status = vm.STATUS_WAITING;
        }

        function submit() {
            vm.status = vm.STATUS_LOADING;
            return AuthService.login(vm.user)
                .catch(function (res) {
                    Notification.warning('Login failed');
                    vm.user.password = "";
                    vm.status = vm.STATUS_WAITING;
                    vm.user.error = res.data.error;
                });
        }
    }
})();

(function () {
    angular
            .module('auth')
            .controller('LoginController', LoginController);

    LoginController.$inject = [
        'AuthService',
        'Notification',
        '$scope',
        '$location'
    ];

    function LoginController(AuthService, Notification, $scope, $location) {
        var vm = this;

        vm.STATUS_WAITING = 0;
        vm.STATUS_LOADING = 1;

        vm.user = {
            username: "",
            password: ""
        };

        vm.submit = submit;

        activate();

        function activate() {
            vm.status = vm.STATUS_WAITING;
        }

        function submit() {
            vm.status = vm.STATUS_LOADING;
            AuthService.login(vm.user)
                .catch(function (res) {
                    Notification.warning('Login failed');
                    vm.user.password = "";
                    vm.status = vm.STATUS_WAITING;
                    vm.user.error = res.data.error;
                });
        }
    }
})();

Fix error after login: V1 is not a function


const webViewElement = document.querySelector('.messages-iframe');

webViewElement.addEventListener('new-window', (e) => {
    require('electron').shell.openExternal(e.url);
})

window.addEventListener('focus', () => webViewElement.focus());
window.addEventListener('blur', () => webViewElement.blur());

Remove webview focus when parent window loses focus


/**
 * User
 *
 * @module      :: Model
 * @description :: A short summary of how this model works and what it represents.
 * @docs		:: http://sailsjs.org/#!documentation/models
 */

module.exports = {

  attributes: {
    email: {
        type: 'email',
        required: true
    }
    name: 'STRING'
  	/* e.g.
  	nickname: 'string'
  	*/

  }

};

/**
 * User
 *
 * @module      :: Model
 * @description :: A short summary of how this model works and what it represents.
 * @docs		:: http://sailsjs.org/#!documentation/models
 */

module.exports = {

  attributes: {
    email: {
        type: 'email',
        required: true
    },
    name: 'STRING'
  	/* e.g.
  	nickname: 'string'
  	*/

  }

};

Fix a typo in user model


const removeKeyInObject = (obj, keyToRemove) => {
  return Object.keys(obj).reduce((acc, current) => {
    const value = acc[current];

    if (value === null) {
      return acc;
    }

    if (Array.isArray(value)) {
      return { ...acc, [current]: value.map(obj => removeKeyInObject(obj, keyToRemove)) };
    }

    if (typeof acc[current] === 'object') {
      return { ...acc, [current]: removeKeyInObject(value, keyToRemove) };
    }

    if (current === keyToRemove) {
      delete acc[current];
    }

    return acc;
  }, obj);
};

export default removeKeyInObject;

const removeKeyInObject = (obj, keyToRemove) => {
  if (!obj) {
    return obj;
  }

  return Object.keys(obj).reduce((acc, current) => {
    const value = acc[current];

    if (value === null) {
      return acc;
    }

    if (Array.isArray(value)) {
      return { ...acc, [current]: value.map(obj => removeKeyInObject(obj, keyToRemove)) };
    }

    if (typeof acc[current] === 'object') {
      return { ...acc, [current]: removeKeyInObject(value, keyToRemove) };
    }

    if (current === keyToRemove) {
      delete acc[current];
    }

    return acc;
  }, obj);
};

export default removeKeyInObject;

Fix null or undefined for remove key in object


import Ember from 'ember';
import { request } from 'ic-ajax';
import Config from './config';

export default Ember.Object.extend({
  setPrefilter: function() {
    var token = this.get('data').token;
    var preFilter = function(options, originalOptions, jqXHR) {
      return jqXHR.setRequestHeader('X-CSRF-Token', token );
    };
    $.ajaxPrefilter(preFilter);
  },
  setData: function(data) {
    var param = Object.keys(data)[0];
    this.set('data', { param: param, token: data[param] });
    this.setPrefilter();

    return this.get('data');
  },
  fetchToken: function() {
    var promise;
    var setData = this.setData.bind(this);

    if (this.get('data')) {
      promise = Ember.RSVP.resolve(this.get('data'));
    } else {
      var token = Ember.$('meta[name="csrf-token"]').attr('content');

      if (!Ember.isEmpty(token)) {
        promise = Ember.RSVP.resolve({'authenticity_token': token });
      } else {
        promise = request(Config.get('url'));
      }

      promise = promise.then(setData);
    }

    return promise;
  }
});

import Ember from 'ember';
import { request } from 'ic-ajax';
import Config from './config';

export default Ember.Object.extend({
  onAjaxComplete: function() {
    var _this = this;
    $(document).on("ajaxComplete", function(event, xhr, settings) {
      var csrf_param = xhr.getResponseHeader('X-CSRF-Param'),
      csrf_token = xhr.getResponseHeader('X-CSRF-Token');

      if (csrf_param && csrf_token) {
        _this.setData({csrf_param: csrf_token});
      }
    });
  }.on('init'),
  setPrefilter: function() {
    var token = this.get('data').token;
    var preFilter = function(options, originalOptions, jqXHR) {
      return jqXHR.setRequestHeader('X-CSRF-Token', token );
    };
    $.ajaxPrefilter(preFilter);
  },
  setData: function(data) {
    var param = Object.keys(data)[0];
    this.set('data', { param: param, token: data[param] });
    this.setPrefilter();

    return this.get('data');
  },
  fetchToken: function() {
    var promise;
    var setData = this.setData.bind(this);

    if (this.get('data')) {
      promise = Ember.RSVP.resolve(this.get('data'));
    } else {
      var token = Ember.$('meta[name="csrf-token"]').attr('content');

      if (!Ember.isEmpty(token)) {
        promise = Ember.RSVP.resolve({'authenticity_token': token });
      } else {
        promise = request(Config.get('url'));
      }

      promise = promise.then(setData);
    }

    return promise;
  }
});

Handle CSRF changes in response headers.


"use strict";
var winston = require('winston');
var loggers = [];
var currentLevel = 'error';

/**
* Convenience function to get logger directly
*/

var newLogger = function () {
  var newInstance = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)()
    ]
  });
  if (currentLevel) {
    newInstance.level = currentLevel;
  }
  loggers.push(newInstance);
  return newInstance;
};

newLogger.setLevel = function(level) {
  currentLevel = level;
  loggers.forEach(function(logger){
    logger.level = level;
  });
};

module.exports = newLogger;

"use strict";
var winston = require('winston');
var loggers = [];
var currentLevel = 'error';

/**
* Convenience function to get logger directly
*/

var newLogger = function () {
  var newInstance = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({ level: 'debug' })
    ]
  });
  newInstance.level = currentLevel || 'debug';
  loggers.push(newInstance);
  return newInstance;
};

newLogger.setLevel = function(level) {
  currentLevel = level;
  loggers.forEach(function(logger){
    logger.level = level;
  });
};

module.exports = newLogger;

Configure log level to debug


import React from 'react'
import Document, { Html, Head, Main, NextScript } from 'next/document'

import { GA_TRACKING_ID } from 'libs/gtag'

export default class extends Document {
  render() {
    return (
      <Html>
        <Head>
          {/* Global Site Tag (gtag.js) - Google Analytics */}
          <script async src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`} />
          <script
            dangerouslySetInnerHTML={{
              __html: `window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '${GA_TRACKING_ID}', { page_path: window.location.pathname, }); `,
            }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

import React from 'react'
import Document, { Html, Head, Main, NextScript } from 'next/document'

import { GA_TRACKING_ID } from 'libs/gtag'

export default class extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          {/* Global Site Tag (gtag.js) - Google Analytics */}
          <script async src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`} />
          <script
            dangerouslySetInnerHTML={{
              __html: `window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '${GA_TRACKING_ID}', { page_path: window.location.pathname, }); `,
            }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

Add language to html tag


function circular(ref) {
  ref = ref || '[Circular]';
  var seen = [];
  return function (key, val) {
    if(!val || typeof (val) !== 'object') {
      return val;
    }
    if(~seen.indexOf(val)) {
      if(typeof ref === 'function') return ref(val);
      return ref;
    }
    seen.push(val);
    return val;
  };
}

function stringify(obj, indent, ref) {
  return JSON.stringify(obj, circular(ref), indent);
}

module.exports = circular;
module.exports.stringify = stringify;

/**
 *  Check circular references.
 *
 *  @param ref A function that returns an alternative reference.
 *  @param methods A boolean that indicates functions should be
 *  coerced to strings.
 */
function circular(ref, methods) {
  ref = ref || '[Circular]';
  var seen = [];
  return function (key, val) {
    if(typeof val === 'function' && methods) {
      val = val.toString();
    }
    if(!val || typeof (val) !== 'object') {
      return val;
    }
    if(~seen.indexOf(val)) {
      if(typeof ref === 'function') return ref(val);
      return ref;
    }
    seen.push(val);
    return val;
  };
}

function stringify(obj, indent, ref, methods) {
  return JSON.stringify(obj, circular(ref, methods), indent);
}

module.exports = circular;
module.exports.stringify = stringify;

Support coercing functions to strings.


/**
* @ngdoc directive
* @name umbraco.directives.directive:umbAvatar
* @restrict E
**/
function avatarDirective() {
    return {
        restrict: "E",    // restrict to an element
        replace: true,   // replace the html element with the template
        templateUrl: 'views/directives/umb-avatar.html',
        scope: {
            name: '@',
            email: '@',
            hash: '@'
        },
        link: function(scope, element, attr, ctrl) {

            scope.$watch("hash", function (val) {
                //set the gravatar url
                scope.gravatar = "http://www.gravatar.com/avatar/" + val + "?s=40";
            });

        }
    };
}

angular.module('umbraco.directives').directive("umbAvatar", avatarDirective);

/**
* @ngdoc directive
* @name umbraco.directives.directive:umbAvatar
* @restrict E
**/
function avatarDirective() {
    return {
        restrict: "E",    // restrict to an element
        replace: true,   // replace the html element with the template
        templateUrl: 'views/directives/umb-avatar.html',
        scope: {
            name: '@',
            email: '@',
            hash: '@'
        },
        link: function(scope, element, attr, ctrl) {

            scope.$watch("hash", function (val) {
                //set the gravatar url
                scope.gravatar = "//www.gravatar.com/avatar/" + val + "?s=40";
            });

        }
    };
}

angular.module('umbraco.directives').directive("umbAvatar", avatarDirective);

Update Gravatar to use protocol relative URL


'use strict';

var path = require('path');
var fs = require('fs');

module.exports = function readConfig(file) {
    var content = fs.readFileSync(
        path.join(
            __dirname,
            'node_modules',
            'vgno-coding-standards',
            file
        ),
        'utf8'
    );

    return JSON.parse(content);
};

'use strict';

var fs = require('fs');

module.exports = function readConfig(file) {
    var content = fs.readFileSync(
        require.resolve('vgno-coding-standards/' + file),
        'utf8'
    );

    return JSON.parse(content);
};

Use node's resolve mechanism when attempting to locate vgno-coding-standard (npm3 fix)


'use strict';

var markovDictionaryBuilder = (function(logger) {

	function buildDict(wordSet, chainSize) {

		logger.logDebug("building dictionary from " + wordSet.length + " words with a chain size of " + chainSize);

		var map = [];
		var dict = [];
		for (var i = 0, len = wordSet.length - chainSize; i < len; i++) {

			var end = i + parseFloat(chainSize);
			var workingSet = wordSet.slice(i, end+1);
			var k = workingSet.slice(0, workingSet.length-1);
			var n = workingSet.slice(-1);

			var dictItem = {
				'key' : k.join('/').toLowerCase(),
				'words' : k,
				'next' : n
			};

			var mi = map[dictItem.key];
			if (typeof(mi) !== 'number') {
				var dictIndex = dict.length;
				dict.push(dictItem);
				map[dictItem.key] = dictIndex;
			} else {
				dict[mi].next.push(dictItem.next[0]);
			}
		}
		return dict;
	}

	return {
		buildDict : buildDict
	};

})(logger);

'use strict';

var markovDictionaryBuilder = (function(logger) {

	function buildDict(wordSet, chainSize) {

		logger.logDebug("building dictionary from " + wordSet.length + " words with a chain size of " + chainSize);

		var map = {};
		var dict = [];
		for (var i = 0, len = wordSet.length - chainSize; i < len; i++) {

			var end = i + parseFloat(chainSize);
			var workingSet = wordSet.slice(i, end+1);
			var k = workingSet.slice(0, workingSet.length-1);
			var n = workingSet.slice(-1);

			var dictItem = {
				'key' : k.join('/').toLowerCase(),
				'words' : k,
				'next' : n
			};

			var mi = map[dictItem.key];
			if (typeof(mi) !== 'number') {
				var dictIndex = dict.length;
				dict.push(dictItem);
				map[dictItem.key] = dictIndex;
			} else {
				dict[mi].next.push(dictItem.next[0]);
			}
		}
		return dict;
	}

	return {
		buildDict : buildDict
	};

})(logger);

Change assoc. map array to use an object


var CommandQueue = require('./command-queue');

/**
 * Creates a new robot arm
 * @constructor
 * @param {object} options The options object.
 * @param {object|array} options.axis A list of servos to control robot arm.
 */
var RobotArm = function(options) {
    this._queue = new CommandQueue();
    this.axis = options.axis;

    this._queue.on('data', function(fn) {
        console.assert(typeof fn === 'function', 'fn is not a function');

        fn.call(this, function() {
            this._queue.next();
        }.bind(this));
    }.bind(this));
};

RobotArm.prototype.then = function(fn) {
    this._queue.push(fn);
    return this;
};

RobotArm.prototype.play = function(options) {
    this._queue.play(options);
    return this;
};

RobotArm.prototype.stop = function() {
    this._queue.stop();
    return this;
};

RobotArm.prototype.replay = function(options) {
    this._queue.replay(options);
    return this;
};

RobotArm.prototype.pause = function() {
    this._queue.pause();
    return this;
};

RobotArm.prototype.reset = function() {
    this._queue.stop();
    this._queue.clear();
    return this;
};

module.exports = RobotArm;

var CommandQueue = require('./command-queue');

/**
 * Creates a new robot arm
 * @constructor
 * @param {object} options The options object.
 * @param {object|array} options.axis A list of servos to control robot arm.
 */
var RobotArm = function(options) {
    this._queue = new CommandQueue();
    this.axis = options.axis;

    this._queue.on('data', function(fn) {
        console.assert(typeof fn === 'function', 'fn is not a function');

        fn.call(this, function() {
            this._queue.next();
        }.bind(this));
    }.bind(this));
};

RobotArm.prototype.then = function(fn) {
    this._queue.push(fn);
    return this;
};

RobotArm.prototype.play = function(options) {
    this._queue.play(options);
    return this;
};

RobotArm.prototype.stop = function() {
    this._queue.stop();
    return this;
};

RobotArm.prototype.replay = function(options) {
    this._queue.replay(options);
    return this;
};

RobotArm.prototype.pause = function() {
    this._queue.pause();
    return this;
};

RobotArm.prototype.reset = function() {
    this._queue.stop();
    this._queue.clear();
    return this;
};

RobotArm.prototype.isRunning = function() {
    return this._queue.isRunning();
};

module.exports = RobotArm;

Add function to check current status


var fs = require("fs");
var path = require("path");

module.exports = {
  website: {
    assets: ".",
    html: {
      "body:start": function(current) {

        var rootPath = current.basePath === "." ? ".." : "../" + current.basePath;
        console.log("basePath:", current.basePath);
        console.log("rootPath:", rootPath);
        var filePath = path.join(this.book.root, "HEADER.html");

        try {
            var content = fs.readFileSync(filePath, {encoding: "utf-8"});
            return content.replace(/BASE_PATH/g, rootPath);
        } catch(err) {
            // if there's no file to include, just continue
        }
      }
    }
  }
};

var fs = require("fs");
var path = require("path");

module.exports = {
  website: {
    assets: ".",
    html: {
      "body:start": function(current) {

        // WARNING: does not work if served via web-server (gitbook will always use ..)
        var rootPath = current.basePath === "." ? ".." : "../" + current.basePath;
        var filePath = path.join(this.book.root, "HEADER.html");

        try {
            var content = fs.readFileSync(filePath, {encoding: "utf-8"});
            return content.replace(/BASE_PATH/g, rootPath);
        } catch(err) {
            // if there's no file to include, just continue
        }
      }
    }
  }
};

Remove debug output, add note that it doesn't work through web servers


/*global require, module*/
/*!
 * missing-keys <https://github.com/tobiasoberrauch/missing-keys>
 *
 * Copyright (c) 2015, Tobias Oberrauch.
 * Licensed under the MIT License.
 */

'use strict';

(function (factory) {
  if (typeof module === "object" && typeof module.exports === "object") {
    module.exports = factory();
  }
  else if (typeof window === "object") {
    window.missingKeys = factory();
  }
}(function () {
  /**
   *
   * @param object
   * @param expectedKeys
   * @returns {Array.<T>|*}
   */
  function missingKeys(object, expectedKeys) {
    var actualKeys = Object.keys(object);
    return expectedKeys.filter(function (expectedKey) {
      return actualKeys.indexOf(expectedKey) === -1;
    });
  }

  /**
   * @type {missingKeys}
   */
  missingKeys.get = missingKeys;

  /**
   *
   * @param object
   * @param expectedKeys
   * @returns {boolean}
   */
  missingKeys.has = function (object, expectedKeys) {
    return missingKeys(object, expectedKeys).length > 0;
  };

  return missingKeys;
}));

/*global require, module*/
/*!
 * missing-keys <https://github.com/tobiasoberrauch/missing-keys>
 *
 * Copyright (c) 2015, Tobias Oberrauch.
 * Licensed under the MIT License.
 */

'use strict';

(function (factory) {
  if (typeof module === "object" && typeof module.exports === "object") {
    module.exports = factory();
  }
  else if (typeof window === "object") {
    window.missingKeys = factory();
  }
}(function () {
  /**
   *
   * @param {object} object
   * @param {string|object} expectedKeys
   * @returns {Array.<T>|*}
   */
  function missingKeys(object, expectedKeys) {
    expectedKeys = Object.prototype.toString.call(expectedKeys) === '[object Array]' ? expectedKeys : [expectedKeys];
    var actualKeys = Object.keys(object);
    return expectedKeys.filter(function (expectedKey) {
      return actualKeys.indexOf(expectedKey) === -1;
    });
  }

  /**
   * @type {missingKeys}
   */
  missingKeys.get = missingKeys;

  /**
   *
   * @param {object} object
   * @param {string|object} expectedKeys
   * @returns {boolean}
   */
  missingKeys.has = function (object, expectedKeys) {
    return missingKeys(object, expectedKeys).length > 0;
  };

  return missingKeys;
}));

Allow string as expectedKeys parameter and update jsdocs


/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-cli-page-object',

  options: {
    nodeAssets: {
      ceibo: function() {
        return {
          enabled: this._shouldIncludeFiles(),
          import: ['index.js']
        };
      }
    }
  },

  treeFor: function(/*name*/) {
    if (!this._shouldIncludeFiles()) {
      return;
    }

    return this._super.treeFor.apply(this, arguments);
  },

  _shouldIncludeFiles: function() {
    return this.app.env !== 'production';
  }
};

/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-cli-page-object',

  options: {
    nodeAssets: {
      ceibo: function() {
        return {
          enabled: this._shouldIncludeFiles(),
          import: ['index.js']
        };
      }
    }
  },

  included: function(app) {
    // see: https://github.com/ember-cli/ember-cli/issues/3718
    if (typeof app.import !== 'function' && app.app) {
      app = app.app;
    }

    this.app = app;

    this._super.included.apply(this, arguments);
  },

  treeFor: function(/*name*/) {
    if (!this._shouldIncludeFiles()) {
      return;
    }

    return this._super.treeFor.apply(this, arguments);
  },

  _shouldIncludeFiles: function() {
    return this.app.env !== 'production';
  }
};

Allow addon to be used as a nested addon


class API extends Function {

  constructor(path = '/', config) {
    super('next', 'return this(next)');
    this.path = path;
    this.globalConfig = Object.assign({ credentials: 'include' }, config);
    return new Proxy(this.bind(next => {
      if (path[path.length - 1] !== '/') next = '/' + next;
      return new API((path + next).replace(/[^:][/]{2}/g, '/'), this.globalConfig);
    }), this);
  }

  get(base, key) {
    if (!/^(?:get|post|delete|put|patch)$/.test(key)) return base(key);
    return config => {
      config = Object.assign({ method: key }, this.globalConfig, config);
      return fetch(this.path, config).then(response => {
        const type = /\bjson\b/.test(response.headers.get('content-type')) ? 'json' : 'text';
        switch (true) {
          case response.status === 204: return null;
          case response.status < 400: return response[type]();
          default: response[type]().then(result => { throw result; });
        }
      });
    };
  }

}

class API extends Function {

  constructor(path = '/', config) {
    super('next', 'return this(next)');
    this.path = path;
    this.globalConfig = Object.assign({ credentials: 'include' }, config);
    return new Proxy(this.bind(next => {
      if (path[path.length - 1] !== '/') next = '/' + next;
      return new API((path + next).replace(/[^:][/]{2}/g, '/'), this.globalConfig);
    }), this);
  }

  get(base, key) {
    if (!/^(?:get|post|delete|put|patch)$/.test(key)) return base(key);
    return config => {
      config = Object.assign({ method: key }, this.globalConfig, config);
      // Convert request body to JSON
      if (typeof config.body === 'object' && !(config.body instanceof Blob) && !(config.body instanceof FormData)) {
        config.body = JSON.stringify(config.body);
        let headers = new Headers(config.headers || {});
        if (!headers.has('Content-Type')) headers.append('Content-Type', 'application/json');
        config.headers = headers;
      }
      // Request actually
      return fetch(this.path, config).then(response => {
        const type = /\bjson\b/.test(response.headers.get('Content-Type')) ? 'json' : 'text';
        switch (true) {
          case response.status === 204: return null;
          case response.status < 400: return response[type]();
          default: return response[type]().then(result => Promise.reject(result));
        }
      });
    };
  }

}

Convert request body to JSON


import React from "react"; // must be in scope when using JSX
import ReactDOM from "react-dom";

function HelloWorld() {
    return (

React.js Hello World!

    );
}

const container = document.getElementById("app-container");
ReactDOM.render(<HelloWorld />, container);

import React from "react"; // must be in scope when using JSX
import ReactDOM from "react-dom";

console.log("git date", GIT_COMMIT_DATE);
console.log("git message", GIT_COMMIT_MESSAGE);
console.log("git rev", GIT_COMMIT_REV);

function HelloWorld() {
    return (

React.js Hello World!

    );
}

const container = document.getElementById("app-container");
ReactDOM.render(<HelloWorld />, container);

Add example of git data


Convert the output to numbers, not strings


define([
    'leaflet', 'leaflet.draw', 'i18n!find/nls/bundle', 'leaflet.draw.negate'
], function(leaflet, leafletDraw, i18n){

    function updateTranslations(prefix, mappedPrefix, obj) {
        _.each(obj, function(val, key){
            const path = prefix + '.' + key;
            const mappedPath = mappedPrefix + '.' + key;

            switch (typeof val) {
                case 'object':
                    updateTranslations(path, mappedPath, val);
                    break;
                case 'string':
                    const translation = i18n[mappedPath];
                    if (translation) {
                        obj[key] = translation;
                    }
                    break;
            }
        })
    }

    // Set the Leaflet.draw strings to the corresponding key in the translation bundle, if available.
    updateTranslations('leaflet.drawLocal', 'search.geography', leaflet.drawLocal);

    return leafletDraw;
})

define([
    'leaflet', 'leaflet.draw', 'i18n!find/nls/bundle', 'leaflet.draw.negate'
], function(leaflet, leafletDraw, i18n){

    function updateTranslations(prefix, mappedPrefix, obj) {
        _.each(obj, function(val, key){
            const path = prefix + '.' + key;
            const mappedPath = mappedPrefix + '.' + key;

            switch (typeof val) {
                case 'object':
                    updateTranslations(path, mappedPath, val);
                    break;
                case 'string':
                    const translation = i18n[mappedPath];
                    if (translation != null) {
                        obj[key] = translation;
                    }
                    break;
            }
        })
    }

    // Set the Leaflet.draw strings to the corresponding key in the translation bundle, if available.
    updateTranslations('leaflet.drawLocal', 'search.geography', leaflet.drawLocal);

    return leafletDraw;
})

Allow empty string in translation.


const path = require('path');
const gulp = require('gulp');
const babel = require('gulp-babel');
const eslint = require('gulp-eslint');
const Server = require('karma').Server;

const src = 'src/*.js';

gulp.task('lint', () => (
  gulp.src(src)
  .pipe(eslint())
  .pipe(eslint.format())
));

gulp.task('test', done => {
  new Server({
    configFile: path.join(__dirname, '/karma.conf.js'),
    singleRun: true,
    autoWatch: false,
  }, done).start();
});

gulp.task('tdd', done => {
  new Server({
    configFile: path.join(__dirname, '/karma.conf.js'),
  }, done).start();
});

gulp.task('build', ['test'], () => (
  gulp.src(src)
  .pipe(babel())
  .pipe(gulp.dest('lib'))
));

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

const path = require('path');
const gulp = require('gulp');
const babel = require('gulp-babel');
const eslint = require('gulp-eslint');
const Server = require('karma').Server;

const src = 'src/*.js';

gulp.task('lint', () => (
  gulp.src(src)
  .pipe(eslint())
  .pipe(eslint.format())
));

gulp.task('test', ['lint'], done => {
  new Server({
    configFile: path.join(__dirname, '/karma.conf.js'),
    singleRun: true,
    autoWatch: false,
  }, done).start();
});

gulp.task('tdd', done => {
  new Server({
    configFile: path.join(__dirname, '/karma.conf.js'),
  }, done).start();
});

gulp.task('build', ['test'], () => (
  gulp.src(src)
  .pipe(babel())
  .pipe(gulp.dest('lib'))
));

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

Add linting task before test task


'use strict';

const gulp = require( 'gulp' );
const mocha = require( 'gulp-mocha' );

gulp.task( 'test', () => {
    return gulp.src([ 'src/**/*.js', 'test/**/*.js' ], { read: false })
    .pipe( mocha())
    .once( 'end', () => process.exit());
});

'use strict';

const gulp = require( 'gulp' );
const mocha = require( 'gulp-mocha' );
const isparta = require( 'isparta' );
const istanbul = require( 'gulp-istanbul' );

gulp.task( 'pre-test', () => {
    return gulp.src( 'src/**/*.js' )
    .pipe( istanbul({
        instrumenter: isparta.Instrumenter,
    }))
    .pipe( istanbul.hookRequire());
});

gulp.task( 'test', ['pre-test'], () => {
    return gulp.src([
        'test/mongo.js',
        'test/s3.js',
        'test/index.js',
    ])
    .pipe( mocha())
    .pipe( istanbul.writeReports())
    .once( 'end', () => {
        process.exit();
    });
});

Update test config with coverage


// Load required plugins
const mdRegex = require('markdown-it-regexp')

var chordPattern = mdRegex(
  // regexp to match
  // Assuming anything within square brackets to be a chord
  /\[(\w+)\]/,

  // this function will be called when something's in square brackets
  function(match, utils) {
    return '' + match[1] + '';
  }
)

var md = require('markdown-it')({
  html:         false,        // Enable HTML tags in source
  xhtmlOut:     true,         // Use '/' to close single tags (
).
                              // This is only for full CommonMark compatibility.
  breaks:       true,         // Convert '\n' in paragraphs into

  linkify:      true,         // Autoconvert URL-like text to links

  // Enable some language-neutral replacement + quotes beautification
  typographer:  false,

  // Double + single quotes replacement pairs, when typographer enabled,
  // and smartquotes on. Could be either a String or an Array.
  quotes: '“”‘’'
}).use(chordPattern);

module.exports = function generateHtml(chordMarkdownText) {

  if(chordMarkdownText === undefined) {
    throw new Error('Argument chordMarkdownText is required.');
  }

  return md.render(data)
}

// Load the markdown-it regex plugin
const mdRegex = require('markdown-it-regexp')

// Set our chord's identifier regex pattern and replacement string
const chordPattern = mdRegex(
  // regexp to match
  // Assuming anything within square brackets to be a chord
  /\[(\w+)\]/,

  // this function will be called when something's in square brackets
  function(match, utils) {
    return '' + match[1] + '';
  }
)

// Import markdown-it and configure it to use our chordpattern
const md = require('markdown-it')({
  html:         false,        // Enable HTML tags in source
  xhtmlOut:     true,         // Use '/' to close single tags (
).
                              // This is only for full CommonMark compatibility.
  breaks:       true,         // Convert '\n' in paragraphs into

  linkify:      true,         // Autoconvert URL-like text to links

  // Enable some language-neutral replacement + quotes beautification
  typographer:  false,

  // Double + single quotes replacement pairs, when typographer enabled,
  // and smartquotes on. Could be either a String or an Array.
  quotes: '“”‘’'
}).use(chordPattern)

// Export our plugin
module.exports = function generateHtml(chordMarkdownText) {

  if(chordMarkdownText === undefined) {
    throw new Error('Argument chordMarkdownText is required.');
  }

  return md.render(data)
}

Replace vars with consts and add better comments


'use strict';

// Move to titaniumifier!
process.execPath || (process.execPath = '/path/to/node');

// Move to titaniumifier!
global.setTimeout = (function (setTimeout) {
  return function _setTimeout(fn, timeout) {
    return setTimeout(fn, timeout);
  };
})(global.setTimeout);
global.clearTimeout = (function (clearTimeout) {
  return function _clearTimeout(timeoutId) {
    if (typeof timeoutId === 'number') return clearTimeout(timeoutId);
    else return undefined;
  };
})(global.clearTimeout);

var Promise = require('bluebird');
var request = require('./lib/request');

var liferay = exports;

liferay.Promise = Promise;
liferay.request = request;

liferay.errors = require('./lib/errors');
liferay.identify = require('./lib/identify');
liferay.camelcase = require('./lib/camelcase');

liferay.base = require('./lib/connectors/base');
liferay.v61 = require('./lib/connectors/liferay61');
liferay.v62 = require('./lib/connectors/liferay62');

liferay.connectors = [
  liferay.v61, liferay.v62
];

liferay.guest = function (portalURL, auth, callback) {
  return liferay.identify(portalURL, null).then(function (connector) {
    return connector.guest(portalURL);
  }).nodeify(callback);
};

liferay.authenticate = function (portalURL, auth, callback) {
  return liferay.identify(portalURL, auth).then(function (connector) {
    return connector.authenticate(portalURL, auth);
  }).nodeify(callback);
};

'use strict';

// Move to titaniumifier!
process.execPath || (process.execPath = '/path/to/node');

var Promise = require('bluebird');
var request = require('./lib/request');

var liferay = exports;

liferay.Promise = Promise;
liferay.request = request;

liferay.errors = require('./lib/errors');
liferay.identify = require('./lib/identify');
liferay.camelcase = require('./lib/camelcase');

liferay.base = require('./lib/connectors/base');
liferay.v61 = require('./lib/connectors/liferay61');
liferay.v62 = require('./lib/connectors/liferay62');

liferay.connectors = [
  liferay.v61, liferay.v62
];

liferay.guest = function (portalURL, auth, callback) {
  return liferay.identify(portalURL, null).then(function (connector) {
    return connector.guest(portalURL);
  }).nodeify(callback);
};

liferay.authenticate = function (portalURL, auth, callback) {
  return liferay.identify(portalURL, auth).then(function (connector) {
    return connector.authenticate(portalURL, auth);
  }).nodeify(callback);
};

Remove now useless timers polyfill


const defaultScriptUrl = '//editor.unlayer.com/embed.js?2';
const callbacks = [];
let loaded = false;

const isScriptInjected = (scriptUrl) => {
  const scripts = document.querySelectorAll('script');
  let injected = false;

  scripts.forEach((script) => {
    if (script.src.includes(scriptUrl)) {
      injected = true;
    }
  });

  return injected;
};

const addCallback = (callback) => {
  callbacks.push(callback);
};

const runCallbacks = () => {
  if (loaded) {
    let callback;

    while ((callback = callbacks.shift())) {
      callback();
    }
  }
};

export const loadScript = (callback, scriptUrl = defaultScriptUrl) => {
  addCallback(callback);

  if (!isScriptInjected(scriptUrl)) {
    const embedScript = document.createElement('script');
    embedScript.setAttribute('src', scriptUrl);
    embedScript.onload = () => {
      loaded = true;
      runCallbacks();
    };
    document.head.appendChild(embedScript);
  } else {
    runCallbacks();
  }
};

const defaultScriptUrl = 'https://editor.unlayer.com/embed.js?2';
const callbacks = [];
let loaded = false;

const isScriptInjected = (scriptUrl) => {
  const scripts = document.querySelectorAll('script');
  let injected = false;

  scripts.forEach((script) => {
    if (script.src.includes(scriptUrl)) {
      injected = true;
    }
  });

  return injected;
};

const addCallback = (callback) => {
  callbacks.push(callback);
};

const runCallbacks = () => {
  if (loaded) {
    let callback;

    while ((callback = callbacks.shift())) {
      callback();
    }
  }
};

export const loadScript = (callback, scriptUrl = defaultScriptUrl) => {
  addCallback(callback);

  if (!isScriptInjected(scriptUrl)) {
    const embedScript = document.createElement('script');
    embedScript.setAttribute('src', scriptUrl);
    embedScript.onload = () => {
      loaded = true;
      runCallbacks();
    };
    document.head.appendChild(embedScript);
  } else {
    runCallbacks();
  }
};

Enforce HTTPS to load editor


import Discord from 'discord.js';
import logger from 'winston';
import request from 'superagent';
import auth from '../auth.json';
import messageHandler from './messageHandler.js';

// Configure logger settings
logger.remove(logger.transports.Console);
logger.add(logger.transports.Console, {
    colorize: true
});
logger.level = 'debug';

const TOKEN = auth.token;
const DBOT_TOKEN = auth.dbot_token;

const bot = new Discord.Client({
  token: TOKEN,
  autorun: true
});

bot.on('ready', (evt) => {
  logger.info('Connected');
  logger.info('Logged in as: ');
  logger.info(bot.user.username + ' - ' + bot.user.id);

  // Server count for discord bot list
  request.post(`https://discordbots.org/api/bots/${bot.user.id}/stats`)
    .set('Authorization', DBOT_TOKEN)
    .send({server_count: bot.guilds.size})
    .end(err => {
      if (err) return console.error(err);
      console.log("Success!");
    });

  bot.user.setPresence({status: 'online', game: {name: '!go fish | !help'}});
});

messageHandler(bot);

bot.login(TOKEN);

import Discord from 'discord.js';
import logger from 'winston';
import request from 'superagent';
import auth from '../auth.json';
import messageHandler from './messageHandler.js';

// Configure logger settings
logger.remove(logger.transports.Console);
logger.add(logger.transports.Console, {
    colorize: true
});
logger.level = 'debug';

const TOKEN = auth.token;
const DBOT_TOKEN = auth.dbot_token;
const PWBOT_TOKEN = auth.pwbot_token;

const bot = new Discord.Client({
  token: TOKEN,
  autorun: true
});

bot.on('ready', (evt) => {
  logger.info('Connected');
  logger.info('Logged in as: ');
  logger.info(bot.user.username + ' - ' + bot.user.id);

  // Server count for discord bot lists
  request.post(`https://discordbots.org/api/bots/${bot.user.id}/stats`)
    .set('Authorization', DBOT_TOKEN)
    .send({server_count: bot.guilds.size})
    .end(err => {
      if (err) return console.error(err);
      console.log("Success (dbot)!");
    });

  request.post(`https://bots.discord.pw/api/bots/${bot.user.id}/stats`)
    .set('Authorization', PWBOT_TOKEN)
    .send({server_count: bot.guilds.size})
    .end(err => {
      if (err) return console.error(err);
      console.log("Success (pwbot)!");
    });

  bot.user.setPresence({status: 'online', game: {name: '!go fish | !help'}});
});

messageHandler(bot);

bot.login(TOKEN);

Add server count for discord pw bot list


require('env2')
const Hapi = require('hapi')

// server plugins
const Inert = require('inert')

// server routes
const Dashboard = require('./routes/nhsViews/Dashboard.js')
const ResourceHandler = require('./routes/nhsViews/ResourceHandler.js')
const BookEvent = require('./routes/YSU-routes/book_event.js')
const BookedEvents = require('./routes/YSU-routes/booked_events.js')
const setInterests = require('./routes/YSU-routes/set_interests.js')
const signUp = require('./routes/YSU-routes/sign_up.js')
const userEvents = require('./routes/YSU-routes/user_events.js')

const Plugins = [ Inert ]
const Routes = [
  Dashboard,
  ResourceHandler,
  BookEvent,
  BookedEvents,
  setInterests,
  signUp,
  userEvents
]

module.exports = (client) => {

  const server = new Hapi.Server()

  server.connection({ port: process.env.PORT || 4000 })
  server.register(Plugins, err => {if (err) console.log(err)})
  server.route(Routes)

  return server
}

require('env2')
const Hapi = require('hapi')

// server plugins
const Inert = require('inert')

// server routes
const Dashboard = require('./routes/nhsViews/Dashboard.js')
const ResourceHandler = require('./routes/nhsViews/ResourceHandler.js')
const BookEvent = require('./routes/YSU-routes/book_event.js')
const BookedEvents = require('./routes/YSU-routes/booked_events.js')
const setInterests = require('./routes/YSU-routes/set_interests.js')
const signUp = require('./routes/YSU-routes/sign_up.js')
const userEvents = require('./routes/YSU-routes/user_events.js')
const addMockUser = require('./routes/YSU-routes/add_mock_user.js')

const Plugins = [ Inert ]
const Routes = [
  Dashboard,
  ResourceHandler,
  BookEvent,
  BookedEvents,
  setInterests,
  signUp,
  userEvents,
  addMockUser
]

module.exports = (client) => {

  const server = new Hapi.Server()

  server.connection({ port: process.env.PORT || 4000 })
  server.register(Plugins, err => {if (err) console.log(err)})
  server.route(Routes)

  return server
}

Add routes to add a mock user for testing


import {createRunner} from 'atom-mocha-test-runner';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';

import until from 'test-until';

chai.use(chaiAsPromised);
global.assert = chai.assert;

// Give tests that rely on filesystem event delivery lots of breathing room.
until.setDefaultTimeout(5000);

module.exports = createRunner({
  htmlTitle: `GitHub Package Tests - pid ${process.pid}`,
  reporter: process.env.MOCHA_REPORTER || 'spec',
  overrideTestPaths: [/spec$/, /test/],
}, mocha => {
  mocha.timeout(5000);
  if (process.env.APPVEYOR_API_URL) {
    mocha.reporter(require('mocha-appveyor-reporter'));
  }
});

import {createRunner} from 'atom-mocha-test-runner';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';

import until from 'test-until';

chai.use(chaiAsPromised);
global.assert = chai.assert;

// Give tests that rely on filesystem event delivery lots of breathing room.
until.setDefaultTimeout(3000);

module.exports = createRunner({
  htmlTitle: `GitHub Package Tests - pid ${process.pid}`,
  reporter: process.env.MOCHA_REPORTER || 'spec',
  overrideTestPaths: [/spec$/, /test/],
}, mocha => {
  mocha.timeout(5000);
  if (process.env.APPVEYOR_API_URL) {
    mocha.reporter(require('mocha-appveyor-reporter'));
  }
});

Drop `test-until` default timeout to under the mocha timeout


import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

global.requestAnimationFrame = function(callback) {
    setTimeout(callback, 0);
};

try {
    require('canvas');
} catch(err) {
    global.HAS_CANVAS = false;
    global.HTMLCanvasElement = function() {};
    global.HTMLCanvasElement.prototype.getContext = () => {
        return {};
    };
}

// add an i18n setup
i18n
    .use(initReactI18next)
    .init({
        keySeparator: false,
        lng: 'dev',
        resources: {
            dev: { translation: {} },
        },
        interpolation: {
            escapeValue: false,
        },
    });

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

global.requestAnimationFrame = function(callback) {
    setTimeout(callback, 0);
};

try {
    require('canvas');
} catch(err) {
    global.HAS_CANVAS = false;
    global.HTMLCanvasElement = function() {};
    global.HTMLCanvasElement.prototype.getContext = () => {
        return {};
    };
}

window.ResizeObserver = jest.fn().mockImplementation(() => ({
    observe: jest.fn(),
    unobserve: jest.fn(),
    disconnect: jest.fn()
}));

// add an i18n setup
i18n
    .use(initReactI18next)
    .init({
        keySeparator: false,
        lng: 'dev',
        resources: {
            dev: { translation: {} },
        },
        interpolation: {
            escapeValue: false,
        },
    });

Add ResizerObserver shim for tests.


var express = require('express');
var nunjucks = require('express-nunjucks');
var app = express();

// Application settings
app.set('view engine', 'html');
app.set('views', __dirname + '/views');

app.use(express.static('assets'));

nunjucks.setup({
  autoescape: true,
  watch: true,
  noCache: true
}, app);

app.get('/', function (req, res) {
  res.render('index');
});

// auto render any view that exists
app.get(/^\/([^.]+)$/, function (req, res) {
  var path = (req.params[0]);
  res.render(path, function(err, html) {
    if (err) {
      res.render(path + "/index", function(err2, html) {
        if (err2) {
          console.log(err);
          res.status(404).send(err + "<br>" + err2);
        } else {
          res.end(html);
        }
      });
    } else {
      res.end(html);
    }
  });
});

// start the app
var port = (process.env.PORT || 3000);
app.listen(port, function () {
  console.log('Example app listening on port 3000!');
});

var express = require('express');
var nunjucks = require('express-nunjucks');
var app = express();

// Application settings
app.set('view engine', 'html');
app.set('views', __dirname + '/views');

app.use(express.static('assets'));

nunjucks.setup({
  autoescape: true,
  watch: true,
  noCache: true
}, app);

app.get('/', function (req, res) {
  res.render('index');
});

// auto render any view that exists
app.get(/^\/([^.]+)$/, function (req, res) {
  var path = (req.params[0]);
  res.render(path, function(err, html) {
    if (err) {
      res.render(path + "/index", function(err2, html) {
        if (err2) {
          console.log(err);
          res.status(404).send(err + "<br>" + err2);
        } else {
          res.end(html);
        }
      });
    } else {
      res.end(html);
    }
  });
});

// start the app
var port = (process.env.PORT || 3000);
app.listen(port, function () {
  console.log('Example app listening on port ' + port);
});

Sort out port log display


var config = require('./config');
var http = require('http');
var bot = require('./modules/bot.js');
var tg = require('./modules/telegramAPI');

tg.setupWebhook();

http.createServer(function (req, res) {
    var body = '';

    req.on('data', function(chunk) {
        body += chunk;
    });

    req.on('end', function() {
        if (req.url === config.BOT_WEBHOOK_PATH) {
            res.writeHead(200);
            try {
                body = JSON.parse(body);
            } catch (e) {
                console.log(`Bad JSON: ${e.message}`);
                return;
            };
            bot.verifyMessage(body);
        } else {
            res.writeHead(400);
        }
        res.end();
    });

}).listen(config.SERVER_PORT);

var config = require('./config');
var http = require('http');
var bot = require('./modules/bot.js');
var tg = require('./modules/telegramAPI');

tg.setupWebhook();

http.createServer(function (req, res) {
    var body = '';

    req.on('data', function(chunk) {
        body += chunk;
    });

    req.on('end', function() {
        if (req.url === config.BOT_WEBHOOK_PATH) {
            res.writeHead(200);
            try {
                body = JSON.parse(body);
            } catch (e) {
                console.log(`Bad JSON: ${e.message}`);
                return;
            };
            bot.verifyMessage(body);
        } else {
            res.writeHead(401);
        }
        res.end();
    });

}).listen(config.SERVER_PORT);

Send 401 Unauthorized for all requests (Except Telegram webhooks)


var main = function() {
    $(".btn-projects").click(function() {
        $('html,body').animate({
                scrollTop: $(".proj").offset().top
            },
            'slow');
    });
    $(".btn-about").click(function() {
        $('html,body').animate({
                scrollTop: $(".bio").offset().top
            },
            'slow');
    });
    $('#myCarousel').carousel({
        interval: 10000
    });
    $('.carousel .item').each(function() {
        var next = $(this).next();
        if (!next.length) {
            next = $(this).siblings(':first');
        }
        next.children(':first-child').clone().appendTo($(this));
        if (next.next().length > 0) {
            next.next().children(':first-child').clone().appendTo($(this));
        } else {
            $(this).siblings(':first').children(':first-child').clone().appendTo($(this));
        }
    });
};

$(document).ready(main);

var main = function() {
    $(".btn-projects").click(function() {
        $('html,body').animate({
                scrollTop: $(".proj").offset().top
            },
            'slow');
    });
    $(".btn-about").click(function() {
        $('html,body').animate({
                scrollTop: $(".bio").offset().top
            },
            'slow');
    });
    $('#myCarousel').carousel({
        interval: 7500
    });
    $('.carousel .item').each(function() {
        var next = $(this).next();
        if (!next.length) {
            next = $(this).siblings(':first');
        }
        next.children(':first-child').clone().appendTo($(this));
        if (next.next().length > 0) {
            next.next().children(':first-child').clone().appendTo($(this));
        } else {
            $(this).siblings(':first').children(':first-child').clone().appendTo($(this));
        }
    });
};

$(document).ready(main);

Modify carousel interval to 7500ms


function changeTitle () {
	var subject = document.getElementById('mail_subject').value;

	if ((subject == null) || (subject == "")) {
		document.title = "SendMail";
		document.getElementById('message_title').innerHTML = "New Message";
	}
	else {
		document.title = "SendMail - " + subject;
		document.getElementById('message_title').innerHTML = subject;
	}
}

function showSignature () {
	document.getElementById('overlay_background').style.display = "block";
	document.getElementById('overlay_body').style.display = "block";
}

function hideSignature () {
	document.getElementById('overlay_background').style.display = "none";
	document.getElementById('overlay_body').style.display = "none";
}

function messageSend () {
	document.getElementById('response_message_div').style.display = "block";
}

function changeTitle () {
	var subject = document.getElementById('mail_subject').value;

	if ((subject == null) || (subject == "")) {
		document.title = "SendMail";
		document.getElementById('message_title').innerHTML = "New Message";
	}
	else {
		document.title = "SendMail - " + subject;
		document.getElementById('message_title').innerHTML = subject;
	}
}

function showSignature () {
	document.getElementById('overlay_background').style.display = "block";
	document.getElementById('overlay_body').style.display = "block";
}

function hideSignature () {
	var signature = document.getElementById('signature_text').value;
	var message = document.getElementById('message_text').value;

	document.getElementById('message_text').value = message + "\n\n" + signature;

	document.getElementById('overlay_background').style.display = "none";
	document.getElementById('overlay_body').style.display = "none";
}

function messageSend () {
	document.getElementById('response_message_div').style.display = "block";
}

Save button adds signature to end of message


/*
    Date: 2016-05-13
*/

var URLCold   = 'http://192.168.240.1/arduino/analog/0';
var URLHot    = ''; // 'http://192.168.240.1/arduino/analog/1';
var loopTime  = 0;
var loopCount = 0;

function getReadings () {
    if (loopTime > 0) {
        if ( URLCold.length > 0 ) {
            loopCount++;
            $('#readingStatus').text('reading:' + loopCount );
            $('#gotSensor').text('getting');
            $.get(URLCold, function (data) {
                $('#gotSensor').text('cold');
                $('#temp1').text(data);
            });
        }
        if ( URLHot.length > 0 ) {
            $('#gotSensor').text('getting');
            $.get(URLHot, function (data) {
                $('#gotSensor').text('hot');
                $('#temp2').text(data);
            });
        }
        setTimeout(getReadings, loopTime);
    } else {
        loopCount = 0;
        $('#readingStatus').text('inactive');
    }
}

/*
    Date: 2016-05-13
    2016-06-21 - Added Ping
*/
var URLTemperature   = 'http://' defaultHostIP + '/arduino/iot/thermistor/0';
var URLPing          = 'http://' defaultHostIP + '/arduino/iot/ultrasound/0';
var loopTime  = 0;
var loopCount = 0;

function getReadings () {
    var distanceReading = '';
    if (loopTime > 0) {
        if ( URLTemperature.length > 0 ) {
            loopCount++;
            $('#appStatus').text('reading:' + loopCount );
            $('#readStatus').text('getting');
            $.get(URLTemperature, function (data) {
                $('#readStatus').text('temperature');
                $('#temperature').text(data);
            });
        }
        if ( URLPing.length > 0 ) {
            loopCount++;
            $('#appStatus').text('reading:' + loopCount );
            $('#readStatus').text('getting');
            $.get(URLPing, function (data) {
                $('#readStatus').text('ping');
                var cmString = new String(data);
                var inString = new String(data/0.393701);
                distanceReading = cmString + "cm (" + inString + "in)";
                $('#ping').text(data);
            });
        }
        setTimeout(getReadings, loopTime);
    } else {
        loopCount = 0;
        $('#appStatus').text('inactive');
    }
}

Change REST interface; added ping sensor


/* @flow */
/* eslint-disable react/prop-types */

import React, {Component} from 'react'
import {globalStyles} from '../../../styles/style-guide'
import {Text, Button} from '../../../common-adapters'

import type {Props} from './index.render'

export default class Render extends Component {
  props: Props;

  render () {
    return (
      <div style={styles.form}>
        <Text type='Header'>Ah Shoot! Something went wrong, wanna try again?</Text>
        <Text type='Body'>Error: {this.props.errorText.stringValue()}</Text>
        <Button type='Secondary' label='Try Again' onClick={() => this.props.resetSignup()}/>
      </div>
    )
  }
}

const styles = {
  form: {
    ...globalStyles.flexBoxColumn,
    flex: 1
  }
}

/* @flow */
/* eslint-disable react/prop-types */

import React, {Component} from 'react'
import {globalStyles} from '../../../styles/style-guide'
import {Text, Button} from '../../../common-adapters'

import type {Props} from './index.render'

export default class Render extends Component {
  props: Props;

  render () {
    return (
      <div style={container}>
        <Text type='Header' style={topMargin}>Ah Shoot! Something went wrong, wanna try again?</Text>
        <Text type='Error' style={topMargin}>{this.props.errorText.stringValue() + ''}</Text>
        <Button style={topMargin} type='Secondary' label='Try Again' onClick={() => this.props.resetSignup()}/>
      </div>
    )
  }
}

const container = {
  ...globalStyles.flexBoxColumn,
  alignItems: 'center',
  flex: 1
}

const topMargin = {marginTop: 30}

Make the signup error page not look broken.


/*jslint forin: true */

var log = console.log;

exports.report = function(file, lint) {
    log(file);

    var options = [], key, value,
        i, len, pad, e;

    for (key in lint.options) {
        value = lint.options[key];
        options.push(key + ": " + value);
    }
    log("/*jslint " + options.join(", ") + " */");

    if (!lint.ok) {
        len = lint.errors.length;
        for (i=0; i<len; i++) {
            pad = '' + (i + 1);
            while (pad.length < 3) {
                pad = ' ' + pad;
            }
            e = lint.errors[i];
            if (e) {
                log(pad + ' ' + e.line + ',' + e.character + ': ' + e.reason);
                log( '    ' + (e.evidence || '').replace(/^\s+|\s+$/, ""));
            }
        }
    } else {
        log("ok!");
    }

    return lint.ok;
};

/*jslint forin: true */

var log = console.log;

exports.report = function(file, lint) {
    log("\n" + file);

    var options = [], key, value,
        i, len, pad, e;

    for (key in lint.options) {
        value = lint.options[key];
        options.push(key + ": " + value);
    }
    log("/*jslint " + options.join(", ") + " */");

    if (!lint.ok) {
        len = lint.errors.length;
        for (i=0; i<len; i++) {
            pad = '' + (i + 1);
            while (pad.length < 3) {
                pad = ' ' + pad;
            }
            e = lint.errors[i];
            if (e) {
                log(pad + ' ' + e.line + ',' + e.character + ': ' + e.reason);
                log( '    ' + (e.evidence || '').replace(/^\s+|\s+$/, ""));
            }
        }
    } else {
        log("No errors found.");
    }

    return lint.ok;
};

Improve readability with newlines between reports.


export const PAUSE_STORAGE_KEY = 'is-logging-paused'

export function isLoggable({ url }) {
    // Just remember http(s) pages, ignoring data uris, newtab, ...
    const loggableUrlPattern = /^https?:\/\/\w+([-/.#=$^@&%?+(),]\w*\/?)*$/
    const urlEndings = ['.svg', '.jpg', '.png', '.jpeg', '.gif']

    // Ignore all pages that are image files
    for (let i = 0; i < urlEndings.length; i++) {
        if (url.endsWith(urlEndings[i])) {
            return false
        }
    }
    return loggableUrlPattern.test(url)
}

export const getPauseState = async () => {
    const state = (await browser.storage.local.get(PAUSE_STORAGE_KEY))[
        PAUSE_STORAGE_KEY
    ]

    switch (state) {
        case 0:
        case 1:
            return true
        case 2:
        default:
            return false
    }
}

export const PAUSE_STORAGE_KEY = 'is-logging-paused'

export function isLoggable({ url }) {
    // Just remember http(s) pages, ignoring data uris, newtab, ...
    const loggableUrlPattern = /^https?:\/\/\w+([-/.#=:$^@&%?+(),]\w*\/?)*$/
    const urlEndings = ['.svg', '.jpg', '.png', '.jpeg', '.gif']

    // Ignore all pages that are image files
    for (let i = 0; i < urlEndings.length; i++) {
        if (url.endsWith(urlEndings[i])) {
            return false
        }
    }
    return loggableUrlPattern.test(url)
}

export const getPauseState = async () => {
    const state = (await browser.storage.local.get(PAUSE_STORAGE_KEY))[
        PAUSE_STORAGE_KEY
    ]

    switch (state) {
        case 0:
        case 1:
            return true
        case 2:
        default:
            return false
    }
}

Add colon to loggable URL pattern


import R from 'ramda';
import isUpperCase from '../src/is-upper-case.js';

// a -> a
const swapCase = R.compose(
  R.join(''),
  R.map(
    R.either(
      R.both(isUpperCase, R.toLower),
      R.both(R.compose(R.not, isUpperCase), R.toUpper)
    )
  )
);

export default swapCase;

import R from 'ramda';
import compose from './util/compose.js';
import isUpperCase from '../src/is-upper-case.js';

// a -> a
const swapCase = compose(
  R.join(''),
  R.map(
    R.either(
      R.both(isUpperCase, R.toLower),
      R.both(compose(R.not, isUpperCase), R.toUpper)
    )
  )
);

export default swapCase;

Refactor swapCase function to use custom compose function


// LinkedIn:
$('title').remove();
$('#name-container').hide();
$('.profile-picture').hide();

// Logged out:
$('h1#name').hide();
$('.reg-upsell').hide();
$('.name-search').hide();

// These should appear only if you're already connected, but just in case:
$('.endorse-v2').hide();
$('.write-endorsement').hide();

// Search results:
$('li.mod > a.result-image').hide();
$('li.mod > .bd > h3 > a.main-headline').text('Person');
$('.profile-actions > .katy-button-group').hide();
$('#siteflow-widget-next').hide();

Hide 'Next search result' box


module.exports = function(browser){
    return {
        trade: function(){
            var data = browser.globals.pages.ticktrade;
            var login = browser.globals.pages.login;
            return browser
                .verifyLogin(login.token,function(result){
                    console.log("Login verification ");
                })
                .url(data.url)
                .waitForElementVisible('body', 3000)
                .verify.elementNotPresent(login.tokenInput)
                .click(data.purchaseButton)
                .waitForElementVisible(data.modalClass, 3000)
                .verify.elementPresent(data.modalClass)

        },
    };
}

module.exports = function(browser){
    return {
        trade: function(){
            var data = browser.globals.pages.ticktrade;
            var login = browser.globals.pages.login;
            return browser
                .verifyLogin(login.token,function(result){
                    console.log("Login verification ");
                })
                .url(data.url)
                .waitForElementVisible('body', 3000)
                .verify.elementNotPresent(login.tokenInput)
                .verify.elementNotPresent(data.modalClass)
                .click(data.purchaseButton)
                .waitForElementVisible(data.modalClass, 3000)
                .verify.elementPresent(data.modalClass)

        },
    };
}

Verify modal class is not present in trade page before purchase button is clicked


import 'dom4';
import Promise from 'bluebird';
import { polyfill as smoothscroll } from 'smoothscroll-polyfill/src/smoothscroll';

smoothscroll();
window.Promise = Promise;

import 'dom4';
import Promise from 'bluebird';
import { polyfill as smoothscroll } from 'smoothscroll-polyfill';

smoothscroll();
window.Promise = Promise;

Remove weird hack, it's not fixed.


import 'isomorphic-fetch'
import { call, select } from 'redux-saga/effects'
import { accessTokenSelector } from './selectors'

export function* fetchCredentials() {
  const accessToken = yield select(accessTokenSelector)
  if (accessToken) {
    return {
      token: {
        access_token: accessToken,
      },
    }
  }

  const tokenPath = (typeof window === 'undefined') ?
        `http://localhost:${process.env.PORT || 6660}/api/webapp-token` :
        `${document.location.protocol}//${document.location.host}/api/webapp-token`

  try {
    const response = yield call(fetch, tokenPath, { credentials: 'same-origin' })
    if (response.ok) {
      // Pass response as binding for response.json
      return yield call([response, response.json])
    }
    return response
  } catch (_err) {
    return yield call(fetchCredentials)
  }
}

function checkStatus(response) {
  if (response.ok) {
    return response
  }
  const error = new Error(response.statusText)
  error.response = response
  throw error
}

export function extractJSON(response) {
  return response ? response.json() : response
}

export function* sagaFetch(path, options) {
  const response = yield call(fetch, path, options)
  checkStatus(response)

  // allow for the json to be empty for a 204
  let json = {}
  if (response.status !== 204) {
    json = yield call(extractJSON, response)
  }
  return { serverResponse: response, json }
}

import 'isomorphic-fetch'
import { call, select } from 'redux-saga/effects'
import { accessTokenSelector } from './selectors'

export function* fetchCredentials() {
  const accessToken = yield select(accessTokenSelector)
  if (accessToken) {
    return {
      token: {
        access_token: accessToken,
      },
    }
  }

  const tokenPath = (typeof window === 'undefined') ?
        `http://localhost:${process.env.PORT || 6660}/api/webapp-token` :
        `${document.location.protocol}//${document.location.host}/api/webapp-token`

  try {
    const response = yield call(fetch, tokenPath, { credentials: 'same-origin' })
    if (response.ok) {
      // Pass response as binding for response.json
      return yield call([response, response.json])
    }
    return response
  } catch (_err) {
    return yield call(fetchCredentials)
  }
}

function checkStatus(response) {
  if (response.ok) {
    return response
  }
  const error = new Error(response.statusText)
  error.response = response
  throw error
}

export function extractJSON(response) {
  return response ? response.json() : response
}

export function* sagaFetch(path, options) {
  const response = yield call(fetch, path, options)
  checkStatus(response)

  // allow for the json to be empty for a 201/202/204
  let json = {}
  if (response.status === 200) {
    json = yield call(extractJSON, response)
  }
  return { serverResponse: response, json }
}

Fix issues when response is 200 with no content.


'use strict'

/**
 * Scans all currently visible rooms and records useful information about them.
 */

class EmpireIntel extends kernel.process {
  constructor (...args) {
    super(...args)
    this.priority = PRIORITIES_EMPIRE_INTEL
  }

  main () {
    this.gatherIntel()
    this.flushIntel()
  }

  gatherIntel () {
    const roomnames = Object.keys(Game.rooms)
    let roomname
    for (roomname of roomnames) {
      const room = Game.rooms[roomname]
      if (room.controller && room.controller.my) {
        continue
      }
      const roominfo = room.getIntel(roomname)
      if (Game.time - roominfo[INTEL_UPDATED] > 60) {
        room.saveIntel()
      }
    }
  }

  flushIntel () {
    if (!Memory.intel) {
      return
    }
    const buffersize = Object.keys(Memory.intel.buffer).length
    if (buffersize < 0) {
      return
    }
    if (!this.data.lastflush || Game.time - this.data.lastflush > 50 || buffersize > 80) {
      Room.flushIntelToSegment()
    }
  }
}

module.exports = EmpireIntel

'use strict'

/**
 * Scans all currently visible rooms and records useful information about them.
 */

class EmpireIntel extends kernel.process {
  constructor (...args) {
    super(...args)
    this.priority = PRIORITIES_EMPIRE_INTEL
  }

  main () {
    this.gatherIntel()
    this.flushIntel()
    if (!this.data.lastclean || Game.time - this.data.lastclean > 100) {
      this.cleanTargets()
      this.data.lastclean = Game.time
    }
  }

  gatherIntel () {
    const roomnames = Object.keys(Game.rooms)
    let roomname
    for (roomname of roomnames) {
      const room = Game.rooms[roomname]
      if (room.controller && room.controller.my) {
        continue
      }
      const roominfo = room.getIntel(roomname)
      if (Game.time - roominfo[INTEL_UPDATED] > 60) {
        room.saveIntel()
      }
    }
  }

  flushIntel () {
    if (!Memory.intel) {
      return
    }
    const buffersize = Object.keys(Memory.intel.buffer).length
    if (buffersize < 0) {
      return
    }
    if (!this.data.lastflush || Game.time - this.data.lastflush > 50 || buffersize > 80) {
      Room.flushIntelToSegment()
    }
  }

  cleanTargets () {
    const targets = Object.keys(Memory.intel.targets)
    for (let target of targets) {
      if (Game.time - Memory.intel.targets[target] > 5000) {
        delete Memory.intel.targets[target]
      }
    }
  }
}

module.exports = EmpireIntel

Remove targets older than 5000 ticks


var ObjectiveJ = { };

(function (global, exports, namespace)
{
#include "Includes.js"
})((function(){return this;}).call(null), ObjectiveJ);

var global = { },
    ObjectiveJ = { };

(function (global, exports, namespace)
{
    var GLOBAL_NAMESPACE = namespace;
#include "Includes.js"
})(global, ObjectiveJ, window);

var hasOwnProperty = Object.prototype.hasOwnProperty;

// If we can't trust the host object, don't treat it as global
// and fall back to inferred global through eval. In IE this
// make a difference.
if (window.window !== window)
{
    for (key in global)
        if (hasOwnProperty.call(global, key))
            eval(key + " = global[\"" + key + "\"];");
}
else
{
    for (key in global)
        if (hasOwnProperty.call(global, key))
            window[key] = global[key];
}

Revert "A better fix for the IE bug. Rather than introduce the secondary global and the eval, just refer to the actual global object (works in any javascript env)."


import { clone, toLowerCase, isFunction, isString, hasOwnProperty } from '../util';
import { isFunctionalComponent } from './functional-component';
import { getNodeType } from '../dom/index';

/** Check if two nodes are equivalent.
 *	@param {Element} node
 *	@param {VNode} vnode
 *	@private
 */
export function isSameNodeType(node, vnode) {
	if (isFunctionalComponent(vnode)) return true;
	let nodeName = vnode.nodeName;
	if (isFunction(nodeName)) return node._componentConstructor===nodeName;
	if (getNodeType(node)===3) return isString(vnode);
	return toLowerCase(node.nodeName)===nodeName;
}

/**
 * Reconstruct Component-style `props` from a VNode.
 * Ensures default/fallback values from `defaultProps`:
 * Own-properties of `defaultProps` not present in `vnode.attributes` are added.
 * @param {VNode} vnode
 * @returns {Object} props
 */
export function getNodeProps(vnode) {
	let props = clone(vnode.attributes),
		c = vnode.children;
	if (c) props.children = c;

	let defaultProps = vnode.nodeName.defaultProps;
	if (defaultProps) {
		for (let i in defaultProps) {
			if (hasOwnProperty.call(defaultProps, i) && !(i in props)) {
				props[i] = defaultProps[i];
			}
		}
	}

	return props;
}

import { clone, isString, toLowerCase, hasOwnProperty } from '../util';
import { isFunctionalComponent } from './functional-component';
import { getNodeType } from '../dom';

/** Check if two nodes are equivalent.
 *	@param {Element} node
 *	@param {VNode} vnode
 *	@private
 */
export function isSameNodeType(node, vnode) {
	if (isString(vnode)) return getNodeType(node)===3;
	let nodeName = vnode.nodeName,
		type = typeof nodeName;
	if (type==='string') {
		return node.normalizedNodeName===nodeName || isNamedNode(node, nodeName);
	}
	if (type==='function') {
		return node._componentConstructor===nodeName || isFunctionalComponent(vnode);
	}
}

export function isNamedNode(node, nodeName) {
	return toLowerCase(node.nodeName)===toLowerCase(nodeName);
}

/**
 * Reconstruct Component-style `props` from a VNode.
 * Ensures default/fallback values from `defaultProps`:
 * Own-properties of `defaultProps` not present in `vnode.attributes` are added.
 * @param {VNode} vnode
 * @returns {Object} props
 */
export function getNodeProps(vnode) {
	let props = clone(vnode.attributes),
		c = vnode.children;
	if (c) props.children = c;

	let defaultProps = vnode.nodeName.defaultProps;
	if (defaultProps) {
		for (let i in defaultProps) {
			if (hasOwnProperty.call(defaultProps, i) && !(i in props)) {
				props[i] = defaultProps[i];
			}
		}
	}

	return props;
}

Optimize heavily called function `isSameNodeType()`


(() => {
    const tools = [];

    DTile.Tool = class DTileTool {
        static register() {
            tools.push(new this());
        }

        static get allTools() { return tools; }

        static get store() { return DTile.store; }
        static get state() { return DTileTool.store.getState(); }

        get currentMap() {
            const state = DTileTool.state;
            return state.entities.maps[state.ui.currentMapId].present;
        }

        get currentLayerIndex() {
            return DTileTool.state.ui.currentLayerIndex;
        }

        get currentLayer() {
            return this.currentMap.layers[this.currentLayerIndex];
        }

        get layerAsTileArea() {
            if (!this.currentLayer) return;

            const map = this.currentMap;
            return {
                width: map.width,
                height: map.height,
                tiles: this.currentLayer.tiles
            };
        }

        get tileArea() {
            return DTileTool.state.ui.currentTileArea;
        }

        getTileMeta(tilesetId, tileId) {
            if (tilesetId < 0 || tileId < 0) return {};
            return DTileTool.state.entities.tilesets[tilesetId].tileMeta[tileId] || {};
        }

        onMove() {}
        onTap() {}
        onTrack() {}
    };
})();

(() => {
    const tools = [];

    DTile.Tool = class DTileTool {
        static register() {
            tools.push(new this());
        }

        static get allTools() { return tools; }

        static get store() { return DTile.store; }
        static get state() { return DTileTool.store.getState(); }

        get currentMap() {
            const state = DTileTool.state;
            return state.entities.maps[state.ui.currentMapId].present;
        }

        get currentLayerIndex() {
            return DTileTool.state.ui.currentLayerIndex;
        }

        get currentLayer() {
            return this.currentMap.layers[this.currentLayerIndex];
        }

        get layerAsTileArea() {
            if (!this.currentLayer) return;

            const map = this.currentMap;
            return {
                width: map.width,
                height: map.height,
                tiles: this.currentLayer.tiles
            };
        }

        get tileArea() {
            return DTileTool.state.ui.currentTileArea || {
                width: 0,
                height: 0,
                tiles: []
            };
        }

        getTileMeta(tilesetId, tileId) {
            if (tilesetId < 0 || tileId < 0) return {};
            return DTileTool.state.entities.tilesets[tilesetId].tileMeta[tileId] || {};
        }

        onMove() {}
        onTap() {}
        onTrack() {}
    };
})();

Fix error when tiles aren't selected