Add documentation to the date module

docs(date): Add documentation to the date module

--- src/jsturbo-date.js
+++ src/jsturbo-date.js
@@ -1,5 +1,10 @@
 import str from '../src/jsturbo-string'

+/**
+ * Converts a date to string in the format 'dd/MM/yyyy'
+ * @param  {Date} Date object
+ * @return {string}
+ */
 function toStringDMY (date) {
   return [
     str.pad(date.getDate().toString(), 2),
@@ -8,10 +13,20 @@
   ].join('/')
 };

+/**
+ * Check if a date object represents the current day
+ * @param  {Date}
+ * @return {Boolean}
+ */
 function isToday (date) {
   return toStringDMY(date) === toStringDMY(new Date())
 };

+/**
+ * Create a Date object based on a string in the format 'dd/MM/yyyy'
+ * @param  {string} string with a date in the format 'dd/MM/yyyy'
+ * @return {Date}
+ */
 function fromStringDMY (stringDdMmYyyy) {
   stringDdMmYyyy = stringDdMmYyyy.replace(/\D/g, '')
   var day = parseInt(stringDdMmYyyy.substr(0, 2))

<|original_code|>
import str from '../src/jsturbo-string'

function toStringDMY (date) {
  return [
    str.pad(date.getDate().toString(), 2),
    str.pad((date.getMonth() + 1).toString(), 2),
    str.pad(date.getFullYear().toString(), 4)
  ].join('/')
};

function isToday (date) {
  return toStringDMY(date) === toStringDMY(new Date())
};

function fromStringDMY (stringDdMmYyyy) {
  stringDdMmYyyy = stringDdMmYyyy.replace(/\D/g, '')
  var day = parseInt(stringDdMmYyyy.substr(0, 2))
  var month = parseInt(stringDdMmYyyy.substr(2, 2)) - 1
  var year = parseInt(stringDdMmYyyy.substr(4, 4))
  return new Date(year, month, day, 0, 0, 0, 0)
};

const mainExport = {
  toStringDMY: toStringDMY,
  isToday: isToday,
  fromStringDMY: fromStringDMY
}

export default mainExport
module.exports = mainExport // for CommonJS compatibility

<|edits_diff|>
--- src/jsturbo-date.js
+++ src/jsturbo-date.js
@@ -1,5 +1,10 @@
 import str from '../src/jsturbo-string'

+/**
+ * Converts a date to string in the format 'dd/MM/yyyy'
+ * @param  {Date} Date object
+ * @return {string}
+ */
 function toStringDMY (date) {
   return [
     str.pad(date.getDate().toString(), 2),
@@ -8,6 +13,11 @@
   ].join('/')
 };

+/**
+ * Check if a date object represents the current day
+ * @param  {Date}
+ * @return {Boolean}
+ */
 function isToday (date) {
   return toStringDMY(date) === toStringDMY(new Date())
 };
<|current_version|>
import str from '../src/jsturbo-string'

/**
 * Converts a date to string in the format 'dd/MM/yyyy'
 * @param  {Date} Date object
 * @return {string}
 */
function toStringDMY (date) {
  return [
    str.pad(date.getDate().toString(), 2),
    str.pad((date.getMonth() + 1).toString(), 2),
    str.pad(date.getFullYear().toString(), 4)
  ].join('/')
};

/**
 * Check if a date object represents the current day
 * @param  {Date}
 * @return {Boolean}
 */
function isToday (date) {
  return toStringDMY(date) === toStringDMY(new Date())
};

function fromStringDMY (stringDdMmYyyy) {
  stringDdMmYyyy = stringDdMmYyyy.replace(/\D/g, '')
  var day = parseInt(stringDdMmYyyy.substr(0, 2))
  var month = parseInt(stringDdMmYyyy.substr(2, 2)) - 1
  var year = parseInt(stringDdMmYyyy.substr(4, 4))
  return new Date(year, month, day, 0, 0, 0, 0)
};

const mainExport = {
  toStringDMY: toStringDMY,
  isToday: isToday,
  fromStringDMY: fromStringDMY
}

export default mainExport
module.exports = mainExport // for CommonJS compatibility

<|next_version|>
import str from '../src/jsturbo-string'

/**
 * Converts a date to string in the format 'dd/MM/yyyy'
 * @param  {Date} Date object
 * @return {string}
 */
function toStringDMY (date) {
  return [
    str.pad(date.getDate().toString(), 2),
    str.pad((date.getMonth() + 1).toString(), 2),
    str.pad(date.getFullYear().toString(), 4)
  ].join('/')
};

/**
 * Check if a date object represents the current day
 * @param  {Date}
 * @return {Boolean}
 */
function isToday (date) {
  return toStringDMY(date) === toStringDMY(new Date())
};

/**
 * Create a Date object based on a string in the format 'dd/MM/yyyy'
 * @param  {string} string with a date in the format 'dd/MM/yyyy'
 * @return {Date}
 */
function fromStringDMY (stringDdMmYyyy) {
  stringDdMmYyyy = stringDdMmYyyy.replace(/\D/g, '')
  var day = parseInt(stringDdMmYyyy.substr(0, 2))
  var month = parseInt(stringDdMmYyyy.substr(2, 2)) - 1
  var year = parseInt(stringDdMmYyyy.substr(4, 4))
  return new Date(year, month, day, 0, 0, 0, 0)
};

const mainExport = {
  toStringDMY: toStringDMY,
  isToday: isToday,
  fromStringDMY: fromStringDMY
}

export default mainExport
module.exports = mainExport // for CommonJS compatibility


Store file upload loading state.

Store file upload loading state.

--- example/src/redux/reducer/storage.js
+++ example/src/redux/reducer/storage.js
@@ -2,6 +2,7 @@

 const initialState = {
   file: null,
+  loading: false,
   url: null,
 };

@@ -15,8 +16,14 @@
     case types.SET_FILE_URL:
       return {
         ...state,
+        loading: false,
         url: action.url,
       }
+    case types.SEND_FILE:
+      return {
+        ...state,
+        loading: true,
+      };
     default:
       return state;
   }

<|original_code|>
import { types } from './storage.actions';

const initialState = {
  file: null,
  url: null,
};

export default function storageReducer(state=initialState, action={}) {
  switch (action.type) {
    case types.SET_FILE:
      return {
        ...state,
        file: action.file,
      }
    case types.SET_FILE_URL:
      return {
        ...state,
        url: action.url,
      }
    default:
      return state;
  }
}

<|edits_diff|>
--- example/src/redux/reducer/storage.js
+++ example/src/redux/reducer/storage.js
@@ -2,6 +2,7 @@

 const initialState = {
   file: null,
+  loading: false,
   url: null,
 };

@@ -15,6 +16,7 @@
     case types.SET_FILE_URL:
       return {
         ...state,
+        loading: false,
         url: action.url,
       }
     default:
<|current_version|>
import { types } from './storage.actions';

const initialState = {
  file: null,
  loading: false,
  url: null,
};

export default function storageReducer(state=initialState, action={}) {
  switch (action.type) {
    case types.SET_FILE:
      return {
        ...state,
        file: action.file,
      }
    case types.SET_FILE_URL:
      return {
        ...state,
        loading: false,
        url: action.url,
      }
    default:
      return state;
  }
}

<|next_version|>
import { types } from './storage.actions';

const initialState = {
  file: null,
  loading: false,
  url: null,
};

export default function storageReducer(state=initialState, action={}) {
  switch (action.type) {
    case types.SET_FILE:
      return {
        ...state,
        file: action.file,
      }
    case types.SET_FILE_URL:
      return {
        ...state,
        loading: false,
        url: action.url,
      }
    case types.SEND_FILE:
      return {
        ...state,
        loading: true,
      };
    default:
      return state;
  }
}


Document workaround for `got` `FormData` bug

See: https://github.com/sindresorhus/got/pull/466

--- js/modules/debuglogs.js
+++ js/modules/debuglogs.js
@@ -9,6 +9,7 @@
 // Workaround: Submitting `FormData` using native `FormData::submit` procedure
 // as integration with `got` results in S3 error saying we haven’t set the
 // `Content-Length` header:
