define('implementations', [], function () {
  'use strict';
  return {
    'es5': [
      {
        isAvailable: function () {
          // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/es5/array.js
          return !!(Array.prototype &&
            Array.prototype.every &&
            Array.prototype.filter &&
            Array.prototype.forEach &&
            Array.prototype.indexOf &&
            Array.prototype.lastIndexOf &&
            Array.prototype.map &&
            Array.prototype.some &&
            Array.prototype.reduce &&
            Array.prototype.reduceRight &&
            Array.isArray &&
            Function.prototype.bind);
        },
        implementation: 'es5-shim'
      },
      {
        isAvailable: function () { return true; },
        module: function () {
          return {};
        }
      }
    ],
    promises: [
      {
        // native ES6 Promises
        isAvailable: function () {
          // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/es6/promises.js
          return 'Promise' in window &&
            'resolve' in window.Promise &&
            'reject' in window.Promise &&
            'all' in window.Promise &&
            'race' in window.Promise &&
            (function() {
              var resolve;
              new window.Promise(function(r) { resolve = r; });
              return typeof resolve === 'function';
            }());
        },
        module: function () {
          return Promise;
        }
      },
      {
        // fallback to Bluebird
        isAvailable: function () { return true; },
        implementation: 'bluebird'
      }
    ]
  };
});

define('implementations', [], function () {
  'use strict';
  return {
    'es5': [
      {
        isAvailable: function () {
          // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/es5/array.js
          return !(Array.prototype &&
            Array.prototype.every &&
            Array.prototype.filter &&
            Array.prototype.forEach &&
            Array.prototype.indexOf &&
            Array.prototype.lastIndexOf &&
            Array.prototype.map &&
            Array.prototype.some &&
            Array.prototype.reduce &&
            Array.prototype.reduceRight &&
            Array.isArray &&
            Function.prototype.bind);
        },
        implementation: 'es5-shim'
      },
      {
        isAvailable: function () { return true; },
        module: function () {
          return {};
        }
      }
    ],
    promises: [
      {
        // native ES6 Promises
        isAvailable: function () {
          // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/es6/promises.js
          return 'Promise' in window &&
            'resolve' in window.Promise &&
            'reject' in window.Promise &&
            'all' in window.Promise &&
            'race' in window.Promise &&
            (function() {
              var resolve;
              new window.Promise(function(r) { resolve = r; });
              return typeof resolve === 'function';
            }());
        },
        module: function () {
          return Promise;
        }
      },
      {
        // fallback to Bluebird
        isAvailable: function () { return true; },
        implementation: 'bluebird'
      }
    ]
  };
});

Revert "fix ES5 shim test"


require('es5-shim');
require('es5-shim/es5-sham');

(function () {

if (typeof console === 'undefined') {
    window.console = {};
    window.console.log = function () {};
}

// These are only required for the case when React wants to reset the HTML element,
// which fails because it cannot set node.innerHTML on IE8
var ElementPrototype = window.Element.prototype;
if (!ElementPrototype.getAttributeNS) {
    ElementPrototype.getAttributeNS = function getAttributeNS (namespace, name) {
        if (namespace) throw new Error("Unsupported getAttributeNS with namespace");
        return this.getAttribute(name);
    };
    ElementPrototype.setAttributeNS = function setAttributeNS (namespace, name, value) {
        if (namespace) throw new Error("Unsupported setAttributeNS with namespace");
        return this.setAttribute(name, value);
    };
    ElementPrototype.removeAttributeNS = function removeAttributeNS (namespace, name) {
        if (namespace) throw new Error("Unsupported removeAttributeNS with namespace");
        return this.removeAttribute(name);
    };
    ElementPrototype.hasAttributeNS = function hasAttributeNS (namespace, name) {
        if (namespace) throw new Error("Unsupported hasAttributeNS with namespace");
        return this.hasAttribute(name);
    };
}

})();

require('es5-shim');
require('es5-shim/es5-sham');

(function () {

if (typeof console === 'undefined') {
    window.console = {};
    window.console.log = function () {};
}

})();

Remove no longer necessary IE8 shims


var moment = require('moment');

// NOTE: month indices are zero-based

module.exports.DATA_START_YEAR = 2012;
module.exports.DATA_START_MONTH = 0;
module.exports.DATA_START_MOMENT = moment([
  module.exports.DATA_START_YEAR,
  module.exports.DATA_START_MONTH]).startOf('month');

module.exports.DATA_END_YEAR = 2015;
module.exports.DATA_END_MONTH = 10;
module.exports.DATA_END_MOMENT = moment([
	module.exports.DATA_END_YEAR,
	module.exports.DATA_END_MONTH]).endOf('month');

module.exports.ASYLUM_APPLICANTS_DATA_UPDATED_MOMENT = moment([2016, 1, 5]);

module.exports.disableLabels = ['BIH', 'MKD', 'ALB', 'LUX', 'MNE', 'ARM', 'AZE', 'LBN'];

module.exports.fullRange = [module.exports.DATA_START_MOMENT.unix(), module.exports.DATA_END_MOMENT.unix()];

module.exports.labelShowBreakPoint = 992;

var moment = require('moment');

// NOTE: month indices are zero-based

module.exports.DATA_START_YEAR = 2012;
module.exports.DATA_START_MONTH = 0;
module.exports.DATA_START_MOMENT = moment([
  module.exports.DATA_START_YEAR,
  module.exports.DATA_START_MONTH]).startOf('month');

module.exports.DATA_END_YEAR = 2015;
module.exports.DATA_END_MONTH = 11;
module.exports.DATA_END_MOMENT = moment([
  module.exports.DATA_END_YEAR,
  module.exports.DATA_END_MONTH]).endOf('month');

module.exports.ASYLUM_APPLICANTS_DATA_UPDATED_MOMENT = moment([2016, 1, 5]);

module.exports.disableLabels = ['BIH', 'MKD', 'ALB', 'LUX', 'MNE', 'ARM', 'AZE', 'LBN'];

module.exports.fullRange = [module.exports.DATA_START_MOMENT.unix(), module.exports.DATA_END_MOMENT.unix()];

module.exports.labelShowBreakPoint = 992;

Extend visualisation period until end of 2015


var expect = require('expect.js');
var ignore = require('../lib/ignore');

describe('ignoring files', function() {
  it('determine if a directory matches an ignore glob', function () {
    expect(ignore.match('/.git')).to.be(true);
    expect(ignore.match('/dir')).to.be(false);
  });

  it('determines if a file matches an ignore glob', function () {
    expect(ignore.match('/.git/somefile.js')).to.be(true);
    expect(ignore.match('/somdir/somefile.js')).to.be(false);
  });
})

var expect = require('expect.js');
var ignore = require('../lib/ignore');

describe('ignoring files', function() {
  it('determine if a directory matches an ignore glob', function () {
    expect(ignore.match('/.git')).to.be(true);
    expect(ignore.match('.DS_STORE')).to.be(true);
    expect(ignore.match('/dir')).to.be(false);
  });

  it('determines if a file matches an ignore glob', function () {
    expect(ignore.match('/.git/somefile.js')).to.be(true);
    expect(ignore.match('/somdir/somefile.js')).to.be(false);
  });
})

Test for ignoring Mac DS_STORE


var utils = require("radiodan-client").utils,
    logger = utils.logger(__filename);

module.exports = routes;

function routes(app, radiodan, bbcServices) {
  var avoidPlayer    = radiodan.player.get("avoider"),
      mainPlayer     = radiodan.player.get("main"),
      announcePlayer = radiodan.player.get("announcer"),
      Avoider        = require("./avoider")(
          bbcServices, mainPlayer, avoidPlayer
      ),
      settings       = require("./settings").create();

    app.get("/", index);
    app.get("/avoid", avoid);

    return app;

  function index(req, res) {
    settings.get().then(function(settings) {
      res.render(
        __dirname+"/views/index",
        { settings: JSON.stringify(settings) }
      );
    }).then(null, utils.failedPromiseHandler(logger));
  }

  function avoid(req, res) {
    bbcServices.ready.then(function() {
      var radio1 = bbcServices.cache["radio1"].audioStream[0].url,
          radio4 = bbcServices.cache["radio4/fm"].audioStream[0].url;

      mainPlayer.add({playlist: [radio1], clear: true})
        .then(mainPlayer.play)
        .then(function() {
          avoidPlayer.add({playlist: [radio4], clear: true});
        })
        .then(function() {
          setTimeout(Avoider.create("radio1").avoid, 5000);
        });

      res.redirect("./");
    }, utils.failedPromiseHandler(logger));
  }
}

var utils = require("radiodan-client").utils,
    logger = utils.logger(__filename);

module.exports = routes;

function routes(app, radiodan, bbcServices) {
  var avoidPlayer    = radiodan.player.get("avoider"),
      mainPlayer     = radiodan.player.get("main"),
      announcePlayer = radiodan.player.get("announcer"),
      Avoider        = require("./avoider")(
          bbcServices, mainPlayer, avoidPlayer
      ),
      settings       = require("./settings").create();

    app.get("/", index);
    app.get("/avoid", avoid);

    return app;

  function index(req, res) {
    settings.get().then(function(settings) {
      res.render(
        __dirname+"/views/index",
        { settings: JSON.stringify(settings) }
      );
    }).then(null, utils.failedPromiseHandler(logger));
  }

  function avoid(req, res) {
    bbcServices.ready.then(function() {
      var radio1 = bbcServices.get("radio1").audioStreams[0].url,
          radio4 = bbcServices.get("radio4").audioStreams[0].url;

      mainPlayer.add({playlist: [radio1], clear: true})
        .then(mainPlayer.play)
        .then(function() {
          avoidPlayer.add({playlist: [radio4], clear: true});
        })
        .then(function() {
          setTimeout(Avoider.create("radio1").avoid, 5000);
        });

      res.redirect("./");
    }, utils.failedPromiseHandler(logger));
  }
}

Update avoider's use of BBCServices


'use strict';

module.exports = function (config) {
  config.set({
    basePath: '../',
    frameworks: ['browserify', 'mocha'],
    plugins: [
      'karma-browserify',
      'karma-phantomjs-launcher',
      'karma-mocha',
      'karma-mocha-reporter'
    ],
    browsers: ['PhantomJS'],
    port: 7357,
    reporters: ['mocha'],
    preprocessors: {
      '**/*.js': ['browserify']
    },
    browserify: {
      extensions: ['.js', '.json'],
      transform: require('../../package.json').browserify.transform,
      ignore: [],
      watch: true,
      debug: true,
      noParse: []
    },
    files: [
      '**/*.js'
    ],
    exclude: ['**/*.swp']
  });
};

'use strict';

module.exports = function (config) {
  config.set({
    basePath: '../',
    frameworks: ['browserify', 'mocha'],
    plugins: [
      'karma-browserify',
      'karma-phantomjs-launcher',
      'karma-mocha',
      'karma-mocha-reporter'
    ],
    browsers: ['PhantomJS'],
    port: 7357,
    reporters: ['mocha'],
    preprocessors: {
      '**/*.js': ['browserify']
    },
    browserify: {
      extensions: ['.js', '.json'],
      transform: require('../../package.json').browserify.transform,
      ignore: [],
      watch: true,
      debug: true,
      noParse: []
    },
    files: [
      '**/*.js'
    ],
    exclude: [
      '**/*.swp',
      '**/publishing/*.js'
    ]
  });
};

Exclude publishing tests from unit tests


'use strict';

/* Controllers */

