exports.httpConfig = {
  staticDir: 'static'
};

exports.urls = [
    [ '/', 'actions' ]
];

exports.middleware = [
    'ringo/middleware/etag',
    'ringo/middleware/responselog',
    // 'ringo/middleware/profiler'
];

exports.app = require('ringo/webapp').handleRequest;

exports.macros = [
    'ringo/skin/macros',
    'ringo/skin/filters'
];

exports.charset = 'UTF-8';
exports.contentType = 'text/html';

exports.httpConfig = {
  staticDir: 'static'
};

exports.urls = [
    [ '/', 'actions' ]
];

exports.middleware = [
    'ringo/middleware/etag',
    'ringo/middleware/responselog',
    'ringo/middleware/error',
    'ringo/middleware/notfound'
    // 'ringo/middleware/profiler'
];

exports.app = require('ringo/webapp').handleRequest;

exports.macros = [
    'ringo/skin/macros',
    'ringo/skin/filters'
];

exports.charset = 'UTF-8';
exports.contentType = 'text/html';

Update middleware stack of skeleton app.


module.exports = function (grunt) {
    grunt.initConfig({
        jshint: {
            jshintrc: '.jshintrc',
            files: ['Gruntfile.js', 'bin/*', 'lib/**/*.js', 'test/**/*.js', '!test/assets/**/*']
        },
        simplemocha: {
            options: {
                reporter: 'spec'
            },
            full: { src: ['test/test.js'] },
            short: {
                options: {
                    reporter: 'dot'
                },
                src: ['test/test.js']
            }
        },
        execute: {
            assets: {
                src: ['test/assets/downloader.js']
            }
        },
        watch: {
            files: ['<%= jshint.files %>'],
            tasks: ['jshint', 'simplemocha:short']
        }
    });

    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-simple-mocha');
    grunt.loadNpmTasks('grunt-execute');

    grunt.registerTask('test', ['execute:assets', 'simplemocha:full']);
    grunt.registerTask('default', ['jshint', 'test']);
};

module.exports = function (grunt) {
    grunt.initConfig({
        jshint: {
            options: {
                jshintrc: '.jshintrc'
            },
            files: ['Gruntfile.js', 'bin/*', 'lib/**/*.js', 'test/**/*.js', '!test/assets/**/*']
        },
        simplemocha: {
            options: {
                reporter: 'spec'
            },
            full: { src: ['test/test.js'] },
            short: {
                options: {
                    reporter: 'dot'
                },
                src: ['test/test.js']
            }
        },
        execute: {
            assets: {
                src: ['test/assets/downloader.js']
            }
        },
        watch: {
            files: ['<%= jshint.files %>'],
            tasks: ['jshint', 'simplemocha:short']
        }
    });

    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-simple-mocha');
    grunt.loadNpmTasks('grunt-execute');

    grunt.registerTask('test', ['execute:assets', 'simplemocha:full']);
    grunt.registerTask('default', ['jshint', 'test']);
};

Make the grunt jshint task use the .jshintrc


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

    // Configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        jscs: {
            options: {
                config: '.jscsrc'
            },
            bin: 'bin/**/*.js',
            grunt: 'Gruntfile.js',
            lib: 'lib/**/*.js',
            test: '<%= nodeunit.all %>'
        },
        jshint: {
            options: {
                jshintrc: true
            },
            bin: 'bin/**/*.js',
            grunt: 'Gruntfile.js',
            lib: 'lib/**/*.js',
            test: '<%= nodeunit.all %>'
        },
        jsonlint: {
            jshint: ['.jshintrc'],
            npm: ['package.json']
        },
        nodeunit: {
            all: ['test/**/*.js']
        },
        release: {
            options: {}
        }
    });

    // Load tasks.
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-jscs-checker');
    grunt.loadNpmTasks('grunt-jsonlint');
    grunt.loadNpmTasks('grunt-contrib-nodeunit');
    grunt.loadNpmTasks('grunt-release');

    // Register tasks.
    grunt.registerTask('lint', ['jsonlint', 'jshint', 'jscs']);
    grunt.registerTask('test', ['nodeunit']);
    grunt.registerTask('default', ['lint', 'test']);
};

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

    // Configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        jscs: {
            options: {
                config: '.jscsrc'
            },
            bin: 'bin/**/*.js',
            grunt: 'Gruntfile.js',
            lib: 'lib/**/*.js',
            test: '<%= nodeunit.all %>'
        },
        jshint: {
            options: {
                jshintrc: true
            },
            bin: 'bin/**/*.js',
            grunt: 'Gruntfile.js',
            lib: 'lib/**/*.js',
            test: '<%= nodeunit.all %>'
        },
        jsonlint: {
            jshint: ['.jshintrc'],
            npm: ['package.json']
        },
        nodeunit: {
            all: ['test/**/*.js']
        },
        release: {
            options: {}
        }
    });

    // Load tasks.
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-jscs-checker');
    grunt.loadNpmTasks('grunt-jsonlint');
    grunt.loadNpmTasks('grunt-contrib-nodeunit');
    grunt.loadNpmTasks('grunt-release');

    // Register tasks.
    grunt.registerTask('lint', ['jsonlint', 'jshint', 'jscs']);
    grunt.registerTask('test', ['nodeunit']);
    grunt.registerTask('travis', ['lint', 'test']);
    grunt.registerTask('default', ['lint', 'test']);
};

Add a `travis` task for grunt.


module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    babel: {
      options: {
        sourceMap: false
      },
      dist: {
        files: [{
          expand: true,
          cwd: 'src',
          src: ['**/*.js'],
          dest: "lib",
          ext: ".js"
        }]
      }
    },

    jshint: {
      options: {
        jshintrc: '.jshintrc',
      },
      all: ['Gruntfile.js', 'src/**/*.js']
    },

    watch: {
      scripts: {
        files: ['src/*.js'],
        tasks: ['default'],
        options: {
          spawn: false
        },
      },
    },

    shell: {
      test: {
        command: 'jasmine',
        options:{
          stdout: true,
          stderr: true,
          failOnError: true
        }
      }
    }
  })

  grunt.loadNpmTasks('grunt-babel')
  grunt.loadNpmTasks('grunt-shell')
  grunt.loadNpmTasks('grunt-contrib-watch')
  grunt.loadNpmTasks('grunt-contrib-jshint')

  grunt.registerTask('clean', function() { require('rimraf').sync('lib') })
  grunt.registerTask('lint', ['jshint'])
  grunt.registerTask('default', ['lint', 'babel'])
  grunt.registerTask('test', ['default', 'shell:test'])
}

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    babel: {
      options: {
        sourceMap: false
      },
      dist: {
        files: [{
          expand: true,
          cwd: 'src',
          src: ['**/*.js'],
          dest: "lib",
          ext: ".js"
        }]
      }
    },

    jshint: {
      options: {
        jshintrc: '.jshintrc',
      },
      all: ['Gruntfile.js', 'src/**/*.js']
    },

    watch: {
      scripts: {
        files: ['src/*.js'],
        tasks: ['default'],
        options: {
          spawn: false
        },
      },
    },

    shell: {
      test: {
        command: 'node_modules/.bin/jasmine',
        options:{
          stdout: true,
          stderr: true,
          failOnError: true
        }
      }
    }
  })

  grunt.loadNpmTasks('grunt-babel')
  grunt.loadNpmTasks('grunt-shell')
  grunt.loadNpmTasks('grunt-contrib-watch')
  grunt.loadNpmTasks('grunt-contrib-jshint')

  grunt.registerTask('clean', function() { require('rimraf').sync('lib') })
  grunt.registerTask('lint', ['jshint'])
  grunt.registerTask('default', ['lint', 'babel'])
  grunt.registerTask('test', ['default', 'shell:test'])
}

Use the bin in node_modules


const handlebars = require('handlebars');
const Plugin = require('../plugin');

module.exports = class Issues extends Plugin {
  // checkIfEventApplies(event) {
  //   return event.issue !== undefined || event.pull_request !== undefined;
  // }

  comment(context, content) {
    const template = handlebars.compile(content)(context.payload);
    return context.github.issues.createComment(context.payload.toIssue({body: template}));
  }

  assign(context, ...assignees) {
    return context.github.issues.addAssigneesToIssue(context.payload.toIssue({assignees}));
  }

  unassign(context, ...assignees) {
    return context.github.issues.removeAssigneesFromIssue(context.payload.toIssue({body: {assignees}}));
  }

  label(context, ...labels) {
    return context.github.issues.addLabels(context.payload.toIssue({body: labels}));
  }

  unlabel(context, ...labels) {
    return labels.map(label => {
      return context.github.issues.removeLabel(
        context.payload.toIssue({name: label})
      );
    });
  }

  lock(context) {
    return context.github.issues.lock(context.payload.toIssue({}));
  }

  unlock(context) {
    return context.github.issues.unlock(context.payload.toIssue({}));
  }

  open(context) {
    return context.github.issues.edit(context.payload.toIssue({state: 'open'}));
  }

  close(context) {
    return context.github.issues.edit(context.payload.toIssue({state: 'closed'}));
  }
};

const handlebars = require('handlebars');
const Plugin = require('../plugin');

module.exports = class Issues extends Plugin {
  comment(context, content) {
    const template = handlebars.compile(content)(context.payload);
    return context.github.issues.createComment(context.payload.toIssue({body: template}));
  }

  assign(context, ...assignees) {
    return context.github.issues.addAssigneesToIssue(context.payload.toIssue({assignees}));
  }

  unassign(context, ...assignees) {
    return context.github.issues.removeAssigneesFromIssue(context.payload.toIssue({body: {assignees}}));
  }

  label(context, ...labels) {
    return context.github.issues.addLabels(context.payload.toIssue({body: labels}));
  }

  unlabel(context, ...labels) {
    return labels.map(label => {
      return context.github.issues.removeLabel(
        context.payload.toIssue({name: label})
      );
    });
  }

  lock(context) {
    return context.github.issues.lock(context.payload.toIssue({}));
  }

  unlock(context) {
    return context.github.issues.unlock(context.payload.toIssue({}));
  }

  open(context) {
    return context.github.issues.edit(context.payload.toIssue({state: 'open'}));
  }

  close(context) {
    return context.github.issues.edit(context.payload.toIssue({state: 'closed'}));
  }
};

Remove commented out conditions for now


import React, { Component } from 'react';
import './App.css';
import TimeTable from './TimeTable.js'

class App extends Component {
	render() {
		//return <TimeTable />;
		//return <TimeTable stopCode="E2036" />;
		return <TimeTable lat={60.1836474999998} lon={24.828072999999993} />;
	}
}

export default App;

import React, { Component } from 'react';
import './App.css';
import Error from './Error.js'
import Loading from './Loading.js'
import TimeTable from './TimeTable.js'
import UserLocation from './UserLocation.js'

class App extends Component {
	constructor(props) {
		super(props);
		this.state = {};
	}