+// https://github.com/sindresorhus/got/pull/466
 const submitFormData = (form, url) =>
   new Promise((resolve, reject) => {
     form.submit(url, (error) => {
@@ -42,6 +43,8 @@
     filename: 'signal-desktop-debug-log.txt',
   });

+  // WORKAROUND: See comment on `submitFormData`:
+  // await got.post(url, { body: form });
   await submitFormData(form, url);

   return `${BASE_URL}/${fields.key}`;

<|original_code|>
/* eslint-env node */

const FormData = require('form-data');
const got = require('got');

const BASE_URL = 'https://debuglogs.org';

// Workaround: Submitting `FormData` using native `FormData::submit` procedure
// as integration with `got` results in S3 error saying we haven’t set the
// `Content-Length` header:
const submitFormData = (form, url) =>
  new Promise((resolve, reject) => {
    form.submit(url, (error) => {
      if (error) {
        return reject(error);
      }

      return resolve();
    });
  });

//      upload :: String -> Promise URL
exports.upload = async (content) => {
  const signedForm = await got.get(BASE_URL, { json: true });
  const { fields, url } = signedForm.body;

  const form = new FormData();
  // The API expects `key` to be the first field:
  form.append('key', fields.key);
  Object.entries(fields)
    .filter(([key]) => key !== 'key')
    .forEach(([key, value]) => {
      form.append(key, value);
    });

  const contentBuffer = Buffer.from(content, 'utf8');
  const contentType = 'text/plain';
  form.append('Content-Type', contentType);
  form.append('file', contentBuffer, {
    contentType,
    filename: 'signal-desktop-debug-log.txt',
  });

  await submitFormData(form, url);

  return `${BASE_URL}/${fields.key}`;
};

<|edits_diff|>
--- js/modules/debuglogs.js
+++ js/modules/debuglogs.js
@@ -9,6 +9,7 @@
 // Workaround: Submitting `FormData` using native `FormData::submit` procedure
 // as integration with `got` results in S3 error saying we haven’t set the
 // `Content-Length` header:
+// https://github.com/sindresorhus/got/pull/466
 const submitFormData = (form, url) =>
   new Promise((resolve, reject) => {
     form.submit(url, (error) => {
<|current_version|>
/* eslint-env node */

const FormData = require('form-data');
const got = require('got');

const BASE_URL = 'https://debuglogs.org';

// Workaround: Submitting `FormData` using native `FormData::submit` procedure
// as integration with `got` results in S3 error saying we haven’t set the
// `Content-Length` header:
// https://github.com/sindresorhus/got/pull/466
const submitFormData = (form, url) =>
  new Promise((resolve, reject) => {
    form.submit(url, (error) => {
      if (error) {
        return reject(error);
      }

      return resolve();
    });
  });

//      upload :: String -> Promise URL
exports.upload = async (content) => {
  const signedForm = await got.get(BASE_URL, { json: true });
  const { fields, url } = signedForm.body;

  const form = new FormData();
  // The API expects `key` to be the first field:
  form.append('key', fields.key);
  Object.entries(fields)
    .filter(([key]) => key !== 'key')
    .forEach(([key, value]) => {
      form.append(key, value);
    });

  const contentBuffer = Buffer.from(content, 'utf8');
  const contentType = 'text/plain';
  form.append('Content-Type', contentType);
  form.append('file', contentBuffer, {
    contentType,
    filename: 'signal-desktop-debug-log.txt',
  });

  await submitFormData(form, url);

  return `${BASE_URL}/${fields.key}`;
};

<|next_version|>
/* eslint-env node */

const FormData = require('form-data');
const got = require('got');

const BASE_URL = 'https://debuglogs.org';

// Workaround: Submitting `FormData` using native `FormData::submit` procedure
// as integration with `got` results in S3 error saying we haven’t set the
// `Content-Length` header:
// https://github.com/sindresorhus/got/pull/466
const submitFormData = (form, url) =>
  new Promise((resolve, reject) => {
    form.submit(url, (error) => {
      if (error) {
        return reject(error);
      }

      return resolve();
    });
  });

//      upload :: String -> Promise URL
exports.upload = async (content) => {
  const signedForm = await got.get(BASE_URL, { json: true });
  const { fields, url } = signedForm.body;

  const form = new FormData();
  // The API expects `key` to be the first field:
  form.append('key', fields.key);
  Object.entries(fields)
    .filter(([key]) => key !== 'key')
    .forEach(([key, value]) => {
      form.append(key, value);
    });

  const contentBuffer = Buffer.from(content, 'utf8');
  const contentType = 'text/plain';
  form.append('Content-Type', contentType);
  form.append('file', contentBuffer, {
    contentType,
    filename: 'signal-desktop-debug-log.txt',
  });

  // WORKAROUND: See comment on `submitFormData`:
  // await got.post(url, { body: form });
  await submitFormData(form, url);

  return `${BASE_URL}/${fields.key}`;
};


Clear payment type form data after succesfully saving a modified payment type

--- ukelonn.web.frontend/src/main/frontend/sagas/modifyPaymenttypeSaga.js
+++ ukelonn.web.frontend/src/main/frontend/sagas/modifyPaymenttypeSaga.js
@@ -4,6 +4,7 @@
     MODIFY_PAYMENTTYPE_REQUEST,
     MODIFY_PAYMENTTYPE_RECEIVE,
     MODIFY_PAYMENTTYPE_FAILURE,
+    CLEAR_PAYMENT_TYPE_FORM,
 } from '../actiontypes';

 function doModifyPaymenttype(paymenttype) {
@@ -20,6 +21,11 @@
     }
 }

+function* clearPaymenttypeForm() {
+    yield put(CLEAR_PAYMENT_TYPE_FORM());
+}
+
 export default function* modifyPaymenttypeSaga() {
     yield takeLatest(MODIFY_PAYMENTTYPE_REQUEST, requestReceiveModifyPaymenttypeSaga);
+    yield takeLatest(MODIFY_PAYMENTTYPE_RECEIVE, clearPaymenttypeForm);
 }

<|original_code|>
import { takeLatest, call, put } from 'redux-saga/effects';
import axios from 'axios';
import {
    MODIFY_PAYMENTTYPE_REQUEST,
    MODIFY_PAYMENTTYPE_RECEIVE,
    MODIFY_PAYMENTTYPE_FAILURE,
} from '../actiontypes';

function doModifyPaymenttype(paymenttype) {
    return axios.post('/ukelonn/api/admin/paymenttype/modify', paymenttype);
}

function* requestReceiveModifyPaymenttypeSaga(action) {
    try {
        const response = yield call(doModifyPaymenttype, action.payload);
        const paymenttypes = (response.headers['content-type'] == 'application/json') ? response.data : [];
        yield put(MODIFY_PAYMENTTYPE_RECEIVE(paymenttypes));
    } catch (error) {
        yield put(MODIFY_PAYMENTTYPE_FAILURE(error));
    }
}

export default function* modifyPaymenttypeSaga() {
    yield takeLatest(MODIFY_PAYMENTTYPE_REQUEST, requestReceiveModifyPaymenttypeSaga);
}

<|edits_diff|>
--- ukelonn.web.frontend/src/main/frontend/sagas/modifyPaymenttypeSaga.js
+++ ukelonn.web.frontend/src/main/frontend/sagas/modifyPaymenttypeSaga.js
@@ -4,6 +4,7 @@
     MODIFY_PAYMENTTYPE_REQUEST,
     MODIFY_PAYMENTTYPE_RECEIVE,
     MODIFY_PAYMENTTYPE_FAILURE,
+    CLEAR_PAYMENT_TYPE_FORM,
 } from '../actiontypes';

 function doModifyPaymenttype(paymenttype) {
@@ -20,6 +21,10 @@
     }
 }

+function* clearPaymenttypeForm() {
+    yield put(CLEAR_PAYMENT_TYPE_FORM());
+}
+
 export default function* modifyPaymenttypeSaga() {
     yield takeLatest(MODIFY_PAYMENTTYPE_REQUEST, requestReceiveModifyPaymenttypeSaga);
 }
<|current_version|>
import { takeLatest, call, put } from 'redux-saga/effects';
import axios from 'axios';
import {
    MODIFY_PAYMENTTYPE_REQUEST,
    MODIFY_PAYMENTTYPE_RECEIVE,
    MODIFY_PAYMENTTYPE_FAILURE,
    CLEAR_PAYMENT_TYPE_FORM,
} from '../actiontypes';

function doModifyPaymenttype(paymenttype) {
    return axios.post('/ukelonn/api/admin/paymenttype/modify', paymenttype);
}

function* requestReceiveModifyPaymenttypeSaga(action) {
    try {
        const response = yield call(doModifyPaymenttype, action.payload);
        const paymenttypes = (response.headers['content-type'] == 'application/json') ? response.data : [];
        yield put(MODIFY_PAYMENTTYPE_RECEIVE(paymenttypes));
    } catch (error) {
        yield put(MODIFY_PAYMENTTYPE_FAILURE(error));
    }
}

function* clearPaymenttypeForm() {
    yield put(CLEAR_PAYMENT_TYPE_FORM());
}

export default function* modifyPaymenttypeSaga() {
    yield takeLatest(MODIFY_PAYMENTTYPE_REQUEST, requestReceiveModifyPaymenttypeSaga);
}

<|next_version|>
import { takeLatest, call, put } from 'redux-saga/effects';
import axios from 'axios';
import {
    MODIFY_PAYMENTTYPE_REQUEST,
    MODIFY_PAYMENTTYPE_RECEIVE,
    MODIFY_PAYMENTTYPE_FAILURE,
    CLEAR_PAYMENT_TYPE_FORM,
} from '../actiontypes';

function doModifyPaymenttype(paymenttype) {
    return axios.post('/ukelonn/api/admin/paymenttype/modify', paymenttype);
}

function* requestReceiveModifyPaymenttypeSaga(action) {
    try {
        const response = yield call(doModifyPaymenttype, action.payload);
        const paymenttypes = (response.headers['content-type'] == 'application/json') ? response.data : [];
        yield put(MODIFY_PAYMENTTYPE_RECEIVE(paymenttypes));
    } catch (error) {
        yield put(MODIFY_PAYMENTTYPE_FAILURE(error));
    }
}

function* clearPaymenttypeForm() {
    yield put(CLEAR_PAYMENT_TYPE_FORM());
}

export default function* modifyPaymenttypeSaga() {
    yield takeLatest(MODIFY_PAYMENTTYPE_REQUEST, requestReceiveModifyPaymenttypeSaga);
    yield takeLatest(MODIFY_PAYMENTTYPE_RECEIVE, clearPaymenttypeForm);
}


Add exclude list to addon dedupe logic

Add exclude list to addon dedupe logic

--- packages/ember-engines/lib/utils/deeply-non-duplicated-addon.js
+++ packages/ember-engines/lib/utils/deeply-non-duplicated-addon.js
@@ -1,4 +1,9 @@
 'use strict';
+
+// Array of addon names that should not be deduped.
+const ADDONS_TO_EXCLUDE_FROM_DEDUPE = [
+  'ember-cli-babel',
+];

 /**
  * Deduplicate one addon's children addons recursively from hostAddons.
@@ -20,6 +25,10 @@
       return true;
     }

+    if (ADDONS_TO_EXCLUDE_FROM_DEDUPE.includes(addon.name)) {
+      return true;
+    }
+
     if (addon.addons.length > 0) {
       addon._orginalAddons = addon.addons;
       deeplyNonDuplicatedAddon(hostAddons, addon, treeName);

<|original_code|>
'use strict';

/**
 * Deduplicate one addon's children addons recursively from hostAddons.
 *
 * @private
 * @param {Object} hostAddons
 * @param {EmberAddon} dedupedAddon
 * @param {String} treeName
 */
module.exports = function deeplyNonDuplicatedAddon(hostAddons, dedupedAddon, treeName) {
  if (dedupedAddon.addons.length === 0) {
    return;
  }

  dedupedAddon._orginalAddons = dedupedAddon.addons;
  dedupedAddon.addons = dedupedAddon.addons.filter(addon => {
    // nested lazy engine will have it's own deeplyNonDuplicatedAddon, just keep it here
    if (addon.lazyLoading && addon.lazyLoading.enabled) {
      return true;
    }

    if (addon.addons.length > 0) {
      addon._orginalAddons = addon.addons;
      deeplyNonDuplicatedAddon(hostAddons, addon, treeName);
    }

    let hostAddon = hostAddons[addon.name];

    if (hostAddon && hostAddon.cacheKeyForTree) {
      let innerCacheKey = addon.cacheKeyForTree(treeName);
      let hostAddonCacheKey = hostAddon.cacheKeyForTree(treeName);

      if (
        innerCacheKey != null &&
        innerCacheKey === hostAddonCacheKey
      ) {
        // the addon specifies cache key and it is the same as host instance of the addon, skip the tree
        return false;
      }
    }

    return true;
  });
}

<|edits_diff|>
--- packages/ember-engines/lib/utils/deeply-non-duplicated-addon.js
+++ packages/ember-engines/lib/utils/deeply-non-duplicated-addon.js
@@ -1,4 +1,9 @@
 'use strict';
+
+// Array of addon names that should not be deduped.
+const ADDONS_TO_EXCLUDE_FROM_DEDUPE = [
+  'ember-cli-babel',
+];

 /**
  * Deduplicate one addon's children addons recursively from hostAddons.
<|current_version|>
'use strict';

// Array of addon names that should not be deduped.
const ADDONS_TO_EXCLUDE_FROM_DEDUPE = [
  'ember-cli-babel',
];

/**
 * Deduplicate one addon's children addons recursively from hostAddons.
 *
 * @private
 * @param {Object} hostAddons
 * @param {EmberAddon} dedupedAddon
 * @param {String} treeName
 */
module.exports = function deeplyNonDuplicatedAddon(hostAddons, dedupedAddon, treeName) {
  if (dedupedAddon.addons.length === 0) {
    return;
  }

  dedupedAddon._orginalAddons = dedupedAddon.addons;
  dedupedAddon.addons = dedupedAddon.addons.filter(addon => {
    // nested lazy engine will have it's own deeplyNonDuplicatedAddon, just keep it here
    if (addon.lazyLoading && addon.lazyLoading.enabled) {
      return true;
    }

    if (addon.addons.length > 0) {
      addon._orginalAddons = addon.addons;
      deeplyNonDuplicatedAddon(hostAddons, addon, treeName);
    }

    let hostAddon = hostAddons[addon.name];

    if (hostAddon && hostAddon.cacheKeyForTree) {
      let innerCacheKey = addon.cacheKeyForTree(treeName);
      let hostAddonCacheKey = hostAddon.cacheKeyForTree(treeName);

      if (
        innerCacheKey != null &&
        innerCacheKey === hostAddonCacheKey
      ) {
        // the addon specifies cache key and it is the same as host instance of the addon, skip the tree
        return false;
      }
    }

    return true;
  });
}

<|next_version|>
'use strict';

// Array of addon names that should not be deduped.
const ADDONS_TO_EXCLUDE_FROM_DEDUPE = [
  'ember-cli-babel',
];

/**
 * Deduplicate one addon's children addons recursively from hostAddons.
 *
 * @private
 * @param {Object} hostAddons
 * @param {EmberAddon} dedupedAddon
 * @param {String} treeName
 */
module.exports = function deeplyNonDuplicatedAddon(hostAddons, dedupedAddon, treeName) {
  if (dedupedAddon.addons.length === 0) {
    return;
  }

  dedupedAddon._orginalAddons = dedupedAddon.addons;
  dedupedAddon.addons = dedupedAddon.addons.filter(addon => {
    // nested lazy engine will have it's own deeplyNonDuplicatedAddon, just keep it here
    if (addon.lazyLoading && addon.lazyLoading.enabled) {
      return true;
    }

    if (ADDONS_TO_EXCLUDE_FROM_DEDUPE.includes(addon.name)) {
      return true;
    }

    if (addon.addons.length > 0) {
      addon._orginalAddons = addon.addons;
      deeplyNonDuplicatedAddon(hostAddons, addon, treeName);
    }

    let hostAddon = hostAddons[addon.name];

    if (hostAddon && hostAddon.cacheKeyForTree) {
      let innerCacheKey = addon.cacheKeyForTree(treeName);
      let hostAddonCacheKey = hostAddon.cacheKeyForTree(treeName);

      if (
        innerCacheKey != null &&
        innerCacheKey === hostAddonCacheKey
      ) {
        // the addon specifies cache key and it is the same as host instance of the addon, skip the tree
        return false;
      }
    }

    return true;
  });
}


Use the database seeds from the Feature spec

--- test/feature.js
+++ test/feature.js
@@ -1,7 +1,12 @@
 var assert = require('assert');
+var seeds = require('../seeds');
 var Feature = require('../feature');

 describe('Feature', function () {
+  before(function (done) {
+    seeds(done);
+  });
+
   describe('schema', function () {
     it('successfully creates a valid document');
     it('fails at creating an invalid document');

<|original_code|>
var assert = require('assert');
var Feature = require('../feature');

describe('Feature', function () {
  describe('schema', function () {
    it('successfully creates a valid document');
    it('fails at creating an invalid document');
  });

  describe('.search()', function () {
    it('performs an empty search, returning all commands', function (done) {
      Feature.search('', function (docs) {
        assert.equal(7, docs.length);
        done();
      });
    });

    it('performs a case-insensitive search for a command', function (done) {
      Feature.search('git ADD', function (docs) {
        assert.equal(1, docs.length)
        done();
      });
    });

    it('performs a search for a command that does not exist', function (done) {
      Feature.search('git yolo', function (docs) {
        assert.equal(0, docs.length);
        done();
      });
    });
  });
});

<|edits_diff|>
--- test/feature.js
+++ test/feature.js
@@ -1,4 +1,5 @@
 var assert = require('assert');
+var seeds = require('../seeds');
 var Feature = require('../feature');

 describe('Feature', function () {
<|current_version|>
var assert = require('assert');
var seeds = require('../seeds');
var Feature = require('../feature');

describe('Feature', function () {
  describe('schema', function () {
    it('successfully creates a valid document');
    it('fails at creating an invalid document');
  });

  describe('.search()', function () {
    it('performs an empty search, returning all commands', function (done) {
      Feature.search('', function (docs) {
        assert.equal(7, docs.length);
        done();
      });
    });

    it('performs a case-insensitive search for a command', function (done) {
      Feature.search('git ADD', function (docs) {
        assert.equal(1, docs.length)
        done();
      });
    });

    it('performs a search for a command that does not exist', function (done) {
      Feature.search('git yolo', function (docs) {
        assert.equal(0, docs.length);
        done();
      });
    });
  });
});

<|next_version|>
var assert = require('assert');
var seeds = require('../seeds');
var Feature = require('../feature');

describe('Feature', function () {
  before(function (done) {
    seeds(done);
  });

  describe('schema', function () {
    it('successfully creates a valid document');
    it('fails at creating an invalid document');
  });

  describe('.search()', function () {
    it('performs an empty search, returning all commands', function (done) {
      Feature.search('', function (docs) {
        assert.equal(7, docs.length);
        done();
      });
    });

    it('performs a case-insensitive search for a command', function (done) {
      Feature.search('git ADD', function (docs) {
        assert.equal(1, docs.length)
        done();
      });
    });

    it('performs a search for a command that does not exist', function (done) {
      Feature.search('git yolo', function (docs) {
        assert.equal(0, docs.length);
        done();
      });
    });
  });
});


Remove empty properties from object

Remove empty properties from object

--- webpack.config.babel.js
+++ webpack.config.babel.js
@@ -2,7 +2,11 @@
 import HtmlWebpackPlugin from 'webpack-html-plugin';
 import webpack from 'webpack';

+/** removes empty items from array */
 const array = (target) => target.filter((item) => item);
+
+/** removes empty properties from object */
+const object = (target) => Object.keys(target).filter((key) => target[key]).reduce((result, key) => Object.assign({[key]: target[key]}, result), {});

 export default ({dev, prod}) => ({
     entry: array([

<|original_code|>
import path from 'path';
import HtmlWebpackPlugin from 'webpack-html-plugin';
import webpack from 'webpack';

const array = (target) => target.filter((item) => item);

export default ({dev, prod}) => ({
    entry: array([
        dev && 'react-hot-loader/patch',
        'babel-polyfill',
        './src/',
    ]),
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        filename: 'bundle.js',
    },
    plugins: array([
        new HtmlWebpackPlugin({
            template: 'src/index.html',
            inject: true,
        }),
        dev && new webpack.NoErrorsPlugin(),
    ]),
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: '/node_modules/',
                options: {
                    presets: ['es2015', 'react'],
                    modules: false,
                },
            },
            {
                test: /\.less$/,
                use: [
                    {loader: 'style-loader'},
                    {loader: 'css-loader'},
                    {loader: 'less-loader'},
                ],
            },
        ],
    },
});

<|edits_diff|>
--- webpack.config.babel.js
+++ webpack.config.babel.js
@@ -2,6 +2,7 @@
 import HtmlWebpackPlugin from 'webpack-html-plugin';
 import webpack from 'webpack';

+/** removes empty items from array */
 const array = (target) => target.filter((item) => item);

 export default ({dev, prod}) => ({
<|current_version|>
import path from 'path';
import HtmlWebpackPlugin from 'webpack-html-plugin';
import webpack from 'webpack';

/** removes empty items from array */
const array = (target) => target.filter((item) => item);

export default ({dev, prod}) => ({
    entry: array([
        dev && 'react-hot-loader/patch',
        'babel-polyfill',
        './src/',
    ]),
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        filename: 'bundle.js',
    },
    plugins: array([
        new HtmlWebpackPlugin({
            template: 'src/index.html',
            inject: true,
        }),
        dev && new webpack.NoErrorsPlugin(),
    ]),
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: '/node_modules/',
                options: {
                    presets: ['es2015', 'react'],
                    modules: false,
                },
            },
            {
                test: /\.less$/,
                use: [
                    {loader: 'style-loader'},
                    {loader: 'css-loader'},
                    {loader: 'less-loader'},
                ],
            },
        ],
    },
});

<|next_version|>
import path from 'path';
import HtmlWebpackPlugin from 'webpack-html-plugin';
import webpack from 'webpack';

/** removes empty items from array */
const array = (target) => target.filter((item) => item);

/** removes empty properties from object */
const object = (target) => Object.keys(target).filter((key) => target[key]).reduce((result, key) => Object.assign({[key]: target[key]}, result), {});

export default ({dev, prod}) => ({
    entry: array([
        dev && 'react-hot-loader/patch',
        'babel-polyfill',
        './src/',
    ]),
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        filename: 'bundle.js',
    },
    plugins: array([
        new HtmlWebpackPlugin({
            template: 'src/index.html',
            inject: true,
        }),
        dev && new webpack.NoErrorsPlugin(),
    ]),
    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'babel-loader',
                exclude: '/node_modules/',
                options: {
                    presets: ['es2015', 'react'],
                    modules: false,
                },
            },
            {
                test: /\.less$/,
                use: [
                    {loader: 'style-loader'},
                    {loader: 'css-loader'},
                    {loader: 'less-loader'},
                ],
            },
        ],
    },
});


Disable a few unused features

firefox: Disable a few unused features

--- firefox/prefs.js
+++ firefox/prefs.js
@@ -3,6 +3,7 @@
 user_pref("browser.backspace_action", 2);
 user_pref("browser.bookmarks.restore_default_bookmarks", false);
 user_pref("browser.newtab.url", "about:blank");
+user_pref("browser.readinglist.enabled", false);
 user_pref("browser.search.suggest.enabled", false);
 user_pref("browser.selfsupport.url", "");
 user_pref("browser.showQuitWarning", true);
@@ -11,9 +12,11 @@
 user_pref("browser.tabs.closeWindowWithLastTab", false);
 user_pref("browser.tabs.warnOnClose", false);
 user_pref("datareporting.healthreport.uploadEnabled", false);
+user_pref("loop.enabled", false);
 user_pref("network.cookie.cookieBehavior", 3);
 user_pref("network.cookie.lifetimePolicy", 2);
 user_pref("network.http.referer.spoofSource", true);
 user_pref("network.http.referer.trimmingPolicy", 2);
 user_pref("network.http.referer.XOriginPolicy", 2);
+user_pref("readinglist.scheduler.enabled", false);
 user_pref("toolkit.telemetry.enabled", false);

<|original_code|>
user_pref("accessibility.typeaheadfind.flashBar", 0);
user_pref("accessibility.typeaheadfind.prefillwithselection", true);
user_pref("browser.backspace_action", 2);
user_pref("browser.bookmarks.restore_default_bookmarks", false);
user_pref("browser.newtab.url", "about:blank");
user_pref("browser.search.suggest.enabled", false);
user_pref("browser.selfsupport.url", "");
user_pref("browser.showQuitWarning", true);
user_pref("browser.startup.homepage", "about:blank");
user_pref("browser.tabs.animate", false);
user_pref("browser.tabs.closeWindowWithLastTab", false);
user_pref("browser.tabs.warnOnClose", false);
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("network.cookie.cookieBehavior", 3);
user_pref("network.cookie.lifetimePolicy", 2);
user_pref("network.http.referer.spoofSource", true);
user_pref("network.http.referer.trimmingPolicy", 2);
user_pref("network.http.referer.XOriginPolicy", 2);
user_pref("toolkit.telemetry.enabled", false);

<|edits_diff|>
--- firefox/prefs.js
+++ firefox/prefs.js
@@ -3,6 +3,7 @@
 user_pref("browser.backspace_action", 2);
 user_pref("browser.bookmarks.restore_default_bookmarks", false);
 user_pref("browser.newtab.url", "about:blank");
+user_pref("browser.readinglist.enabled", false);
 user_pref("browser.search.suggest.enabled", false);
 user_pref("browser.selfsupport.url", "");
 user_pref("browser.showQuitWarning", true);
@@ -11,6 +12,7 @@
 user_pref("browser.tabs.closeWindowWithLastTab", false);
 user_pref("browser.tabs.warnOnClose", false);
 user_pref("datareporting.healthreport.uploadEnabled", false);
+user_pref("loop.enabled", false);
 user_pref("network.cookie.cookieBehavior", 3);
 user_pref("network.cookie.lifetimePolicy", 2);
 user_pref("network.http.referer.spoofSource", true);
<|current_version|>
user_pref("accessibility.typeaheadfind.flashBar", 0);
user_pref("accessibility.typeaheadfind.prefillwithselection", true);
user_pref("browser.backspace_action", 2);
user_pref("browser.bookmarks.restore_default_bookmarks", false);
user_pref("browser.newtab.url", "about:blank");
user_pref("browser.readinglist.enabled", false);
user_pref("browser.search.suggest.enabled", false);
user_pref("browser.selfsupport.url", "");
user_pref("browser.showQuitWarning", true);
user_pref("browser.startup.homepage", "about:blank");
user_pref("browser.tabs.animate", false);
user_pref("browser.tabs.closeWindowWithLastTab", false);
user_pref("browser.tabs.warnOnClose", false);
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("loop.enabled", false);
user_pref("network.cookie.cookieBehavior", 3);
user_pref("network.cookie.lifetimePolicy", 2);
user_pref("network.http.referer.spoofSource", true);
user_pref("network.http.referer.trimmingPolicy", 2);
user_pref("network.http.referer.XOriginPolicy", 2);
user_pref("toolkit.telemetry.enabled", false);

<|next_version|>
user_pref("accessibility.typeaheadfind.flashBar", 0);
user_pref("accessibility.typeaheadfind.prefillwithselection", true);
user_pref("browser.backspace_action", 2);
user_pref("browser.bookmarks.restore_default_bookmarks", false);
user_pref("browser.newtab.url", "about:blank");
user_pref("browser.readinglist.enabled", false);
user_pref("browser.search.suggest.enabled", false);
user_pref("browser.selfsupport.url", "");
user_pref("browser.showQuitWarning", true);
user_pref("browser.startup.homepage", "about:blank");
user_pref("browser.tabs.animate", false);
user_pref("browser.tabs.closeWindowWithLastTab", false);
user_pref("browser.tabs.warnOnClose", false);
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("loop.enabled", false);
user_pref("network.cookie.cookieBehavior", 3);
user_pref("network.cookie.lifetimePolicy", 2);
user_pref("network.http.referer.spoofSource", true);
user_pref("network.http.referer.trimmingPolicy", 2);
user_pref("network.http.referer.XOriginPolicy", 2);
user_pref("readinglist.scheduler.enabled", false);
user_pref("toolkit.telemetry.enabled", false);


Add ids to the markup

Add ids to the markup

--- brainfuck.js
+++ brainfuck.js
@@ -18,12 +18,14 @@
         // thead.appendChild(tr);
         for (i = 0; i < 3; i++) {
             tr = document.createElement('tr');
+            tr.id = "row-" + i;
             // th = document.createElement('th');
             // th.textContent = i + 1;
             // tr.appendChild(th);
             for (j = 0; j < 30; j++) {
                 td = document.createElement('td');
                 td.textContent = 0;
+                td.id = "cell-" + (i * 30 + j);
                 tr.appendChild(td);
             }
             tbody.appendChild(tr);

<|original_code|>
(function(global) {
    'use strict';

    (function(id) {
        var i, j;
        var tab = document.getElementById(id);
        var thead = tab.querySelector('thead');
        var tbody = tab.querySelector('tbody');
        var tr, th, td;
        // tr = document.createElement('tr');
        // th = document.createElement('td');
        // tr.appendChild(th);
        // for (i = 0; i < 30; i++) {
        //     th = document.createElement('th');
        //     th.textContent = i + 1;
        //     tr.appendChild(th);
        // }
        // thead.appendChild(tr);
        for (i = 0; i < 3; i++) {
            tr = document.createElement('tr');
            // th = document.createElement('th');
            // th.textContent = i + 1;
            // tr.appendChild(th);
            for (j = 0; j < 30; j++) {
                td = document.createElement('td');
                td.textContent = 0;
                tr.appendChild(td);
            }
            tbody.appendChild(tr);
        }
    })('rams');

})(this)

<|edits_diff|>
--- brainfuck.js
+++ brainfuck.js
@@ -18,6 +18,7 @@
         // thead.appendChild(tr);
         for (i = 0; i < 3; i++) {
             tr = document.createElement('tr');
+            tr.id = "row-" + i;
             // th = document.createElement('th');
             // th.textContent = i + 1;
             // tr.appendChild(th);
<|current_version|>
(function(global) {
    'use strict';

    (function(id) {
        var i, j;
        var tab = document.getElementById(id);
        var thead = tab.querySelector('thead');
        var tbody = tab.querySelector('tbody');
        var tr, th, td;
        // tr = document.createElement('tr');
        // th = document.createElement('td');
        // tr.appendChild(th);
        // for (i = 0; i < 30; i++) {
        //     th = document.createElement('th');
        //     th.textContent = i + 1;
        //     tr.appendChild(th);
        // }
        // thead.appendChild(tr);
        for (i = 0; i < 3; i++) {
            tr = document.createElement('tr');
            tr.id = "row-" + i;
            // th = document.createElement('th');
            // th.textContent = i + 1;
            // tr.appendChild(th);
            for (j = 0; j < 30; j++) {
                td = document.createElement('td');
                td.textContent = 0;
                tr.appendChild(td);
            }
            tbody.appendChild(tr);
        }
    })('rams');

})(this)

<|next_version|>
(function(global) {
    'use strict';

    (function(id) {
        var i, j;
        var tab = document.getElementById(id);
        var thead = tab.querySelector('thead');
        var tbody = tab.querySelector('tbody');
        var tr, th, td;
        // tr = document.createElement('tr');
        // th = document.createElement('td');
        // tr.appendChild(th);
        // for (i = 0; i < 30; i++) {
        //     th = document.createElement('th');
        //     th.textContent = i + 1;
        //     tr.appendChild(th);
        // }
        // thead.appendChild(tr);
        for (i = 0; i < 3; i++) {
            tr = document.createElement('tr');
            tr.id = "row-" + i;
            // th = document.createElement('th');
            // th.textContent = i + 1;
            // tr.appendChild(th);
            for (j = 0; j < 30; j++) {
                td = document.createElement('td');
                td.textContent = 0;
                td.id = "cell-" + (i * 30 + j);
                tr.appendChild(td);
            }
            tbody.appendChild(tr);
        }
    })('rams');

})(this)


Allow almost all puppeteer pdf configurations

--- lib/converter.js
+++ lib/converter.js
@@ -7,9 +7,16 @@
   "--disable-gpu"
 ]

+
 const allowedOptions = [
   "scale",
+  "displayHeaderFooter",
   "printBackground",
+  "format",
+  "landscape",
+  "pageRanges",
+  "width",
+  "height",
   "margin"
 ]

<|original_code|>
const puppeteer = require("puppeteer")
const defaults = require("../configurations/defaults")

const puppeteerArgs = [
  "--no-sandbox",
  "--disable-setuid-sandbox",
  "--disable-gpu"
]

const allowedOptions = [
  "scale",
  "printBackground",
  "margin"
]

const formatOptions = options => allowedOptions.reduce((filtered, key) => {
  if (options[key] == 'true') {
    filtered[key] = true
    return filtered
  }

  if (options[key] == 'false') {
    filtered[key] = false
    return filtered
  }

  if (!isNaN(options[key])) {
    filtered[key] = +options[key]
    return filtered
  }

  filtered[key] = options[key]
  return filtered
}, {})

const pageToPdf = options => page =>
  page
    .goto(options.uri, { waitUntil: "networkidle" })
    .then(() => page.pdf(Object.assign(defaults, formatOptions(options))))

const browserToPdf = options => browser =>
  browser
    .newPage()
    .then(pageToPdf(options))
    .then(pdf => {
      browser.close()
      return pdf
    })

const uriToPdf = options =>
  puppeteer
    .launch({ args: puppeteerArgs })
    .then(browserToPdf(options))

module.exports = {
  uriToPdf
}

<|edits_diff|>
--- lib/converter.js
+++ lib/converter.js
@@ -7,8 +7,10 @@
   "--disable-gpu"
 ]

+
 const allowedOptions = [
   "scale",
+  "displayHeaderFooter",
   "printBackground",
   "margin"
 ]
<|current_version|>
const puppeteer = require("puppeteer")
const defaults = require("../configurations/defaults")

const puppeteerArgs = [
  "--no-sandbox",
  "--disable-setuid-sandbox",
  "--disable-gpu"
]

const allowedOptions = [
  "scale",
  "displayHeaderFooter",
  "printBackground",
  "margin"
]

const formatOptions = options => allowedOptions.reduce((filtered, key) => {
  if (options[key] == 'true') {
    filtered[key] = true
    return filtered
  }

  if (options[key] == 'false') {
    filtered[key] = false
    return filtered
  }

  if (!isNaN(options[key])) {
    filtered[key] = +options[key]
    return filtered
  }

  filtered[key] = options[key]
  return filtered
}, {})

const pageToPdf = options => page =>
  page
    .goto(options.uri, { waitUntil: "networkidle" })
    .then(() => page.pdf(Object.assign(defaults, formatOptions(options))))

const browserToPdf = options => browser =>
  browser
    .newPage()
    .then(pageToPdf(options))
    .then(pdf => {
      browser.close()
      return pdf
    })

const uriToPdf = options =>
  puppeteer
    .launch({ args: puppeteerArgs })
    .then(browserToPdf(options))

module.exports = {
  uriToPdf
}

<|next_version|>
const puppeteer = require("puppeteer")
const defaults = require("../configurations/defaults")

const puppeteerArgs = [
  "--no-sandbox",
  "--disable-setuid-sandbox",
  "--disable-gpu"
]

const allowedOptions = [
  "scale",
  "displayHeaderFooter",
  "printBackground",
  "format",
  "landscape",
  "pageRanges",
  "width",
  "height",
  "margin"
]

const formatOptions = options => allowedOptions.reduce((filtered, key) => {
  if (options[key] == 'true') {
    filtered[key] = true
    return filtered
  }

  if (options[key] == 'false') {
    filtered[key] = false
    return filtered
  }

  if (!isNaN(options[key])) {
    filtered[key] = +options[key]
    return filtered
  }

  filtered[key] = options[key]
  return filtered
}, {})

const pageToPdf = options => page =>
  page
    .goto(options.uri, { waitUntil: "networkidle" })
    .then(() => page.pdf(Object.assign(defaults, formatOptions(options))))

const browserToPdf = options => browser =>
  browser
    .newPage()
    .then(pageToPdf(options))
    .then(pdf => {
      browser.close()
      return pdf
    })

const uriToPdf = options =>
  puppeteer
    .launch({ args: puppeteerArgs })
    .then(browserToPdf(options))

module.exports = {
  uriToPdf
}


$(document).ready( function () {
  $("button.upvote").click( function() {
    var commentId = $(".upvote").data("id");
    event.preventDefault();
    $.ajax({
      url: '/response/up_vote',
      method: 'POST',
      data: { id: commentId },
      dataType: 'JSON'
    }).done( function (response) {
      $("button.upvote").closest(".response").append("<p>" + response + "</p>")
    }).fail( function (response) {
        console.log("Failed. Here is the response:")
        console.log(response);
    })
  })
})

Add ajax to upvote a response.

Add ajax to upvote a response.

--- app/assets/javascripts/responses.js
+++ app/assets/javascripts/responses.js
@@ -8,7 +8,9 @@
       data: { id: commentId },
       dataType: 'JSON'
     }).done( function (response) {
+      $("button.upvote").closest(".response").append("<p>" + response + "</p>")
     }).fail( function (response) {
+        console.log("Failed. Here is the response:")
         console.log(response);
     })
   })