angular.module('myApp.controllers', []).
  controller('AppCtrl', function($scope) {
    $scope.website = {url: ''};
    $scope.check = function() {
      var url = $scope.website.url;
      if (url !== "") {
        $scope.makeRequest(url, $scope.handleRequest);
      }
    }
    $scope.handleRequest = function(code, body) {
      writeTitle();

      if (code === 200) {
        writeMessage(body.message);
      } else {
        writeError(body.error);
      }
    }
    $scope.makeRequest = function(url, cb) {
      console.log(url);
      var http = new XMLHttpRequest();
      console.log(encodeURIComponent(url))
      http.open("GET", "/?url=" + encodeURIComponent(url), true);
      http.onreadystatechange = function() {
        if (http.readyState == 4) {
          console.log(http.responseText)
          cb(http.status, JSON.parse(http.responseText));
        }
      };
      http.send(null);
    }
  });

'use strict';

/* Controllers */

angular.module('myApp.controllers', []).
  controller('AppCtrl', function($scope, $http) {
    $scope.website = {url: ''};
    $scope.check = function() {
      var url = $scope.website.url;
      if (url !== "") {
        $scope.makeRequest(url);
      }
    }
    $scope.makeRequest = function(url) {
      $http({method: 'GET', url: "/?url=" +encodeURIComponent(url)}).
        success(function(data, status, headers, config) {
          console.log(status);
          console.log(data);
        }).
        error(function(data, status, headers, config) {
          console.log(status);
        });
    }
  });

Use to make GET request


// Tests FileLoader.Promise with the Promises / A+ Test Suite (https://github.com/promises-aplus/promises-tests)
require("./support/titanium");
var expect             = require("chai").expect;
var promisesAplusTests = require("promises-aplus-tests").mocha;
var FileLoader         = require("file_loader");

function getAdapter(Promise) {
  return {
    deferred: Promise.defer
  };
}

describe("Promises/A+ Tests", function () {
  promisesAplusTests(getAdapter(FileLoader.Promise));
});

// Tests FileLoader.Promise with the Promises / A+ Test Suite (https://github.com/promises-aplus/promises-tests)
// Includes tests for custom features.
require("./support/titanium");
var expect             = require("chai").expect;
var promisesAplusTests = require("promises-aplus-tests").mocha;
var FileLoader         = require("file_loader");

function getAdapter(Promise) {
  return {
    deferred: Promise.defer
  };
}

describe("Promises/A+ Tests", function () {
  promisesAplusTests(getAdapter(FileLoader.Promise));
});

describe("Promise Extentions", function(){
  var adapter = getAdapter(FileLoader.Promise);
  this.timeout(200);

  describe("#progress / #notify", function() {
    beforeEach(function() {
      this.deferred = adapter.deferred();
    });

    it("calls the onProgress function", function(done) {
      this.deferred.promise.progress(function(v) {
        expect( v ).to.equal("test");
        done();
      });
      this.deferred.notify("test");
    });

    it("calls the onProgress function when chained", function(done) {
      function onFullfilled(v) { return v; }
      this.deferred.promise
        .then(onFullfilled)
        .then(onFullfilled)
        .progress(function(v) {
          expect( v ).to.equal("test");
          done();
        }).done();
      this.deferred.notify("test");
    });

    it("accepts onProgress via then() function");

    it("does a noop if promise is fulfilled/rejected");
  });

  describe("#get", function() {
    it("returns the value from the promises's value object");

    it("rejects the promise if the object does not have requested property");
  });

  describe("#invoke", function() {
    it("calls the function on the promise's value object");

    it("rejects promise if object does not have requested function");
  });

  describe("#fin", function() {
    it("calls function on resolved");

    it("calls function on rejected");

    it("returns the same promise");
  });
});

Add initial specs for custom features (pending)


/* global describe it */
var path = require('path')
var chai = require('chai')
var shell = require('shelljs')

var expect = chai.expect

var INDEX_JS = path.join(__dirname, '/../index.js')
var PUML = 'node ' + INDEX_JS

describe('node-plantuml CLI', function () {
  describe('#encode', function () {
    it('should generate file into png stream', function () {
      var cli = shell.exec(PUML + ' encode "A -> B: Hello"', {silent: true})
      expect(cli.output).to.equal('UDfpLD2rKt2oKl18pSd91m0KGWDz\n')
    })
  })
})

/* global describe it */
var path = require('path')
var chai = require('chai')
var shell = require('shelljs')

var expect = chai.expect

var INDEX_JS = path.join(__dirname, '/../index.js')
var PUML = 'node ' + INDEX_JS

describe('node-plantuml CLI', function () {
  describe('#encode', function () {
    it('should encode "A -> B: Hello"', function () {
      var cli = shell.exec(PUML + ' encode "A -> B: Hello"', {silent: true})
      expect(cli.output).to.equal('UDfpLD2rKt2oKl18pSd91m0KGWDz\n')
    })
  })
})

Fix description of CLI encode test


module.exports = {
  scenarios: [
    {
      name: 'default',
      dependencies: { }
    },
    {
      name: 'ember-1.13.X',
      dependencies: {
        'ember': '1.13.10'
      }
    },
    {
      name: 'ember-release',
      dependencies: {
        'ember': 'components/ember#release'
      },
      resolutions: {
        'ember': 'release'
      }
    },
    {
      name: 'ember-beta',
      dependencies: {
        'ember': 'components/ember#beta'
      },
      resolutions: {
        'ember': 'beta'
      }
    },
    {
      name: 'ember-canary',
      dependencies: {
        'ember': 'components/ember#canary'
      },
      resolutions: {
        'ember': 'canary'
      }
    }
  ]
};

module.exports = {
  scenarios: [
    {
      name: 'default',
      dependencies: { }
    },
    {
      name: 'ember-1.12.X',
      dependencies: {
        'ember': '1.12.1'
      }
    },
    {
      name: 'ember-1.13.X',
      dependencies: {
        'ember': '1.13.10'
      }
    },
    {
      name: 'ember-release',
      dependencies: {
        'ember': 'components/ember#release'
      },
      resolutions: {
        'ember': 'release'
      }
    },
    {
      name: 'ember-beta',
      dependencies: {
        'ember': 'components/ember#beta'
      },
      resolutions: {
        'ember': 'beta'
      }
    },
    {
      name: 'ember-canary',
      dependencies: {
        'ember': 'components/ember#canary'
      },
      resolutions: {
        'ember': 'canary'
      }
    }
  ]
};

Fix add Ember Try config for 1.12.X


module.exports = {
  fonts: {
    files: [{
      expand: true,
      cwd: 'node_modules/cartoassets/src/fonts',
      src: ['**/*'],
      dest: '<%= config.dist %>/fonts/'
    }]
  }
}

module.exports = {
  fonts: {
    files: [{
      expand: true,
      cwd: 'node_modules/cartoassets/src/fonts',
      src: ['**/*'],
      dest: '<%= config.dist %>/themes/fonts'
    }]
  }
}

Move fonts inside themes, at css level


'use strict';

var csslint = require('../lib/csslint'),
    fs = require('fs'),
    path = require('path');

var formatter = csslint.getFormatter('compact');

module.exports = (function() {
    var tests = {};

    fs.readdirSync('test/less').forEach(function(file) {
        if (!/\.less/.test(file)) {
            return;
        }

        if (file === 'utility.less') {
            return;
        }

        tests[file] = function(test) {
            var basename = path.basename(file, '.less');
            file = path.join('test/less', file);

            test.expect(4);

            fs.readFile(file, 'utf8', function(err, data) {
                test.ifError(err);

                csslint.verify(file, data, csslint.getRuleset(), function(err, results) {
                    test.ifError(err);

                    fs.readFile(path.join('test/less', basename + '.txt'), 'utf8', function(err, expectedResults) {
                        test.ifError(err);
                        test.equal(formatter.formatResults(results, file), expectedResults);
                        test.done();
                    });
                });
            });
        };
    });

    return tests;
}());

'use strict';

var csslint = require('../lib/csslint'),
    fs = require('fs'),
    path = require('path');

var formatter = csslint.getFormatter('compact');

module.exports = (function() {
    var tests = {};

    fs.readdirSync('test/less').forEach(function(file) {
        if (!/\.less/.test(file)) {
            return;
        }

        tests[file] = function(test) {
            var basename = path.basename(file, '.less');
            file = path.join('test/less', file);

            test.expect(4);

            fs.readFile(file, 'utf8', function(err, data) {
                test.ifError(err);

                csslint.verify(file, data, csslint.getRuleset(), function(err, results) {
                    test.ifError(err);

                    fs.readFile(path.join('test/less', basename + '.txt'), 'utf8', function(err, expectedResults) {
                        test.ifError(err);
                        test.equal(formatter.formatResults(results, file), expectedResults);
                        test.done();
                    });
                });
            });
        };
    });

    return tests;
}());

Enable a test case which was failing previously.


import path from 'path'
import postcss from 'postcss'
import tailwind from '../src/index'

test('it uses the values from the custom config file', () => {
  return postcss([tailwind(path.resolve(`${__dirname}/fixtures/customConfig.js`))])
    .process(
      `
        @responsive {
          .foo {
            color: blue;
          }
        }
      `,
      { from: undefined }
    )
    .then(result => {
      const expected = `
        .foo {
          color: blue;
        }
        @media (min-width: 400px) {
          .mobile\\:foo {
            color: blue;
          }
        }
      `

      expect(result.css).toMatchCss(expected)
    })
})

test('custom config can be passed as an object', () => {
  return postcss([tailwind({
    screens: {
      mobile: '400px',
    },
  })])
    .process(
      `
        @responsive {
          .foo {
            color: blue;
          }
        }
      `,
      { from: undefined }
    )
    .then(result => {
      const expected = `
        .foo {
          color: blue;
        }
        @media (min-width: 400px) {
          .mobile\\:foo {
            color: blue;
          }
        }
      `

      expect(result.css).toMatchCss(expected)
    })
})

Test config can be passed as object instead of path


import { tracked } from '@glimmer/tracking';
import { Resource } from 'ember-could-get-used-to-this';
export default class AsyncProcessResource extends Resource {
  @tracked data;

  get value() {
    return this.data;
  }

  async setup() {
    const fn = this.args.positional[0];

    //pass any remaining arguments directly to the processor function
    this.data = await fn(...this.args.positional.slice(1));
  }
}

import { tracked } from '@glimmer/tracking';
import { Resource } from 'ember-could-get-used-to-this';
export default class AsyncProcessResource extends Resource {
  @tracked data;

  get value() {
    return this.data;
  }

  async setup() {
    const fn = this.args.positional[0];

    //pass any remaining arguments directly to the processor function
    const promise = fn(...this.args.positional.slice(1));
    this.data = promise;
    this.data = await promise;
  }
}

Return the promise before it is resolved


'use strict';

angular
  .module('mwl.calendar')
  .provider('calendarConfig', function() {

    var defaultDateFormats = {
      hour: 'ha',
      day: 'D MMM',
      month: 'MMMM',
      // CUSTOMIZATION: change to dd for Sa Su Mo Tu We Th Fr
      // weekDay: 'ddd'
      weekDay: 'dddd'
    };

    var defaultTitleFormats = {
      day: 'dddd D MMMM, YYYY',
      week: 'Week {week} of {year}',
      month: 'MMMM YYYY',
      year: 'YYYY'
    };

    var i18nStrings = {
      eventsLabel: 'Events',
      timeLabel: 'Time'
    };

    var configProvider = this;

    configProvider.setDateFormats = function(formats) {
      angular.extend(defaultDateFormats, formats);
      return configProvider;
    };

    configProvider.setTitleFormats = function(formats) {
      angular.extend(defaultTitleFormats, formats);
      return configProvider;
    };

    configProvider.setI18nStrings = function(strings) {
      angular.extend(i18nStrings, strings);
      return configProvider;
    };

    configProvider.$get = function() {
      return {
        dateFormats: defaultDateFormats,
        titleFormats: defaultTitleFormats,
        i18nStrings: i18nStrings
      };
    };

  });