	componentDidMount() {
		var self = this;
		try {
			UserLocation.getUserLocation((loc) => {
				console.log("Got coordinates: " + loc.coords.latitude + "," + loc.coords.longitude);
				self.setState({
					lat:loc.coords.latitude, lon:loc.coords.longitude
				});
			}, (e) => { throw e; });
		} catch (e) {
			this.setState({error: {
				name: "User location not available.",
				message: e.toString()
			}});
		}
	}

	render() {
		if (this.state.hasOwnProperty("error")) {
			return <Error name={this.state.error.name} message={this.state.error.msg.toString()}/>;
		}
		if (!this.state.hasOwnProperty("lat") || !this.state.hasOwnProperty("lat")) {
			return <Loading />
		}
		return <TimeTable lat={this.state.lat} lon={this.state.lon} maxDistance={1000} />;
	}
}

export default App;

Add implementation to show closest departures.


(function() {
    var osdOpentok = angular.module('osdOpentok', [
        'ngLodash'
    ]);
})();

(function() {
    var osdOpentok = angular.module('osdOpentok', []);
})();

Remove lodash and Array dependencies


#!/usr/bin/node

var test = require('tap').test;
var child = require('child_process');

test("Agents are installed", function(t) {
    t.plan(3);

    child.exec("find /opt/smartdc/agents/bin/ -follow -type f ! -perm -a+x",
        function(err, stdout, stderr){
            t.equal(err, null, "Agents bin directory exists");
            t.equal(stdout, '', "No un-executable scripts are linked to");
            t.equal(stderr, '', "No output on stderr");
            t.end();
        });

});

#!/usr/bin/node

var test = require('tap').test;
var child = require('child_process');

// This test is to check for regressions against AGENT-420
test("Agents are installed", function(t) {
    t.plan(3);

    child.exec("find /opt/smartdc/agents/bin/ -follow -type f ! -perm -a+x",
        function(err, stdout, stderr){
            t.equal(err, null, "Agents bin directory exists");
            t.equal(stdout, '', "No un-executable scripts are linked to");
            t.equal(stderr, '', "No output on stderr");
            t.end();
        });

});

Add note as to why agent test exists


Package.describe({
  name: 'bquarks:aerialjs',
  version: '0.1.4',
  // Brief, one-line summary of the package.
  summary: 'Suite Aerialjs to connect Meteor applications with Corble Platform.',
  // URL to the Git repository containing the source code for this package.
  git: 'https://github.com/bquarks/aerialjs.git',
  // By default, Meteor will default to using README.md for documentation.
  // To avoid submitting documentation, set this field to null.
  documentation: 'README.md'
});

Package.onUse(function(api) {
  api.versionsFrom('METEOR@1.3.2.4');
  api.use(['ecmascript', 'bquarks:aerial-mongo@0.0.14', 'bquarks:aerial-minimongo@0.0.14',
            'bquarks:aerial-corbel@0.2.1', 'bquarks:aerial-accounts@0.3.1'], {weak: false, unordered:false});

  api.mainModule('aerialjs.js');
});

// Package.onTest(function(api) {
//   api.use('ecmascript');
//   api.use('tinytest');
//   api.use('bquarks:aerialjs');
//   api.mainModule('aerialjs-tests.js');
// });

Package.describe({
  name: 'bquarks:aerialjs',
  version: '0.1.4',
  // Brief, one-line summary of the package.
  summary: 'Suite Aerialjs to connect Meteor applications with Corble Platform.',
  // URL to the Git repository containing the source code for this package.
  git: 'https://github.com/bquarks/aerialjs.git',
  // By default, Meteor will default to using README.md for documentation.
  // To avoid submitting documentation, set this field to null.
  documentation: 'README.md'
});

Package.onUse(function(api) {
  api.versionsFrom('METEOR@1.3.2.4');
  api.use(['ecmascript', 'bquarks:aerial-mongo@0.0.14', 'bquarks:aerial-minimongo@0.0.14',
            'bquarks:aerial-corbel@0.2.1', 'bquarks:aerial-accounts@0.4.0'], {weak: false, unordered:false});

  api.mainModule('aerialjs.js');
});

// Package.onTest(function(api) {
//   api.use('ecmascript');
//   api.use('tinytest');
//   api.use('bquarks:aerialjs');
//   api.mainModule('aerialjs-tests.js');
// });

Update aerial-accounts version -> 0.4.0


function fetchDefinition() {
    var term = document.getElementById('id_term-text').value;
    var language = document.getElementById('id_term-language').value;
    var url = '/api/define.json?term=' + term + '&language=' + language;

    fetch(url)
    .then(function(response) {
        return response.json();
    })
    .then(function(data) {
        var definitionInput = document.getElementById('id_term-definition');
        var highlightsInput = document.getElementById('id_term-highlights');
        definitionInput.value = data.definition;
        highlightsInput.value = data.highlights;

        var linkButton = document.getElementById('link_button');
        var occurrencesCount = document.getElementById('occurrences_count');

        // If the term already exists, disable the definition and highlights
        // textareas and add a link to the page for viewing it.
        if (data.view_link) {
            linkButton.className = 'ui blue button';
            linkButton.href = data.view_link;

            occurrencesCount.innerText = '(' + data.num_occurrences + ' occurrences)';
        } else {
            definitionInput.disabled = false;
            highlightsInput.disabled = false;
            linkButton.className = 'ui disabled button';
            occurrencesCount.innerText = '';
        }
    });
}

$('.editable-rating').rating({
    maxRating: 5,
    interactive: true,
    onRate: function(value) {
        $('#section_rating').val(value);
    }
});

$('.display-rating').rating({
    maxRating: 5,
    interactive: false,
});

function fetchDefinition() {
    var term = document.getElementById('id_term-text').value;
    var language = document.getElementById('id_term-language').value;
    var url = '/api/define.json?term=' + term + '&language=' + language;

    fetch(url)
    .then(function(response) {
        return response.json();
    })
    .then(function(data) {
        var definitionInput = document.getElementById('id_term-definition');
        var highlightsInput = document.getElementById('id_term-highlights');
        definitionInput.value = data.definition;
        highlightsInput.value = data.highlights;

        var linkButton = document.getElementById('link_button');
        var occurrencesCount = document.getElementById('occurrences_count');

        // If the term already exists, disable the definition and highlights
        // textareas and add a link to the page for viewing it.
        if (data.view_link) {
            linkButton.className = 'ui blue button';
            linkButton.href = data.view_link;

            occurrencesCount.innerText = '(' + data.num_occurrences + ' occurrences)';

            // Also set the category to 'notable'.
            document.getElementById('id_occurrence-category').value = '1';
        } else {
            definitionInput.disabled = false;
            highlightsInput.disabled = false;
            linkButton.className = 'ui disabled button';
            occurrencesCount.innerText = '';
        }
    });
}

$('.editable-rating').rating({
    maxRating: 5,
    interactive: true,
    onRate: function(value) {
        $('#section_rating').val(value);
    }
});

$('.display-rating').rating({
    maxRating: 5,
    interactive: false,
});

Set term category when fetching definition


import Ember from 'ember';
import I18nInstanceInitializer from 'ember-flexberry/instance-initializers/i18n';
import { module, test } from 'qunit';
import startApp from '../../helpers/start-app';
import destroyApp from '../../helpers/destroy-app';

let application;
let appInstance;

module('Unit | Instance Initializer | i18n', {
  beforeEach: function() {
    application = startApp();
    appInstance = application.buildInstance();
  },
  afterEach: function() {
    Ember.run(appInstance, 'destroy');
    destroyApp(appInstance);
  }
});

test('It works', function(assert) {
  assert.expect(1);
  I18nInstanceInitializer.initialize(appInstance);
  assert.ok(true);
});

test('Add true logic', function(assert) {
  assert.expect(2);
  assert.strictEqual(appInstance.__container__.factoryCache['service:i18n'], undefined);
  I18nInstanceInitializer.initialize(appInstance);
  assert.strictEqual(appInstance.__container__.factoryCache['service:i18n']._toString, 'dummy@service:i18n:');
});

test('Configures i18n service for locale', function(assert) {
  assert.expect(1);

  var controlValue = window.navigator.languages ? window.navigator.languages[0] : (window.navigator.language || window.navigator.userLanguage);
  I18nInstanceInitializer.initialize(appInstance);
  assert.strictEqual(appInstance.__container__.cache['service:i18n'].locale, controlValue);
});

import I18nInstanceInitializer from 'ember-flexberry/instance-initializers/i18n';
import { module, test } from 'qunit';
import startApp from '../../helpers/start-app';
import destroyApp from '../../helpers/destroy-app';

let application;
let appInstance;
let fakeLocale;

module('Unit | Instance Initializer | i18n', {
  beforeEach: function() {
    application = startApp();
    appInstance = application.buildInstance();

    // Set 'fake-locale' as default i18n-service locale.
    let i18n = appInstance.lookup('service:i18n');
    fakeLocale = 'fake-locale';
    i18n.set('locale', fakeLocale);
  },
  afterEach: function() {
    destroyApp(appInstance);
    destroyApp(application);
  }
});

test('Configures i18n service for locale', function(assert) {
  assert.expect(2);

  let i18n = appInstance.lookup('service:i18n');
  assert.strictEqual(i18n.get('locale'), fakeLocale, 'Default i18n-service locale is \'' + fakeLocale + '\'');

  var browserCurrentLocale = window.navigator.languages ? window.navigator.languages[0] : (window.navigator.language || window.navigator.userLanguage);
  I18nInstanceInitializer.initialize(appInstance);

  assert.strictEqual(i18n.get('locale'), browserCurrentLocale, 'Current i18n-service locale is \'' + browserCurrentLocale + '\'');
});

Remove unnecessary tests from i18n instance-initializer tests


// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

function retrieveAccountInfo() {
  fetch("/account").then(response => {
    if (response.redirected) return;
    else return response.json();
  }).then(account => {
    // Filling out the form with the account information.
    document.getElementById("logout").href = account.logoutUrl;
    if (account.isUserBusinessOwner) {
      document.getElementById("businessName").value = account.nickname;
    } else {
      document.getElementById("nickname").value = account.nickname;
    }
    document.getElementById("street").value = account.street;
    document.getElementById("city").value = account.city;
    document.getElementById("state").value = account.state;
    document.getElementById("zipCode").value = account.zipCode;
    document.getElementById("userGreeting").value = account.nickname;
  });
}

// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

function retrieveAccountInfo() {
  fetch("/account").then(response => {
    if (response.redirected) return;
    else return response.json();
  }).then(account => {
    // Filling out the form with the account information.
    document.getElementById("logout").href = account.logoutUrl;
    if (account.isUserBusinessOwner) {
      document.getElementById("businessName").value = account.nickname;
    } else {
      document.getElementById("nickname").value = account.nickname;
    }
    document.getElementById("street").value = account.street;
    document.getElementById("city").value = account.city;
    document.getElementById("state").value = account.state;
    document.getElementById("zipCode").value = account.zipCode;
    document.getElementById("userGreeting").innerText = "Hello, " + account.nickname;
  });
}

Add greeting when logged into the account


"use babel";