$(document).ready( function () {
  $("button.upvote").click( function() {
    var commentId = $(".upvote").data("id");
    event.preventDefault();
    $.ajax({
      url: '/response/up_vote',
      method: 'POST',
      data: { id: commentId },
      dataType: 'JSON'
    }).done( function (response) {
      $("button.upvote").closest(".response").append("<p>" + response + "</p>")
    }).fail( function (response) {
        console.log(response);
    })
  })
})

<|original_code|>
$(document).ready( function () {
  $("button.upvote").click( function() {
    var commentId = $(".upvote").data("id");
    event.preventDefault();
    $.ajax({
      url: '/response/up_vote',
      method: 'POST',
      data: { id: commentId },
      dataType: 'JSON'
    }).done( function (response) {
    }).fail( function (response) {
        console.log(response);
    })
  })
})

<|edits_diff|>
--- app/assets/javascripts/responses.js
+++ app/assets/javascripts/responses.js
@@ -8,6 +8,7 @@
       data: { id: commentId },
       dataType: 'JSON'
     }).done( function (response) {
+      $("button.upvote").closest(".response").append("
" + response + "
")
     }).fail( function (response) {
         console.log(response);
     })
<|current_version|>
$(document).ready( function () {
  $("button.upvote").click( function() {
    var commentId = $(".upvote").data("id");
    event.preventDefault();
    $.ajax({
      url: '/response/up_vote',
      method: 'POST',
      data: { id: commentId },
      dataType: 'JSON'
    }).done( function (response) {
      $("button.upvote").closest(".response").append("
" + response + "
")
    }).fail( function (response) {
        console.log(response);
    })
  })
})

<|next_version|>
$(document).ready( function () {
  $("button.upvote").click( function() {
    var commentId = $(".upvote").data("id");
    event.preventDefault();
    $.ajax({
      url: '/response/up_vote',
      method: 'POST',
      data: { id: commentId },
      dataType: 'JSON'
    }).done( function (response) {
      $("button.upvote").closest(".response").append("
" + response + "
")
    }).fail( function (response) {
        console.log("Failed. Here is the response:")
        console.log(response);
    })
  })
})


Update user schema for application merge

--- server/db/schemas/User.js
+++ server/db/schemas/User.js
@@ -5,10 +5,17 @@
     _id: { type: Number },
     profileImageName: { type: String, default: 'default.png' },
     email: { type: String, unique: true },
+    age: { type: Number, min: 10, max: 100 },
+    grade: { type: Number, min: 8, max: 12 },
     phoneNumber: { type: String },
     name: {
         first: { type: String, trim: true },
         last: { type: String, trim: true }
+    },
+    application: {
+        recommender: { type: Number, ref: 'User' },
+        why: String,
+        writingFileName: String
     },
     registeredDate: { type: Date, default: Date.now },
     admin: { type: Boolean, default: false },

<|original_code|>
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    _id: { type: Number },
    profileImageName: { type: String, default: 'default.png' },
    email: { type: String, unique: true },
    phoneNumber: { type: String },
    name: {
        first: { type: String, trim: true },
        last: { type: String, trim: true }
    },
    registeredDate: { type: Date, default: Date.now },
    admin: { type: Boolean, default: false },
    verified: { type: Boolean, default: false }
}, {
    toObject: {
        virtuals: true
    },
    toJSON: {
        virtuals: true
    }
});

userSchema.methods.findCamps = function() {
    return this.model('Camp').find().or([{ ambassador: this._id }, { director: this._id}, { teachers: this._id }]).populate('location').exec();
}

userSchema.virtual('name.full').get(function() {
    return this.name.first + ' ' + this.name.last;
});

module.exports = { name: 'User', schema: userSchema };
<|edits_diff|>
--- server/db/schemas/User.js
+++ server/db/schemas/User.js
@@ -5,6 +5,8 @@
     _id: { type: Number },
     profileImageName: { type: String, default: 'default.png' },
     email: { type: String, unique: true },
+    age: { type: Number, min: 10, max: 100 },
+    grade: { type: Number, min: 8, max: 12 },
     phoneNumber: { type: String },
     name: {
         first: { type: String, trim: true },
<|current_version|>
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    _id: { type: Number },
    profileImageName: { type: String, default: 'default.png' },
    email: { type: String, unique: true },
    age: { type: Number, min: 10, max: 100 },
    grade: { type: Number, min: 8, max: 12 },
    phoneNumber: { type: String },
    name: {
        first: { type: String, trim: true },
        last: { type: String, trim: true }
    },
    registeredDate: { type: Date, default: Date.now },
    admin: { type: Boolean, default: false },
    verified: { type: Boolean, default: false }
}, {
    toObject: {
        virtuals: true
    },
    toJSON: {
        virtuals: true
    }
});