'use strict';

angular
  .module('mwl.calendar')
  .provider('calendarConfig', function() {

    var defaultDateFormats = {
      hour: 'ha',
      day: 'D MMM',
      month: 'MMMM',
      // CUSTOMIZATION: change to dd for Sa Su Mo Tu We Th Fr
      // weekDay: 'ddd'
      weekDay: 'ddd'
    };

    var defaultTitleFormats = {
      day: 'dddd D MMMM, YYYY',
      week: 'Week {week} of {year}',
      month: 'MMMM YYYY',
      year: 'YYYY'
    };

    var i18nStrings = {
      eventsLabel: 'Events',
      timeLabel: 'Time'
    };

    var configProvider = this;

    configProvider.setDateFormats = function(formats) {
      angular.extend(defaultDateFormats, formats);
      return configProvider;
    };

    configProvider.setTitleFormats = function(formats) {
      angular.extend(defaultTitleFormats, formats);
      return configProvider;
    };

    configProvider.setI18nStrings = function(strings) {
      angular.extend(i18nStrings, strings);
      return configProvider;
    };

    configProvider.$get = function() {
      return {
        dateFormats: defaultDateFormats,
        titleFormats: defaultTitleFormats,
        i18nStrings: i18nStrings
      };
    };

  });

Change default day format to 3-letter day.


"use strict";

var debug = require('debug')('socket');
var io = require('socket.io')();
var room = require('./room');

exports.attach = function (server) {
  io.attach(server);
};

var sessionParser = null;
exports.setSessionParser = function (parser) {
  sessionParser = parser;
};

function initialize(socket) {
  socket.on('lobby/connect', function () {
    var lobby = room.get('lobby');

    lobby.join(socket);

    var updateUserList = function () {
      var userList = lobby.sockets.map(function (userSocket) {
        return {
          username: userSocket.username,
          me: userSocket.username === socket.username
        };
      });
      socket.emit('lobby/userList', {userList: userList});
    };

    socket.on('lobby/join', updateUserList);
    socket.on('lobby/leave', updateUserList);
  });

  socket.on('disconnect', function () {
    debug('-1 socket connection');
  });
}

io.on('connection', function (socket) {
  if (!sessionParser) {
    console.log('no session parser!');
    socket.disconnect();
    return;
  }

  debug('+1 socket connection');
  sessionParser(socket, function (err, session) {
    if (err || !session) {
      socket.disconnect();
      return;
    }

    socket.username = session.username;
    initialize(socket);
  });
});

"use strict";

var debug = require('debug')('socket');
var error = require('debug')('error');
var io = require('socket.io')();
var room = require('./room');

exports.attach = function (server) {
  io.attach(server);
};

var sessionParser = null;
exports.setSessionParser = function (parser) {
  sessionParser = parser;
};

function initialize(socket) {
  socket.on('lobby/connect', function () {
    var lobby = room.get('lobby');

    lobby.join(socket);

    var updateUserList = function () {
      var userList = lobby.sockets.map(function (userSocket) {
        return {
          username: userSocket.username,
          me: userSocket.username === socket.username
        };
      });
      socket.emit('lobby/userList', {userList: userList});
    };

    socket.on('lobby/join', updateUserList);
    socket.on('lobby/leave', updateUserList);
  });

  socket.on('disconnect', function () {
    debug('-1 socket connection');
  });
}

io.on('connection', function (socket) {
  if (!sessionParser) {
    error('no session parser!');
    socket.disconnect();
    return;
  }

  debug('+1 socket connection');
  sessionParser(socket, function (err, session) {
    if (err || !session) {
      socket.disconnect();
      return;
    }

    socket.username = session.username;
    initialize(socket);
  });
});

Change console.log to error using debug module.


var swig = require('swig');
var http = require('http');
var url = require('url');

var output = swig.renderFile('./opensearch-template/chrome-splunk.xml', {
        host: 'localhost',
        port: '8000'
});

console.log(output);

// TODO: Loop through all browsers and render open search provider xml
var testRendering = function () {

}

// TODO: Render, using browser to find template xml file
var renderBrowser = function (host, port, https, browser) {

}

var swig = require('swig');
var http = require('http');
var url = require('url');

var broswers = [ 'firefox', 'chrome', 'ie-7-8', 'ie-9-10-11', 'edge' ]

var output = swig.renderFile('./opensearch-template/chrome-splunk.xml', {
        host: 'localhost',
        port: '8000'
});

//console.log(output);

// TODO: Loop through all browsers and render open search provider xml
var testRendering = function () {
    broswers.forEach( function (browser) {
        console.log('----------------------' + browser + '----------------------');
        console.log(renderBrowser('localhost','8000', false, browser));
        renderAndSave('localhost','8000',false, browser);
    });

}

// TODO: Render, using browser to find template xml file
var renderBrowser = function (host, port, https, browser) {
    var file = './opensearch-template/' + browser + '-splunk.xml';
    var output = swig.renderFile(file, {
        host: host,
        port: port,
        https: https
    });

    return output;
}

var render = function (host, port, https) {
}
var renderAndSave = function (host, port, https, browser) {
    var output = renderBrowser(host, port, https, browser);
    var file = '';
    [host, port, https, browser].forEach( function (item) {
        file = filea + item + '-'
    });
    file = file + 'spunk.xml';
    console.log(file);
}

testRendering();

Add functionatlity for rendering all browser


/**
 * External dependencies
 */
import { storiesOf } from '@storybook/react';
import PageHeader from 'GoogleComponents/page-header';

storiesOf( 'Global', module )
	.add( 'Page Headers', () => (

				<PageHeader
					title="Module Page Title"
					status="connected"
					statusText="Analytics is connected"
				/>

				<PageHeader
					title="Module Page Title with Icon"
					icon
					iconWidth="23"
					iconHeight="26"
					iconID="analytics"
					status="not-connected"
					statusText="Analytics is not connected"
				/>

	) );

/**
 * External dependencies
 */
import { storiesOf } from '@storybook/react';
import PageHeader from 'GoogleComponents/page-header';
/**
 * WordPress dependencies
 */
import { removeAllFilters } from '@wordpress/hooks';

storiesOf( 'Global', module )
	.add( 'Page Headers', () => {
		removeAllFilters( 'googlesitekit.showDateRangeSelector-analytics' );
		return

				<PageHeader
					title="Module Page Title"
					status="connected"
					statusText="Analytics is connected"
				/>

				<PageHeader
					title="Module Page Title with Icon"
					icon
					iconWidth="23"
					iconHeight="26"
					iconID="analytics"
					status="not-connected"
					statusText="Analytics is not connected"
				/>

;
	} );

Set reset showDateRangeSelector for PageHeader VRT.


Template.registerHelper('preview', function(value, options) {
  var length = options.hash.length || 140;
  var content = value.replace(/<(?:.|\n)*?>/gm, ' ');
  if(content.length > length) content = content.substring(0, length-1).trim() + '…';
  return content;
});

Template.registerHelper('date', function(date) {
  return moment(date).format('lll');
});

Template.registerHelper('preview', function(value, options) {
  if (!value) return;
  var length = options.hash.length || 140;
  var content = value.replace(/<(?:.|\n)*?>/gm, ' ');
  if(content.length > length) content = content.substring(0, length-1).trim() + '…';
  return content;
});

Template.registerHelper('date', function(date) {
  return moment(date).format('lll');
});

Fix preview of bodies with no content


'use strict';

var gulp = require('gulp');

var paths = gulp.paths;

var $ = require('gulp-load-plugins')();

gulp.task('markups', function() {
  function renameToHtml(path) {
    path.extname = '.html';
  }

  return gulp.src(paths.src + '/{app,components}/**/*.<%= props.htmlPreprocessor.extension %>')
<% if (props.htmlPreprocessor.key === 'jade') { %>
    .pipe($.consolidate('jade', { pretty: '  ' }))
<% } else if (props.htmlPreprocessor.key === 'haml') { %>
    .pipe($.consolidate('hamljs'))
<% } else if (props.htmlPreprocessor.key === 'handlebars') { %>
    .pipe($.consolidate('handlebars'))
<% } %>
    .pipe($.rename(renameToHtml))
    .pipe(gulp.dest(paths.tmp + '/serve/'));
});

'use strict';

var gulp = require('gulp');

var paths = gulp.paths;

var $ = require('gulp-load-plugins')();

gulp.task('markups', function() {
  function renameToHtml(path) {
    path.extname = '.html';
  }

  return gulp.src(paths.src + '/{app,components}/**/*.<%= props.htmlPreprocessor.extension %>')
<% if (props.htmlPreprocessor.key === 'jade') { %>
    .pipe($.consolidate('jade', { pretty: '  ' }))
<% } else if (props.htmlPreprocessor.key === 'haml') { %>
    .pipe($.consolidate('hamljs'))
<% } else if (props.htmlPreprocessor.key === 'handlebars') { %>
    .pipe($.consolidate('handlebars'))
<% } %>
    .on('error', function handleError(err) {
      console.error(err.toString());
      this.emit('end');
    })
    .pipe($.rename(renameToHtml))
    .pipe(gulp.dest(paths.tmp + '/serve/'));
});

Add error handler on html preprocessing


module.exports = Dom;

function Dom () { }

Dom.prototype.XMLHttpRequest = XMLHttpRequest;

Dom.prototype.getHTMLElement = function () {
  return document.getElementsByTagName('html')[0];
};

Dom.prototype.getBodyElement = function () {
  return document.body;
};

Dom.prototype.getElementById = function (id) {
  return document.getElementById(id);
};

Dom.prototype.getLocationHash = function () {
  return window.location.hash;
};

Dom.prototype.setLocationHash = function (hash) {
  if (typeof window.history.replaceState === 'function' && document.origin !== 'null') {
    window.history.replaceState(undefined, undefined, hash);
  }
  else {
    window.location.hash = hash;
  }
};

module.exports = Dom;

function Dom () { }

Dom.prototype.XMLHttpRequest = XMLHttpRequest;

Dom.prototype.getHTMLElement = function () {
  return document.getElementsByTagName('html')[0];
};

Dom.prototype.getBodyElement = function () {
  return document.body;
};

Dom.prototype.getElementById = function (id) {
  return document.getElementById(id);
};

Dom.prototype.getLocationHash = function () {
  return window.location.hash;
};

Dom.prototype.setLocationHash = function (hash) {
  if (typeof window.history.replaceState === 'function' && window.origin !== 'null') {
    window.history.replaceState(undefined, undefined, hash);
  }
  else {
    window.location.hash = hash;
  }
};

Change document.origin to window.origin on DOM JS


'use strict';

angular.module('scegratooApp')
.service('Project', function Project($resource, $http) {
  // AngularJS will instantiate a singleton by calling "new" on this function
  var apiRoot = 'api/v1'
  var route = apiRoot + '/projects/:project.:format'
  var resource = $resource(route, {format: 'json'})
  return {
    get: function(params, fn) {
      if (params.file) {
        var url = [
          apiRoot,
          'projects',
          encodeURI(params.project),
          encodeURI(params.file)
        ].join('/')
        var res = $resource(url, {}, {
          get: {method: 'GET', transformResponse: function(data) {
            return {data: data}
          }}
        })
        return res.get(fn)
      } else {
        return resource.get(params, fn)
      }
    },
    query: resource.query
    // getFile: function(params) {
    //   var url = [
    //     apiRoot,
    //     'projects',
    //     encodeURI(params.project),
    //     encodeURI(params.file)
    //   ].join('/')
    //   return $http.get(url)
    // }
  }
})