import { CompositeDisposable } from "atom";

const PANES = ["inspector", "kernel-monitor", "output-area", "watches"];
const utils = require("../dist/utils");

describe("Panes", () => {
  PANES.map((file) => {
    describe(file, () => {
      let pane;
      beforeEach(() => {
        spyOn(utils, "reactFactory");
        const Pane = require("../dist/panes/" + file);
        pane = new Pane();
      });
      it("should correctly initialize", () => {
        expect(pane.element instanceof HTMLElement).toBe(true);
        expect(pane.disposer instanceof CompositeDisposable).toBe(true);
        // Be more specific:
        expect(utils.reactFactory).toHaveBeenCalled();
        expect(typeof pane.getTitle()).toBe("string");
        expect(typeof pane.getURI()).toBe("string");
        expect(typeof pane.getDefaultLocation()).toBe("string");
        expect(Array.isArray(pane.getAllowedLocations())).toBe(true);
      });
      it("should corectly destroy", () => {
        spyOn(pane.disposer, "dispose");
        spyOn(pane.element, "remove");
        pane.destroy();
        expect(pane.disposer.dispose).toHaveBeenCalled();
      });
    });
  });
});

"use babel";

import { CompositeDisposable } from "atom";

const PANES = ["inspector", "kernel-monitor", "output-area", "watches"];
const utils = require("../dist/utils");

describe("Panes", () => {
  PANES.map((file) => {
    describe(file, () => {
      let pane;
      beforeEach(() => {
        spyOn(utils, "reactFactory");
        const Pane = require("../dist/panes/" + file).default;
        pane = new Pane();
      });
      it("should correctly initialize", () => {
        expect(pane.element instanceof HTMLElement).toBe(true);
        expect(pane.disposer instanceof CompositeDisposable).toBe(true);
        // Be more specific:
        expect(utils.reactFactory).toHaveBeenCalled();
        expect(typeof pane.getTitle()).toBe("string");
        expect(typeof pane.getURI()).toBe("string");
        expect(typeof pane.getDefaultLocation()).toBe("string");
        expect(Array.isArray(pane.getAllowedLocations())).toBe(true);
      });
      it("should corectly destroy", () => {
        spyOn(pane.disposer, "dispose");
        spyOn(pane.element, "remove");
        pane.destroy();
        expect(pane.disposer.dispose).toHaveBeenCalled();
      });
    });
  });
});

Fix default import of Pane


/**
 * Feature flags configuration.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

exports.featureFlags = {
	widgets: {
		dashboard: {
			enabled: 'development',
		},
		pageDashboard: {
			enabled: 'development',
		},
	},
};

/**
 * Feature flags configuration.
 *
 * Site Kit by Google, Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

exports.featureFlags = {
	widgets: {
		dashboard: {
			enabled: 'development',
		},
		pageDashboard: {
			enabled: 'development',
		},
		userInput: {
			enabled: 'development',
		},
	},
};

Add user0input to feature flags.


// Copyright (C) 2020 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.absolute.prototype.todatetime
---*/

const values = [
  [null, "null"],
  [true, "true"],
  ["iso8601", "iso8601"],
  [2020, "2020"],
  [2n, "2"],
];

const absolute = Temporal.Absolute.from("1975-02-02T14:25:36.123456789Z");

const calendar = Temporal.Calendar.from("iso8601");
for (const [input, output] of values) {
  Temporal.Calendar.from = function(argument) {
    assert.sameValue(argument, output);
    return calendar;
  };

  absolute.toDateTime("UTC", input);
}

Temporal.Calendar.from = function() {
  throw new Test262Error("Should not call Calendar.from");
};

assert.throws(TypeError, () => absolute.toDateTime("UTC", Symbol()));

// Copyright (C) 2020 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.absolute.prototype.todatetime
---*/

const values = [
  [null, "null"],
  [true, "true"],
  ["iso8601", "iso8601"],
  [2020, "2020"],
  [2n, "2"],
];

const absolute = Temporal.Absolute.from("1975-02-02T14:25:36.123456789Z");

const calendar = Temporal.Calendar.from("iso8601");
for (const [input, output] of values) {
  let called = 0;
  Temporal.Calendar.from = function(argument) {
    ++called;
    assert.sameValue(argument, output);
    return calendar;
  };

  const dateTime = absolute.toDateTime("UTC", input);
  assert.sameValue(called, 1);
  assert.sameValue(dateTime.calendar, calendar);
}

Temporal.Calendar.from = function() {
  throw new Test262Error("Should not call Calendar.from");
};

assert.throws(TypeError, () => absolute.toDateTime("UTC", Symbol()));

Improve some tests for calendar conversions.


module.exports = function() {
  return `<html>
    <head>
    </head>
    <body>
      <script src='main.js' type='application/javascript'>
      </script>
    </body>
  </html>`
}

module.exports = function() {
  return `<html>
    <head>
    </head>
    <body>
      <script src='/main.js' type='application/javascript'>
      </script>
    </body>
  </html>`
}

Make sure we allways get /main.js from root.


const path = require('path');