userSchema.methods.findCamps = function() {
    return this.model('Camp').find().or([{ ambassador: this._id }, { director: this._id}, { teachers: this._id }]).populate('location').exec();
}

userSchema.virtual('name.full').get(function() {
    return this.name.first + ' ' + this.name.last;
});

module.exports = { name: 'User', schema: userSchema };
<|next_version|>
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    _id: { type: Number },
    profileImageName: { type: String, default: 'default.png' },
    email: { type: String, unique: true },
    age: { type: Number, min: 10, max: 100 },
    grade: { type: Number, min: 8, max: 12 },
    phoneNumber: { type: String },
    name: {
        first: { type: String, trim: true },
        last: { type: String, trim: true }
    },
    application: {
        recommender: { type: Number, ref: 'User' },
        why: String,
        writingFileName: String
    },
    registeredDate: { type: Date, default: Date.now },
    admin: { type: Boolean, default: false },
    verified: { type: Boolean, default: false }
}, {
    toObject: {
        virtuals: true
    },
    toJSON: {
        virtuals: true
    }
});

userSchema.methods.findCamps = function() {
    return this.model('Camp').find().or([{ ambassador: this._id }, { director: this._id}, { teachers: this._id }]).populate('location').exec();
}

userSchema.virtual('name.full').get(function() {
    return this.name.first + ' ' + this.name.last;
});