'use strict';

angular.module('scegratooApp')
.service('Project', function Project($resource, $http, Constants) {
  // AngularJS will instantiate a singleton by calling "new" on this function
  var route = Constants.apiRoot + '/projects/:project.:format'
  var resource = $resource(route, {format: 'json'})
  return {
    get: function(params, fn) {
      if (params.file) {
        var url = [
          Constants.apiRoot,
          'projects',
          encodeURI(params.project),
          encodeURI(params.file)
        ].join('/')
        var res = $resource(url, {}, {
          get: {method: 'GET', transformResponse: function(data) {
            return {data: data}
          }}
        })
        return res.get(fn)
      } else {
        return resource.get(params, fn)
      }
    },
    query: resource.query
    // getFile: function(params) {
    //   var url = [
    //     apiRoot,
    //     'projects',
    //     encodeURI(params.project),
    //     encodeURI(params.file)
    //   ].join('/')
    //   return $http.get(url)
    // }
  }
})

Use Constants service instead of hardcoded apiRoot


/*global describe,it*/
'use strict';
var assert = require('assert'),
  <%= safeSlugname %> = require('../lib/<%= slugname %>.js');

describe('<%= slugname %> node module.', function() {
  it('must be awesome', function() {
    assert.equal( <%= safeSlugname %>.awesome(), 'awesome');
  });
});

/*global describe,it*/
'use strict';
var assert = require('assert'),
  <%= safeSlugname %> = require('../lib/<%= slugname %>.js');

describe('<%= slugname %> node module', function() {
  it('must be awesome', function() {
    assert.equal( <%= safeSlugname %>.awesome(), 'awesome');
  });
});

describe('<%= slugname %> node module', function() {
  it('must have at least one test', function() {
    assert(false, 'I was too lazy to write any tests. Shame on me.');
  });
});

Add failing test example to scaffolded tests


var express = require('express');
var router = express.Router();
var JsonDB = require('node-json-db');

// Recipes listing
router.get('/', function (req, res, next) {
  var db = new JsonDB('db', false, false);
  var recipes = db.getData('/recipes');
  res.json(recipes);
});

module.exports = router;

var express = require('express');
var router = express.Router();
var JsonDB = require('node-json-db');
var _ = require('lodash');

// Recipes listing
router.get('/', function (req, res, next) {
  var db = new JsonDB('db', false, false);
  var recipes = db.getData('/recipes');

  // Expand requested resources if they exist
  // Users and ingredients for the recipes are loaded
  if (!_.isUndefined(req.query._expand)) {
    var users = db.getData('/users');
    _(recipes)
      .forEach(function (recipe) {
        recipe.user = _(users).findWhere({ id: recipe.userId });
        delete recipe.userId;
      })
      .value();
  }

  res.json(recipes);
});

module.exports = router;

Add recipe listing with optional expansion of properties


// Events are in the Backbone form of
// {
//   '[type] [selector]':'[function]'
// }
// where selector may have a space, e.g. 'foo > bar'
function DOMViewMixin(view) {
  var _this = this;
  var events = view.events || {};
  for (var key in events) {
    if (events.hasOwnProperty(key)) {
      var firstSpaceIndex = key.indexOf(' ');
      var type = key.substr(0, firstSpaceIndex);
      var selector = key.substr(firstSpaceIndex + 1);
      var fn = events[key];
      (function(fn) {
        view.$el.find(selector)[type](function(event) {
          if (_this[fn] === undefined) {
            throw new Error('mixin target has no function: ' + fn);
          }
          _this[fn](event);
        });
      })(fn);
    }
  }
}

module.exports = DOMViewMixin;

// Events are in the Backbone form of
// {
//   '[type] [selector]':'[function]'
//   '[type]'           :'[function]'
// }
// where selector may have a space, e.g. 'foo > bar'
function DOMViewMixin(view) {
  var _this = this;
  var events = view.events || {};
  for (var key in events) {
    if (events.hasOwnProperty(key)) {
      var firstSpaceIndex = key.indexOf(' ');
      // Event on root element
      var type;
      var selector;
      if (firstSpaceIndex === -1) {
        type = key;
      } else {
        type = key.substr(0, firstSpaceIndex);
        selector = key.substr(firstSpaceIndex + 1);
      }
      var fn = events[key];
      (function(fn) {
        var elem = (selector === undefined) ? view.$el : view.$el.find(selector);
        if (!elem.length) {
          console.warn('no selector "' + selector + '" on view');
        }
        elem[type](function(event) {
          if (_this[fn] === undefined) {
            throw new Error('mixin target has no function: ' + fn);
          }
          _this[fn](event);
        });
      })(fn);
    }
  }
}

module.exports = DOMViewMixin;

Support event on root element


import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import Box from '../box';
import cx from 'classnames';
import theme from './theme.css';

class AvatarStack extends PureComponent {
  static propTypes = {
    children: PropTypes.node,
    className: PropTypes.string,
    direction: PropTypes.oneOf(['horizontal', 'vertical']),
    displayMax: PropTypes.number,
    inverse: PropTypes.bool,
    onOverflowClick: PropTypes.func,
    size: PropTypes.oneOf(['tiny', 'small', 'medium']),
  };

  static defaultProps = {
    direction: 'horizontal',
    displayMax: 0,
    inverse: false,
    size: 'medium',
  };

  render() {
    const { children, className, direction, displayMax, inverse, onOverflowClick, size, ...others } = this.props;

    const classNames = cx(
      theme['stack'],
      theme[direction],
      theme[size],
      inverse ? [theme['light']] : [theme['dark']],
      className,
    );

    const childrenToDisplay = displayMax > 0 ? children.slice(0, displayMax) : children;
    const overflowAmount = children.length - displayMax;

    return (
      <Box data-teamleader-ui="avatar-stack" className={classNames} {...others}>
        {overflowAmount !== children.length && (

{`+${overflowAmount}`}

        )}
        {childrenToDisplay}
      </Box>
    );
  }
}

export default AvatarStack;

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import Box from '../box';
import cx from 'classnames';
import theme from './theme.css';

class AvatarStack extends PureComponent {
  render() {
    const { children, className, direction, displayMax, inverse, onOverflowClick, size, ...others } = this.props;

    const classNames = cx(
      theme['stack'],
      theme[direction],
      theme[size],
      inverse ? [theme['light']] : [theme['dark']],
      className,
    );

    const childrenToDisplay = displayMax > 0 ? children.slice(0, displayMax) : children;
    const overflowAmount = children.length - displayMax;

    return (
      <Box data-teamleader-ui="avatar-stack" className={classNames} {...others}>
        {overflowAmount !== children.length && (

{`+${overflowAmount}`}

        )}
        {childrenToDisplay}
      </Box>
    );
  }
}

AvatarStack.propTypes = {
  children: PropTypes.node,
  className: PropTypes.string,
  direction: PropTypes.oneOf(['horizontal', 'vertical']),
  displayMax: PropTypes.number,
  inverse: PropTypes.bool,
  onOverflowClick: PropTypes.func,
  size: PropTypes.oneOf(['tiny', 'small', 'medium']),
};

AvatarStack.defaultProps = {
  direction: 'horizontal',
  displayMax: 0,
  inverse: false,
  size: 'medium',
};

export default AvatarStack;

Move propTypes & defaultProps outside of the component class


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

const WeekDay = ({ weekday, className, localeUtils, locale, size }) => {
  const weekdayName = localeUtils.formatWeekdayLong(weekday, locale);

  return (
    <div className={className} title={weekdayName}>
      {size === 'large' ? weekdayName.slice(0, 2) : weekdayName.slice(0, 1)}
    </div>
  );
};

WeekDay.propTypes = {
  className: PropTypes.string,
  locale: PropTypes.string,
  localeUtils: PropTypes.object,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
  weekday: PropTypes.number,
};

export default WeekDay;

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

const WeekDay = ({ weekday, className, localeUtils, locale, size }) => {
  const weekdayName = localeUtils.formatWeekdayLong(weekday, locale);

  return (
    <div className={className} title={weekdayName}>
      {weekdayName.slice(0, size === 'large' ? 2 : 1)}
    </div>
  );
};

WeekDay.propTypes = {
  className: PropTypes.string,
  locale: PropTypes.string,
  localeUtils: PropTypes.object,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
  weekday: PropTypes.number,
};

export default WeekDay;

Write weekdayName.slice in a shorter way


import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

NProgress.configure({
	parent: '.header'
})

const API = {
	fetch(url, params) {
		params = params || {}
		params.credentials = 'same-origin'

		params.headers = params.headers || {}
		params.headers['Accept'] = 'application/json'

		API.startLoading()

		return window.fetch(url, params)
					.then(response => response.json())
					.then(response => {
						API.stopLoading()
						return response
					})
	},

	send(url, data, params) {
		params = params || {}
		params.method = params.method || 'POST'
		params.body = JSON.stringify(data)

		params.headers = params.headers || {}
		params.headers['Content-Type'] = 'application/json'

		return API.fetch(url, params)
	},

	query(query, variables) {
		query = 'query { ' + query + ' }'
		variables = variables || {}
		return API.send('/graphql', {query, variables}).then(json => json.data)
	},

	startLoading() {
		NProgress.start()
		NProgress.set(0.5)
	},

	stopLoading() {
		NProgress.done()
	},
}

export default API

import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

NProgress.configure({
	parent: '.header'
})

const API = {
	fetch(url, params) {
		params = params || {}
		params.credentials = 'same-origin'

		params.headers = params.headers || {}
		params.headers['Accept'] = 'application/json'

		if (params.showLoader !== false)
			API.startLoading()
		delete params.showLoader

		return window.fetch(url, params)
					.then(response => response.json())
					.then(response => {
						API.stopLoading()
						return response
					})
	},

	send(url, data, params) {
		params = params || {}
		params.method = params.method || 'POST'
		params.body = JSON.stringify(data)

		params.headers = params.headers || {}
		params.headers['Content-Type'] = 'application/json'

		return API.fetch(url, params)
	},

	query(query, variables) {
		query = 'query { ' + query + ' }'
		variables = variables || {}
		return API.send('/graphql', {query, variables}).then(json => json.data)
	},

	startLoading() {
		NProgress.start()
		NProgress.set(0.5)
	},

	stopLoading() {
		NProgress.done()
	},
}

export default API

Add an option to API.fetch to not trigger the loader


const spawn = require('spawndamnit');
const ember = `./node_modules/.bin/ember`;

const userName = process.env['BROWSERSTACK_USERNAME']
const accessKey = process.env['BROWSERSTACK_ACCESS_KEY']

const canConnectToBrowserStack =  (
  userName && userName.trim().length !== 0 &&
  accessKey && accessKey.trim().length !== 0
);

const hookupLoggers = (proc) => {
  proc.on('stdout', data => console.log(data.toString()));
  proc.on('stderr', data => console.error(data.toString()));
};

const execEmberProcess = async (cmd) => {
  let proc = spawn(ember, [cmd]);
  hookupLoggers(proc);
  try {
    await proc;
  } catch (e) {
    return process.exit(1);
  }
};

(async () => {
  if (canConnectToBrowserStack) {
    await execEmberProcess('browserstack:connect');
  }

  await execEmberProcess('exam');

  if (canConnectToBrowserStack) {
    await execEmberProcess('browserstack:results');
    await execEmberProcess('browserstack:disconnect');
  }

})();

const spawn = require('spawndamnit');
const ember = `./node_modules/.bin/ember`;

const userName = process.env['BROWSERSTACK_USERNAME']
const accessKey = process.env['BROWSERSTACK_ACCESS_KEY']