module.exports = (Franz, options) => {
	// Add back button to individual rants
	if ($('.addcomment-btn').length) {
		$('.rantlist').append('
Back

');
	}

	// Add target attribute to app buttons so they open in browser
	$('.app-btns-container a').each( function() {
		$(this).attr('target', '_blank');
	});

	function getMessages() {
		let unread = '';

		if ($('.top-bar-notif.notif-badge').length) {
			unread = $('.top-bar-notif.notif-badge').text();
		}

		Franz.setBadge(unread);
	}

	Franz.loop(getMessages);
};

const path = require('path');

module.exports = (Franz, options) => {
	// Add back button to individual rants
	if ($('.addcomment-btn').length) {
		$('.rantlist').append('
Back

');
	}

	// Add target attribute to app buttons so they open in browser
	$('.app-btns-container a').each( function() {
		$(this).attr('target', '_blank');
	});

	// Add help link to devrant menu
	$('.menu-option-log-out').before('
Franz Integration
');

	function getMessages() {
		let unread = '';

		if ($('.top-bar-notif.notif-badge').length) {
			unread = $('.top-bar-notif.notif-badge').text();
		}

		Franz.setBadge(unread);
	}

	Franz.loop(getMessages);
};

Add help link to devrant menu


// run with
// node test/node-test.js
var QUnit = require("../qunit/qunit");
QUnit.log(function(details) {
	if (!details.result) {
		var output = "FAILED: " + (details.message ? details.message + ", " : "");
		if (details.actual) {
			output += "expected: " + details.expected + ", actual: " + details.actual;
		}
		if (details.source) {
			output += ", " + details.source;
		}
		console.log(output);
	}
});
QUnit.test("yo", function() {
	QUnit.equal(true, false);
	QUnit.equal(true, false, "gotta fail");
});

// run with
// node test/node-test.js
var QUnit = require("../qunit/qunit");
QUnit.log(function(details) {
	if (!details.result) {
		var output = "FAILED: " + (details.message ? details.message + ", " : "");
		if (details.actual) {
			output += "expected: " + details.expected + ", actual: " + details.actual;
		}
		if (details.source) {
			output += ", " + details.source;
		}
		console.log(output);
	}
});
QUnit.test("yo", function() {
	QUnit.equal(true, false);
	QUnit.equal(true, false, "gotta fail");
	x.y.z;
});

Extend nodejs test runner to check for stacktrace output, twice


seajs.config({
  base: './specs/config-base/'
})

define(function(require) {

  var test = require('../../test')
  var a = require('a')

  test.assert(a.name === 'a', a.name)

  seajs.config({
    base: '../'
  })

  var base = seajs.config.data.base
  test.assert(/seajs\/$/.test(base), base)

  test.done()

})

seajs.config({
  base: './specs/config-base/'
})

define(function(require) {

  var test = require('../../test')
  var a = require('a')

  test.assert(a.name === 'a', a.name)

  seajs.config({
    base: './'
  })

  var base = seajs.config.data.base
  test.assert(/tests\/$/.test(base), base)

  test.done()

})

Fix a bug in travis ci environment


/** Default scene sets is a scene that has automatically created camera node. */
var DefaultScene=Scene.extend({
	init: function() {
		this._super();

		// Create default camera node and add camera component to it
		this.root.name="Root";

		this.cameraNode=new Node("Camera");
		this.cameraComponent=this.cameraNode.addComponent(new PerspectiveCamera());
		this.cameraComponent.aspect=false; // Forces PerspectiveCamera to autodetect aspect ratio
		this.camera=this.cameraComponent.camera;	///< Main camera used for rendering scene. Beware! This is not camera component meaning that its view matrix gets overwritten by camera component each frame
		this.root.addNode(this.cameraNode);

		this.lightNode=new Node("Light");
		this.light=new Light();
		this.light.color= new Color(1, 1, 0.98, 1);
		this.light.intensity = 1.15;
		this.light.setLightDirection(vec3.fromValues(0.9, 1.0, 0.9));
		this.lightNode.addComponent(this.light);
		this.root.addNode(this.lightNode);
	}
});

/** Default scene sets is a scene that has automatically created camera node. */
var DefaultScene=Scene.extend({
	init: function() {
		this._super();

		// Create default camera node and add camera component to it
		this.root.name="Root";

		this.cameraNode=new Node("Camera");
		this.cameraComponent=this.cameraNode.addComponent(new PerspectiveCamera());
		this.cameraComponent.aspect=false; // Forces PerspectiveCamera to autodetect aspect ratio
		this.camera=this.cameraComponent.camera;	///< Main camera used for rendering scene. Beware! This is not camera component meaning that its view matrix gets overwritten by camera component each frame
		this.root.addNode(this.cameraNode);

		this.lightNode=new Node("Light");
		this.light=new Light();
		this.light.color= new Color(1, 1, 1, 1);
		this.light.intensity = 1.0;
		this.light.setLightDirection(vec3.fromValues(0.9, 1.0, 0.9));
		this.lightNode.addComponent(this.light);
		this.root.addNode(this.lightNode);
	}
});

Set default light intensity to 1.0


// test/lib/TempDir.js
//

'use strict';

var fs = require('fs');
var path = require('path');
var spawnSync = require('child_process').spawnSync;

var mkdirp = require('mkdirp');
var rimraf = require('rimraf');

var TempDir = {
  tmpLocation: null,

  prepare: function () {
    mkdirp.sync(this.tmpLocation);
  },

  clean: function () {
    rimraf.sync(this.tmpLocation);
  },

  getPath: function (name) {
    return path.join(this.tmpLocation, name);
  },

  read: function (name) {
    return fs.readFileSync(this.getPath(name), 'utf8');
  },

  readJson: function (name) {
    return JSON.parse(this.read(name));
  },

  exists: function (name) {
    return fs.accessSync(path.join(this.tmpLocation, name), fs.F_OK);
  },

  collider: function (args) {
    args = args || [];
    return spawnSync('collider', args, { cwd: this.tmpLocation });
  },
};

module.exports = TempDir;

// test/lib/TempDir.js
//

'use strict';

var cmds = require('../../lib/commands');

var fs = require('fs');
var path = require('path');
var spawnSync = require('child_process').spawnSync;

var mkdirp = require('mkdirp');
var rimraf = require('rimraf');

var TempDir = {
  tmpLocation: null,

  prepare: function () {
    mkdirp.sync(this.tmpLocation);
  },

  clean: function () {
    rimraf.sync(this.tmpLocation);
  },

  getPath: function (name) {
    return path.join(this.tmpLocation, name);
  },

  read: function (name) {
    return fs.readFileSync(this.getPath(name), 'utf8');
  },

  readJson: function (name) {
    return JSON.parse(this.read(name));
  },

  exists: function (name) {
    return fs.accessSync(path.join(this.tmpLocation, name), fs.F_OK);
  },

  runCmd: function (cmd, argv) {
    argv = [cmd].concat(argv);
    return cmds[cmd](argv, this.tmpLocation);
  },

  collider: function (args) {
    args = args || [];
    return spawnSync('collider', args, { cwd: this.tmpLocation });
  },
};

module.exports = TempDir;

Add runCmd method to execute CMD handlers


import glob from 'glob';
import path from 'path';

function loadLanguages() {
  const files = glob
    .sync('src/client/*/i18n/*.js')
    .map(file => {
      const translations = require(path.join(__dirname, '../../../', file));
      const tokens = file.match(/([^/]+)\/i18n\/([^/]+).js$/);
      return {
        language: tokens[2],
        feature: tokens[1],
        translations
      };
    });

  const messages = {};
  const locales = [];

  files.forEach(({language, feature, translations}) => {
    if (!messages[language]) messages[language] = {};
    messages[language][feature] = translations;

    if (locales.indexOf(language) < 0) locales.push(language);
  });

  return {
    formats: {},
    locales,
    messages
  };
}

function extractLocaleFromReq(req, locales) {
  return req.acceptsLanguages(locales);
}

export default function middleware({defaultLocale, getLocaleFromRequest = extractLocaleFromReq}) {
  const {locales, messages} = loadLanguages();

  return (req, res, next) => {
    const locale = getLocaleFromRequest(req, locales);
    if (!messages[locale]) locale = defaultLocale;
    req.i18n = {
      locale,
      messages: messages[locale]
    };
    next();
  };

}

import glob from 'glob';
import path from 'path';
import immutable from 'immutable';
import merger from './merger';

function loadLanguages() {
  const files = glob
    .sync('src/client/*/i18n/*.js')
    .map(file => {
      const translations = require(path.join(__dirname, '../../../', file));
      const tokens = file.match(/([^/]+)\/i18n\/([^/]+).js$/);
      return {
        language: tokens[2],
        feature: tokens[1],
        translations
      };
    });

  const messages = {};
  const locales = [];

  files.forEach(({language, feature, translations}) => {
    if (!messages[language]) messages[language] = {};
    messages[language][feature] = translations;

    if (locales.indexOf(language) < 0) locales.push(language);
  });

  return {
    formats: {},
    locales,
    messages
  };
}

function extractLocaleFromReq(req, locales) {
  return req.acceptsLanguages(locales);
}

export default function middleware({defaultLocale, getLocaleFromRequest = extractLocaleFromReq}) {
  const {locales, messages} = loadLanguages();

  return (req, res, next) => {
    const locale = getLocaleFromRequest(req, locales);
    const defaultMessages = messages[defaultLocale];
    const localeMessages = messages[locale];
    req.i18n = {
      locale,
      messages: defaultLocale !== locale
        ? immutable.fromJS(defaultMessages).mergeWith(merger, localeMessages)
        : defaultMessages
    };
    next();
  };

}

Extend translations with default ones


#!/usr/bin/env node

/*
 * Module dependencies.
 */

var fs = require('fs');
var path = require('path');
var program = require('commander');
var web2splash = require('./../lib/web2splash');

/*
 * Load package.json
 */

var packageJSON = JSON.parse(fs.readFileSync(path.join(__dirname,'..','package.json'), 'utf8'));

/*
 * Command-line usage
 */

program
    .version(packageJSON.version)
    .usage('[options] <input html>')
    .option('-o, --output [path]',           'set output path for images', './output/');

/*
 * Command-line help
 */

program.on('--help', function(){
    console.log('  Examples:');
    console.log('');
    console.log('    $', program.name, '/path/to/splash.html');
    console.log('');
});

/*
 * Parse the command-line
 */

program.parse(process.argv);
program.input = program.args[0];

if (!program.input) {
    console.log('');
    console.log('Error: <input html> must be provided.');
    console.log('');
    return false;
}

/*
 * Render an HTML document to a set of splash screen images
 */

web2splash.onRenderImage = function(image) {
    console.log('  rendered: %s (%d x %dpx)', image.name, image.width, image.height);
};

web2splash.render(program.input, program.output, function(e, images) {
    // complete
});

#!/usr/bin/env node

/*
 * Module dependencies.
 */

var fs = require('fs');
var path = require('path');
var program = require('commander');
var web2splash = require('./../lib/web2splash');

/*
 * Load package.json
 */

var packageJSON = JSON.parse(fs.readFileSync(path.join(__dirname,'..','package.json'), 'utf8'));

/*
 * Command-line usage
 */

program
    .version(packageJSON.version)
    .usage('[options] <input html>')
    .option('-o, --output [path]', 'set output path for images', './');

/*
 * Command-line help
 */

program.on('--help', function(){
    console.log('  Examples:');
    console.log('');
    console.log('    $', program.name, '/path/to/splash.html');
    console.log('');
});

/*
 * Parse the command-line
 */

program.parse(process.argv);
program.input = program.args[0];

if (!program.input) {
    console.log('');
    console.log('Error: <input html> must be provided.');
    console.log('');
    return false;
}

/*
 * Render an HTML document to a set of splash screen images
 */

web2splash.onRenderImage = function(image) {
    console.log('  rendered: %s (%d x %dpx)', image.name, image.width, image.height);
};

web2splash.render(program.input, program.output, function(e, images) {
    // complete
});

Update default output path for bin/


var connect = require( 'connect' ),
    shell = require( 'shelljs' ),
    flick = require( '..' ),
    handler = flick(),
    app = connect();

handler.use( 'romac/romac.github.com', gitPull( '/var/www/romac.me', { rebase: true } ) );

function gitPull( root, options )
{
    return function( req, res, next )
    {
        var cmd = 'git pull' + ( options.rebase ? ' --rebase' : '' );

        shell.cd( root );
        shell.exec( cmd, function( code, output )
        {
            console.log( cmd ' exited with code ' + code );
        } );

        next();
    };
}

app.use( connect.bodyParser() );
app.use( flick.whitelist( { local: true } ) );
app.use( flick.payload() );
app.use( handler );
app.use( function( req, res )
{
    res.writeHead( 200 );
    res.end( 'Thank you, dear friend.\n' );
} );

app.listen( 4001 );
console.log( 'flick is listening on port 4001' );

var connect = require( 'connect' ),
    shell = require( 'shelljs' ),
    flick = require( '..' ),
    handler = flick(),
    app = connect();

handler.use( 'romac/romac.github.com', gitPull( '/var/www/romac.me', { rebase: true } ) );

function gitPull( root, options )
{
    return function( req, res, next )
    {
        var cmd = 'git pull' + ( options.rebase ? ' --rebase' : '' );

        shell.cd( root );
        shell.exec( cmd, function( code, output )
        {
            console.log( cmd ' exited with code ' + code );
        } );

        next();
    };
}

app.use( connect.bodyParser() );

// 1.
app.use( flick.whitelist( { local: true } ) );
app.use( flick.payload() );
app.use( handler );

// 2.
// handler.use( flick.whitelist( { local: true } ) );
// handler.use( flick.payload() );
// app.use( handler );

// 3.
// app.use( flick.default() );

app.use( function( req, res )
{
    res.writeHead( 200 );
    res.end( 'Thank you, dear friend.\n' );
} );

app.listen( 4001 );
console.log( 'flick is listening on port 4001' );

Update the example with different usage example.


"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var index_1 = require("../../index");
({});
var Foo = { 'foo': "foo" };
console.log(Foo.foo);
({ foo: "foo", 'bar': "bar" }.bar);
var FooBarBaz = { 'foo': "foo", 'bar': "bar", 'baz': "baz" };
FooBarBaz.ping = 'pong';
function enumerate() {
    return '';
}
var a = enumerate();
index_1.enumerate.toString();
var MyClass = /** @class */ (function () {
    function MyClass() {
    }
    MyClass.prototype.enumerate = function () {
        return {};
    };
    return MyClass;
}());

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var index_1 = require("../../index");
({});
var Foo = { 'foo': "foo" };
console.log(Foo.foo);
({ 'foo': "foo", 'bar': "bar" }.bar);
var FooBarBaz = { 'foo': "foo", 'bar': "bar", 'baz': "baz" };
FooBarBaz.ping = 'pong';
function enumerate() {
    return '';
}
var a = enumerate();
index_1.enumerate.toString();
var MyClass = /** @class */ (function () {
    function MyClass() {
    }
    MyClass.prototype.enumerate = function () {
        return {};
    };
    return MyClass;
}());

Update objects in tests to have quotes (again)


/**
 *
 */
module.exports = {
  extends: 'airbnb-base',

  env: {
    jest: true,
  },

  rules: {
    'no-underscore-dangle': ['off'],
    'global-require': ['off'],
    'no-use-before-define': ['warn'],
    'brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
    'import/prefer-default-export': ['off'],
    'import/imports-first': ['off'],
    'import/no-extraneous-dependencies': ['error', {
      devDependencies: ['**/*.test.js', '**/__mocks__/**', '**/__fixtures__/**'],
    }],
    'max-len': ['error', 150, 2, {
      ignoreUrls: true,
      ignoreComments: true,
      ignoreStrings: true,
      ignoreTemplateLiterals: true,
    }],
  },
};

/**
 *
 */
module.exports = {
  extends: 'airbnb-base',

  env: {
    jest: true,
  },

  rules: {
    'no-duplicate-imports': ['off'],
    'no-underscore-dangle': ['off'],
    'global-require': ['off'],
    'no-use-before-define': ['warn'],
    'brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
    'import/prefer-default-export': ['off'],
    'import/imports-first': ['off'],
    'import/no-extraneous-dependencies': ['error', {
      devDependencies: ['**/*.test.js', '**/__mocks__/**', '**/__fixtures__/**'],
    }],
    'max-len': ['error', 150, 2, {
      ignoreUrls: true,
      ignoreComments: true,
      ignoreStrings: true,
      ignoreTemplateLiterals: true,
    }],
  },
};

Allow duplicate imports (useful when importing flow types)


AutofocusableTags = ['input', 'textarea', 'button'];

var autofocusSelector = _.map(AutofocusableTags, function (tag) {
  return tag + '[autofocus]';
}).join(', ');

var _super = Template.prototype.constructView;

Template.prototype.constructView = function (/* arguments */) {
  var args = Array.prototype.slice.call(arguments);
  var view = _super.apply(this, args);
  view.onViewReady(function () {
    var tpl = Template.instance();
    var autofocusField = tpl && tpl.find(autofocusSelector);
    if (autofocusField) {
      autofocusField.focus();
    }
  });
  return view;
};

AutofocusableTags = ['input', 'textarea', 'button'];

var autofocusSelector = _.map(AutofocusableTags, function (tag) {
  return tag + '[autofocus]';
}).join(', ');

var autofocusRenderedCallback = function() {
  var autofocusField = this.find(autofocusSelector);
  if (autofocusField) {
    autofocusField.focus();
  }
}

var _super = Template.prototype._getCallbacks;
Template.prototype._getCallbacks = function(which) {
  var callbacks = _super.call(this, which);
  if (which === 'rendered') {
    callbacks.push(autofocusRenderedCallback);
  }
  return callbacks;
};

Fix the implementation for the upcoming release of Meteor (v1.0.4)


const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  // webpack folder's entry js - excluded from jekll's build process.
  entry: './webpack/entry.js',
  output: {
    // we're going to put the generated file in the assets folder so jekyll will grab it.
    path: path.resolve(__dirname, './assets/js/'),
    filename: 'bundle.js',
  },
  stats: {
    assets: true,
    children: false,
    chunks: false,
    errors: true,
    errorDetails: true,
    modules: false,
    timings: true,
    colors: true,
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            js: 'babel?presets[]=es2015',
          },
        },
      },
      {
        test: /\.js?$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
      },
    ],
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
    },
    extensions: ['*', '.js', '.vue', '.json'],
  },
  plugins: [
    new VueLoaderPlugin(),
  ],
};