module.exports = { name: 'User', schema: userSchema };


Add reformatted (EN) verse references to dump

--- bin/extract_references.js
+++ bin/extract_references.js
@@ -3,6 +3,7 @@
 var readline = require('readline');
 var bcv_parser = require('bible-passage-reference-parser/js/tr_bcv_parser').bcv_parser;
 var bcv = new bcv_parser();
+var formatter = require('bible-reference-formatter/es6/en');

 bcv.set_options({
   'sequence_combination_strategy': 'separate'
@@ -23,6 +24,7 @@
     var ref = {};
     ref.original = data.slice(match.indices[0], match.indices[1]);
     ref.osis = match.osis;
+    ref.reformat = formatter('niv-long', match.osis);
     references.push(ref);
   });
 }

<|original_code|>
#!/usr/bin/env node

var readline = require('readline');
var bcv_parser = require('bible-passage-reference-parser/js/tr_bcv_parser').bcv_parser;
var bcv = new bcv_parser();

bcv.set_options({
  'sequence_combination_strategy': 'separate'
});
bcv.include_apocrypha(true);

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

var references = [];

function extract_references (data) {
  var res = bcv.parse(data).osis_and_indices();
  res.forEach(function(match) {
    var ref = {};
    ref.original = data.slice(match.indices[0], match.indices[1]);
    ref.osis = match.osis;
    references.push(ref);
  });
}

function output_references () {
  var output = JSON.stringify(references, null, '  ');
  process.stdout.write(output);
}

rl.on('line', extract_references);
rl.on('close', output_references);

<|edits_diff|>
--- bin/extract_references.js
+++ bin/extract_references.js
@@ -3,6 +3,7 @@
 var readline = require('readline');
 var bcv_parser = require('bible-passage-reference-parser/js/tr_bcv_parser').bcv_parser;
 var bcv = new bcv_parser();