const canConnectToBrowserStack =  (
  userName && userName.trim().length !== 0 &&
  accessKey && accessKey.trim().length !== 0
);

const hookupLoggers = (proc) => {
  proc.on('stdout', data => console.log(data.toString()));
  proc.on('stderr', data => console.error(data.toString()));
};

const execEmberProcess = async (cmd) => {
  let proc = spawn(ember, [cmd]);
  hookupLoggers(proc);
  try {
    await proc;
  } catch (e) {
    return process.exit(1);
  }
};

(async () => {
  if (canConnectToBrowserStack) {
    await execEmberProcess('browserstack:connect');
  }

  await execEmberProcess('exam');

  if (canConnectToBrowserStack) {
    if (process.env['TRAVIS_JOB_NUMBER']) {
      await execEmberProcess('browserstack:results');
    }
    await execEmberProcess('browserstack:disconnect');
  }

})();

Access results only on travis


var loopback = require('loopback'),
    debug = require('debug')('openframe:isPublicOrOwner');

/**
 * This mixin requires a model to have 'is_public: true' or the current user
 * to be the object's owner in order to provide access.
 */
module.exports = function(Model, options) {
    Model.observe('access', function(reqCtx, next) {
        var appCtx = loopback.getCurrentContext(),
            currentUser = appCtx && appCtx.get('currentUser');

        debug('currentUser', currentUser);

        reqCtx.query.where = reqCtx.query.where || {};

        if (currentUser) {
            reqCtx.query.where.or = [
                {is_public: true},
                {ownerId: currentUser.id}
            ];
        } else {
            reqCtx.query.where.is_public = true;
        }

        next();
    });
};

var loopback = require('loopback'),
    debug = require('debug')('openframe:isPublicOrOwner');

/**
 * This mixin requires a model to have 'is_public: true' or the current user
 * to be the object's owner in order to provide access.
 */
module.exports = function(Model, options) {
    Model.observe('access', function(reqCtx, next) {
        var appCtx = loopback.getCurrentContext(),
            currentUser = appCtx && appCtx.get('currentUser');

        debug('currentUser', currentUser);

        reqCtx.query.where = reqCtx.query.where || {};

        if (currentUser && !reqCtx.query.where.is_public) {
            reqCtx.query.where.or = [
                {is_public: true},
                {ownerId: currentUser.id}
            ];
        } else {
            reqCtx.query.where.is_public = true;
        }

        next();
    });
};

Update is public access logic


import 'babel-polyfill';

import meow from 'meow';
import logSymbols from 'log-symbols';
import parseURL from './lib/parse-url';
import checkURL from './lib/check-url';

const cli = meow(`
    Example
      $ is-js-error example.com
      ${logSymbols.success} OK
`);

if (cli.input.length === 0) {
    console.error('Specify a URL');
    process.exit(1);
}

const url = parseURL(cli.input[0]);
const maxWait = Math.max(cli.flags.wait || cli.flags.w, 1000);

checkURL(url, maxWait, (err, results) => {
    if (err) {
        console.log(`${logSymbols.warning} ${err}`);
        process.exit(1);
    } else {
        const hasError = results[1];

        console.log(hasError ? `${logSymbols.error} KO` : `${logSymbols.success} OK`);
        process.exit(hasError ? 2 : 0);
    }
});

import 'babel-polyfill';

import meow from 'meow';
import logSymbols from 'log-symbols';
import parseURL from './lib/parse-url';
import checkURL from './lib/check-url';

const cli = meow(`
    Example
      $ is-js-error example.com
      ${logSymbols.success} OK
      $ is-js-error example.com --wait 3000
      ${logSymbols.success} OK

    Options
      --help,      Display this help
      --version,   Display the version number
      --wait [ms], Wait for a given period before reporting no error.
`);

if (cli.input.length === 0) {
    console.error('Specify a URL');
    process.exit(1);
}

const url = parseURL(cli.input[0]);
const maxWait = Math.max(cli.flags.wait, 1000);

checkURL(url, maxWait, (err, results) => {
    if (err) {
        console.log(`${logSymbols.warning} ${err}`);
        process.exit(1);
    } else {
        const hasError = results[1];

        console.log(hasError ? `${logSymbols.error} KO` : `${logSymbols.success} OK`);
        process.exit(hasError ? 2 : 0);
    }
});

Add documentation on wait parameter


import helperElement from '../lib/element';
import helperFixture from '../lib/fixture';
import helperReady from '../lib/ready';
import skate from '../../src/index';
import supportCustomElements from '../../src/support/custom-elements';

describe('lifecycle-scenarios', function () {
  it('definition is registered before the element is created', function (done) {
    var el = helperElement();
    var called = false;

    skate(el.safe, {
      created () {
        called = true;
      }
    });
    helperFixture(document.createElement(el.safe));

    if (supportCustomElements()) {
      expect(called).to.equal(true);
    } else {
      expect(called).to.equal(false);
      helperReady(function () {
        expect(called).to.equal(true);
        done();
      });
    }
  });

  it('definition is registered after the element is created', function (done) {
    var el = helperElement();
    var called = false;

    helperFixture(el.create());
    skate(el.safe, {
      created () {
        called = true;
      }
    });

    // We have to debounce in non-native for performance.
    if (supportCustomElements()) {
      expect(called).to.equal(true);
    } else {
      expect(called).to.equal(false);
      helperReady(function () {
        expect(called).to.equal(true);
        done();
      });
    }
  });
});

import helperElement from '../lib/element';
import helperFixture from '../lib/fixture';
import helperReady from '../lib/ready';
import skate from '../../src/index';
import supportCustomElements from '../../src/support/custom-elements';

describe('lifecycle-scenarios', function () {
  it('definition is registered before the element is created', function (done) {
    var el = helperElement();
    var called = false;

    skate(el.safe, {
      created () {
        called = true;
      }
    });
    helperFixture(document.createElement(el.safe));

    if (supportCustomElements()) {
      expect(called).to.equal(true);
      done();
    } else {
      expect(called).to.equal(false);
      helperReady(function () {
        expect(called).to.equal(true);
        done();
      });
    }
  });

  it('definition is registered after the element is created', function (done) {
    var el = helperElement();
    var called = false;

    helperFixture(el.create());
    skate(el.safe, {
      created () {
        called = true;
      }
    });

    // We have to debounce in non-native for performance.
    if (supportCustomElements()) {
      expect(called).to.equal(true);
      done();
    } else {
      expect(called).to.equal(false);
      helperReady(function () {
        expect(called).to.equal(true);
        done();
      });
    }
  });
});

Fix tests for browsers that support native custom elements.


/**
 * Configure Stylint
 *
 * @see https://stylelint.io/user-guide/configuration
 */
module.exports = {
  extends: ['stylelint-config-recommended']
};

/**
 * Configure Stylint
 *
 * https://github.com/stylelint/stylelint-config-recommended
 */
module.exports = {
  extends: ['stylelint-config-recommended']
};

Revert "Update stylelint config link"


(function () {
  'use strict';

  var app = angular.module('pie', ['chart.js']);

  app.directive('mySpecialPie', function (ChatJsFactory) { return new ChatJsFactory('Pie'); });

  app.controller('PieCtrl', ['$scope', '$timeout', function ($scope, $timeout) {
    $scope.labels = ['Series A', 'Series B'];
    $scope.data = [5, 59];

    $timeout(function () {
      $scope.data = [5, 65];
    }, 0);
  }]);

})();

(function () {
  'use strict';

  var app = angular.module('pie', ['chart.js']);

  app.directive('mySpecialPie', function (ChartJsFactory) { return new ChartJsFactory('Pie'); });

  app.controller('PieCtrl', ['$scope', '$timeout', function ($scope, $timeout) {
    $scope.labels = ['Series A', 'Series B'];
    $scope.data = [5, 59];

    $timeout(function () {
      $scope.data = [5, 65];
    }, 0);
  }]);

})();

Fix custom directive test (typo)


/**
 * Created by zsolt on 3/31/14.
 */

'use strict';
if (typeof window === 'undefined') {

    // server-side setup
    var requirejs = require("requirejs");
    var testConfig = require("../../test-conf.js").testConfig;
    requirejs.config(testConfig.requirejs);

    var chai = require('chai'),
        should = chai.should(),
        assert = chai.assert,
        expect = chai.expect;
}

var exec = require('child_process').exec;

describe("Plugin tests", function() {

    it('should run ChildrenConfig on Test', function(done) {
        var child = exec('node node_modules/webgme/bin/run_plugin.js -c config.json -p Test -n ChildrenConfig',
            function (error, stdout, stderr) {
                console.log('stdout: ' + stdout);
                console.log('stderr: ' + stderr);
                if (error !== null) {
                    console.log('exec error: ' + error);
                }
                expect(error).to.be.null;
                done();
            });
    });
});

/**
 * Created by zsolt on 3/31/14.
 */

'use strict';
if (typeof window === 'undefined') {

    var webgme = require('webgme');

    // server-side setup
    var requirejs = require("requirejs");
    //var testConfig = require("../../test-conf.js").testConfig;
    // TODO: fix this path issue
    requirejs.config({
        paths: {
            "plugin/ChildrenConfig": "../../src/plugins/Examples"
        }
        });

    var chai = require('chai'),
        should = chai.should(),
        assert = chai.assert,
        expect = chai.expect;

    var CONFIG = require('../../config.json');
}

//var exec = require('child_process').exec;

describe("Plugin tests", function() {
    it('should run ChildrenConfig on Test', function(done) {
        webgme.runPlugin.main(CONFIG, {
            projectName: 'Test',
            pluginName: 'ChildrenConfig'
        }, function (err) {
            expect(err).to.equal(null);
            done();
        });
    });

// TODO: remove this block
// run tests in a separate process
//    it('should run ChildrenConfig on Test', function(done) {
//        var child = exec('node node_modules/webgme/bin/run_plugin.js -c config.json -p Test -n ChildrenConfig',
//            function (error, stdout, stderr) {
//                console.log('stdout: ' + stdout);
//                console.log('stderr: ' + stderr);
//                if (error !== null) {
//                    console.log('exec error: ' + error);
//                }
//                expect(error).to.be.null;
//                done();
//            });
//    });

});

Use run_plugin directly for tests.


import {
  moduleFor,
  test
} from 'ember-qunit';

moduleFor('service:tour', {
  // Specify the other units that are required for this test.
  // needs: ['service:foo']
});

// Replace this with your real tests.
test('it exists', function(assert) {
  var service = this.subject();
  assert.ok(service);
});

import Ember from 'ember';
import { moduleFor, test } from 'ember-qunit';

var steps = [
  {
    id: 'intro',
    options: {
      attachTo: '.test-element bottom',
      builtInButtons: [
        {
          classes: 'shepherd-button-secondary',
          text: 'Exit',
          type: 'cancel'
        },
        {
          classes: 'shepherd-button-primary',
          text: 'Next',
          type: 'next'
        }
      ],
      classes: 'shepherd shepherd-open shepherd-theme-arrows shepherd-transparent-text',
      copyStyles: false,
      title: 'Welcome to Ember-Shepherd!',
      text: ['Test text']
    }
  }
];

var mockTourObject = Ember.Object.createWithMixins(Ember.Evented, {
  start() {
    this.trigger('start');
  }
});

moduleFor('service:tour', {
  afterEach() {
    // Remove start actions
    mockTourObject.off('start');
  }
});

// Replace this with your real tests.
test('it starts the tour when all required properties are available', function(assert) {
  assert.expect(1);

  mockTourObject.on('start', function() {
    assert.ok(true, 'This tour was started');
  });

  var service = this.subject({
    steps: steps,
    _tourObject: mockTourObject
  });

  Ember.run(function() {
    service.trigger('start');
  });

});