const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  // webpack folder's entry js - excluded from jekll's build process.
  entry: './webpack/entry.js',
  output: {
    // we're going to put the generated file in the assets folder so jekyll will grab it.
    path: path.resolve(__dirname, '../assets/js/'),
    filename: 'bundle.js',
  },
  stats: {
    assets: true,
    children: false,
    chunks: false,
    errors: true,
    errorDetails: true,
    modules: false,
    timings: true,
    colors: true,
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            js: 'babel?presets[]=es2015',
          },
        },
      },
      {
        test: /\.js?$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
      },
    ],
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
    },
    extensions: ['*', '.js', '.vue', '.json'],
  },
  plugins: [
    new VueLoaderPlugin(),
  ],
};

Fix for webpack output location on CI server (part deux)


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

module.exports = {
  devtool: 'cheap-module-eval-source-map',
  entry: [
    'webpack-hot-middleware/client',
    './index'
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ],
  module: {
    loaders: [
      {
        test: /\.js$/,
        loaders: ['babel'],
        exclude: /node_modules/,
        include: __dirname
      },
      {
        test: /\.css$/,
        loader: 'style.css?modules&localIdentName=[name]---[local]---[hash:base64:5]'
      }
    ]
  }
}

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

module.exports = {
  devtool: 'cheap-module-eval-source-map',
  entry: [
    'webpack-hot-middleware/client',
    './index'
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ],
  module: {
    loaders: [
      {
        test: /\.js$/,
        loaders: ['babel'],
        exclude: /node_modules/,
        include: __dirname
      },
      {
        test: /\.css$/,
        loaders: ['style', 'css']
      }
    ]
  }
}

Use simpler syntax for webpack CSS loaders


/* eslint-env node */

module.exports = {
  entry: './DayPicker.js',
  devtool: 'source-map',
  output: {
    path: __dirname + '/dist',
    filename: 'DayPicker.js',
    library: 'DayPicker',
    libraryTarget: 'var',
  },
  externals: {
    react: 'React',
  },
};

/* eslint-env node */

module.exports = {
  entry: './DayPicker.js',
  devtool: 'source-map',
  output: {
    path: __dirname + '/dist',
    filename: 'DayPicker.js',
    library: 'DayPicker',
    libraryTarget: 'umd'
  },
  externals: {
    'react': {
      root: 'React',
      commonjs2: 'react',
      commonjs: 'react',
      amd: 'react'
    }
  },
};

Build the library as a UMD module


var find_common_pkg = function(pkglist) {
    var common = [pkglist[0].split(/\./)];
    pkglist.forEach(function(pkg) {
        var spl = pkg.split(/\./);
        var fnd = false;
        common.forEach(function(com, ind) {
            if (spl[0] === com[0]) {
                common[ind] = spl.filter(function(n) {
                    return com.indexOf(n) != -1;
                });
                fnd = true;
            }
        });
        if (!fnd) common.push(spl);
    });

    var strjoin = [];
    common.forEach(function(arg) {
        strjoin.push(arg.join("."));
    });
    return strjoin;
};

var arr_to_vector = function(arr) {
    var vec = $('java.util.Vector');
    var vector = new vec();
    arr.forEach(function(thing) {
        vector.add(thing);
    });
    return vector;
};

$.command("eval", function() {
    var fcmd = [].slice.call(arguments).join(" ");
    eval(fcmd);
});

Add eval command for JS scripting


// scripts for header

// for capitalizing id
String.prototype.capitalize = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
};

// detects scroll for top resizing and lower nav show
$(window).scroll(function() {
  if ($(document).scrollTop() > 50) {
    $('.main-nav').addClass('shrink');
    if ($('#inner-page-links').children().length > 0) {
      $('.navbar-lower').removeClass('hide-lower');
    }
  } else {
    $('.main-nav').removeClass('shrink');
    $('.navbar-lower').addClass('hide-lower');
  }
});

// fills in lower nav with inner page links
$(document).ready(function(){
  $('.accordion-heading').addClass('link');
  $('.link').each(function(i, obj) {
     $("#inner-page-links").append('
'+obj.id.capitalize()+'
');
  });
  $(".scroll-link").each(function(i, obj) {
    $(obj).click(function() {
      scrollToAnchor(obj.text.toLowerCase());
    });
  });
  if ($('#inner-page-links').children().length < 1) {
    $('.navbar-lower').addClass('hide-lower');
  }
});

// for smooth scrolling
function scrollToAnchor(aid){
    var aTag = $('#'+aid);
    if(aTag.length){
      $('html, body').animate({scrollTop:$(aTag).position().top}, 'slow');
    }
}

// scripts for header

// for capitalizing id
String.prototype.capitalize = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
};

// detects scroll for top resizing and lower nav show
$(window).scroll(function() {
  if ($(document).scrollTop() > 50) {
    $('.main-nav').addClass('shrink');
    if ($('#inner-page-links').children().length > 0) {
      $('.navbar-lower').removeClass('hide-lower');
    }
  } else {
    $('.main-nav').removeClass('shrink');
    $('.navbar-lower').addClass('hide-lower');
  }
});

// fills in lower nav with inner page links
$(document).ready(function(){
  $('.accordion-heading').addClass('link');
  $('.link').each(function(i, obj) {
     $("#inner-page-links").append('
'+obj.title.capitalize()+'
');
  });
  $(".scroll-link").each(function(i, obj) {
    $(obj).click(function() {
      scrollToAnchor(obj.text.toLowerCase());
    });
  });
  if ($('#inner-page-links').children().length < 1) {
    $('.navbar-lower').addClass('hide-lower');
  }
});

// for smooth scrolling
function scrollToAnchor(aid){
    var aTag = $('#'+aid);
    if(aTag.length){
      $('html, body').animate({scrollTop:$(aTag).position().top}, 'slow');
    }
}

Use title property instead of id, since id usually has string constraints (used for URLs). Title is something different that we can make whatever we want


import { connect } from 'react-redux'
import { fetchQueue, queueSong } from '../modules/queue'
import QueueView from '../components/QueueView'

//  Object of action creators (can also be function that returns object).
const mapActionCreators = {
  fetchQueue,
  queueSong
}

const mapStateToProps = (state) => ({
  queuedIds: state.queue.result,
  queuedItems: state.queue.entities,
  errorMessage: state.queue.errorMessage,
  // library data
  artistIds: state.library.artists.result,
  artists: state.library.artists.entities,
  songUIDs: state.library.songs.result,
  songs: state.library.songs.entities,
})

export default connect(mapStateToProps, mapActionCreators)(QueueView)

import { connect } from 'react-redux'
import { fetchQueue, queueSong } from '../modules/queue'
import QueueView from '../components/QueueView'

//  Object of action creators (can also be function that returns object).
const mapActionCreators = {
  fetchQueue,
  queueSong
}

const mapStateToProps = (state) => ({
  queuedIds: state.queue.result,
  queuedItems: state.queue.entities,
  errorMessage: state.queue.errorMessage,
  // library data
  artistIds: state.library.artists.result,
  artists: state.library.artists.entities,
  songUIDs: state.library.songs.result,
  songs: state.library.songs.entities,
  // user data
  user: state.account.user,
})

export default connect(mapStateToProps, mapActionCreators)(QueueView)

Connect current user data to Queue view


"use strict";

const webpack = require("webpack");

const DEV_ENV = "development";
const NODE_ENV = process.env.NODE_ENV || DEV_ENV;

module.exports = {
  entry: "./home",
  output: {
    filename: "build.js",
    library: "home"
  },

  watch: NODE_ENV == DEV_ENV,

  watchOptions: {
    aggregateOptions: 100
  },

  devtool: NODE_ENV == DEV_ENV ? "cheap-inline-module-source-map" : null,

  plugins: [
    new webpack.DefinePlugin({
      NODE_ENV: JSON.stringify(NODE_ENV),
      LANG: '"ru"'
    })
  ],

  resolve: {
    modulesDirectories: ["node_modules"],
    extentions: ["", ".js"]
  },

  resolveLoader: {
    modulesDirectories: ["node_modules"],
    moduleTemplates: ["*-loader", "*"],
    extentions: ["", ".js"]
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel"
      }
    ]
  }
};

"use strict";

const webpack = require("webpack");

const DEV_ENV = "development";
const PRODUCTION_ENV = "production";
const NODE_ENV = process.env.NODE_ENV || DEV_ENV;

module.exports = {
  entry: "./home",
  output: {
    filename: "build.js",
    library: "home"
  },

  watch: NODE_ENV == DEV_ENV,

  watchOptions: {
    aggregateOptions: 100
  },

  devtool: NODE_ENV == DEV_ENV ? "cheap-inline-module-source-map" : null,

  plugins: [
    new webpack.DefinePlugin({
      NODE_ENV: JSON.stringify(NODE_ENV),
      DEV_ENV: JSON.stringify(DEV_ENV),
      LANG: '"ru"'
    })
  ],

  resolve: {
    modulesDirectories: ["node_modules"],
    extentions: ["", ".js"]
  },

  resolveLoader: {
    modulesDirectories: ["node_modules"],
    moduleTemplates: ["*-loader", "*"],
    extentions: ["", ".js"]
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel"
      }
    ]
  }
};

if (NODE_ENV == PRODUCTION_ENV) {
  module.exports.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        // don't show anreachable variables etc
        warnings: false,
        drop_console: false,
        unsafe: true
      }
    })
  )
}