+var formatter = require('bible-reference-formatter/es6/en');

 bcv.set_options({
   'sequence_combination_strategy': 'separate'
<|current_version|>
#!/usr/bin/env node

var readline = require('readline');
var bcv_parser = require('bible-passage-reference-parser/js/tr_bcv_parser').bcv_parser;
var bcv = new bcv_parser();
var formatter = require('bible-reference-formatter/es6/en');

bcv.set_options({
  'sequence_combination_strategy': 'separate'
});
bcv.include_apocrypha(true);

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

var references = [];

function extract_references (data) {
  var res = bcv.parse(data).osis_and_indices();
  res.forEach(function(match) {
    var ref = {};
    ref.original = data.slice(match.indices[0], match.indices[1]);
    ref.osis = match.osis;
    references.push(ref);
  });
}

function output_references () {
  var output = JSON.stringify(references, null, '  ');
  process.stdout.write(output);
}

rl.on('line', extract_references);
rl.on('close', output_references);

<|next_version|>
#!/usr/bin/env node

var readline = require('readline');
var bcv_parser = require('bible-passage-reference-parser/js/tr_bcv_parser').bcv_parser;
var bcv = new bcv_parser();
var formatter = require('bible-reference-formatter/es6/en');

bcv.set_options({
  'sequence_combination_strategy': 'separate'
});
bcv.include_apocrypha(true);

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

var references = [];

function extract_references (data) {
  var res = bcv.parse(data).osis_and_indices();
  res.forEach(function(match) {
    var ref = {};
    ref.original = data.slice(match.indices[0], match.indices[1]);
    ref.osis = match.osis;
    ref.reformat = formatter('niv-long', match.osis);
    references.push(ref);
  });
}

function output_references () {
  var output = JSON.stringify(references, null, '  ');
  process.stdout.write(output);
}

rl.on('line', extract_references);
rl.on('close', output_references);


Add filters to snapshot preview

Add filters to snapshot preview

--- test/__snapshots__/show.js
+++ test/__snapshots__/show.js
@@ -4,11 +4,14 @@
 var path = require('path')
 var chalk = require('chalk')

+var filter = process.argv[2]
+
 function show (result) {
   Object.keys(result).sort().reverse().forEach(file => {
     var test = file.replace(/\.test\.js\.snap$/, '')
     result[file].split('exports[`')
       .filter(str => str.indexOf('// ') !== 0)
+      .filter(str => !filter || str.indexOf(filter) !== -1)
       .forEach(str => {
         if (str.trim().length === 0) return
         var parts = str.replace(/"\s*`;\s*$/, '').split(/`] = `\s*"/)

<|original_code|>
#!/usr/bin/env node

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

function show (result) {
  Object.keys(result).sort().reverse().forEach(file => {
    var test = file.replace(/\.test\.js\.snap$/, '')
    result[file].split('exports[`')
      .filter(str => str.indexOf('// ') !== 0)
      .forEach(str => {
        if (str.trim().length === 0) return
        var parts = str.replace(/"\s*`;\s*$/, '').split(/`] = `\s*"/)
        process.stdout.write(
          chalk.gray(`${ test } ${ parts[0].replace(/ 1$/, '') }:\n\n`))
        process.stdout.write(parts[1])
      })
  })
}

fs.readdir(__dirname, (err, list) => {
  if (err) throw err
  var snaps = list.filter(i => /\.snap$/.test(i))

  var result = { }
  snaps.forEach(file => {
    fs.readFile(path.join(__dirname, file), (err2, content) => {
      if (err2) throw err2
      result[file] = content.toString()
      if (Object.keys(result).length === snaps.length) show(result)
    })
  })
})

<|edits_diff|>
--- test/__snapshots__/show.js
+++ test/__snapshots__/show.js
@@ -3,6 +3,8 @@
 var fs = require('fs')
 var path = require('path')
 var chalk = require('chalk')
+
+var filter = process.argv[2]

 function show (result) {
   Object.keys(result).sort().reverse().forEach(file => {
<|current_version|>
#!/usr/bin/env node

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

var filter = process.argv[2]

function show (result) {
  Object.keys(result).sort().reverse().forEach(file => {
    var test = file.replace(/\.test\.js\.snap$/, '')
    result[file].split('exports[`')
      .filter(str => str.indexOf('// ') !== 0)
      .forEach(str => {
        if (str.trim().length === 0) return
        var parts = str.replace(/"\s*`;\s*$/, '').split(/`] = `\s*"/)
        process.stdout.write(
          chalk.gray(`${ test } ${ parts[0].replace(/ 1$/, '') }:\n\n`))
        process.stdout.write(parts[1])
      })
  })
}

fs.readdir(__dirname, (err, list) => {
  if (err) throw err
  var snaps = list.filter(i => /\.snap$/.test(i))

  var result = { }
  snaps.forEach(file => {
    fs.readFile(path.join(__dirname, file), (err2, content) => {
      if (err2) throw err2
      result[file] = content.toString()
      if (Object.keys(result).length === snaps.length) show(result)
    })
  })
})

<|next_version|>
#!/usr/bin/env node

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

var filter = process.argv[2]

function show (result) {
  Object.keys(result).sort().reverse().forEach(file => {
    var test = file.replace(/\.test\.js\.snap$/, '')
    result[file].split('exports[`')
      .filter(str => str.indexOf('// ') !== 0)
      .filter(str => !filter || str.indexOf(filter) !== -1)
      .forEach(str => {
        if (str.trim().length === 0) return
        var parts = str.replace(/"\s*`;\s*$/, '').split(/`] = `\s*"/)
        process.stdout.write(
          chalk.gray(`${ test } ${ parts[0].replace(/ 1$/, '') }:\n\n`))
        process.stdout.write(parts[1])
      })
  })
}

fs.readdir(__dirname, (err, list) => {
  if (err) throw err
  var snaps = list.filter(i => /\.snap$/.test(i))

  var result = { }
  snaps.forEach(file => {
    fs.readFile(path.join(__dirname, file), (err2, content) => {
      if (err2) throw err2
      result[file] = content.toString()
      if (Object.keys(result).length === snaps.length) show(result)
    })
  })
})


Refresh data on app going foreground

Refresh data on app going foreground

--- project/src/js/main.js
+++ project/src/js/main.js
@@ -15,6 +15,10 @@
 var play = require('./ui/play');
 var seek = require('./ui/seek');

+function onResume() {
+  session.refresh(true);
+}
+
 function main() {

   m.route(document.body, '/', {
@@ -24,8 +28,12 @@
     '/play/:id': play
   });

+  // refresh data once and on app resume
   if (utils.hasNetwork()) session.refresh(true);
+  document.addEventListener('resume', onResume, false);

+  // iOs keyboard hack
+  // TODO we may want to remove this and call only on purpose
   window.cordova.plugins.Keyboard.disableScroll(true);

   if (window.gaId) window.analytics.startTrackerWithId(window.gaId);

<|original_code|>
/* application entry point */

// require mithril globally for convenience
window.m = require('mithril');

// cordova plugins polyfills for browser
if (!window.cordova) require('./cordovaPolyfills.js');

var utils = require('./utils');
var session = require('./session');
var i18n = require('./i18n');

var home = require('./ui/home');
var login = require('./ui/login');
var play = require('./ui/play');
var seek = require('./ui/seek');

function main() {

  m.route(document.body, '/', {
    '/': home,
    '/login': login,
    '/seek/:id': seek,
    '/play/:id': play
  });

  if (utils.hasNetwork()) session.refresh(true);

  window.cordova.plugins.Keyboard.disableScroll(true);

  if (window.gaId) window.analytics.startTrackerWithId(window.gaId);

  setTimeout(function() {
    window.navigator.splashscreen.hide();
  }, 500);
}

document.addEventListener('deviceready',
  // i18n must be loaded before any rendering happens
  utils.ƒ(i18n.loadPreferredLanguage, main),
  false
);

<|edits_diff|>
--- project/src/js/main.js
+++ project/src/js/main.js
@@ -15,6 +15,10 @@
 var play = require('./ui/play');
 var seek = require('./ui/seek');

+function onResume() {
+  session.refresh(true);
+}
+
 function main() {

   m.route(document.body, '/', {
@@ -24,7 +28,9 @@
     '/play/:id': play
   });

+  // refresh data once and on app resume
   if (utils.hasNetwork()) session.refresh(true);
+  document.addEventListener('resume', onResume, false);

   window.cordova.plugins.Keyboard.disableScroll(true);

<|current_version|>
/* application entry point */

// require mithril globally for convenience
window.m = require('mithril');

// cordova plugins polyfills for browser
if (!window.cordova) require('./cordovaPolyfills.js');

var utils = require('./utils');
var session = require('./session');
var i18n = require('./i18n');

var home = require('./ui/home');
var login = require('./ui/login');
var play = require('./ui/play');
var seek = require('./ui/seek');

function onResume() {
  session.refresh(true);
}

function main() {

  m.route(document.body, '/', {
    '/': home,
    '/login': login,
    '/seek/:id': seek,
    '/play/:id': play
  });

  // refresh data once and on app resume
  if (utils.hasNetwork()) session.refresh(true);
  document.addEventListener('resume', onResume, false);

  window.cordova.plugins.Keyboard.disableScroll(true);

  if (window.gaId) window.analytics.startTrackerWithId(window.gaId);

  setTimeout(function() {
    window.navigator.splashscreen.hide();
  }, 500);
}

document.addEventListener('deviceready',
  // i18n must be loaded before any rendering happens
  utils.ƒ(i18n.loadPreferredLanguage, main),
  false
);

<|next_version|>
/* application entry point */

// require mithril globally for convenience
window.m = require('mithril');

// cordova plugins polyfills for browser
if (!window.cordova) require('./cordovaPolyfills.js');

var utils = require('./utils');
var session = require('./session');
var i18n = require('./i18n');

var home = require('./ui/home');
var login = require('./ui/login');
var play = require('./ui/play');
var seek = require('./ui/seek');

function onResume() {
  session.refresh(true);
}

function main() {

  m.route(document.body, '/', {
    '/': home,
    '/login': login,
    '/seek/:id': seek,
    '/play/:id': play
  });

  // refresh data once and on app resume
  if (utils.hasNetwork()) session.refresh(true);
  document.addEventListener('resume', onResume, false);

  // iOs keyboard hack
  // TODO we may want to remove this and call only on purpose
  window.cordova.plugins.Keyboard.disableScroll(true);

  if (window.gaId) window.analytics.startTrackerWithId(window.gaId);

  setTimeout(function() {
    window.navigator.splashscreen.hide();
  }, 500);
}

document.addEventListener('deviceready',
  // i18n must be loaded before any rendering happens
  utils.ƒ(i18n.loadPreferredLanguage, main),
  false
);


Add mocks to movies controller tests

Add mocks to movies controller tests

--- client/angular/src/app/controllers/movies.controller.spec.js
+++ client/angular/src/app/controllers/movies.controller.spec.js
@@ -13,6 +13,9 @@
     httpBackend.whenGET(mocks.allMoviesUrl).respond(
       JSON.stringify(mocks.allMoviesResults)
     );
+    httpBackend.whenDELETE(mocks.deleteUrl).respond(
+      JSON.stringify(mocks.deleteResults)
+    );

     createController = function() {
         return $controller('MoviesCtrl', {
@@ -24,6 +27,7 @@
   describe('controller', function() {
     it('should exist', function() {
       var controller = createController();
+      httpBackend.flush();
       expect(controller).toBeDefined();
     });
   });

<|original_code|>
'use strict';

describe('controllers', function() {
  var httpBackend, scope, createController;
  beforeEach(module('polyflix'));

  beforeEach(inject(function($rootScope, $httpBackend, $controller) {
    httpBackend = $httpBackend;
    scope = $rootScope.$new();
    httpBackend.whenGET(mocks.configUrl).respond(
      JSON.stringify(mocks.configResults)
    );
    httpBackend.whenGET(mocks.allMoviesUrl).respond(
      JSON.stringify(mocks.allMoviesResults)
    );

    createController = function() {
        return $controller('MoviesCtrl', {
            '$scope': scope
        });
    };
  }));

  describe('controller', function() {
    it('should exist', function() {
      var controller = createController();
      expect(controller).toBeDefined();
    });
  });
});
<|edits_diff|>
--- client/angular/src/app/controllers/movies.controller.spec.js
+++ client/angular/src/app/controllers/movies.controller.spec.js
@@ -12,6 +12,9 @@
     );
     httpBackend.whenGET(mocks.allMoviesUrl).respond(
       JSON.stringify(mocks.allMoviesResults)
+    );
+    httpBackend.whenDELETE(mocks.deleteUrl).respond(
+      JSON.stringify(mocks.deleteResults)
     );

     createController = function() {
<|current_version|>
'use strict';

describe('controllers', function() {
  var httpBackend, scope, createController;
  beforeEach(module('polyflix'));

  beforeEach(inject(function($rootScope, $httpBackend, $controller) {
    httpBackend = $httpBackend;
    scope = $rootScope.$new();
    httpBackend.whenGET(mocks.configUrl).respond(
      JSON.stringify(mocks.configResults)
    );
    httpBackend.whenGET(mocks.allMoviesUrl).respond(
      JSON.stringify(mocks.allMoviesResults)
    );
    httpBackend.whenDELETE(mocks.deleteUrl).respond(
      JSON.stringify(mocks.deleteResults)
    );

    createController = function() {
        return $controller('MoviesCtrl', {
            '$scope': scope
        });
    };
  }));

  describe('controller', function() {
    it('should exist', function() {
      var controller = createController();
      expect(controller).toBeDefined();
    });
  });
});
<|next_version|>
'use strict';

describe('controllers', function() {
  var httpBackend, scope, createController;
  beforeEach(module('polyflix'));

  beforeEach(inject(function($rootScope, $httpBackend, $controller) {
    httpBackend = $httpBackend;
    scope = $rootScope.$new();
    httpBackend.whenGET(mocks.configUrl).respond(
      JSON.stringify(mocks.configResults)
    );
    httpBackend.whenGET(mocks.allMoviesUrl).respond(
      JSON.stringify(mocks.allMoviesResults)
    );
    httpBackend.whenDELETE(mocks.deleteUrl).respond(
      JSON.stringify(mocks.deleteResults)
    );

    createController = function() {
        return $controller('MoviesCtrl', {
            '$scope': scope
        });
    };
  }));

  describe('controller', function() {
    it('should exist', function() {
      var controller = createController();
      httpBackend.flush();
      expect(controller).toBeDefined();
    });
  });
});


Add output returned by the fixer

Test: Add output returned by the fixer

--- tests/lib/rules/no-const-outside-module-scope.js
+++ tests/lib/rules/no-const-outside-module-scope.js
@@ -27,9 +27,11 @@

   invalid: [{
     code: '{ const FOOBAR = 5; }',
+    output: '{ let FOOBAR = 5; }',
     errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
   }, {
     code: 'function foobar() { const FOOBAR = 5; return FOOBAR; }',
+    output: 'function foobar() { let FOOBAR = 5; return FOOBAR; }',
     errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
   }]
 });

<|original_code|>
'use strict';

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

var rule = require('../../../lib/rules/no-const-outside-module-scope');
var RuleTester = require('eslint').RuleTester;

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

var ruleTester = new RuleTester({
  parserOptions: {
    ecmaVersion: 6,
    sourceType: 'module'
  }
});

ruleTester.run('no-const-outside-module-scope', rule, {
  valid: [
    'const FOOBAR = 5;',
    'export const FOOBAR = 5;'
  ],

  invalid: [{
    code: '{ const FOOBAR = 5; }',
    errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
  }, {
    code: 'function foobar() { const FOOBAR = 5; return FOOBAR; }',
    errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
  }]
});

<|edits_diff|>
--- tests/lib/rules/no-const-outside-module-scope.js
+++ tests/lib/rules/no-const-outside-module-scope.js
@@ -27,6 +27,7 @@

   invalid: [{
     code: '{ const FOOBAR = 5; }',
+    output: '{ let FOOBAR = 5; }',
     errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
   }, {
     code: 'function foobar() { const FOOBAR = 5; return FOOBAR; }',
<|current_version|>
'use strict';

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

var rule = require('../../../lib/rules/no-const-outside-module-scope');
var RuleTester = require('eslint').RuleTester;

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

var ruleTester = new RuleTester({
  parserOptions: {
    ecmaVersion: 6,
    sourceType: 'module'
  }
});

ruleTester.run('no-const-outside-module-scope', rule, {
  valid: [
    'const FOOBAR = 5;',
    'export const FOOBAR = 5;'
  ],

  invalid: [{
    code: '{ const FOOBAR = 5; }',
    output: '{ let FOOBAR = 5; }',
    errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
  }, {
    code: 'function foobar() { const FOOBAR = 5; return FOOBAR; }',
    errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
  }]
});

<|next_version|>
'use strict';

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

var rule = require('../../../lib/rules/no-const-outside-module-scope');
var RuleTester = require('eslint').RuleTester;

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

var ruleTester = new RuleTester({
  parserOptions: {
    ecmaVersion: 6,
    sourceType: 'module'
  }
});

ruleTester.run('no-const-outside-module-scope', rule, {
  valid: [
    'const FOOBAR = 5;',
    'export const FOOBAR = 5;'
  ],

  invalid: [{
    code: '{ const FOOBAR = 5; }',
    output: '{ let FOOBAR = 5; }',
    errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
  }, {
    code: 'function foobar() { const FOOBAR = 5; return FOOBAR; }',
    output: 'function foobar() { let FOOBAR = 5; return FOOBAR; }',
    errors: [{ message: '`const` should only be used in module scope (not inside functions/blocks).' }]
  }]
});


Remove pc.DepthMaterial from API ref.

Remove pc.DepthMaterial from API ref.

--- src/scene/scene_depthmaterial.js
+++ src/scene/scene_depthmaterial.js
@@ -1,6 +1,7 @@
 pc.extend(pc, function () {

     /**
+     * @private
      * @name pc.DepthMaterial
      * @class A Depth material is is for rendering linear depth values to a render target.
      * @author Will Eastcott
@@ -12,6 +13,7 @@

     pc.extend(DepthMaterial.prototype, {
         /**
+         * @private
          * @function
          * @name pc.DepthMaterial#clone
          * @description Duplicates a Depth material.

<|original_code|>
pc.extend(pc, function () {

    /**
     * @name pc.DepthMaterial
     * @class A Depth material is is for rendering linear depth values to a render target.
     * @author Will Eastcott
     */
    var DepthMaterial = function () {
    };

    DepthMaterial = pc.inherits(DepthMaterial, pc.Material);

    pc.extend(DepthMaterial.prototype, {
        /**
         * @function
         * @name pc.DepthMaterial#clone
         * @description Duplicates a Depth material.
         * @returns {pc.DepthMaterial} A cloned Depth material.
         */
        clone: function () {
            var clone = new pc.DepthMaterial();

            Material.prototype._cloneInternal.call(this, clone);

            clone.update();
            return clone;
        },

        update: function () {
        },

        updateShader: function (device) {
            var options = {
                skin: !!this.meshInstances[0].skinInstance
            };
            var library = device.getProgramLibrary();
            this.shader = library.getProgram('depth', options);
        }
    });

    return {
        DepthMaterial: DepthMaterial
    };
}());
<|edits_diff|>
--- src/scene/scene_depthmaterial.js
+++ src/scene/scene_depthmaterial.js
@@ -1,6 +1,7 @@
 pc.extend(pc, function () {

     /**
+     * @private
      * @name pc.DepthMaterial
      * @class A Depth material is is for rendering linear depth values to a render target.
      * @author Will Eastcott
<|current_version|>
pc.extend(pc, function () {

    /**
     * @private
     * @name pc.DepthMaterial
     * @class A Depth material is is for rendering linear depth values to a render target.
     * @author Will Eastcott
     */
    var DepthMaterial = function () {
    };

    DepthMaterial = pc.inherits(DepthMaterial, pc.Material);

    pc.extend(DepthMaterial.prototype, {
        /**
         * @function
         * @name pc.DepthMaterial#clone
         * @description Duplicates a Depth material.
         * @returns {pc.DepthMaterial} A cloned Depth material.
         */
        clone: function () {
            var clone = new pc.DepthMaterial();

            Material.prototype._cloneInternal.call(this, clone);

            clone.update();
            return clone;
        },

        update: function () {
        },

        updateShader: function (device) {
            var options = {
                skin: !!this.meshInstances[0].skinInstance
            };
            var library = device.getProgramLibrary();
            this.shader = library.getProgram('depth', options);
        }
    });

    return {
        DepthMaterial: DepthMaterial
    };
}());
<|next_version|>
pc.extend(pc, function () {

    /**
     * @private
     * @name pc.DepthMaterial
     * @class A Depth material is is for rendering linear depth values to a render target.
     * @author Will Eastcott
     */
    var DepthMaterial = function () {
    };

    DepthMaterial = pc.inherits(DepthMaterial, pc.Material);

    pc.extend(DepthMaterial.prototype, {
        /**
         * @private
         * @function
         * @name pc.DepthMaterial#clone
         * @description Duplicates a Depth material.
         * @returns {pc.DepthMaterial} A cloned Depth material.
         */
        clone: function () {
            var clone = new pc.DepthMaterial();

            Material.prototype._cloneInternal.call(this, clone);

            clone.update();
            return clone;
        },

        update: function () {
        },

        updateShader: function (device) {
            var options = {
                skin: !!this.meshInstances[0].skinInstance
            };
            var library = device.getProgramLibrary();
            this.shader = library.getProgram('depth', options);
        }
    });

    return {
        DepthMaterial: DepthMaterial
    };
}());


Add routes for Aksels further development

--- client/src/App/index.js
+++ client/src/App/index.js
@@ -14,6 +14,11 @@

 // Our pages
 import Home from 'Home'
+import Browse from 'SOMEWHERE'
+import Upload from 'SOMEWHERE'
+import Register from 'SOMEWHERE'
+import Login from 'SOMEWHERE'
+import User from 'SOMEWHERE'

 // Create enhanced history
 const history = syncHistoryWithStore(browserHistory, store, {
@@ -34,6 +39,11 @@
         <Router history={history}>
           <Route path='/' component={Container}>
             <IndexRoute component={Home} />
+            <Route path='browse/:id' component={Browse} />
+            <Route path='upload' component={Upload} />
+            <Route path='login' component={Login} />
+            <Route path='register' component={Register} />
+            <Route path='user/:id' component={User} />
           </Route>
         </Router>
       </Provider>

<|original_code|>
// Import libraries
import 'rxjs'
import { Provider } from 'react-redux'
import React, { PureComponent } from 'react'
import { syncHistoryWithStore } from 'react-router-redux'
import { Router, Route, browserHistory, IndexRoute } from 'react-router'

// Add CSS framework
import 'foundation-sites/dist/foundation.min.css'

// Our modules
import store from 'store'
import Container from 'shared/Container'

// Our pages
import Home from 'Home'

// Create enhanced history
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState (state) {
    return state.get('routing').toJS()
  }
})

export default class App extends PureComponent {
  // App component never needs to update
  shouldComponentUpdate (nextProps, nextState) {
    return false
  }

  render () {
    return (
      <Provider store={store}>
        <Router history={history}>
          <Route path='/' component={Container}>
            <IndexRoute component={Home} />
          </Route>
        </Router>
      </Provider>
    )
  }
}

<|edits_diff|>
--- client/src/App/index.js
+++ client/src/App/index.js
@@ -14,6 +14,11 @@

 // Our pages
 import Home from 'Home'
+import Browse from 'SOMEWHERE'
+import Upload from 'SOMEWHERE'
+import Register from 'SOMEWHERE'
+import Login from 'SOMEWHERE'
+import User from 'SOMEWHERE'

 // Create enhanced history
 const history = syncHistoryWithStore(browserHistory, store, {
<|current_version|>
// Import libraries
import 'rxjs'
import { Provider } from 'react-redux'
import React, { PureComponent } from 'react'
import { syncHistoryWithStore } from 'react-router-redux'
import { Router, Route, browserHistory, IndexRoute } from 'react-router'

// Add CSS framework
import 'foundation-sites/dist/foundation.min.css'

// Our modules
import store from 'store'
import Container from 'shared/Container'

// Our pages
import Home from 'Home'
import Browse from 'SOMEWHERE'
import Upload from 'SOMEWHERE'
import Register from 'SOMEWHERE'
import Login from 'SOMEWHERE'
import User from 'SOMEWHERE'

// Create enhanced history
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState (state) {
    return state.get('routing').toJS()
  }
})

export default class App extends PureComponent {
  // App component never needs to update
  shouldComponentUpdate (nextProps, nextState) {
    return false
  }

  render () {
    return (
      <Provider store={store}>
        <Router history={history}>
          <Route path='/' component={Container}>
            <IndexRoute component={Home} />
          </Route>
        </Router>
      </Provider>
    )
  }
}

<|next_version|>
// Import libraries
import 'rxjs'
import { Provider } from 'react-redux'
import React, { PureComponent } from 'react'
import { syncHistoryWithStore } from 'react-router-redux'
import { Router, Route, browserHistory, IndexRoute } from 'react-router'

// Add CSS framework
import 'foundation-sites/dist/foundation.min.css'

// Our modules
import store from 'store'
import Container from 'shared/Container'

// Our pages
import Home from 'Home'
import Browse from 'SOMEWHERE'
import Upload from 'SOMEWHERE'
import Register from 'SOMEWHERE'
import Login from 'SOMEWHERE'
import User from 'SOMEWHERE'

// Create enhanced history
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState (state) {
    return state.get('routing').toJS()
  }
})

export default class App extends PureComponent {
  // App component never needs to update
  shouldComponentUpdate (nextProps, nextState) {
    return false
  }

  render () {
    return (
      <Provider store={store}>
        <Router history={history}>
          <Route path='/' component={Container}>
            <IndexRoute component={Home} />
            <Route path='browse/:id' component={Browse} />
            <Route path='upload' component={Upload} />
            <Route path='login' component={Login} />
            <Route path='register' component={Register} />
            <Route path='user/:id' component={User} />
          </Route>
        </Router>
      </Provider>
    )
  }
}


Change the value of revealBtn when clicked

--- js/main.js
+++ js/main.js
@@ -35,6 +35,7 @@

 function revealAns() {
 	question.innerHTML = questions[questionNum].answer;
+	revealBtn.value = "NEXT";
 }

 function nextSet() {
@@ -43,3 +44,4 @@
 }

 revealBtn.onclick = revealAns;
+

<|original_code|>
var questions = [
  Q1 = {
		question: "What does HTML means?",
		answer: "HyperText Markup Language"
  },
  Q2 = {
		question: "What does CSS means?",
		answer: "Cascading Style Sheet"
  },
  Q3 = {
		question: "Why the \"C\" in CSS, is called Cascading?",
		answer: "When CSS rules are duplicated, the rule to be use is chosen by cascading down from more general rules to the specific rule required"
  }
];

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

var questionNum = 0,
	answeredQA = [];

// Generate random number to display random QA set
function createNum() {
	questionNum = Math.floor(Math.random() * 3);
	// Recursively create random questionNum so that last QA set will not be repeated
	if (answeredQA.indexOf(questionNum) !== -1) {
		createNum();
	}
	question.innerHTML = questions[questionNum].question;
	answeredQA.push(questionNum);
}

createNum();

var revealBtn = document.getElementById('reveal-answer');

function revealAns() {
	question.innerHTML = questions[questionNum].answer;
}

function nextSet() {
	createNum();
	question.innerHTML = questions[questionNum].question;
}

revealBtn.onclick = revealAns;

<|edits_diff|>
--- js/main.js
+++ js/main.js
@@ -35,6 +35,7 @@

 function revealAns() {
 	question.innerHTML = questions[questionNum].answer;
+	revealBtn.value = "NEXT";
 }

 function nextSet() {
<|current_version|>
var questions = [
  Q1 = {
		question: "What does HTML means?",
		answer: "HyperText Markup Language"
  },
  Q2 = {
		question: "What does CSS means?",
		answer: "Cascading Style Sheet"
  },
  Q3 = {
		question: "Why the \"C\" in CSS, is called Cascading?",
		answer: "When CSS rules are duplicated, the rule to be use is chosen by cascading down from more general rules to the specific rule required"
  }
];

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

var questionNum = 0,
	answeredQA = [];

// Generate random number to display random QA set
function createNum() {
	questionNum = Math.floor(Math.random() * 3);
	// Recursively create random questionNum so that last QA set will not be repeated
	if (answeredQA.indexOf(questionNum) !== -1) {
		createNum();
	}
	question.innerHTML = questions[questionNum].question;
	answeredQA.push(questionNum);
}

createNum();

var revealBtn = document.getElementById('reveal-answer');

function revealAns() {
	question.innerHTML = questions[questionNum].answer;
	revealBtn.value = "NEXT";
}

function nextSet() {
	createNum();
	question.innerHTML = questions[questionNum].question;
}

revealBtn.onclick = revealAns;

<|next_version|>
var questions = [
  Q1 = {
		question: "What does HTML means?",
		answer: "HyperText Markup Language"
  },
  Q2 = {
		question: "What does CSS means?",
		answer: "Cascading Style Sheet"
  },
  Q3 = {
		question: "Why the \"C\" in CSS, is called Cascading?",
		answer: "When CSS rules are duplicated, the rule to be use is chosen by cascading down from more general rules to the specific rule required"
  }
];

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

var questionNum = 0,
	answeredQA = [];

// Generate random number to display random QA set
function createNum() {
	questionNum = Math.floor(Math.random() * 3);
	// Recursively create random questionNum so that last QA set will not be repeated
	if (answeredQA.indexOf(questionNum) !== -1) {
		createNum();
	}
	question.innerHTML = questions[questionNum].question;
	answeredQA.push(questionNum);
}

createNum();

var revealBtn = document.getElementById('reveal-answer');

function revealAns() {
	question.innerHTML = questions[questionNum].answer;
	revealBtn.value = "NEXT";
}

function nextSet() {
	createNum();
	question.innerHTML = questions[questionNum].question;
}

revealBtn.onclick = revealAns;


Add singleGroup publication, clarifying comments

--- server/publications/groups.js
+++ server/publications/groups.js
@@ -1,3 +1,9 @@
 Meteor.publish('allGroups', function () {
+  // Publish all groups
   return Groups.find();
 });
+
+Meteor.publish('singleGroup', function (groupId) {
+  // Publish only one group, specified as groupId
+  return Groups.find(groupId);
+});

<|original_code|>
Meteor.publish('allGroups', function () {
  return Groups.find();
});

<|edits_diff|>
--- server/publications/groups.js
+++ server/publications/groups.js
@@ -1,3 +1,4 @@
 Meteor.publish('allGroups', function () {
+  // Publish all groups
   return Groups.find();
 });
<|current_version|>
Meteor.publish('allGroups', function () {
  // Publish all groups
  return Groups.find();
});

<|next_version|>
Meteor.publish('allGroups', function () {
  // Publish all groups
  return Groups.find();
});

Meteor.publish('singleGroup', function (groupId) {
  // Publish only one group, specified as groupId
  return Groups.find(groupId);
});


Add react tap event plugin

Add react tap event plugin

--- src/index.js
+++ src/index.js
@@ -3,6 +3,7 @@
 import { Provider } from "react-redux";
 import { createStore, applyMiddleware } from "redux";
 import thunk from "redux-thunk";
+import injectTapEventPlugin from "react-tap-event-plugin";
 import App from "./containers/App";
 import rootReducer from "./reducers";
 import { getTodosIfNeeded } from "./actions";
@@ -11,6 +12,7 @@
 const store = createStoreWithMiddleware(rootReducer)

 store.dispatch(getTodosIfNeeded())
+injectTapEventPlugin();

 render(
   <Provider store={store}>

<|original_code|>
import React from 'react';
import { render } from 'react-dom';
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import App from "./containers/App";
import rootReducer from "./reducers";
import { getTodosIfNeeded } from "./actions";

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const store = createStoreWithMiddleware(rootReducer)

store.dispatch(getTodosIfNeeded())

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#root')
);

<|edits_diff|>
--- src/index.js
+++ src/index.js
@@ -3,6 +3,7 @@
 import { Provider } from "react-redux";
 import { createStore, applyMiddleware } from "redux";
 import thunk from "redux-thunk";
+import injectTapEventPlugin from "react-tap-event-plugin";
 import App from "./containers/App";
 import rootReducer from "./reducers";
 import { getTodosIfNeeded } from "./actions";
<|current_version|>
import React from 'react';
import { render } from 'react-dom';
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import injectTapEventPlugin from "react-tap-event-plugin";
import App from "./containers/App";
import rootReducer from "./reducers";
import { getTodosIfNeeded } from "./actions";

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const store = createStoreWithMiddleware(rootReducer)

store.dispatch(getTodosIfNeeded())

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#root')
);

<|next_version|>
import React from 'react';
import { render } from 'react-dom';
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import injectTapEventPlugin from "react-tap-event-plugin";
import App from "./containers/App";
import rootReducer from "./reducers";
import { getTodosIfNeeded } from "./actions";

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const store = createStoreWithMiddleware(rootReducer)

store.dispatch(getTodosIfNeeded())
injectTapEventPlugin();

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#root')
);


Add control buttons to auth

Add control buttons to auth

--- app/components/Auth/Auth.js
+++ app/components/Auth/Auth.js
@@ -7,6 +7,7 @@
 import Login from './Login';
 import Signup from './Signup';
 import Info from './Info';
+import Controls from '../Controls';

 import { addUser } from '../../actions/user';

@@ -28,6 +29,7 @@
     const { isNewUser } = this.state;
     return (

+        <Controls />

           {
             isNewUser

<|original_code|>
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import jwtDecode from 'jwt-decode';
import styles from './styles.scss';

import Login from './Login';
import Signup from './Signup';
import Info from './Info';

import { addUser } from '../../actions/user';

const mapDispatchToProps = dispatch => ({
  addUserFromToken: token => dispatch(addUser(jwtDecode(token))),
});

class Auth extends Component {
  state = {
    isNewUser: false
  }

  toggleNewUser = () => {
    this.setState({ isNewUser: !this.state.isNewUser });
  }

  render() {
    const { addUserFromToken } = this.props;
    const { isNewUser } = this.state;
    return (

          {
            isNewUser
            ? <Signup switchForm={this.toggleNewUser} addUser={addUserFromToken} />
            : <Login switchForm={this.toggleNewUser} addUser={addUserFromToken} />
          }
          <Info
            message={isNewUser ? 'Take a part in creating better video games!' : 'Welcome back!'}
            isNewUser={isNewUser}
          />

    );
  }
}

Auth.propTypes = {
  addUserFromToken: PropTypes.func.isRequired
};

export default connect(null, mapDispatchToProps)(Auth);

<|edits_diff|>
--- app/components/Auth/Auth.js
+++ app/components/Auth/Auth.js
@@ -7,6 +7,7 @@
 import Login from './Login';
 import Signup from './Signup';
 import Info from './Info';
+import Controls from '../Controls';

 import { addUser } from '../../actions/user';

<|current_version|>
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import jwtDecode from 'jwt-decode';
import styles from './styles.scss';

import Login from './Login';
import Signup from './Signup';
import Info from './Info';
import Controls from '../Controls';

import { addUser } from '../../actions/user';

const mapDispatchToProps = dispatch => ({
  addUserFromToken: token => dispatch(addUser(jwtDecode(token))),
});

class Auth extends Component {
  state = {
    isNewUser: false
  }

  toggleNewUser = () => {
    this.setState({ isNewUser: !this.state.isNewUser });
  }

  render() {
    const { addUserFromToken } = this.props;
    const { isNewUser } = this.state;
    return (

          {
            isNewUser
            ? <Signup switchForm={this.toggleNewUser} addUser={addUserFromToken} />
            : <Login switchForm={this.toggleNewUser} addUser={addUserFromToken} />
          }
          <Info
            message={isNewUser ? 'Take a part in creating better video games!' : 'Welcome back!'}
            isNewUser={isNewUser}
          />

    );
  }
}

Auth.propTypes = {
  addUserFromToken: PropTypes.func.isRequired
};

export default connect(null, mapDispatchToProps)(Auth);

<|next_version|>
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import jwtDecode from 'jwt-decode';
import styles from './styles.scss';

import Login from './Login';
import Signup from './Signup';
import Info from './Info';
import Controls from '../Controls';

import { addUser } from '../../actions/user';

const mapDispatchToProps = dispatch => ({
  addUserFromToken: token => dispatch(addUser(jwtDecode(token))),
});

class Auth extends Component {
  state = {
    isNewUser: false
  }

  toggleNewUser = () => {
    this.setState({ isNewUser: !this.state.isNewUser });
  }

  render() {
    const { addUserFromToken } = this.props;
    const { isNewUser } = this.state;
    return (

        <Controls />

          {
            isNewUser
            ? <Signup switchForm={this.toggleNewUser} addUser={addUserFromToken} />
            : <Login switchForm={this.toggleNewUser} addUser={addUserFromToken} />
          }
          <Info
            message={isNewUser ? 'Take a part in creating better video games!' : 'Welcome back!'}
            isNewUser={isNewUser}
          />

    );
  }
}

Auth.propTypes = {
  addUserFromToken: PropTypes.func.isRequired
};

export default connect(null, mapDispatchToProps)(Auth);


Fix Campaign keyword, send Gambit reply

Fix Campaign keyword, send Gambit reply

--- lib/middleware/campaign-keyword.js
+++ lib/middleware/campaign-keyword.js
@@ -8,6 +8,7 @@
       return next();
     }

+    // Did User send a Campaign keyword?
     return Campaigns.findByKeyword(req.userCommand)
       .then((campaign) => {
         if (! campaign) {
@@ -16,6 +17,8 @@

         req.campaign = campaign;
         req.keyword = req.userCommand;
+        // Gambit to handle the Confirmation/Continue reply.
+        req.reply.template = 'gambit';

         return next();
       });

<|original_code|>
'use strict';

const Campaigns = require('../../app/models/Campaign');

module.exports = function getCampaignForKeyword() {
  return (req, res, next) => {
    if (req.reply.template) {
      return next();
    }

    return Campaigns.findByKeyword(req.userCommand)
      .then((campaign) => {
        if (! campaign) {
          return next();
        }

        req.campaign = campaign;
        req.keyword = req.userCommand;

        return next();
      });
  };
};

<|edits_diff|>
--- lib/middleware/campaign-keyword.js
+++ lib/middleware/campaign-keyword.js
@@ -8,6 +8,7 @@
       return next();
     }

+    // Did User send a Campaign keyword?
     return Campaigns.findByKeyword(req.userCommand)
       .then((campaign) => {
         if (! campaign) {
<|current_version|>
'use strict';

const Campaigns = require('../../app/models/Campaign');

module.exports = function getCampaignForKeyword() {
  return (req, res, next) => {
    if (req.reply.template) {
      return next();
    }

    // Did User send a Campaign keyword?
    return Campaigns.findByKeyword(req.userCommand)
      .then((campaign) => {
        if (! campaign) {
          return next();
        }

        req.campaign = campaign;
        req.keyword = req.userCommand;

        return next();
      });
  };
};

<|next_version|>
'use strict';

const Campaigns = require('../../app/models/Campaign');

module.exports = function getCampaignForKeyword() {
  return (req, res, next) => {
    if (req.reply.template) {
      return next();
    }

    // Did User send a Campaign keyword?
    return Campaigns.findByKeyword(req.userCommand)
      .then((campaign) => {
        if (! campaign) {
          return next();
        }

        req.campaign = campaign;
        req.keyword = req.userCommand;
        // Gambit to handle the Confirmation/Continue reply.
        req.reply.template = 'gambit';

        return next();
      });
  };
};