Verify that the service starts the library


var colors = require('colors');

if (process.platform === 'win32') {
  var fs = require('fs');
  var path = require('path');
  // https://github.com/atom/apm/blob/master/src/apm.coffee#L84
  if (process.env.GYP_MSVS_VERSION === '2015') {
    return;
  }
  var programDir = process.env["ProgramFiles(x86)"] || process.env["ProgramFiles"];
  var VSPath = path.join(programDir, "Microsoft Visual Studio 14.0", "Common7", "IDE");
  try {
    fs.statSync(VSPath).isDirectory();
  } catch (err) {
    console.error(`Missing dependency: ${'Visual C++ Build Tools 2015'.bold} must be installed`.red);
  }
} else {
  var commandExists = require('command-exists');
  var depedencies = [
    'make',
    'gcc',
    'wget',
    'python2.7'
  ];

  depedencies.forEach(function(dep) {
    commandExists(dep, function(err, commandExists) {
      if(!commandExists) {
        console.error(`Missing dependency: ${dep.bold} Could not be found on your system.`.red);
      }
    });
  });
}

var colors = require('colors');

if (process.platform === 'win32') {
  var fs = require('fs');
  var path = require('path');
  // https://github.com/atom/apm/blob/master/src/apm.coffee#L84
  if (process.env.GYP_MSVS_VERSION === '2015') {
    return;
  }
  var programDir = process.env["ProgramFiles(x86)"] || process.env["ProgramFiles"];
  var VSPath = path.join(programDir, "Microsoft Visual Studio 14.0", "Common7", "IDE");
  try {
    fs.statSync(VSPath).isDirectory();
  } catch (err) {
    console.error(`Missing dependency: ${'Visual C++ Build Tools 2015'.bold} must be installed`.red);
  }
} else {
  var commandExists = require('command-exists');
  var depedencies = [
    'make',
    'gcc',
    'wget',
    'python2.7'
  ];

  depedencies.forEach(function(dep) {
    commandExists(dep, function(err, commandExists) {
      if(!commandExists) {
        console.error(`Missing dependency: ${dep.bold} Could not be found on your system.`.red);
      }
    });
  });

  if (process.platform === 'linux') {
    var publishDeps = ['icnsutils', 'graphicsmagick', 'xz-utils'];
    publishDeps.forEach(function(dep) {
      commandExists(dep, function(err, commandExists) {
        if(!commandExists) {
          console.error(`Missing dependency: ${dep.bold} is necessary if you want to package a release.`.yellow);
        }
      });
    });
  }
}

Add check for electron-builder dependencies


import createDispatcher from './createDispatcher'
import withActions from './withActions'
import withStore from './widthStore'

export {
  createDispatcher,
  withActions,
  withStore
}

import createDispatcher from './createDispatcher'
import withActions from './withActions'
import withStore from './withStore'

export {
  createDispatcher,
  withActions,
  withStore
}

Fix typo in withStore export


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

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

global.React = React;

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

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

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

	return cs;
}

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

		return section;
	});
}

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

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

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

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

global.React = React;

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

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

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

	return cs;
}

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

		return section;
	});
}

components = processComponents(components);
sections = processSections(sections || []);

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

Allow components and sections to be used in parallel


require('coffee-script');

exports.validate = require('./validate');
exports.matchers = require('./matchers');

require('coffee-script/register');

exports.validate = require('./validate');
exports.matchers = require('./matchers');

Fix problem when loading module with javascript


import assign from 'object-assign';
import render from 'skatejs/src/api/render';

function getState (elem) {
  return Object.keys(elem.constructor.properties || {}).reduce(function (prev, curr) {
    prev[curr] = elem[curr];
  }, {});
}

function setState(elem, newState) {
  const ctor = elem.constructor;
  const shouldUpdate = !ctor.update || ctor.update(elem) !== false;
  assign(elem, newState);
  if (shouldUpdate) {
    render(elem);
  }
}

export default function (elem, newState) {
  return typeof newState === 'undefined' ? getState(elem) : setState(elem, newState);
}

import assign from 'object-assign';
import render from 'skatejs/lib/api/render';

function getState (elem) {
  return Object.keys(elem.constructor.properties || {}).reduce(function (prev, curr) {
    prev[curr] = elem[curr];
  }, {});
}

function setState(elem, newState) {
  const ctor = elem.constructor;
  const shouldUpdate = !ctor.update || ctor.update(elem) !== false;
  assign(elem, newState);
  if (shouldUpdate) {
    render(elem);
  }
}

export default function (elem, newState) {
  return typeof newState === 'undefined' ? getState(elem) : setState(elem, newState);
}

Use lib instead of src.


var assert = require('assert')
var cluster = require('cluster')
var request = require('request')
var test = require('tape')
var slacker = require('../')

test('http connections', function(t) {
  t.plan(3)

  var service = slacker(__dirname + '/fixtures/server.js')
  .timeout(100)
  .listen(7091, function() {
    request('http://localhost:7090', function(err, res) {
      t.ifError(err)
      t.equal(res.statusCode, 200)
      t.equal(res.body, 'success')
      service.close()
    })
  })
})

var assert = require('assert')
var cluster = require('cluster')
var request = require('request')
var test = require('tape')
var slacker = require('../')

test('http connections', function(t) {
  t.plan(3)

  var service = slacker(__dirname + '/fixtures/server.js')
  .timeout(100)
  .listen(7091, function() {
    request('http://localhost:7091', function(err, res) {
      t.ifError(err)
      t.equal(res.statusCode, 200)
      t.equal(res.body, 'success')
      service.close()
    })
  })
})

Use correct port in test.


var express = require('express');

var app = express();

app.get('/', function(req, res){
  res.send("Welcome to my app!");
})

app.listen(3000, console.log("Server listening on localhost:3000 "))

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

var app = express();

app.get('/', function(req, res){
  res.send("Welcome to my app!");
});

app.get('/games', function(req, res){

});

app.listen(3000, console.log("Server listening on localhost:3000 "))

Include fs module, add empty get route for games


import React from 'react';
import PokeMap from './components/PokeMap';

let pokemons = [
  { name: "Bulbasaur", position: {lat: 19.541980, lng: -96.927581} },
  { name: "Yvisaur", position: {lat: 20.223488, lng: -97.956551} },
  { name: "Venusaur", position: {lat: 21.088393, lng: -98.713452} },
  { name: "Charmander", position: {lat: 22.288521, lng: -100.669963} },
  { name: "Charmeleon", position: {lat: 24.072572, lng: -100.636729} },
  { name: "Charizard", position: {lat: 25.657715,  lng: -100.366785} },
  { name: "Squirtle", position: {lat: 19.444299, lng: -96.189209} },
  { name: "Warturtle", position: {lat: 19.703085, lng: -96.255126} },
  { name: "Blastoise", position: {lat: 19.081306, lng: -95.826660} }
];

main();

function main() {
    React.render(<PokeMap pokemons={pokemons} />, document.getElementById('container-map'));
}

import React from 'react';
import PokeGame from './components/PokeGame';

React.render(<PokeGame  />, document.getElementById('container-map'));

Update file to render PokeGame


// Root file loaded by RequireJS

require.config({
    paths: {
        'jquery': 'lib/jquery',
        'handlebars': 'lib/handlebars'
    },
});

require([
    'jQuery',
    'map_controller'
  ],
function($, MapController) {
  $(function() {
    $('.js-map').each(function(_index, canvas) {
      var controller = new MapController(canvas);
    });
  });
});

// Root file loaded by RequireJS

require.config({
    paths: {
        'jquery': 'vendor/jquery',
        'handlebars': 'vendor/handlebars'
    },
});

require([
    'jquery',
    'map_controller'
  ],
function($, MapController) {
  $(function() {
    $('.js-map').each(function(_index, canvas) {
      var controller = new MapController(canvas);
    });
  });
});

Fix bugs introduced by Code Climate changes


import { Promise } from 'es6-promise';
import distance from 'google-distance';
import dotenv from 'dotenv';

dotenv.load();

distance.apiKey = process.env.GOOGLE_DISTANCE_API_KEY;

export function getUserIdFromRequest( req ) {
  return req.user.sub;
}

export function removeElementFromArray( ary, element ) {
  return ary.reduce( ( collection, el ) => {
    if ( el !== element ) collection.push( el );
    return collection;
  }, [] );
}

export function fetchDistanceBetween( origin, destination ) {
  return new Promise( ( resolve, reject ) => {
    distance.get( { origin, destination }, ( err, data ) => {
      if ( err ) return reject( err );
      resolve( data.distanceValue );
    } );
  } );
}

import { Promise } from 'es6-promise';
import distance from 'google-distance';
import dotenv from 'dotenv';

dotenv.load();

distance.apiKey = process.env.GOOGLE_DISTANCE_API_KEY;

export function getUserIdFromRequest( req ) {
  return req.user.sub;
}

export function getUserNameFromRequest( req ) {
  return req.user.name || req.user.nickname || req.user.email || req.user.user_id;
}

export function removeElementFromArray( ary, element ) {
  return ary.reduce( ( collection, el ) => {
    if ( el !== element ) collection.push( el );
    return collection;
  }, [] );
}

export function fetchDistanceBetween( origin, destination ) {
  return new Promise( ( resolve, reject ) => {
    distance.get( { origin, destination }, ( err, data ) => {
      if ( err ) return reject( err );
      resolve( data.distanceValue );
    } );
  } );
}

Add getUserNameFromRequest helper method to server


import path from 'path';
import express from 'express';
import exphbs  from 'express-handlebars';
import mongoose from 'mongoose';
import Bootstrap from 'bootstrap/dist/css/bootstrap.css';

import app = express();

import serverConfig from './config';

// Connection to MongoDB
mongoose.connect(serverConfig.mongo_url, (error) => {
  if (error) {
    console.error('Please verify if Mongodb is up and running!');
    throw error;
  }
});

// Serve public assets and static content
app.use('/static', express.static(path.resolve(__dirname, '../build')));

app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');

require('./routes/routes')(app);

app.listen(serverConfig.port, function () {
  console.log('MERN stack app listening on port ' + serverConfig.port + '!');
});

var path = require('path');
var express = require('express');
var exphbs  = require('express-handlebars');
var mongoose = require('mongoose');

var app = express();

var serverConfig = require('./config');

// Connection to MongoDB
mongoose.connect(serverConfig.mongo_url, (error) => {
  if (error) {
    console.error('Please verify if Mongodb is up and running!');
    throw error;
  }
});

// Serve public assets and static content
app.use('/static', express.static(path.resolve(__dirname, '../build')));

app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');

require('./routes/routes')(app);

app.listen(serverConfig.port, function () {
  console.log('MERN stack app listening on port ' + serverConfig.port + '!');
});

Rollback on changes from commonsJS require to import.


var kiwi_app = './kiwi.js';

var daemon = require('daemonize2').setup({
    main: kiwi_app,
    name: 'kiwiirc',
    pidfile: '../kiwiirc.pid'
});

switch (process.argv[2]) {
    case '-f':
        require(kiwi_app);
        break;

    case 'start':
        daemon.start();
        break;

    case 'stop':
        daemon.stop();
        break;

    case 'restart':
        daemon.stop(function(err) {
            daemon.start();
        });
        break;

    case 'status':
        var pid = daemon.status();
        if (pid)
            console.log('Daemon running. PID: ' + pid);
        else
            console.log('Daemon is not running.');
        break;

    case 'reconfig':
        console.log('Loading new config..');
        daemon.sendSignal("SIGUSR1");
        break;

    default:
        console.log('Usage: [-f|start|stop|restart|status|reconfig]');
}