Use DEV_ENV to webpack.DefinePlugin. Add PRODUCTION_ENV constant. Use webpack.optimize.UglifyJsPlugin if PRODUCTION_ENV


var webpack = require('webpack');

module.exports = {
  entry: {
    main: ['babel-polyfill', './lib/index.js'],
    test: ['babel-polyfill', 'mocha!./test/index.js']
  },
  output: {
    path: __dirname,
    filename: '[name].bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'react']
        }
      },
      { test: /\.css$/, loader: 'style!css' },
      { test: /\.scss$/, loader: 'style!css!sass' }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.jsx', '.json', '.scss', '.css'],
    alias: {
      'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
    }
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    })
  ]
};

const webpack = require('webpack');

module.exports = {
  entry: {
    main: ['babel-polyfill', './lib/index.js'],
    test: ['babel-polyfill', 'mocha!./test/index.js'],
  },
  output: {
    path: __dirname,
    filename: '[name].bundle.js',
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'react'],
        },
      },
      { test: /\.css$/, loader: 'style!css' },
      { test: /\.scss$/, loader: 'style!css!sass' },
    ],
  },
  resolve: {
    extensions: ['', '.js', '.jsx', '.json', '.scss', '.css'],
    alias: {
      'jquery-ui': 'jquery-ui-dist/jquery-ui.js',
    },
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
    }),
  ],
};

Change var to const for webpack.


const path = require('path');
const webpack = require('webpack');
const manifest = require('./package.json');

const mainFile = manifest.main;
const packageName = manifest.name;
const destinationDirectory = path.dirname(mainFile);
const exportFileName = path.basename(mainFile, path.extname(mainFile));

module.exports = {
  entry: ['./src/formwood.js'],
  output: {
    path: path.resolve(__dirname, destinationDirectory),
    filename: `${exportFileName}.js`,
    library: packageName,
    libraryTarget: 'umd'
  },
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: {loader: 'babel-loader'}
    }]
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false
    }),
    new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      mangle: {keep_fnames: true},
      comments: false
    })
  ]
};

const path = require('path');
const webpack = require('webpack');
const manifest = require('./package.json');

const mainFile = manifest.main;
const packageName = manifest.name;
const destinationDirectory = path.dirname(mainFile);
const exportFileName = path.basename(mainFile, path.extname(mainFile));

module.exports = {
  entry: ['./src/formwood.js'],
  output: {
    path: path.resolve(__dirname, destinationDirectory),
    filename: `${exportFileName}.js`,
    library: packageName,
    libraryTarget: 'umd'
  },
  externals: ['react'],
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: {loader: 'babel-loader'}
    }]
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false
    }),
    new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      mangle: {keep_fnames: true},
      comments: false
    })
  ]
};

Exclude react from the build


var path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
};

var path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  module: {
    rules: [
      {test: /\.js$/, use: "babel-loader"},
    ],
  },
};

Use babel-loader for .js files


"use strict";

function transformWildcardToPattern(wildcardString) {
  var length = wildcardString.length;
  var character;
  var pattern = '';
  if(wildcardString === '') {
    pattern = '^$';
  } else {
    for (var index = 0; index < length; index++) {
      character = wildcardString.charAt(index);
      if (character === '*') {
        pattern = pattern + '.*'
      } else {
        pattern = pattern + character;
      }
    }
  }
  return pattern;
};

function transformArrayToPattern(arrayOfWildcardStrings) {
  var length = arrayOfWildcardStrings.length;
  var wildcardString;
  var nextSubPattern;
  var pattern = '';
  for (var index = 0; index < length; index++) {
    wildcardString = arrayOfWildcardStrings[index];
    nextSubPattern = transformWildcardToPattern(wildcardString);
    if (index === 0) {
      pattern = pattern + nextSubPattern;
    } else {
      pattern = pattern + '|' + nextSubPattern;
    }
  }
  return pattern;
};

function wildcardRegex(stringOrArray) {
  var pattern;
  if (stringOrArray.constructor === String) {
    pattern = transformWildcardToPattern(stringOrArray);
  } else if (stringOrArray.constructor === Array) {
    pattern = transformArrayToPattern(stringOrArray);
  } else {
    throw TypeError('WildcardRegex only accepts a string or array as an argument');
  }
  var regex = new RegExp(pattern);
  return regex;
};

module.exports = wildcardRegex;

"use strict";

function transformWildcardToPattern(wildcardString) {
  var length = wildcardString.length;
  var character;
  var pattern = '^';
  for (var index = 0; index < length; index++) {
    character = wildcardString.charAt(index);
    if (character === '*') {
      pattern = pattern + '.*'
    } else {
      pattern = pattern + character;
    }
  }
  pattern = pattern + '$';
  return pattern;
};

function transformArrayToPattern(arrayOfWildcardStrings) {
  var length = arrayOfWildcardStrings.length;
  var wildcardString;
  var nextSubPattern;
  var pattern = '';
  for (var index = 0; index < length; index++) {
    wildcardString = arrayOfWildcardStrings[index];
    nextSubPattern = transformWildcardToPattern(wildcardString);
    if (index === 0) {
      pattern = pattern + nextSubPattern;
    } else {
      pattern = pattern + '|' + nextSubPattern;
    }
  }
  return pattern;
};

function wildcardRegex(stringOrArray) {
  var pattern;
  if (stringOrArray.constructor === String) {
    pattern = transformWildcardToPattern(stringOrArray);
  } else if (stringOrArray.constructor === Array) {
    pattern = transformArrayToPattern(stringOrArray);
  } else {
    throw TypeError('WildcardRegex only accepts a string or array as an argument');
  }
  var regex = new RegExp(pattern);
  return regex;
};

module.exports = wildcardRegex;

Enforce beginning and ending of transformed RegExp patterns


var exec = require('cordova/exec');

exports.coolMethod = function(arg0, success, error) {
    exec(success, error, "open", "coolMethod", [arg0]);
};

var exec = require('cordova/exec');

exports.open = function(args, success, error) {
  var argsArray =
    (Object.prototype.toString.call(args) === '[object Array]') ? args : [args];

  function defaultSuccess() {
    if (typeof success === 'function') {
      success();
    }
  }

  function defaultError() {
    if (typeof error === 'function') {
      error();
    }
  }
  exec(defaultSuccess, defaultError, "open", "open", [argsArray]);
};

Add default methods for plugin


var window = window || {};
var self = self || {};

// High-resulution counter: emulate window.performance.now() for THREE.CLOCK
if( window.performance === undefined ) {

	window.performance = { };

}

if( window.performance.now === undefined ) {

	window.performance.now = function () {

		var time = process.hrtime();
		return ( time[0] + time[1] / 1e9 ) * 1000;

	};

}

Use process.hrtime() for Clock in node.js builds


/**
 * @fileOverview Level 01 controller.
 */

var Vector = require('../vector/main.vector');
var Level = require('../level/level.base');

/**
 * Level 01 controller.
 *
 * @constructor
 */
var Level01 = module.exports = function () {
};

/**
 * Initialize Level 01.
 *
 */
Level01.prototype.init = function() {

  this.vector = new Vector();

  var levelPart1 = new Level(this.vector);
  var levelPartLoop1 = new Level(this.vector);

  levelPartLoop1.makePlaceholderOperation(600, 400);
  levelPartLoop1.makePlaceholderOperation(650, 420);

  var level = new Level(this.vector);

  level.makeLine(50,200, 500, 200);

  level.makePlaceholderIfLoop({
    x1: 500,
    y1: 200,
    routeZero: levelPart1,
    routeLoop: levelPartLoop1,
  });

  this.vector.update();
};

/**
 * @fileOverview Level 01 controller.
 */

var Vector = require('../vector/main.vector');
var Level = require('../level/level.base');

/**
 * Level 01 controller.
 *
 * @constructor
 */
var Level01 = module.exports = function () {
};

/**
 * Initialize Level 01.
 *
 */
Level01.prototype.init = function() {

  this.vector = new Vector();

//  var levelPart1 = new Level(this.vector);
//  var levelPartLoop1 = new Level(this.vector);

//  levelPartLoop1.makePlaceholderOperation(600, 400);
//  levelPartLoop1.makePlaceholderOperation(650, 420);

  var level = new Level(this.vector);

  level.makeLine(50,200, 500, 200);

//  level.makePlaceholderIfLoop({
//    x1: 500,
//    y1: 200,
//    routeZero: levelPart1,
//    routeLoop: levelPartLoop1,
//  });

  this.vector.update();
};

Comment out unimplemented methods invocation


module.exports = {
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true,
        "node": true,
        "mocha": true
    },
    "extends": "eslint:recommended",
    "plugins": ["eslint-plugin-jsdoc", "eslint-plugin-markdown"],
    "parserOptions": {
        "ecmaVersion": 2018
    },
    "overrides": {
      files: ["**/*.md"],
      rules: {
        "eol-last": ["off"],
        "no-console": ["off"],
        "no-undef": ["off"],
        "no-unused-vars": ["warn"],
        "padded-blocks": ["off"],
        "import/unambiguous": ["off"],
        "import/no-unresolved": ["off"],
        "node/no-missing-import": ["off"]
      }
    },
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "double"
        ],
        "semi": [
            "error",
            "always"
        ],
        "no-console": ["off"]
    }
};

module.exports = {
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true,
        "node": true,
        "mocha": true
    },
    "extends": "eslint:recommended",
    "plugins": ["eslint-plugin-jsdoc", "eslint-plugin-markdown"],
    "parserOptions": {
        "ecmaVersion": 2018
    },
    "overrides": {
      files: ["**/*.md"],
      rules: {
        "eol-last": ["off"],
        "no-console": ["off"],
        "no-undef": ["off"],
        "no-unused-vars": ["warn"],
        "padded-blocks": ["off"],
        "import/unambiguous": ["off"],
        "import/no-unresolved": ["off"],
        "node/no-missing-import": ["off"]
      }
    },
    "rules": {
        "indent": [
            "error",
            4,
            { "SwitchCase": 1 }
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "double"
        ],
        "semi": [
            "error",
            "always"
        ],
        "no-console": ["off"]
    }
};

Fix linting rule for switch-case indentation


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

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

Remove nonexistent js services directory


//= require jquery
//= require jquery_ujs
//= require jquery.remotipart
//= require select2
//= require cocoon
//= require dropzone
//= require moj
//= require modules/moj.cookie-message
//= require_tree .

/*For JSHint to ignore ADP object*/
/* globals rorData */

var moj = moj || {};

moj.Modules.devs.init = function(){};

// Accordion
$('#claim-accordion h2').each(function(){
  $(this).next('section').hide();
  $(this).click(function(){
    $(this).toggleClass('open').next('section').slideToggle('slow');
  });
});
$('#claim-accordion h2:first-of-type').addClass('open').next('section').show();

$('#footer').css('margin-top', $(document).height() - ($('#global-header').height() + $('.outer-block:eq(1)').height()  ) - $('#footer').height());

$('#fixed-fees, #misc-fees, #expenses, #documents').on('cocoon:after-insert', function(e, insertedItem) {
  $(insertedItem).find('.select2').select2();
});