var kiwi_app = './kiwi.js';

var daemon = require('daemonize2').setup({
    main: kiwi_app,
    name: 'kiwiirc',
    pidfile: '../kiwiirc.pid'
});

switch (process.argv[2]) {
    case '-f':
        require(kiwi_app);
        break;

    case 'start':
        daemon.start();
        break;

    case 'stop':
        daemon.stop();
        break;

    case 'restart':
        daemon.stop(function(err) {
            daemon.start();
        });
        break;

    case 'status':
        var pid = daemon.status();
        if (pid)
            console.log('Daemon running. PID: ' + pid);
        else
            console.log('Daemon is not running.');
        break;

    case 'reconfig':
        console.log('Loading new config..');
        daemon.sendSignal("SIGUSR1");
        break;

    case 'build':
        require('../client/assets/dev/build.js');
        break;

    default:
        console.log('Usage: [-f|start|stop|restart|status|reconfig|build]');
}

Build command added to bash wrapper


import {Controller} from "stimulus"

export default class extends Controller {

    static targets = ["mapInfo"]

    connect() {
        const courseId = this.mapInfoTarget.dataset.courseId;
        const splitId = this.mapInfoTarget.dataset.splitId;

        Rails.ajax({
            url: "/api/v1/courses/" + courseId,
            type: "GET",
            success: function (response) {
                const attributes = response.data.attributes;

                var locations = null;
                if(splitId === undefined) {
                    locations = attributes.locations;
                } else {
                    locations = attributes.locations.filter(function(e) {
                        return e.id === parseInt(splitId)
                    })
                }

                const trackPoints = attributes.trackPoints;
                gmap_show(locations, trackPoints);
            }
        })
    }
}

import {Controller} from "stimulus"

export default class extends Controller {

    static targets = ["mapInfo"]

    connect() {
        const courseId = this.mapInfoTarget.dataset.courseId;
        const splitId = this.mapInfoTarget.dataset.splitId;

        Rails.ajax({
            url: "/api/v1/courses/" + courseId,
            type: "GET",
            success: function (response) {
                const attributes = response.data.attributes;

                let locations = null;
                if(splitId === undefined) {
                    locations = attributes.locations;
                } else {
                    locations = attributes.locations.filter(function(e) {
                        return e.id === parseInt(splitId)
                    })
                }

                const trackPoints = attributes.trackPoints;
                gmap_show(locations, trackPoints);
            }
        })
    }
}

Use let instead of var


controller = new BasicController({
    supports: {
        playpause: true,
        next: true,
        previous: true,
        favorite: true,
        thumbsDown: false  // Changes dynamically
    },
    playPauseSelector: '.player-controls__btn_play',
    previousSelector: '.player-controls__btn_prev',
    nextSelector: '.player-controls__btn_next',
    titleSelector: '.player-controls .track__title',
    artistSelector: '.player-controls .track__artists',
    playStateSelector: '.player-controls__btn_play',
    playStateClass: 'player-controls__btn_pause',
    artworkImageSelector: '.player-controls .album-cover',
    favoriteSelector: '.player-controls .like',
    isFavoriteSelector: '.player-controls .like_on',
    thumbsDownSelector: '.dislike.player-controls__btn'
});

controller.override('getAlbumArt', function() {
    var img = document.querySelector(this.artworkImageSelector);
    if (img) {
        return img.src.replace('40x40', '150x150');
    }
    return undefined
});

controller.override('isPlaying', function(_super) {
    this.supports.thumbsDown = window.getComputedStyle(document.querySelector(this.thumbsDownSelector)).display != 'none'
    return _super()
});

controller = new BasicController({
    supports: {
        playpause: true,
        next: true,
        previous: true,
        favorite: true,
        thumbsDown: false  // Changes dynamically
    },
    playPauseSelector: '.player-controls__btn_play',
    previousSelector: '.player-controls__btn_prev',
    nextSelector: '.player-controls__btn_next',
    titleSelector: '.player-controls .track__title',
    artistSelector: '.player-controls .track__artists',
    playStateSelector: '.player-controls__btn_play',
    playStateClass: 'player-controls__btn_pause',
    artworkImageSelector: '.player-controls .album-cover',
    favoriteSelector: '.player-controls .like',
    isFavoriteSelector: '.player-controls .like_on',
    thumbsDownSelector: '.dislike.player-controls__btn'
});

controller.override('getAlbumArt', function() {
    var img = document.querySelector(this.artworkImageSelector);
    if (img) {
        return img.src.replace('50x50', '150x150');
    }
    return undefined
});

controller.override('isPlaying', function(_super) {
    this.supports.thumbsDown = window.getComputedStyle(document.querySelector(this.thumbsDownSelector)).display != 'none'
    return _super()
});

Update album art size at Yandex.Music


var alreadyExistingTag = document.querySelector("script[async][src='chrome-extension://afcmfnlbcoginnfdkokfgpcmooekakhf/content-script-js-accesser.js']");
if(!alreadyExistingTag) {
	var scriptTag = document.createElement("script");
	scriptTag.src = chrome.runtime.getURL("content-script-js-accesser.js");
	scriptTag.async = true;
	document.head.appendChild(scriptTag);
	window.addEventListener("message",function(){
		if(event.data == "tabplaylist: ended") {
			chrome.runtime.sendMessage("ended");
		}
	});
}

var alreadyExistingTag = document.querySelector("script[async][src='" + chrome.runtime.getURL("content-script-js-accesser.js") + "']");
if(!alreadyExistingTag) {
	var scriptTag = document.createElement("script");
	scriptTag.src = chrome.runtime.getURL("content-script-js-accesser.js");
	scriptTag.async = true;
	document.head.appendChild(scriptTag);
	window.addEventListener("message",function(){
		if(event.data == "tabplaylist: ended") {
			chrome.runtime.sendMessage("ended");
		}
	});
}

Use runtime.getURL instead of hardcoding


class Common {

    static sanitizeNickname(nickname) {
        return nickname.replace(/[^a-z]/ig, '').toLowerCase();
    }

    static avoidHighlighting(nickname) {
        return '\u8288' + nickname
    }
}

module.exports = Common;

class Common {

    static sanitizeNickname(nickname) {
        return nickname.replace(/[^a-z]/ig, '').toLowerCase();
    }

    static avoidHighlighting(nickname) {
        return '\u2060' + nickname
    }
}

module.exports = Common;

Use UTF-8 "word-joiner" to avoid highlighting


const Job = ({ locations, deadline, companyImage, companyName, jobTitle, ingress, jobName }) => {
  if (locations.length >= 2) {
    locations = `${locations.slice(0, -1).join(', ')} and ${locations[locations.length - 1]}`;
  } else if (locations.length === 0) {
    locations = 'Ikke spesifisert';
  }

  return (

          <picture>
            <source srcset={companyImage.lg} media="(max-width: 992px)" />

          </picture>

          {companyName} - {jobTitle}

{ingress}

Type: {jobName}

Sted: {locations}

Frist: {deadline}

  );
};

export default Job;

const Job = ({ locations, deadline, companyImage, companyName, jobTitle, ingress, jobName }) => {
  if (locations.length >= 2) {
    locations = `${locations.slice(0, -1).join(', ')} and ${locations[locations.length - 1]}`;
  } else if (locations.length === 0) {
    locations = 'Ikke spesifisert';
  }

  return (

          <picture>
            <source srcSet={companyImage.lg} media="(max-width: 992px)" />

          </picture>

          {companyName} - {jobTitle}

{ingress}

Type: {jobName}

Sted: {locations}

Frist: {deadline}

  );
};

export default Job;

Fix warning from React component prop not being camelCased


var irregulars = require('english-irregular-verbs');

// Extract all past participles.
var irregularParticiples = [];
irregulars.forEach(function(verb) {
  verb.participles.forEach(function(participle) {
    irregularParticiples.push(participle);
  });
});

var toBe = [ 'am', 'are', 'were', 'being', 'is', 'been', 'was', 'be' ];

// Write a Node module that exports a regular expression to standard output.
process.stdout.write(
  'module.exports = ' +
  'new RegExp("(\\\\b(' +
  toBe.join('|') +
  ')\\\\b\\\\s*([\\\\w]+ed|' +
  irregularParticiples.join('|') +
  ')\\\\b)", "gi")\n'
);

var irregularVerbs = require('english-irregular-verbs');

// Extract all past participles.
var irregularParticiples = [];
irregularVerbs.forEach(function(verb) {
  verb.participles.forEach(function(participle) {
    irregularParticiples.push(participle);
  });
});

var toBe = [ 'am', 'are', 'were', 'being', 'is', 'been', 'was', 'be' ];

// Write to standard output ...
process.stdout.write(
  // a Node module that exports ...
  'module.exports = ' +
  // a regular expression ...
  'new RegExp("' +
    // entirely enclosed in a capture group ...
    '(' +
      // that matches a form of "to be" ...
      '\\\\b' +
      '(' + toBe.join('|') + ')' +
      '\\\\b' +
      // followed by space ...
      '\\\\s*' +
      '(' +
        // and a word that ends in "-ed" ...
        '[\\\\w]+ed' +
        // or ...
        '|' +
        // an irregular past participle ...
        irregularParticiples.join('|') +
      ')' +
      '\\\\b' +
    ')' +
  '",' +
  // that one or more case-insensitive substrings.
  ' "gi")\n'
);

Add regular expression builder commentary


(function () {

var eleven = /[\u4e00-\u9fbf\u3040-\u309f\u30a0-\u30ff]/;

oneeSama.hook('menuOptions', function (info) {
	// TODO use model instead
	var text = $('#' + info.num).find('blockquote').text();
	if (text && eleven.exec(text))
		info.options.push('Speak');
});

menuHandlers.Speak = function ($post) {
	var $audio = $('<audio/>', {
		src: $post.attr('id') + '/voice',
		attr: {autoplay: 'autoplay'},
	});
	$audio.prop({
		onended: $.proxy($audio, 'remove'),
		onerror: function (err) {
			// TODO
			console.error('audio error', err);
		},
	}).appendTo('body');
};

})();

(function () {

var eleven = /[\u4e00-\u9fbf\u3040-\u309f\u30a0-\u30ff]/;

oneeSama.hook('menuOptions', function (info) {
	// TODO use model instead
	var text = $('#' + info.num).find('blockquote').text();
	if (text && eleven.exec(text))
		info.options.push('Speak');
});

menuHandlers.Speak = function ($post) {
	var $audio = $('<audio/>', {
		src: $post.attr('id') + '/voice',
		attr: {autoplay: 'autoplay'},
	});
	$audio[0].addEventListener('ended', function () {
		$audio.remove();
	}, false);
	// TODO notify error
	$audio.appendTo('body');
};

})();

Remove voice audio after play properly


'use strict'

const stream = require('stream')
const Transform = stream.Transform
const PassThrough = stream.PassThrough

/**
 * Returns a transform stream that branches
 * the input stream to several streams given by argument.
 */
module.exports = function selectTask (config) {
  /**
   * (inputStream) -> transform -> each task -> transform -> (outputStream)
   */
  return new Transform({
    objectMode: true,

    transform (file, encoding, callback) {
      const rule = config.findRuleByInput(file.path)

      if (rule === null) {
        callback(null, file)
        return
      }

      const src = new PassThrough({ objectMode: true })
      rule.task(src).on('data', file => {
        file.extname = '.' + rule.outputExt
        callback(null, file)
      })
      src.end(file)
    }
  })
}

'use strict'

const stream = require('stream')
const Transform = stream.Transform
const Readable = stream.Readable