//Stops the form from submitting when the user presses 'Enter' key
$("#claim-form form").on("keypress", function (e) {
  if (e.keyCode === 13) {
      return false;
  }
});

moj.init();

//= require jquery
//= require jquery_ujs
//= require jquery.remotipart
//= require select2
//= require cocoon
//= require dropzone
//= require moj
//= require modules/moj.cookie-message
//= require_tree .

(function () {
  "use strict";

  delete moj.Modules.devs;

  // Accordion
  $('#claim-accordion')
    .find('h2')
      .next('section').hide()
      .parent()
    .on('click', 'h2', function(e, animationDuration) {
      $(this).toggleClass('open').next('section').slideToggle(animationDuration);
    })
    .find('h2:first-of-type').trigger('click', 0);

  $('#fixed-fees, #misc-fees, #expenses, #documents').on('cocoon:after-insert', function (e, insertedItem) {
    $(insertedItem).find('.select2').select2();
  });

  //Stops the form from submitting when the user presses 'Enter' key
  $("#claim-form form").on("keypress", function (e) {
    if (e.keyCode === 13) {
      return false;
    }
  });

  moj.init();
}());

Fix JSHint warnings, refactor accordion, remove footer margins


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require foundation
//= require turbolinks
//= require_tree
//= require d3

$(function(){ $(document).foundation(); });

var loader = document.getElementById('loader');

startLoading();
function startLoading() {
  $("#map").toggleClass("loading");
  loader.className = '';
}

function finishedLoading() {
  loader.className = 'done';
  setTimeout(function() {
    loader.className = 'hide';
  }, 500);
  $("#map").toggleClass("loading");
}

Remove loader js - moved to own file


import AsyncStorage from '@react-native-community/async-storage';
import { persistStore, persistReducer } from 'redux-persist';
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import { createReactNavigationReduxMiddleware } from 'react-navigation-redux-helpers';
import reducers from './reducers';

// Create middleware and connect
const appNavigatorMiddleware = createReactNavigationReduxMiddleware(state => state.nav, 'root');

const persistConfig = {
  keyPrefix: '',
  key: 'root',
  storage: AsyncStorage,
  blacklist: ['nav', 'pages', 'user', 'prescription'],
};

const persistedReducer = persistReducer(persistConfig, reducers);

const store = createStore(persistedReducer, {}, applyMiddleware(thunk, appNavigatorMiddleware));

const persistedStore = persistStore(store);

export { store, persistedStore };

import AsyncStorage from '@react-native-community/async-storage';
import { persistStore, persistReducer } from 'redux-persist';
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import { createReactNavigationReduxMiddleware } from 'react-navigation-redux-helpers';
import reducers from './reducers';

// Create middleware and connect
const appNavigatorMiddleware = createReactNavigationReduxMiddleware(state => state.nav, 'root');

const persistConfig = {
  keyPrefix: '',
  key: 'root',
  storage: AsyncStorage,
  blacklist: ['nav', 'pages', 'user', 'prescription', 'patient'],
};

const persistedReducer = persistReducer(persistConfig, reducers);

const store = createStore(persistedReducer, {}, applyMiddleware(thunk, appNavigatorMiddleware));

const persistedStore = persistStore(store);

export { store, persistedStore };

Add blacklisting of PatientReducer in redux store


// This is stage 1, it can be changed but you must bump the version of the project.
// Note: This must only be loaded from inside of a sandbox-iframe.
define([
    '/common/requireconfig.js',
    '/common/test.js'
], function (RequireConfig, Test) {
    require.config(RequireConfig());

    // most of CryptPad breaks if you don't support isArray
    if (!Array.isArray) {
        Array.isArray = function(arg) { // CRYPTPAD_SHIM
            return Object.prototype.toString.call(arg) === '[object Array]';
        };
    }

    var mkFakeStore = function () {
        var fakeStorage = {
            getItem: function (k) { return fakeStorage[k]; },
            setItem: function (k, v) { fakeStorage[k] = v; return v; },
            removeItem: function (k) { delete fakeStorage[k]; }
        };
        return fakeStorage;
    };
    window.__defineGetter__('localStorage', function () { return mkFakeStore(); });
    window.__defineGetter__('sessionStorage', function () { return mkFakeStore(); });

    window.CRYPTPAD_INSIDE = true;

    // This test is for keeping the testing infrastructure operating
    // until all tests have been registered.
    // This test is completed in common-interface.js
    Test(function (t) { Test.__ASYNC_BLOCKER__ = t; });

    require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]);
});

// This is stage 1, it can be changed but you must bump the version of the project.
// Note: This must only be loaded from inside of a sandbox-iframe.
define([
    '/common/requireconfig.js',
    '/common/test.js'
], function (RequireConfig, Test) {
    require.config(RequireConfig());

    // most of CryptPad breaks if you don't support isArray
    if (!Array.isArray) {
        Array.isArray = function(arg) { // CRYPTPAD_SHIM
            return Object.prototype.toString.call(arg) === '[object Array]';
        };
    }

    // RPC breaks if you don't support Number.MAX_SAFE_INTEGER
    if (Number && !Number.MAX_SAFE_INTEGER) {
        Number.MAX_SAFE_INTEGER = 9007199254740991;
    }

    var mkFakeStore = function () {
        var fakeStorage = {
            getItem: function (k) { return fakeStorage[k]; },
            setItem: function (k, v) { fakeStorage[k] = v; return v; },
            removeItem: function (k) { delete fakeStorage[k]; }
        };
        return fakeStorage;
    };
    window.__defineGetter__('localStorage', function () { return mkFakeStore(); });
    window.__defineGetter__('sessionStorage', function () { return mkFakeStore(); });

    window.CRYPTPAD_INSIDE = true;

    // This test is for keeping the testing infrastructure operating
    // until all tests have been registered.
    // This test is completed in common-interface.js
    Test(function (t) { Test.__ASYNC_BLOCKER__ = t; });

    require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]);
});

Fix 'NaN' txid for RPC when using IE


$('[data-clipboard]').each(function() {
  var text = $(this).parent().find('code').text().replace('<', '<').replace('>', '>');
  var clipboard = new Clipboard(this, {text: function() {return text}});
  clipboard.on('success', function(e) {
    $(e.trigger).text('Copied!');
    e.clearSelection();
  });
});

$('[data-clipboard]').each(function() {
  var self = this;
  var clipboard = new Clipboard(this, {text: function() {
    var text = $(self).parents('.code-box').find('code:visible').text().replace('<', '<').replace('>', '>');
    return text;
  }});
  clipboard.on('success', function(e) {
    $(e.trigger).text('Copied!');
    e.clearSelection();
  });
});

Fix copy in new markup structure


/**
 * Ripple Client Configuration
 *
 * Copy this file to config.js and edit to suit your preferences.
 */
var Options = {
  server: {
    "trusted" : true,
    "websocket_ip" : "s1.ripple.com",
    "websocket_port" : 51233,
    "websocket_ssl" : true
//    "websocket_ip" : "127.0.0.1",
//    "websocket_port" : 5006,
//    "websocket_ssl" : false
  },
  blobvault : "https://blobvault.payward.com",

  // If set, login will persist across sessions (page reload). This is mostly
  // intended for developers, be careful about using this in a real setting.
  persistent_auth : false,

  // Number of transactions each page has in balance tab notifications
  transactions_per_page: 50
};

// Load client-side overrides
if (store.enabled) {
  $.extend(true, Options, JSON.parse(store.get('ripple_settings') || "{}"));
}

/**
 * Ripple Client Configuration
 *
 * Copy this file to config.js and edit to suit your preferences.
 */
var Options = {
  server: {
    "trusted" : true,
    "websocket_ip" : "s1.ripple.com",
    "websocket_port" : 51233,
    "websocket_ssl" : true
//    "websocket_ip" : "127.0.0.1",
//    "websocket_port" : 5006,
//    "websocket_ssl" : false
  },
  blobvault : "https://blobvault.payward.com",

  // If set, login will persist across sessions (page reload). This is mostly
  // intended for developers, be careful about using this in a real setting.
  persistent_auth : false,

  // Number of transactions each page has in balance tab notifications
  transactions_per_page: 50,

  // Configure bridges
  bridge: {
    out: {
//    "bitcoin": "localhost:3000"
    }
  }
};

// Load client-side overrides
if (store.enabled) {
  $.extend(true, Options, JSON.parse(store.get('ripple_settings') || "{}"));
}

Add config example for Bitcoin outbound bridge.


function getVariables(showIf, operator) {
  if ( showIf.indexOf(operator) > -1 ) {
    const array = showIf.split(operator);

    if ( array.length === 2 ) {
      return {
        left:  array[0],
        right: array[1]
      };
    } else {
      return null;
    }
  }

  return null;
}

function getAnswer(variable, questions) {
  const found = questions.find((q) => q.variable === variable);

  if ( found ) {
    return found.answer;
  } else {
    return variable;
  }
}

export function evaluate(question, allQuestions) {
  if ( !question.showIf ) {
    return true;
  }

  const and = question.showIf.split('&&');

  const result = and.every((showIf) => {
    showIf = showIf.trim();
    const variables = getVariables(showIf, '=');

    if ( variables ) {
      const left = stringifyAnswer(getAnswer(variables.left, allQuestions));
      const right = stringifyAnswer(variables.right);

      return left === right;
    }

    return false;
  });

  return result;
}

export function stringifyAnswer(answer) {
  if ( answer === undefined || answer === null ) {
    return '';
  } else if ( typeof answer === 'string' ) {
    return answer;
  } else {
    return `${ answer  }`;
  }
}

import { get } from '@ember/object'

function getVariables(showIf, operator) {
  if ( showIf.indexOf(operator) > -1 ) {
    const array = showIf.split(operator);

    if ( array.length === 2 ) {
      return {
        left:  array[0],
        right: array[1]
      };
    } else {
      return null;
    }
  }

  return null;
}

function getAnswer(variable, questions) {
  const found = questions.find((q) => q.variable === variable);

  if ( found ) {
    return found.answer;
  } else {
    return variable;
  }
}

function isEqual(showIf, allQuestions) {
  showIf = showIf.trim();
  const variables = getVariables(showIf, '=');

  if ( variables ) {
    const left = stringifyAnswer(getAnswer(variables.left, allQuestions));
    const right = stringifyAnswer(variables.right);

    return left === right;
  }

  return false;
}

export function evaluate(question, allQuestions) {
  if ( !question.showIf ) {
    return true;
  }

  const and = question.showIf.split('&&');
  const or = question.showIf.split('||');

  let result;

  if ( get(or, 'length') > 1 ) {
    result = or.some((showIf) => isEqual(showIf, allQuestions));
  } else {
    result = and.every((showIf) => isEqual(showIf, allQuestions));
  }

  return result;
}

export function stringifyAnswer(answer) {
  if ( answer === undefined || answer === null ) {
    return '';
  } else if ( typeof answer === 'string' ) {
    return answer;
  } else {
    return `${ answer  }`;
  }
}

Support or for catalog question


import React from 'react'

export default class BlockRoot extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const {widthUnits, extraStyles} = this.props;
    const widthPx = 64*widthUnits - 2;

    return (

{this.props.children}

    );
  }
}

Fix issue with block overflow


export default function maReferencedListColumn(NgAdminConfiguration) {
    return {
        scope: {
            'field': '&',
            'datastore': '&'
        },
        restrict: 'E',
        link: {
            pre: function(scope) {
                scope.field = scope.field();
                var targetEntity = scope.field.targetEntity();
                scope.entries = scope.datastore().getEntries(targetEntity.uniqueId + '_list');
                scope.entity = NgAdminConfiguration().getEntity(targetEntity.name());
            }
        },
        template: `
<ma-datagrid ng-if="::entries.length > 0" name="{{ field.datagridName() }}"
    entries="::entries"
    fields="::field.targetFields()"
    list-actions="::field.listActions()"
    entity="::entity"
    datastore="::datastore()">
</ma-datagrid>`
    };
}

maReferencedListColumn.$inject = ['NgAdminConfiguration'];

export default function maReferencedListColumn(NgAdminConfiguration) {
    return {
        scope: {
            'field': '&',
            'datastore': '&'
        },
        restrict: 'E',
        link: {
            pre: function(scope) {
                scope.field = scope.field();
                var targetEntity = scope.field.targetEntity();
                scope.entries = scope.datastore().getEntries(targetEntity.uniqueId + '_list');
                scope.entity = NgAdminConfiguration().getEntity(targetEntity.name());
            }
        },
        template: `
<ma-datagrid ng-if="::entries.length > 0" name="{{ field.datagridName() }}"
    entries="::entries"
    fields="::field.targetFields()"
    list-actions="::field.listActions()"
    entity="::entity"
    datastore="::datastore()"
    entry-css-classes="::field.entryCssClasses()">
</ma-datagrid>`
    };
}

maReferencedListColumn.$inject = ['NgAdminConfiguration'];

Add entryCssClasses functionality to referenced list field.


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

module.exports = {

  attributes: {
    name: 'STRING'
  	/* e.g.
  	nickname: 'string'
  	*/

  }

};

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

module.exports = {

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

  }

};

Add some additional validation for organization model


/*
*	Code to display coderwall.com badges
*/

$(document).ready(function(){
        var member = $('#github_user').text();
        var coderwallJSONurl ="http://www.coderwall.com/" + member + ".json?callback=?";
        var height = 75;
        var width = 75;

        $.getJSON(coderwallJSONurl, function(data) {
        $("Coderwall Achievements

").appendTo("#coderwall");
          $.each(data.data.badges, function(i, item) {
            $("").attr("src", item.badge)
              .attr("float", "left")
              .attr("title", item.name + ": " + item.description)
              .attr("alt", item.name)
              .attr("height", height)
              .attr("width", width)
              .appendTo("#coderwall")
              .hover(
                  function(){
                      $(this).css("opacity","0.6");
                  },
                  function(){
                      $(this).css("opacity","1.0");
                  }
              )
            });
        });
});

/*
*	Code to display coderwall.com badges
*/

$(document).ready(function(){
        var member = $('#github_user').text();
        var coderwallJSONurl ="http://www.coderwall.com/" + member + ".json?callback=?";
        var height = 75;
        var width = 75;

        $.getJSON(coderwallJSONurl, function(data) {
        $("
Coderwall Achievements

").appendTo("#coderwall");
          $.each(data.data.badges, function(i, item) {
            $("").attr("src", item.badge)
              .attr("float", "left")
              .attr("title", item.name + ": " + item.description)
              .attr("alt", item.name)
              .attr("height", height)
              .attr("width", width)
              .appendTo("#coderwall")
              .hover(
                  function(){
                      $(this).css("opacity","0.6");
                  },
                  function(){
                      $(this).css("opacity","1.0");
                  }
              )
            });
        });
});

Fix distance for margin title on layout


export {Utilities} from './validation/utilities';
export {ValidationConfig} from './validation/validation-config';
export {ValidationLocale} from './validation/validation-locale';
export * from './validation/validation-result';
export * from './validation/validation-rules';
export {Validation} from './validation/validation';
export {ValidateCustomAttribute} from './validation/validate-custom-attribute';
export {ValidateCustomAttributeViewStrategy} from './validation/validate-custom-attribute-view-strategy';
export {ValidateCustomAttributeViewStrategyBase} from './validation/validate-custom-attribute-view-strategy';
export {ensure} from './validation/decorators';

import {ValidationConfig} from './validation/validation-config';
import {Validation} from './validation/validation';

export function configure(aurelia, configCallback) {

  aurelia.globalizeResources('./validation/validate-custom-attribute');
  if(configCallback !== undefined && typeof(configCallback) === 'function')
  {
    configCallback(Validation.defaults);
  }
  aurelia.withSingleton(ValidationConfig, Validation.defaults);
  return Validation.defaults.locale();
}

export {Utilities} from './validation/utilities';
export {ValidationConfig} from './validation/validation-config';
export {ValidationLocale} from './validation/validation-locale';
export * from './validation/validation-result';
export * from './validation/validation-rules';
export {Validation} from './validation/validation';
export {ValidateCustomAttribute} from './validation/validate-custom-attribute';
export {ValidateCustomAttributeViewStrategy} from './validation/validate-custom-attribute-view-strategy';
export {ValidateCustomAttributeViewStrategyBase} from './validation/validate-custom-attribute-view-strategy';
export {ensure} from './validation/decorators';

import {ValidationConfig} from './validation/validation-config';
import {Validation} from './validation/validation';

export function configure(aurelia, configCallback) {

  aurelia.globalResources('./validation/validate-custom-attribute');
  if(configCallback !== undefined && typeof(configCallback) === 'function')
  {
    configCallback(Validation.defaults);
  }
  aurelia.singleton(ValidationConfig, Validation.defaults);
  return Validation.defaults.locale();
}

Fix make plugin global after API change


module.exports = {
  API_URL: process.env.USE_LOCAL ? 'http://localhost:5000' : 'http://api.rumors.hacktabl.org',

  // If is dev but connet to production api, don't use appId = RUMORS_SITE.
  // Use RUMORS_SITE only on production, or when connecting to local dev server
  //
  APP_ID: process.env.USE_LOCAL || process.env.NODE_ENV === 'production' ? 'RUMORS_SITE' : 'DEV',
};

module.exports = {
  API_URL: process.env.USE_LOCAL ? 'http://localhost:5000' : 'https://api.rumors.hacktabl.org',

  // If is dev but connet to production api, don't use appId = RUMORS_SITE.
  // Use RUMORS_SITE only on production, or when connecting to local dev server
  //
  APP_ID: process.env.USE_LOCAL || process.env.NODE_ENV === 'production' ? 'RUMORS_SITE' : 'DEV',
};

Use https in API calls


// @flow

import React from 'react';
import ReactDOM from 'react-dom';
// AppContainer is a necessary wrapper component for HMR
import { AppContainer } from 'react-hot-loader';
import { BrowserRouter as Router } from 'react-router-dom';
import 'normalize.css';
import App from './app';

const rootElement = document.getElementById('react-root');
const renderApp = () => {
  ReactDOM.render(
    <AppContainer>
      <Router>
        <App />
      </Router>
    </AppContainer>,
    rootElement
  );
};

renderApp();

// Hot Module Replacement API
if (module.hot) {
  // for Webpack 2, do not need to re-import module for HMR
  // https://github.com/gaearon/react-hot-loader/tree/master/docs#webpack-2
  // $FlowFixMe: how to annotate types for module, module.hot
  module.hot.accept('./app', renderApp);
}

// @flow

import React from 'react';
import ReactDOM from 'react-dom';
// AppContainer is a necessary wrapper component for HMR
import { AppContainer } from 'react-hot-loader';
import { BrowserRouter as Router } from 'react-router-dom';
import 'normalize.css';
import App from './app';

const rootElement = document.getElementById('react-root');
const renderApp = rootElement
  ? () => {
    ReactDOM.render(
      <AppContainer>
        <Router>
          <App />
        </Router>
      </AppContainer>,
      rootElement
    );
  }
  : () => {}; // set renderApp to a noop if we don't have `rootElement`

renderApp();

// Hot Module Replacement API
if (module.hot) {
  // for Webpack 2, do not need to re-import module for HMR
  // https://github.com/gaearon/react-hot-loader/tree/master/docs#webpack-2
  // $FlowFixMe: how to annotate types for module, module.hot
  module.hot.accept('./app', renderApp);
}

Handle flow check error when React mount node is not found


var path = require('path');
var _ = require('lodash');
var assert = require('assert');

var fs = require("fs");
var fsUtil = require("../lib/utils/fs");

var testGeneration = function(book, type, func, done) {
    var OUTPUT_PATH = book.options.output;

    qdone(
        book.generate(type)
            .then(function() {
                func(OUTPUT_PATH);
            })
            .fin(function() {
                return fsUtil.remove(OUTPUT_PATH);
            }),
        done);
};

describe('Book generation', function () {
    it('should correctly generate a book to json', function(done) {
    	testGeneration(book1, "json", function(output) {
            assert(!fs.existsSync(path.join(output, "README.json")));
            assert(fs.existsSync(path.join(output, "intro.json")));
            assert(fs.existsSync(path.join(output, "sub/test1.json")));

            var test1 = JSON.parse(fs.readFileSync(path.join(output, "sub/test1.json")));
            assert(test1.sections[0].content.indexOf("intro.html") > 0);
        }, done);
    });

    it('should correctly generate a multilingual book to json', function(done) {
    	testGeneration(book2, "json", function(output) {

        }, done);
    });
});

var path = require('path');
var _ = require('lodash');
var assert = require('assert');

var fs = require("fs");
var fsUtil = require("../lib/utils/fs");

var testGeneration = function(book, type, func, done) {
    var OUTPUT_PATH = book.options.output;

    qdone(
        book.generate(type)
            .then(function() {
                func(OUTPUT_PATH);
            })
            .fin(function() {
                return fsUtil.remove(OUTPUT_PATH);
            }),
        done);
};

describe('Book generation', function () {
    it('should correctly generate a book to json', function(done) {
    	testGeneration(book1, "json", function(output) {
            assert(!fs.existsSync(path.join(output, "README.json")));
            assert(fs.existsSync(path.join(output, "intro.json")));
            assert(fs.existsSync(path.join(output, "sub/test1.json")));

            var test1 = JSON.parse(fs.readFileSync(path.join(output, "sub/test1.json")));
            assert(test1.sections[0].content.indexOf("intro.html") > 0);
        }, done);
    });

    it('should correctly generate a multilingual book to json', function(done) {
    	testGeneration(book2, "json", function(output) {
            assert(fs.existsSync(path.join(output, "README.json")));
            assert(fs.existsSync(path.join(output, "en/README.json")));
            assert(fs.existsSync(path.join(output, "fr/README.json")));
        }, done);
    });
});

Improve tests for multilingual json output