/**
 * Returns a transform stream that branches
 * the input stream to several streams given by argument.
 */
module.exports = function selectTask (config) {
  /**
   * (inputStream) -> transform -> each task -> transform -> (outputStream)
   */
  return new Transform({
    objectMode: true,

    transform (file, encoding, callback) {
      const rule = config.findRuleByInput(file.path)

      if (rule === null) {
        callback(null, file)
        return
      }

      const src = new Readable({ objectMode: true })
      src.push(file)
      src.push(null)

      rule.task(src).on('data', file => {
        file.extname = '.' + rule.outputExt
        callback(null, file)
      })
    }
  })
}

Use readable stream instead of pass through


var fs = require('fs-extra');
var path = require('path');
var serveStatic = require('serve-static');
var finalhandler = require('finalhandler');

module.exports = function(options) {
  options = options || {};

  var rcfile = path.join(options.cwd || process.cwd(), '.webmodulesrc');
  var rc = fs.existsSync(rcfile) ? JSON.parse(fs.readFileSync(rcfile)) : {};
  var base = options.base || rc.directory || path.join(process.cwd(), 'web_modules');

  var runtimedir = serveStatic(path.normalize(path.join(__dirname, '..', '..')));
  var moduledir = serveStatic(base);

  return function webmodules(req, res, next) {
    if( arguments.length <= 2 ) next = finalhandler(req, res);

    //console.log('req', req.url);
    if( req.url.startsWith('/webmodules/') ) {
      req.url = req.url.substring('/webmodules/'.length);
      runtimedir(req, res, next);
    } else {
      moduledir(req, res, next);
    }
  };
};

var fs = require('fs-extra');
var path = require('path');
var serveStatic = require('serve-static');
var finalhandler = require('finalhandler');

module.exports = function(options) {
  options = options || {};

  var rcfile = path.join(options.cwd || process.cwd(), '.webmodulesrc');
  var rc = fs.existsSync(rcfile) ? JSON.parse(fs.readFileSync(rcfile)) : {};
  var base = path.join(process.cwd(), options.base || rc.directory || 'web_modules');

  var runtimedir = serveStatic(path.normalize(path.join(__dirname, '..', '..')));
  var moduledir = serveStatic(base);

  return function webmodules(req, res, next) {
    if( arguments.length <= 2 ) next = finalhandler(req, res);

    //console.log('req', req.url);
    if( req.url.startsWith('/webmodules/') ) {
      req.url = req.url.substring('/webmodules/'.length);
      runtimedir(req, res, next);
    } else {
      moduledir(req, res, next);
    }
  };
};

Fix base dir in router


/* Helper function to add an event listener.
 * @param el The element we want to add an event listener to.
 * @param event The event we want to listen to.
 * @param callback The callback function to call when the event is transmitted.
 */
function addEvent(el, event, callback) {
  if ('addEventListener' in el) {
    el.addEventListener(event, callback, false);
  } else {
    el['e' + event + callback] = callback;
    el[event + callback] = function() {
      el['e' + event + callback](window.event);
    };
    el.attachEvent('on' + event, el[event + callback]);
  }
}

function clearWarningOnInput(inputId, warningId) {
  var el= document.getElementById(inputId);
  addEvent(el, 'input', function() {
    var cl = document.getElementById(warningId).classList;
    if (!cl.contains('hidden-warning')) {
      cl.add('hidden-warning');
    }
  });
}

/* Helper function to add an event listener.
 * @param {Element} el - The element we want to add an event listener to.
 * @param {Event} event - The event we want to listen to.
 * @param {function} callback - The callback function to call when the event is
 * transmitted.
 */
function addEvent(el, event, callback) {
  if ('addEventListener' in el) {
    el.addEventListener(event, callback, false);
  } else {
    el['e' + event + callback] = callback;
    el[event + callback] = function() {
      el['e' + event + callback](window.event);
    };
    el.attachEvent('on' + event, el[event + callback]);
  }
}

function clearWarningOnInput(inputId, warningId) {
  var el= document.getElementById(inputId);
  addEvent(el, 'input', function() {
    var cl = document.getElementById(warningId).classList;
    if (!cl.contains('hidden-warning')) {
      cl.add('hidden-warning');
    }
  });
}

Change doc style in addEvent()


var Mocha = require('mocha'),
    _ = require('underscore');

module.exports = function (browser, module, suite, config, tests) {

  suite = Mocha.Suite.create(suite, module.slug);

  tests = _.extend({
    exists: function () {
      return browser
        .$('#' + module.slug).isDisplayed()
          .should.eventually.be.ok;
    },

    'has a title': function () {
      return browser
        .$('#' + module.slug + ' h2').text()
          .should.eventually.equal(module.title);
    }

  }, tests);

  _.each(tests, function (test, key) {
    suite.addTest(new Mocha.Test(key, test));
  });

  try { // to load a test suite corresponding with the module-type
    var moduleTests = require('./modules/' + module['module-type']);
    moduleTests(browser, module, suite, config);
  } catch (e) {
    if (e.code === 'MODULE_NOT_FOUND') {
      suite.addTest(new Mocha.Test('no test suite is defined for module-type ' + module['module-type']));
    }
  }

  return suite;

};

var Mocha = require('mocha'),
    _ = require('underscore');

module.exports = function (browser, module, suite, config, tests) {

  suite = Mocha.Suite.create(suite, module.slug);

  tests = _.extend({
    exists: function () {
      return browser
        .$('#' + module.slug).isDisplayed()
          .should.eventually.be.ok;
    },

    'contains no error message': function () {
      return browser
        .hasElementByCssSelector('#' + module.slug + ' h2.error')
          .should.eventually.not.be.ok;
    },

    'has a title': function () {
      return browser
        .$('#' + module.slug + ' h2').text()
          .should.eventually.equal(module.title);
    }

  }, tests);

  _.each(tests, function (test, key) {
    suite.addTest(new Mocha.Test(key, test));
  });

  try { // to load a test suite corresponding with the module-type
    var moduleTests = require('./modules/' + module['module-type']);
    moduleTests(browser, module, suite, config);
  } catch (e) {
    if (e.code === 'MODULE_NOT_FOUND') {
      suite.addTest(new Mocha.Test('no test suite is defined for module-type ' + module['module-type']));
    }
  }

  return suite;

};

Add tests for the non-existence of error messages


"use strict";

import assert from "assert";
import ftl from "../src/index";

suite("blank lines", function() {
  test("leading", function() {
    assert.equal(
      ftl`

        foo
        `,
      "\nfoo"
    );
  });

  test("middle", function() {
    assert.equal(
      ftl`
        foo

        bar
        `,
      "foo\n\nbar"
    );
  });

  test("trailing", function() {
    assert.equal(
      ftl`
        foo

        `,
      "foo\n"
    );
  });
});

"use strict";

import assert from "assert";
import ftl from "../src/index";

suite("blank lines", function() {
  test("leading", function() {
    assert.equal(
      ftl`

        foo
        `,
      "\nfoo"
    );
  });

  test("middle", function() {
    assert.equal(
      ftl`
        foo

        bar
        `,
      "foo\n\nbar"
    );
  });

  test("trailing", function() {
    assert.equal(
      ftl`
        foo

        `,
      "foo\n"
    );
  });

  test("containing the same amount of spaces as the common indent", function() {
    assert.equal(
      ftl`

      `,
      ""
    );
  });

  test("containing too few spaces", function() {
    assert.throws(
      () => ftl`

      `,
      /Insufficient indentation in line 0/
    );
  });

  test("containing too many spaces", function() {
    assert.equal(
      ftl`

      `,
      "  "
    );
  });
});

Add tests for blank lines containing whitespace


import rollupBabel from "rollup-plugin-babel";

const pkg = require("./package.json");

export default {
    entry: "src/index.js",
    plugins: [
        rollupBabel({
            babelrc: false,
            presets: [
                ["env", { modules: false }],
                "stage-3"
            ]
        })
    ],
    targets: [
        {
            dest: pkg.main,
            format: "umd",
            moduleName: "dtileTilemap",
            sourceMap: true
        },
        {
            dest: pkg.module,
            format: "es",
            sourceMap: true
        }
    ]
};

import rollupBabel from "rollup-plugin-babel";

const pkg = require("./package.json");

export default {
    entry: "src/index.js",
    plugins: [
        rollupBabel({
            babelrc: false,
            presets: [
                ["env", { modules: false }],
                "stage-3"
            ]
        })
    ],
    targets: [
        {
            dest: pkg.main,
            format: "umd",
            moduleName: "TileTools",
            sourceMap: true
        },
        {
            dest: pkg.module,
            format: "es",
            sourceMap: true
        }
    ]
};

Fix module name for UMD


'use strict';

var _ = require('underscore');

var util = require('./util.js');
var scan = require('./scan.js');
var analyze = require('./analyze.js');

var cani = function (files, browsers) {
  var supportedBrowsers = util.getSupportedBrowserList(browsers);

  util.getFileList(files)
    .then(function (files) {
      _.each(files, function (file) {
        var tokensToCheck = scan(file);
        var badTokens = analyze(tokensToCheck, supportedBrowsers);
        return badTokens;
      });
    });
};

module.exports = cani;

'use strict';

var _ = require('underscore');

var util = require('./util.js');
var scan = require('./scan.js');
var analyze = require('./analyze.js');

var cani = function (files, browsers) {
  var supportedBrowsers = util.getSupportedBrowserList(browsers);

  util.getFileList(files)
    .then(function (files) {
      _.each(files, function (file) {
        var tokensToCheck = scan(file);
        var badTokens = analyze(tokensToCheck, supportedBrowsers);
        console.log(badTokens);
        return badTokens;
      });
    });
};

module.exports = cani;

Add a logging statement for the time being


const default_state = {menu: null, user: {}, sidebar: true, screens: []}

function top(state=default_state, action){
  switch(action.type){
    case 'TOP_TOGGLE_MENU':
      if (state.menu==action.menu)
        state={...state, menu: undefined}
      else
        state={...state, menu: action.menu}
      break;
    case 'TOP_TOGGLE_SIDEBAR':
      state={...state, sidebar: !state.sidebar}
      break;
    case 'TOP_UPDATE_SCREENS':
      state = {...state, screens: action.payload}
      break;
  }
  return state
}

export default top

const default_state = {
  menu: null,
  user: {},
  sidebar: localStorage.show_sidebar == "true",
  screens: []
}

function top(state=default_state, action){
  switch(action.type){
    case 'TOP_TOGGLE_MENU':
      if (state.menu==action.menu)
        state={...state, menu: undefined}
      else
        state={...state, menu: action.menu}
      break;
    case 'TOP_TOGGLE_SIDEBAR':
      // I store already modified
      localStorage.show_sidebar = state.sidebar ? "false" : "true"
      state={...state, sidebar: !state.sidebar}
      break;
    case 'TOP_UPDATE_SCREENS':
      state = {...state, screens: action.payload}
      break;
  }
  return state
}

export default top

Store sidebar status for next session


const { createWebpackConfig } = require('../config/webpack');

module.exports = {
  getDefaultWebpackConfig: createWebpackConfig
};

const pkg = require('../../package');

module.exports = {
  version: pkg.version
};

Replace existing API (no longer used by news-core) with stub containing version number.


export const socketOptions = {
  protocol: 'http',
  hostname: 'remotedev.io',
  port: 80,
  autoReconnect: true
};

export const socketOptions = {
  protocol: 'http',
  hostname: 'remotedev.io',
  port: 80,
  autoReconnect: true,
  autoReconnectOptions: {
    randomness: 60000
  }
};

Add randomness to the reconnect delay not to flood the server after a worker crash