<commit_before>import Ember from 'ember';
import GetText from 'i18n';

const {
  computed,
  Service,
  inject,
  RSVP: { Promise },
  get,
  merge,
  copy,
  typeOf: getTypeOf,
  Evented,
  isNone
} = Ember;

/**
 * This service translates through gettext.js.
 * There are two available methods to be used
 * for translations message ids from JS source:
 *
 * - t(msgid, hash);
 * - n(msgid, msgidPlural, count, hash);
 *
 * Furthermore, there's an auto initialization
 * feature (default: true), which detects user's
 * locale according to system preferences. If the
 * user's locale is supported in `availableLocales`,
 * the corresponding translations are loaded. If the
 * user's locale is not supported, the default locale
 * will be used instead (default: 'en'). Please use the
 * following method to change locales:
 *
 * - setLocale(locale);
 *
 * The following utility methods are also availalbe:
 *
 * - hasLocale(locale);
 * - detectLocale();
 *
 * To configure the path of the JSON files (depending on
 * the path configured via gettext.sh extractor) use the
 * `jsonPath` property (default: '/assets/locales').
 *
 * @namespace Service
 * @class L10N
 * @extends Ember.Service
 * @extends Ember.Evented
 * @public
 */
export default Service.extend(Evented, {
  // -------------------------------------------------------------------------
  // Dependencies

  ajax: inject.service('l10n-ajax'),
  window: inject.service('window'),

  // -------------------------------------------------------------------------
  // Properties

  /**
   * Current locale from user, defaults
   * to 'defaultLocale' if not retrievable
   * or currently available due to missing
   * translations.
   *
   * @property locale
   * @type {String}
   * @default null
   * @public
   */
  locale: null,

  /**
   * Use this property if you want to force
   * a specific locale and skip automatic
   * detection of user's system settings.
   * This is useful for signed in users,
   * but beware that unsupported locales
   * will fallback to the default locale!
   *
   * @property forceLocale
   * @type {String}
   * @default null
   * @public
   */
  forceLocale: null,

  /**
   * Fallback locale for unavailable locales.
   *
   * @property defaultLocale
   * @type {String}
   * @default 'en'
   * @public
   */
  defaultLocale: 'en',

  /**
   * Will invoke a language detection or loads
   * language from `forceLanguage` on service
   * instantiation. If disabling, make sure to
   * set locale manually with setLocale().
   *
   * @property autoInitialize
   * @type {String}
   * @default null
   * @public
   */
  autoInitialize: true,

  /**
   * Directory containing JSON files with all
   * translations for corresponding locale.
   *
   * @property jsonPath
   * @type {String}
   * @default 'assets/locales'
   * @public
   */
  jsonPath: '/assets/locales',

  /**
   * A map of fingerprints per language.
   * Overwrite this with your actual fingerprint map!
   *
   * @property fingerprintMap
   * @type {Object}
   * @protected
   */
  fingerprintMap: null,

  /**
   * Currently available translations hash.
   *
   * @property availableLocales
   * @type {Object}
   * @public
   */
  availableLocales: computed(function() {
    return {
      'en': this.t('en')
    };
  }),

  /**
   * Cache persisting loaded JSON files to
   * avoid duplicated requests going out.
   *
   * @property _cache
   * @type {Object}
   * @default {}
   * @private
   */
  _cache: computed(function() {
    return {}; // complex type!
  }),

  /**
   * Reference to gettext library. This gets
   * lazily initialized within `init` method.
   *
   * @property _gettext
   * @type {String}
   * @default null
   * @private
   */
  _gettext: null,

  // -------------------------------------------------------------------------
  // Methods

  /**
   * Sets initial locale. If you want to to
   * skip language detection, please provide
   * `forceLocale` property with reopen().
   *
   * @method init
   * @return {Void}
   * @public
   */
  init() {
    this._super(...arguments);
    this.set('_gettext', new GetText());
    if (!this.get('autoInitialize')) {
      return;
    }

    this.setLocale(this.detectLocale());
  },

  /**
   * Provides current locale. If not set,
   * delivers default locale.
   *
   * @method setLocale
   * @param {String} locale
   * @return {String}
   * @public
   */
  getLocale() {
    let defaultLocale = this.get('defaultLocale');
    let locale = this.get('locale');
    if (isNone(locale)) {
      return defaultLocale;
    }

    return locale;
  },

  /**
   * Sets active locale if available. Returns a
   * RSPV Promise for asynchronous JSON request.
   *
   * @method setLocale
   * @param {String} locale
   * @return {RSVP.Promise}
   * @public
   */
  setLocale(locale) {
    return new Promise((resolve, reject) => {
      if (!this.hasLocale(locale)) {
        reject();
        return;
      }

      let old = this.getLocale();

      this.set('locale', locale);
      this.get('_gettext').setLocale(locale);

      let successCallback = () => {
        this.notifyPropertyChange('locale');
        this.notifyPropertyChange('availableLocales');

        resolve();
      };

      let failureCallback = () => {
        try {
          this.get('_gettext').setLocale(old);
          this.set('locale', old);
        } catch (e) {
          // probably destroyed
        }

        reject();
      };

      this._loadJSON(locale).then(
        successCallback,
        failureCallback
      );
    });
  },

  /**
   * Checks if locale is available.
   *
   * @method setLocale
   * @param {String} locale
   * @return {Boolean}
   * @public
   */
  hasLocale(locale) {
    let availableLocales = this.get('availableLocales');
    let hasLocale = !isNone(availableLocales[locale]);
    if (!hasLocale) {
      console.warn(`l10n.js: Locale "${locale}" is not available!`);
    }

    return hasLocale;
  },

  /**
   * Gets user's current client language and
   * provides extracted ISO-Code.
   *
   * @method detectLocale
   * @return {String}
   * @public
   */
  detectLocale() {
    let navigator = this.get('window.navigator');
    let defaultLocale = this.get('defaultLocale');
    let forceLocale = this.get('forceLocale');
    let locale;

    // auto detect locale if no force locale
    if (isNone(forceLocale)) {

      // special case: android user agents
      if (navigator && navigator.userAgent &&
        (locale = navigator.userAgent.match(
          /android.*\W(\w\w)-(\w\w)\W/i
        ))
      ) {
        locale = locale[1];
      }

      // for all other browsers
      if (isNone(locale) && navigator) {
        if (navigator.language) {
          locale = navigator.language;
        } else if (navigator.browserLanguage) {
          locale = navigator.browserLanguage;
        } else if (navigator.systemLanguage) {
          locale = navigator.systemLanguage;
        } else if (navigator.userLanguage) {
          locale = navigator.userLanguage;
        }
      }

      if (locale) {
        locale = locale.substr(0,2);
      } else {
        locale = defaultLocale
          ? defaultLocale
          : "en";
      }

      locale = locale.substr(0, 2);
    } else {
      locale = forceLocale;
    }

    // provide default locale if not available
    if (!this.hasLocale(locale)) {
      console.info(`l10n.js: Falling back to default language: "${defaultLocale}"!`);
      return defaultLocale;
    }

    // otherwise return detected locale
    if (isNone(forceLocale)) {
      console.info(`l10n.js: Automatically detected user language: "${locale}"`);
    } else {
      console.info(`l10n.js: Using forced locale: "${locale}"`);
    }

    return locale;
  },

  /**
   * Translates a singular form message id.
   *
   * @method t
   * @param {String} msgid
   * @param {Object} hash
   * @return {String}
   * @public
   */
  t(msgid, hash = {}) {
    if (getTypeOf(msgid) !== 'string') {
      try {
        msgid = msgid.toString();
      } catch (e) {
        console.log('l10n.js: "msgid" param for t() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    return this._strfmt(this.get('_gettext').gettext(msgid), hash);
  },

  /**
   * Translate a singular string without indexing it.
   * This is useful when passing variables to it, e.g. `l10n.tVar(myVar)`
   * If you would use `l10n.t(myVar)` in this case, myVar would be (wrongly) parsed by `gettext.sh`.
   *
   * @method tVariable
   * @param {String} msgid
   * @param {Object} hash
   * @return {String}
   * @public
   */
  tVar(msgid, hash = {}) {
    return this.t(msgid, hash);
  },

  /**
   * Translates a plural form message id.
   *
   * @method n
   * @param {String} msgid
   * @param {String} msgidPlural
   * @param {Number} count
   * @param {Object} hash
   * @return {String}
   * @public
   */
  n(msgid, msgidPlural, count = 1, hash = {}) {
    if (getTypeOf(msgid) !== 'string') {
      try {
        msgid = msgid.toString();
      } catch (e) {
        console.log('l10n.js: "msgid" param for n() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    if (getTypeOf(msgidPlural) !== 'string') {
      try {
        msgidPlural = msgidPlural.toString();
      } catch (e) {
        console.log('l10n.js: "msgid_plural" param for n() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    // If count is not manually set in the hash, use the provided count variable
    // This is a small utility function that can reduce boilerplate code
    if (!get(hash, 'count')) {
      // hash should not be mutated
      hash = merge({}, hash);
      hash.count = count;
    }

    return this._strfmt(this.get('_gettext').ngettext(msgid, msgidPlural, count), hash);
  },

  /**
   * Replaces placeholders like {{placeholder}} from string.
   *
   * @method _strfmt
   * @param {String} string
   * @param {Object} hash
   * @return {String}
   * @private
   */
  _strfmt(string, hash) {
    // don't process empty hashes
    if (isNone(hash)) {
      return string;
    }

    // find and replace all {{placeholder}}
    let pattern = /{{\s*([\w]+)\s*}}/g;
    let replace = (idx, match) => {
      let value = hash[match];
      if (isNone(value)) {
        return `{{${match}}}`;
      }

      return value;
    };

    return string.replace(pattern, replace);
  },

  /**
   * Loads current locale translation file.
   * Note that `locale` will trigger change
   * after loading JSON file, so watching the
   * `locale` informs about new translations!
   *
   * @method _loadJSON
   * @param {String} locale
   * @return {Void}
   * @private
   */
  _loadJSON(locale) {
    return new Promise((resolve, reject) => {
      let ajax = this.get('ajax');
      let cache = this.get('_cache');

      let fingerprintMap = get(this, 'fingerprintMap');
      let fingerprint = fingerprintMap ? get(fingerprintMap, locale) : null;

      let basePath = this.get('jsonPath');
      let path = fingerprint ? `${basePath}/${fingerprint}` : basePath;
      let url = `${path}/${locale}.json`;

      let successCallback = (response) => {
        let cachedResponse = copy(response, true);
        this.get('_gettext').loadJSON(response);

        cache[locale] = cachedResponse;
        resolve();
      };

      let failureCallback = (reason) => {
        console.error(`l10n.js: An error occurred loading "${url}": ${reason}`);
        reject();
      };

      // used cache translation if present
      if (cache.hasOwnProperty(locale)) {
        successCallback(cache[locale]);
        resolve(cache[locale]);
        return;
      }

      // otherwise load json file from assets
      ajax.request(url).then(
        successCallback,
        failureCallback
      );
    });
  }

});
<commit_msg>Use custom log method to prevent log output when testing<commit_after>import Ember from 'ember';
import GetText from 'i18n';

const {
  computed,
  Service,
  inject,
  RSVP: { Promise },
  get,
  merge,
  copy,
  typeOf: getTypeOf,
  Evented,
  isNone,
  Logger,
  testing
} = Ember;

/**
 * This service translates through gettext.js.
 * There are two available methods to be used
 * for translations message ids from JS source:
 *
 * - t(msgid, hash);
 * - n(msgid, msgidPlural, count, hash);
 *
 * Furthermore, there's an auto initialization
 * feature (default: true), which detects user's
 * locale according to system preferences. If the
 * user's locale is supported in `availableLocales`,
 * the corresponding translations are loaded. If the
 * user's locale is not supported, the default locale
 * will be used instead (default: 'en'). Please use the
 * following method to change locales:
 *
 * - setLocale(locale);
 *
 * The following utility methods are also availalbe:
 *
 * - hasLocale(locale);
 * - detectLocale();
 *
 * To configure the path of the JSON files (depending on
 * the path configured via gettext.sh extractor) use the
 * `jsonPath` property (default: '/assets/locales').
 *
 * @namespace Service
 * @class L10N
 * @extends Ember.Service
 * @extends Ember.Evented
 * @public
 */
export default Service.extend(Evented, {
  // -------------------------------------------------------------------------
  // Dependencies

  ajax: inject.service('l10n-ajax'),
  window: inject.service('window'),

  // -------------------------------------------------------------------------
  // Properties

  /**
   * Current locale from user, defaults
   * to 'defaultLocale' if not retrievable
   * or currently available due to missing
   * translations.
   *
   * @property locale
   * @type {String}
   * @default null
   * @public
   */
  locale: null,

  /**
   * Use this property if you want to force
   * a specific locale and skip automatic
   * detection of user's system settings.
   * This is useful for signed in users,
   * but beware that unsupported locales
   * will fallback to the default locale!
   *
   * @property forceLocale
   * @type {String}
   * @default null
   * @public
   */
  forceLocale: null,

  /**
   * Fallback locale for unavailable locales.
   *
   * @property defaultLocale
   * @type {String}
   * @default 'en'
   * @public
   */
  defaultLocale: 'en',

  /**
   * Will invoke a language detection or loads
   * language from `forceLanguage` on service
   * instantiation. If disabling, make sure to
   * set locale manually with setLocale().
   *
   * @property autoInitialize
   * @type {String}
   * @default null
   * @public
   */
  autoInitialize: true,

  /**
   * Directory containing JSON files with all
   * translations for corresponding locale.
   *
   * @property jsonPath
   * @type {String}
   * @default 'assets/locales'
   * @public
   */
  jsonPath: '/assets/locales',

  /**
   * A map of fingerprints per language.
   * Overwrite this with your actual fingerprint map!
   *
   * @property fingerprintMap
   * @type {Object}
   * @protected
   */
  fingerprintMap: null,

  /**
   * Currently available translations hash.
   *
   * @property availableLocales
   * @type {Object}
   * @public
   */
  availableLocales: computed(function() {
    return {
      'en': this.t('en')
    };
  }),

  /**
   * Cache persisting loaded JSON files to
   * avoid duplicated requests going out.
   *
   * @property _cache
   * @type {Object}
   * @default {}
   * @private
   */
  _cache: computed(function() {
    return {}; // complex type!
  }),

  /**
   * Reference to gettext library. This gets
   * lazily initialized within `init` method.
   *
   * @property _gettext
   * @type {String}
   * @default null
   * @private
   */
  _gettext: null,

  // -------------------------------------------------------------------------
  // Methods

  /**
   * Sets initial locale. If you want to to
   * skip language detection, please provide
   * `forceLocale` property with reopen().
   *
   * @method init
   * @return {Void}
   * @public
   */
  init() {
    this._super(...arguments);
    this.set('_gettext', new GetText());
    if (!this.get('autoInitialize')) {
      return;
    }

    this.setLocale(this.detectLocale());
  },

  /**
   * Provides current locale. If not set,
   * delivers default locale.
   *
   * @method setLocale
   * @param {String} locale
   * @return {String}
   * @public
   */
  getLocale() {
    let defaultLocale = this.get('defaultLocale');
    let locale = this.get('locale');
    if (isNone(locale)) {
      return defaultLocale;
    }

    return locale;
  },

  /**
   * Sets active locale if available. Returns a
   * RSPV Promise for asynchronous JSON request.
   *
   * @method setLocale
   * @param {String} locale
   * @return {RSVP.Promise}
   * @public
   */
  setLocale(locale) {
    return new Promise((resolve, reject) => {
      if (!this.hasLocale(locale)) {
        reject();
        return;
      }

      let old = this.getLocale();

      this.set('locale', locale);
      this.get('_gettext').setLocale(locale);

      let successCallback = () => {
        this.notifyPropertyChange('locale');
        this.notifyPropertyChange('availableLocales');

        resolve();
      };

      let failureCallback = () => {
        try {
          this.get('_gettext').setLocale(old);
          this.set('locale', old);
        } catch(e) {
          // probably destroyed
        }

        reject();
      };

      this._loadJSON(locale).then(
        successCallback,
        failureCallback
      );
    });
  },

  /**
   * Checks if locale is available.
   *
   * @method setLocale
   * @param {String} locale
   * @return {Boolean}
   * @public
   */
  hasLocale(locale) {
    let availableLocales = this.get('availableLocales');
    let hasLocale = !isNone(availableLocales[locale]);
    if (!hasLocale) {
      this._log(`l10n.js: Locale "${locale}" is not available!`, 'warn');
    }

    return hasLocale;
  },

  /**
   * Gets user's current client language and
   * provides extracted ISO-Code.
   *
   * @method detectLocale
   * @return {String}
   * @public
   */
  detectLocale() {
    let navigator = this.get('window.navigator');
    let defaultLocale = this.get('defaultLocale');
    let forceLocale = this.get('forceLocale');
    let locale;

    // auto detect locale if no force locale
    if (isNone(forceLocale)) {

      // special case: android user agents
      if (navigator && navigator.userAgent &&
        (locale = navigator.userAgent.match(
          /android.*\W(\w\w)-(\w\w)\W/i
        ))
      ) {
        locale = locale[1];
      }

      // for all other browsers
      if (isNone(locale) && navigator) {
        if (navigator.language) {
          locale = navigator.language;
        } else if (navigator.browserLanguage) {
          locale = navigator.browserLanguage;
        } else if (navigator.systemLanguage) {
          locale = navigator.systemLanguage;
        } else if (navigator.userLanguage) {
          locale = navigator.userLanguage;
        }
      }

      if (locale) {
        locale = locale.substr(0, 2);
      } else {
        locale = defaultLocale
          ? defaultLocale
          : "en";
      }

      locale = locale.substr(0, 2);
    } else {
      locale = forceLocale;
    }

    // provide default locale if not available
    if (!this.hasLocale(locale)) {
      this._log(`l10n.js: Falling back to default language: "${defaultLocale}"!`);
      return defaultLocale;
    }

    // otherwise return detected locale
    if (isNone(forceLocale)) {
      this._log(`l10n.js: Automatically detected user language: "${locale}"`);
    } else {
      this._log(`l10n.js: Using forced locale: "${locale}"`);
    }

    return locale;
  },

  /**
   * Translates a singular form message id.
   *
   * @method t
   * @param {String} msgid
   * @param {Object} hash
   * @return {String}
   * @public
   */
  t(msgid, hash = {}) {
    if (getTypeOf(msgid) !== 'string') {
      try {
        msgid = msgid.toString();
      } catch(e) {
        this._log('l10n.js: "msgid" param for t() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    return this._strfmt(this.get('_gettext').gettext(msgid), hash);
  },

  /**
   * Translate a singular string without indexing it.
   * This is useful when passing variables to it, e.g. `l10n.tVar(myVar)`
   * If you would use `l10n.t(myVar)` in this case, myVar would be (wrongly) parsed by `gettext.sh`.
   *
   * @method tVariable
   * @param {String} msgid
   * @param {Object} hash
   * @return {String}
   * @public
   */
  tVar(msgid, hash = {}) {
    return this.t(msgid, hash);
  },

  /**
   * Translates a plural form message id.
   *
   * @method n
   * @param {String} msgid
   * @param {String} msgidPlural
   * @param {Number} count
   * @param {Object} hash
   * @return {String}
   * @public
   */
  n(msgid, msgidPlural, count = 1, hash = {}) {
    if (getTypeOf(msgid) !== 'string') {
      try {
        msgid = msgid.toString();
      } catch(e) {
        this._log('l10n.js: "msgid" param for n() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    if (getTypeOf(msgidPlural) !== 'string') {
      try {
        msgidPlural = msgidPlural.toString();
      } catch(e) {
        this._log('l10n.js: "msgid_plural" param for n() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    // If count is not manually set in the hash, use the provided count variable
    // This is a small utility function that can reduce boilerplate code
    if (!get(hash, 'count')) {
      // hash should not be mutated
      hash = merge({}, hash);
      hash.count = count;
    }

    return this._strfmt(this.get('_gettext').ngettext(msgid, msgidPlural, count), hash);
  },

  /**
   * Replaces placeholders like {{placeholder}} from string.
   *
   * @method _strfmt
   * @param {String} string
   * @param {Object} hash
   * @return {String}
   * @private
   */
  _strfmt(string, hash) {
    // don't process empty hashes
    if (isNone(hash)) {
      return string;
    }

    // find and replace all {{placeholder}}
    let pattern = /{{\s*([\w]+)\s*}}/g;
    let replace = (idx, match) => {
      let value = hash[match];
      if (isNone(value)) {
        return `{{${match}}}`;
      }

      return value;
    };

    return string.replace(pattern, replace);
  },

  /**
   * Loads current locale translation file.
   * Note that `locale` will trigger change
   * after loading JSON file, so watching the
   * `locale` informs about new translations!
   *
   * @method _loadJSON
   * @param {String} locale
   * @return {Void}
   * @private
   */
  _loadJSON(locale) {
    return new Promise((resolve, reject) => {
      let ajax = this.get('ajax');
      let cache = this.get('_cache');

      let fingerprintMap = get(this, 'fingerprintMap');
      let fingerprint = fingerprintMap ? get(fingerprintMap, locale) : null;

      let basePath = this.get('jsonPath');
      let path = fingerprint ? `${basePath}/${fingerprint}` : basePath;
      let url = `${path}/${locale}.json`;

      let successCallback = (response) => {
        let cachedResponse = copy(response, true);
        this.get('_gettext').loadJSON(response);

        cache[locale] = cachedResponse;
        resolve();
      };

      let failureCallback = (reason) => {
        this._log(`l10n.js: An error occurred loading "${url}": ${reason}`, 'error');
        reject();
      };

      // used cache translation if present
      if (cache.hasOwnProperty(locale)) {
        successCallback(cache[locale]);
        resolve(cache[locale]);
        return;
      }

      // otherwise load json file from assets
      ajax.request(url).then(
        successCallback,
        failureCallback
      );
    });
  },

  /**
   * Log a message.
   * When testing, this will be swallowed to keep the output clean.
   *
   * @method _log
   * @param {String} str
   * @param {'log'|'warn'|'error'} type
   * @private
   */
  _log(str, type = 'log') {
    if (testing) {
      return;
    }

    if (!['log', 'warn', 'error'].includes(type)) {
      type = 'log';
    }

    Logger[type](str);
  }

});
<|endoftext|>


<commit_before>import React, { Component } from "react";
import { Layout, Header, Content, Spinner } from "react-mdl";
import { graphql } from "react-apollo";
import gql from "graphql-tag";

import TodoItem from "./TodoItem";

const query = gql`
  query allTodoItems {
    allTodoItems {
      id
      name
      description
      completed
    }
  }
`;

class App extends Component {
  render() {
    const { data: { loading, allTodoItems } } = this.props;
    return (
      <Layout fixedHeader>

        <Content>
          { loading ? <Spinner /> : (

            { allTodoItems.map((item) => <TodoItem key={item.id} { ...item } />) }

          )}
        </Content>
      </Layout>
    );
  }
}

export default graphql(query)(App);
<commit_msg>Removed line break.<commit_after>import React, { Component } from "react";
import { Layout, Header, Content, Spinner } from "react-mdl";
import { graphql } from "react-apollo";
import gql from "graphql-tag";
import TodoItem from "./TodoItem";

const query = gql`
  query allTodoItems {
    allTodoItems {
      id
      name
      description
      completed
    }
  }
`;

class App extends Component {
  render() {
    const { data: { loading, allTodoItems } } = this.props;
    return (
      <Layout fixedHeader>

        <Content>
          { loading ? <Spinner /> : (

            { allTodoItems.map((item) => <TodoItem key={item.id} { ...item } />) }

          )}
        </Content>
      </Layout>
    );
  }
}

export default graphql(query)(App);
<|endoftext|>


<commit_before>var View = require('./view');
var template = require('./templates/oncovis');
var FeatureMatrix = require('../models/featureMatrix');

module.exports = View.extend({
    model:FeatureMatrix,
    template:template,
    label:"Oncovis",

    events:{
        "click .reset-sliders":"resetSliders"
    },

    initialize:function () {
        _.bindAll(this, 'renderGraph', 'initControls', 'autocomplete', 'render', 'resetSliders');
    },

    getRenderData:function () {
    },

    afterRender:function () {
        this.$el.addClass('row');
        this.model.fetch().done(this.renderGraph);
    },

    renderGraph:function () {
        this.initControls();

        console.log("renderGraph:start");

        var loaded_data = this.model.toJSON();

        var cluster_property = "C:CLIN:Assisted_Pregnancy:M::::";
        var rowLabels = [
            "C:SURV:Alcohol_Consumption:F::::",
            "C:SURV:Alcohol_Consumption:M::::",
            "C:SURV:Family_History_of_PTB:F::::",
            "C:SURV:Family_History_of_PTB:M::::",
            "C:SURV:Mothers_Country_of_Birth:F::::"
        ];

        var data = {};
        var clusterGroups = {};
        var clusterLabels = [];
        var categories_by_rowlabel = {};

        _.each(loaded_data, function (item) {
            var feature_id = item["feature_id"];

            var isRowLabel = (rowLabels.indexOf(feature_id) >= 0);

            var isClusterLabel = (cluster_property == feature_id);
            var sample_ids = _.without(_.without(_.keys(item), "label"), "feature_id");

            _.each(sample_ids, function (sampleId) {
                var value = item[sampleId];
                if (!data[sampleId]) data[sampleId] = {};

                if (isRowLabel) {
                    data[sampleId][feature_id] = { "value":value, "row": feature_id, "label":sampleId + "\n" + item.label + "\n" + value };

                    if (!categories_by_rowlabel[feature_id]) categories_by_rowlabel[feature_id] = {};
                    categories_by_rowlabel[feature_id][value] = true;
                }

                if (isClusterLabel) {
                    if (!clusterGroups[value]) clusterGroups[value] = [];
                    clusterGroups[value].push(sampleId);
                    clusterLabels.push(value);
                }
            });
        });

        var oncovisData = {
            data: data,
            columns_by_cluster: clusterGroups,
            cluster_labels:_.uniq(clusterLabels),
            row_labels: rowLabels
        };

        var columns_by_cluster = {};
        _.each(oncovisData.columns_by_cluster, function (columns, cluster) {
            columns_by_cluster[cluster] = _.sortBy(columns, function (sample) {
                return _.map(oncovisData.row_labels, function (row_label) {
                    return oncovisData.data[sample][row_label]["value"];
                });
            });
        });

        var colorscales_by_rowlabel = {};
        _.each(categories_by_rowlabel, function(obj, rowLabel) {
            var categories = _.keys(obj);
            colorscales_by_rowlabel[rowLabel] = d3.scale.ordinal()
                                                          .domain(categories)
                                                          .range(d3.range(categories.length)
                                                          .map(d3.scale.linear().domain([0, categories.length - 1])
                                                          .range(["yellow", "blue"])
                                                          .interpolate(d3.interpolateLab)));
        });

        var optns = {
            bar_width:4,
            column_spacing:1,
            plot_width:3000,
            label_width:70,
            highlight_fill:colorbrewer.RdYlGn[3][2],
            color_fn:function (d) {
                return colorscales_by_rowlabel[d.row](d.value);
            },
            columns_by_cluster:columns_by_cluster,
            cluster_labels:oncovisData.cluster_labels,
            row_labels:oncovisData.row_labels
        };

        _.extend(optns, { "bar_height":this.$el.find(".slider_barheight").oncovis_range_value() });
        _.extend(optns, { "row_spacing":this.$el.find(".slider_rowspacing").oncovis_range_value() });
        _.extend(optns, { "bar_width":this.$el.find(".slider_barwidth").oncovis_range_value() });
        _.extend(optns, { "column_spacing":this.$el.find(".slider_barspacing").oncovis_range_value() });
        _.extend(optns, { "cluster_spacing":this.$el.find(".slider_clusterspacing").oncovis_range_value() });
        _.extend(optns, { "label_fontsize":this.$el.find(".slider_fontsize").oncovis_range_value() });

        this.$el.find(".oncovis-container").oncovis(oncovisData.data, optns);

        this.renderLegend(categories_by_rowlabel, colorscales_by_rowlabel);

        console.log("renderGraph:end");
    },

    renderLegend: function(categories_by_rowlabel, colorscales_by_rowlabel) {
        console.log("renderLegend:start");

        var accordionEl = this.$el.find(".oncovis-legend");
        _.each(categories_by_rowlabel, function(obj, rowLabel) {
            var categories = _.keys(obj);
            accordionEl.append("
" + rowLabel + "
");
            var lis = [];
            _.each(categories, function(category) {
                var color = colorscales_by_rowlabel[rowLabel](category);
                lis.push("
   " + category + "
");
            });
            accordionEl.append("
" + lis.join("") + "
");
        });

        accordionEl.accordion({ "collapsible": true, "autoHeight": false });

        console.log("renderLegend:end");
    },

    initControls:function () {
        console.log("initControls:start");
        var me = this;
        var visrangeFn = function (property) {
            return function (value) {
                var dim = {};
                dim[property] = value;
                me.$el.find(".oncovis-container").update(dim);
            }
        };

        this.$el.find(".slider_barheight").oncovis_range({ storageId:"slider_barheight", min:10, max:50, initialStep:20, slide:visrangeFn("bar_height") });
        this.$el.find(".slider_rowspacing").oncovis_range({ storageId:"slider_rowspacing", min:0, max:50, initialStep:10, slide:visrangeFn("row_spacing") });
        this.$el.find(".slider_barwidth").oncovis_range({ storageId:"slider_barwidth", min:1, max:10, initialStep:5, slide:visrangeFn("bar_width") });
        this.$el.find(".slider_barspacing").oncovis_range({ storageId:"slider_barspacing", min:0, max:10, initialStep:2, slide:visrangeFn("column_spacing") });
        this.$el.find(".slider_clusterspacing").oncovis_range({ storageId:"slider_clusterspacing", min:0, max:50, initialStep:10, slide:visrangeFn("cluster_spacing") });
        this.$el.find(".slider_fontsize").oncovis_range({ storageId:"slider_fontsize", min:5, max:21, initialStep:14, slide:visrangeFn("label_fontsize") });

        console.log("initControls:end");
    },

    autocomplete:function (query, resultBin) {
        var found = [];

        var queryterms = query.toLowerCase().split(" ");
        _.each(queryterms, function (queryterm) {
            _.each(oncovisData.data, function (val, key) {
                if (key.toLowerCase().indexOf(queryterm) >= 0) {
                    found.push("Patient ID " + key + "");
                }
            });
        });
        resultBin(found);
    },

    resetSliders:function () {
        this.$el.find(".slider_barheight").oncovis_range_reset();
        this.$el.find(".slider_rowspacing").oncovis_range_reset();
        this.$el.find(".slider_barwidth").oncovis_range_reset();
        this.$el.find(".slider_barspacing").oncovis_range_reset();
        this.$el.find(".slider_clusterspacing").oncovis_range_reset();
        this.$el.find(".slider_fontsize").oncovis_range_reset();
    }
});
<commit_msg>optimized array handling<commit_after>var View = require('./view');
var template = require('./templates/oncovis');
var FeatureMatrix = require('../models/featureMatrix');

module.exports = View.extend({
    model:FeatureMatrix,
    template:template,
    label:"Oncovis",

    events:{
        "click .reset-sliders":"resetSliders"
    },

    initialize:function () {
        _.bindAll(this, 'renderGraph', 'initControls', 'autocomplete', 'render', 'resetSliders');
    },

    getRenderData:function () {
    },

    afterRender:function () {
        this.$el.addClass('row');
        this.model.fetch().done(this.renderGraph);
    },

    renderGraph:function () {
        this.initControls();

        console.log("renderGraph:start");

        var loaded_data = this.model.toJSON();

        var cluster_property = "C:CLIN:Assisted_Pregnancy:M::::";
        var rowLabels = [
            "C:SURV:Alcohol_Consumption:F::::",
            "C:SURV:Alcohol_Consumption:M::::",
            "C:SURV:Family_History_of_PTB:F::::",
            "C:SURV:Family_History_of_PTB:M::::",
            "C:SURV:Mothers_Country_of_Birth:F::::"
        ];

        var data = {};
        var clusterGroups = {};
        var clusterLabels = {};
        var categories_by_rowlabel = {};

        _.each(loaded_data, function (item) {
            var feature_id = item["feature_id"];

            var isRowLabel = (rowLabels.indexOf(feature_id) >= 0);

            var isClusterLabel = (cluster_property == feature_id);
            var sample_ids = _.without(_.without(_.keys(item), "label"), "feature_id");

            _.each(sample_ids, function (sampleId) {
                var value = item[sampleId];
                if (!data[sampleId]) data[sampleId] = {};

                if (isRowLabel) {
                    data[sampleId][feature_id] = { "value":value, "row": feature_id, "label":sampleId + "\n" + item.label + "\n" + value };

                    if (!categories_by_rowlabel[feature_id]) categories_by_rowlabel[feature_id] = {};
                    categories_by_rowlabel[feature_id][value] = true;
                }

                if (isClusterLabel) {
                    if (!clusterGroups[value]) clusterGroups[value] = [];
                    clusterGroups[value].push(sampleId);
                    clusterLabels[value] = true;
                }
            });
        });

        var oncovisData = {
            data: data,
            columns_by_cluster: clusterGroups,
            cluster_labels:_.keys(clusterLabels),
            row_labels: rowLabels
        };

        var columns_by_cluster = {};
        _.each(oncovisData.columns_by_cluster, function (columns, cluster) {
            columns_by_cluster[cluster] = _.sortBy(columns, function (sample) {
                return _.map(rowLabels, function (row_label) { return data[sample][row_label]["value"]; });
            });
        });

        var colorscales_by_rowlabel = {};
        _.each(categories_by_rowlabel, function(obj, rowLabel) {
            var categories = _.keys(obj);
            colorscales_by_rowlabel[rowLabel] = d3.scale.ordinal()
                                                          .domain(categories)
                                                          .range(d3.range(categories.length)
                                                          .map(d3.scale.linear().domain([0, categories.length - 1])
                                                          .range(["yellow", "blue"])
                                                          .interpolate(d3.interpolateLab)));
        });

        var optns = {
            bar_width:4,
            column_spacing:1,
            plot_width:3000,
            label_width:70,
            highlight_fill:colorbrewer.RdYlGn[3][2],
            color_fn:function (d) {
                return colorscales_by_rowlabel[d.row](d.value);
            },
            columns_by_cluster:columns_by_cluster,
            cluster_labels:oncovisData.cluster_labels,
            row_labels:oncovisData.row_labels
        };

        _.extend(optns, { "bar_height":this.$el.find(".slider_barheight").oncovis_range_value() });
        _.extend(optns, { "row_spacing":this.$el.find(".slider_rowspacing").oncovis_range_value() });
        _.extend(optns, { "bar_width":this.$el.find(".slider_barwidth").oncovis_range_value() });
        _.extend(optns, { "column_spacing":this.$el.find(".slider_barspacing").oncovis_range_value() });
        _.extend(optns, { "cluster_spacing":this.$el.find(".slider_clusterspacing").oncovis_range_value() });
        _.extend(optns, { "label_fontsize":this.$el.find(".slider_fontsize").oncovis_range_value() });

        this.$el.find(".oncovis-container").oncovis(oncovisData.data, optns);

        this.renderLegend(categories_by_rowlabel, colorscales_by_rowlabel);

        console.log("renderGraph:end");
    },

    renderLegend: function(categories_by_rowlabel, colorscales_by_rowlabel) {
        console.log("renderLegend:start");

        var accordionEl = this.$el.find(".oncovis-legend");
        _.each(categories_by_rowlabel, function(obj, rowLabel) {
            var categories = _.keys(obj);
            accordionEl.append("
" + rowLabel + "
");
            var lis = [];
            _.each(categories, function(category) {
                var color = colorscales_by_rowlabel[rowLabel](category);
                lis.push("
   " + category + "
");
            });
            accordionEl.append("
" + lis.join("") + "
");
        });

        accordionEl.accordion({ "collapsible": true, "autoHeight": false });

        console.log("renderLegend:end");
    },

    initControls:function () {
        console.log("initControls:start");
        var me = this;
        var visrangeFn = function (property) {
            return function (value) {
                var dim = {};
                dim[property] = value;
                me.$el.find(".oncovis-container").update(dim);
            }
        };

        this.$el.find(".slider_barheight").oncovis_range({ storageId:"slider_barheight", min:10, max:50, initialStep:20, slide:visrangeFn("bar_height") });
        this.$el.find(".slider_rowspacing").oncovis_range({ storageId:"slider_rowspacing", min:0, max:50, initialStep:10, slide:visrangeFn("row_spacing") });
        this.$el.find(".slider_barwidth").oncovis_range({ storageId:"slider_barwidth", min:1, max:10, initialStep:5, slide:visrangeFn("bar_width") });
        this.$el.find(".slider_barspacing").oncovis_range({ storageId:"slider_barspacing", min:0, max:10, initialStep:2, slide:visrangeFn("column_spacing") });
        this.$el.find(".slider_clusterspacing").oncovis_range({ storageId:"slider_clusterspacing", min:0, max:50, initialStep:10, slide:visrangeFn("cluster_spacing") });
        this.$el.find(".slider_fontsize").oncovis_range({ storageId:"slider_fontsize", min:5, max:21, initialStep:14, slide:visrangeFn("label_fontsize") });

        console.log("initControls:end");
    },

    autocomplete:function (query, resultBin) {
        var found = [];

        var queryterms = query.toLowerCase().split(" ");
        _.each(queryterms, function (queryterm) {
            _.each(oncovisData.data, function (val, key) {
                if (key.toLowerCase().indexOf(queryterm) >= 0) {
                    found.push("Patient ID " + key + "");
                }
            });
        });
        resultBin(found);
    },

    resetSliders:function () {
        this.$el.find(".slider_barheight").oncovis_range_reset();
        this.$el.find(".slider_rowspacing").oncovis_range_reset();
        this.$el.find(".slider_barwidth").oncovis_range_reset();
        this.$el.find(".slider_barspacing").oncovis_range_reset();
        this.$el.find(".slider_clusterspacing").oncovis_range_reset();
        this.$el.find(".slider_fontsize").oncovis_range_reset();
    }
});
<|endoftext|>


<commit_before>export default function Directive() {
    'ngInject';

    const directive = {
        restrict: 'E',
        templateUrl: 'app/home/instances/instance/instance.html',
        scope: {},
        controller: Controller,
        controllerAs: 'vm',
        bindToController: {
            container: '=',
        },
    };

    return directive;
}

////////////

class Controller {
    constructor(IconsService, InstancesCacheService, ToastService) {
        'ngInject';

        this.InstancesCacheService = InstancesCacheService;
        this.IconsService = IconsService;
        this.ToastService = ToastService;
    }

    kill() {
        this.InstancesCacheService
            .deleteInstance(this.container.content.name)
            .then(() => {
                this.ToastService.success(`Remove ${this.container.content.name} asked.`)
            })
            .catch((err) => {
                this.ToastService.error(err.data)
            });
    }
}
<commit_msg>refactor(lint): linter<commit_after>export default function Directive() {
    'ngInject';

    const directive = {
        restrict: 'E',
        templateUrl: 'app/home/instances/instance/instance.html',
        scope: {},
        controller: Controller,
        controllerAs: 'vm',
        bindToController: {
            container: '=',
        },
    };

    return directive;
}

////////////

class Controller {
    constructor(IconsService, InstancesCacheService, ToastService) {
        'ngInject';

        this.InstancesCacheService = InstancesCacheService;
        this.IconsService = IconsService;
        this.ToastService = ToastService;
    }

    kill() {
        this.InstancesCacheService
            .deleteInstance(this.container.content.name)
            .then(() => {
                this.ToastService.success(`Remove ${this.container.content.name} asked.`);
            })
            .catch((err) => {
                this.ToastService.error(err.data);
            });
    }
}
<|endoftext|>


<commit_before>(function($){

  $.fn.enableFolding = function(autofold, snap) {
    var fragId = document.location.hash;
    if (fragId && /^#no\d+$/.test(fragId))
      fragId = parseInt(fragId.substr(3));
    if (snap == undefined)
      snap = false;

    var count = 1;
    return this.each(function() {
      // Use first child  as a trigger, or generate a trigger from the text
      var trigger = $(this).children("a").eq(0);
      if (trigger.length == 0) {
        trigger = $("");
        trigger.html($(this).html());
        $(this).text("");
        $(this).append(trigger);
      }

      trigger.click(function() {
        var div = $(this.parentNode.parentNode).toggleClass("collapsed");
        return snap && !div.hasClass("collapsed");
      });
      if (autofold && (count != fragId))
        trigger.parents().eq(1).addClass("collapsed");
      count++;
    });
  }

  /** Enable columns of a table to be hidden by clicking on the column header.
   *
   * +------------------+------+---- ... ---+---------------------+
   * |column_headers[0] | ...  |            | column_headers[k-1] | <- c_h_row
   * +==================+======+==== ... ===+=====================+
   * | row_headers[0]   | row_headers[1]    | row_headers[1*k-1]  | <- rows[0]
   * | row_headers[k]   | row_headers[k+1]  | row_headers[2*k-1]  | <- rows[1]
   * ...
   */
  $.fn.enableCollapsibleColumns = function(recovery_area) {
    // column headers
    var c_h_row = $('thead tr', this);
    var column_headers = $('th', c_h_row).not(recovery_area);
    var k = column_headers.length;
    // row headers
    var tbody = $('tbody', this);
    var row_headers = $('th', tbody);
    var rows = $('tr', tbody);
    var n = row_headers.length / k;

    // add a 'hide' callback to each column header
    column_headers.each(function(j) {
        function hide() {
          // remove and save column j
          var th = $(this);
          th.css('display', 'none');
          for ( var i = 0; i < n; i++ )
            row_headers.eq(i*k+j).css('display', 'none');
          // create a recovery button and its "show" callback
          recovery_area.prepend($("").addClass("recover")
            .text(_("Show %(title)s", {title: th.text()}))
            .click(function() {
              $(this).remove();
              th.show();
              for (var i = 0; i < n; i++)
                row_headers.eq(i*k+j).css('display', 'table-cell');
            })
          );
        };
        $(this).click(hide)
          .css('cursor', 'pointer')
          .attr('title', _("%(title)s (click to hide column)",
                           {title: $(this).attr('title')}));
      });
  }

})(jQuery);
<commit_msg>1.3.2dev: Fix possible type coercion in `folding.js`<commit_after>(function($){

  $.fn.enableFolding = function(autofold, snap) {
    var fragId = document.location.hash;
    if (fragId && /^#no\d+$/.test(fragId))
      fragId = parseInt(fragId.substr(3));
    if (snap === undefined)
      snap = false;

    var count = 1;
    return this.each(function() {
      // Use first child  as a trigger, or generate a trigger from the text
      var trigger = $(this).children("a").eq(0);
      if (trigger.length === 0) {
        trigger = $("");
        trigger.html($(this).html());
        $(this).text("");
        $(this).append(trigger);
      }

      trigger.click(function() {
        var div = $(this.parentNode.parentNode).toggleClass("collapsed");
        return snap && !div.hasClass("collapsed");
      });
      if (autofold && (count !== fragId))
        trigger.parents().eq(1).addClass("collapsed");
      count++;
    });
  };

  /** Enable columns of a table to be hidden by clicking on the column header.
   *
   * +------------------+------+---- ... ---+---------------------+
   * |column_headers[0] | ...  |            | column_headers[k-1] | <- c_h_row
   * +==================+======+==== ... ===+=====================+
   * | row_headers[0]   | row_headers[1]    | row_headers[1*k-1]  | <- rows[0]
   * | row_headers[k]   | row_headers[k+1]  | row_headers[2*k-1]  | <- rows[1]
   * ...
   */
  $.fn.enableCollapsibleColumns = function(recovery_area) {
    // column headers
    var c_h_row = $('thead tr', this);
    var column_headers = $('th', c_h_row).not(recovery_area);
    var k = column_headers.length;
    // row headers
    var tbody = $('tbody', this);
    var row_headers = $('th', tbody);
    var n = row_headers.length / k;

    // add a 'hide' callback to each column header
    column_headers.each(function(j) {
        function hide() {
          // remove and save column j
          var th = $(this);
          th.css('display', 'none');
          for ( var i = 0; i < n; i++ )
            row_headers.eq(i*k+j).css('display', 'none');
          // create a recovery button and its "show" callback
          recovery_area.prepend($("").addClass("recover")
            .text(_("Show %(title)s", {title: th.text()}))
            .click(function() {
              $(this).remove();
              th.show();
              for (var i = 0; i < n; i++)
                row_headers.eq(i*k+j).css('display', 'table-cell');
            })
          );
        }
        $(this).click(hide)
          .css('cursor', 'pointer')
          .attr('title', _("%(title)s (click to hide column)",
                           {title: $(this).attr('title')}));
      });
  }

})(jQuery);
<|endoftext|>


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

import WorkerPlugin from '../src';
import path from 'path';
import { createStaticServer } from './_server';
import { runWebpack } from './_util';
import { evaluatePage } from './_page';

jest.setTimeout(30000);

describe('Integration', () => {
  test('The resulting Worker is instantiated correctly', async () => {
    const fixture = 'basic';

    await runWebpack(fixture, {
      plugins: [new WorkerPlugin()]
    });

    const server = await createStaticServer(path.resolve(__dirname, 'fixtures', fixture));

    const consoleText = await evaluatePage(server.url, /page got data/g);

    expect(consoleText).toMatch(/page got data/g);

    await server.stop();
  });
  test('The SharedWorker is instantiated correctly', async () => {
    const fixture = 'shared';

    await runWebpack(fixture, {
      plugins: [new WorkerPlugin()]
    });

    const server = await createStaticServer(path.resolve(__dirname, 'fixtures', fixture));

    const consoleText = await evaluatePage(server.url, /page got data/g);

    expect(consoleText).toMatch(/page got data/g);

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

import WorkerPlugin from '../src';
import path from 'path';
import { createStaticServer } from './_server';
import { runWebpack } from './_util';
import { evaluatePage } from './_page';

jest.setTimeout(30000);

describe('Integration', () => {
  test('The resulting Worker is instantiated correctly', async () => {
    const fixture = 'basic';

    await runWebpack(fixture, {
      plugins: [new WorkerPlugin()]
    });

    const server = await createStaticServer(path.resolve(__dirname, 'fixtures', fixture));

    const consoleText = await evaluatePage(server.url, /page got data/g);

    expect(consoleText).toMatch(/page got data/g);

    await server.stop();
  });

  test('SharedWorker is instantiated correctly', async () => {
    const fixture = 'shared';

    await runWebpack(fixture, {
      plugins: [new WorkerPlugin({
        sharedWorker: true
      })]
    });

    const server = await createStaticServer(path.resolve(__dirname, 'fixtures', fixture));

    const consoleText = await evaluatePage(server.url, /page got data/g);

    expect(consoleText).toMatch(/page got data/g);

    await server.stop();
  });
});
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var path = require('path');
var util = require('util');
var _ = require('@sailshq/lodash');

// generateSecret is used to generate a one-off session secret if one wasn't configured
var generateSecret = require('./generateSecret');

// (this dependency is just for creating new cookies)
var uid = require('uid-safe').sync;

// (these two dependencies are only here for sails.session.parseSessionIdFromCookie(),
//  which is only here to enable socket lifecycle callbacks)
var parseCookie = require('cookie').parse;
var stringifyCookie = require('cookie').serialize;
var unsignCookie = require('cookie-signature').unsign;
var signCookie = require('cookie-signature').sign;
var pathToRegexp = require('path-to-regexp');

module.exports = function(app) {

  var getSession = function(sessionId, errorMessage, cb) {
    app.config.session.store.get(sessionId, function (err, session) {
      if (err) { return cb(err); }
      if (!session) {
        return cb((function _createError(){
          var e = new Error(errorMessage);
          e.code = 'E_SESSION';
          return e;
        })());
      }
      return cb(null, session);
    });
  };
  // `session` hook definition
  var SessionHook = {

    defaults: {
      session: {
        adapter: 'memory',
        key: 'sails.sid',
        routesDisabled: ['GET r|^[^?]*/[^?/]+\\.[^?/]+(\\?.*)?$|']
      }
    },

    /**
     * Normalize and validate configuration for this hook.
     * Then fold any modifications back into `sails.config`
     */
    configure: function() {

      // Validate config
      // Ensure that secret is specified if a custom session store is used
      if (app.config.session) {
        if (!_.isObject(app.config.session)) {
          throw new Error('Invalid custom session store configuration!\n' +
            '\n' +
            'Basic usage ::\n' +
            '{ session: { adapter: "memory", secret: "someVerySecureString", /* ...if applicable: host, port, etc... */ } }' +
            '\n\nCustom usage ::\n' +
            '{ session: { store: { /* some custom connect session store instance */ }, secret: "someVerySecureString", /* ...custom settings.... */ } }'
          );
        }

      }

      // If session secret is undefined, set a secure, one-time use secret
      if (!app.config.session || !app.config.session.secret) {

        app.log.verbose('Session secret not defined-- automatically generating one for now...');

        if (app.config.environment === 'production') {
          app.log.warn('Session secret should be manually specified in production!');
          app.log.warn('Automatically generating one for now...');

          app.log.error('This generated session secret is NOT OK for production!');
          app.log.error('It will change each time the server starts and break multi-instance deployments.');
          app.log.blank();
          app.log.error('To set up a session secret, add or update it in `config/session.js`:');
          app.log.error('module.exports.session = { secret: "keyboardcat" }');
          app.log.blank();
        }

        app.config.session.secret = generateSecret();
      }

      // If secret _is_ defined, make sure it's a string
      else if (app.config.session.secret && !_.isString(app.config.session.secret)) {
        throw new Error('If provided, sails.config.session.secret should be a string.');
      }

      // Validate `routesDisabled`, if specified.
      if (app.config.session.routesDisabled && !_.isArray(app.config.session.routesDisabled)) {
        throw new Error('Invalid `sails.config.session.routesDisabled` configuration!\n' +
          '(must be an array of route address strings)'
        );
      }

      // Backwards-compatibility / shorthand notation
      // (allow mongo or redis session stores to be specified directly)
      if (app.config.session.adapter === 'redis') {
        app.config.session.adapter = 'connect-redis';
      }
      else if (app.config.session.adapter === 'mongo') {
        app.config.session.adapter = 'connect-mongo';
      }
    },

    /**
     * initialize() is run when the session hook is loaded.
     *
     * (Its primary responsibility is to create a session store instance
     *  and keep it around.)
     *
     * @api private
     */
    initialize: function(cb) {
      var sessionConfig = app.config.session;

      // Build `sails.hooks.session.routesDisabled`.
      // (only salient if `sails.config.session.routesDisabled` was specified)
      try {
        // Regex to check if the route is...a regex.
        var regExRoute = /^r\|(.*)\|(.*)$/;

        app.hooks.session.routesDisabled = _.reduce(sessionConfig.routesDisabled || [], function (memo, routeAddressStr){

          // Validate and parse route address.
          if (!_.isString(routeAddressStr)){
            throw new Error('Cannot parse route address (`'+routeAddressStr+'`). Must be a string.');
          }
          var addrPieces = routeAddressStr.split(/\s/);

          var method;
          var urlPattern;
          if (addrPieces.length === 1) {
            method = '';
            urlPattern = addrPieces[0];
          }
          else if (addrPieces.length === 2) {
            method = addrPieces[0];
            urlPattern = addrPieces[1];
          }
          else {
            throw new Error('Cannot parse route address (`'+routeAddressStr+'`). When split on whitespace, there are either too many or too few pieces (`'+addrPieces.length+'`).');
          }

          // Generate a regular expression from the URL pattern string.
          var urlPatternRegExp;

          // Perform the check
          var matches = urlPattern.match(regExRoute);

          // If it *is* a regex, create a RegExp object that Express can bind,
          // pull out the params, and wrap the handler in regexRouteWrapper
          if (matches) {
            urlPatternRegExp = new RegExp(matches[1]);
          } else {
            urlPatternRegExp = pathToRegexp(urlPattern, []);
          }

          memo.push({
            method: method,
            urlPatternRegExp: urlPatternRegExp
          });
          return memo;
        }, []);//</_.reduce()>

      } catch (e) {
        return cb(
          new Error('Failed to parse one of the route addresses provided in `sails.config.session.routesDisabled`.\n'+
          'If specified, this config must be an array of normal route address strings.\n'+
          'Error details:'+e.stack)
        );
      }

      // Intepret session adapter config and "new up" a session store
      if (_.isObject(sessionConfig) && !_.isObject(sessionConfig.store)) {

        // Unless the session is explicitly disabled, require the appropriate adapter
        if (sessionConfig.adapter) {

          // 'memory' is a special case
          if (sessionConfig.adapter === 'memory') {
            var MemoryStore = require('express-session').MemoryStore;
            sessionConfig.store = new MemoryStore();
          }
          // Try and load the specified adapter from the local sails project,
          // or catch and return error:
          else {

            var SessionAdapter;
            try {
              // Attempt to initialize the adapter using the express-session module
              SessionAdapter = require(path.resolve(app.config.appPath, 'node_modules', sessionConfig.adapter));
              try {
                var CustomStore = SessionAdapter(require('express-session'));
                sessionConfig.store = new CustomStore(sessionConfig);
              } catch (rawErr) {
                // If that fails, attempt to initialize the adapter using express
                // (required by older session adapters)
                try {
                  var CustomStore = SessionAdapter(require('express'));
                  sessionConfig.store = new CustomStore(sessionConfig);
                }
                catch (unused) {

                  // Failed attempting to initialize adapter; output a message w/ error info
                  // TODO: negotiate error and give better error msg depending on code
                  return cb(new Error(
                    'Encountered error in the installed version of `' + sessionConfig.adapter + '` (a session adapter).\n'+
                    'Raw error from the session adapter:\n'+
                    '---\n'+
                    (function _getAppropriateMessageFromRawSessionAdapterErr(){
                      if (_.isError(rawErr)) { return rawErr.stack; }
                      else if (_.isString(rawErr)) { return rawErr; }
                      else { return util.inspect(rawErr, { depth: null }); }
                    })()+'\n'+
                    '---\n'+
                    '\n'
                  ));

                }//</catch :: failed to instantiate session adapter by passing in express-session AND by passing express!>
              }//</catch :: failed to instantiate session adapter by passing in express-session>

            } catch(rawRequireErr) {

              // If an error occurred while attempting to require() the adapter, include
              // some (hopefully) helpful instructions on installing the adapter.
              return cb(new Error(
                // 'Could not require `' + sessionConfig.adapter + '` (a session adapter).\n'+
                'Do you have `' + sessionConfig.adapter + '` installed locally?\n'+
                'If not, try running the following command in your app\'s root directory:\n'+
                'npm install ' + sessionConfig.adapter + '\n'+
                '(Note: Make sure to install a Connect session adapter that is compatible with this version of Sails.)\n'+
                '\n'+
                'For debugging purposes, here is the error from attempting to run `require(\''+sessionConfig.adapter+'\')`:\n'+
                '---\n'+
                (function _getAppropriateMessageFromRawRequireErr(){
                  if (_.isError(rawRequireErr)) { return rawRequireErr.stack; }
                  else if (_.isString(rawRequireErr)) { return rawRequireErr; }
                  else { return util.inspect(rawRequireErr, { depth: null }); }
                })()+'\n'+
                '---\n'
              ));

            }//</catch :: require>
          }//</else>
        }//</if sessionConfig.adapter is truthy>
      }//</if sessionConfig is an object, but sessionConfig.store is NOT an object>

      // Expose hook as `sails.session`
      app.session = SessionHook;

      // Create the Session middleware to be shared by the private Sails router and
      // the HTTP session middleware.
      var opts = _.merge({
        resave: true,
        saveUninitialized: true
      }, app.config.session);

      app._privateSessionMiddleware = function(req, res, next) {

        // If configured to do so (i.e. there is at least one entry in the `sails.hooks.session.routesDisabled` blacklist)
        // then check this request against each entry in the blacklist and skip running session middleware if this is a match.
        var isSessionDisabled = _.any(app.hooks.session.routesDisabled, function (disabledRouteInfo){

          // Figure out if the request's method matches.
          var isMethodExactMatch = req.method === disabledRouteInfo.method;
          var isMethodImplicitMatch = disabledRouteInfo.method === 'ALL' || (disabledRouteInfo.method === '' && _.contains(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], req.method));
          // If not, then skip this disabled route- it's not a match.
          if (!isMethodExactMatch && !isMethodImplicitMatch) {
            return;
          }

          // Then figure out if the request's url path matches.
          var isUrlPathMatch = req.path.match(disabledRouteInfo.urlPatternRegExp);
          return isUrlPathMatch;

        });//</_.any()>

        // If the session is disabled, then skip running the middleware.
        if (isSessionDisabled) {
          return next();
        }

        // Run the express session middleware that actually sets up the session.
        return require('express-session')(opts)(req, res, next);

      };

      return cb();
    },

    /**
     * Generate a cookie to represent a new session.
     *
     * @return {String}
     * @api private
     */

    generateNewSidCookie: function (){
      var sid = uid(24);
      var signedSid = 's:' + signCookie(sid, app.config.session.secret);
      var cookie = stringifyCookie(app.config.session.key, signedSid, {});
      return cookie;
    },

    /**
     * Parse and unsign (i.e. decrypt) the provided cookie to get the session id.
     *
     * (adapted from code in the `express-session`)
     * (TODO: pull out into separate module as part of jshttp/pillarjs)
     *
     * @param  {String} cookie
     * @return {String}                [sessionId]
     *
     * @throws {Error} If cookie cannot be parsed or unsigned
     */
    parseSessionIdFromCookie: function (cookie){

      // e.g. "lolcatparty"
      var sessionSecret = app.config.session.secret;

      // Parse cookie
      var parsedSidCookie = parseCookie(cookie)[app.config.session.key];

      if (typeof parsedSidCookie !== 'string') {
        throw (function createError(){
          var err = new Error('No sid cookie exists');
          err.status = 401;
          err.code = 'E_SESSION_PARSE_COOKIE';
          return err;
        })();
      }

      if (parsedSidCookie.substr(0, 2) !== 's:') {
        throw (function createError(){
          var err = new Error('Cookie unsigned');
          err.status = 401;
          err.code = 'E_SESSION_PARSE_COOKIE';
          return err;
        })();
      }

      // Unsign cookie
      var sessionId = unsignCookie(parsedSidCookie.slice(2), sessionSecret);

      if (sessionId === false) {
        throw (function createError(){
          var err = new Error('Cookie signature invalid');
          err.status = 401;
          err.code = 'E_SESSION_PARSE_COOKIE';
          return err;
        })();
      }

      return sessionId;
    },

    /**
     * @param {String} sessionId
     * @param {Function} cb
     *
     * @api private
     */
    get: function(sessionId, cb) {
      if (!_.isFunction(cb)) {
        throw new Error('Invalid usage :: `sails.hooks.session.get(sessionId, cb)`');
      }
      return getSession(sessionId, 'Session could not be loaded', cb);
    },

    /**
     * @param {String} sessionId
     * @param {} data
     * @param {Function} cb
     *
     * @api private
     */
    set: function(sessionId, data, cb) {
      if (!_.isFunction(cb)) {
        throw new Error('Invalid usage :: `sails.hooks.session.set(sessionId, data, cb)`');
      }
      return app.config.session.store.set(sessionId, data, function (err) {
        if (err) return cb(err);
        return getSession(sessionId, 'Session could not be saved', cb);
      });
    }
  };

  return SessionHook;
};
<commit_msg>Only instantiate/configure express-session one time per load.<commit_after>/**
 * Module dependencies.
 */

var path = require('path');
var util = require('util');
var _ = require('@sailshq/lodash');

// generateSecret is used to generate a one-off session secret if one wasn't configured
var generateSecret = require('./generateSecret');

// (this dependency is just for creating new cookies)
var uid = require('uid-safe').sync;

// (these two dependencies are only here for sails.session.parseSessionIdFromCookie(),
//  which is only here to enable socket lifecycle callbacks)
var parseCookie = require('cookie').parse;
var stringifyCookie = require('cookie').serialize;
var unsignCookie = require('cookie-signature').unsign;
var signCookie = require('cookie-signature').sign;
var pathToRegexp = require('path-to-regexp');

module.exports = function(app) {

  var getSession = function(sessionId, errorMessage, cb) {
    app.config.session.store.get(sessionId, function (err, session) {
      if (err) { return cb(err); }
      if (!session) {
        return cb((function _createError(){
          var e = new Error(errorMessage);
          e.code = 'E_SESSION';
          return e;
        })());
      }
      return cb(null, session);
    });
  };
  // `session` hook definition
  var SessionHook = {

    defaults: {
      session: {
        adapter: 'memory',
        key: 'sails.sid',
        routesDisabled: ['GET r|^[^?]*/[^?/]+\\.[^?/]+(\\?.*)?$|']
      }
    },

    /**
     * Normalize and validate configuration for this hook.
     * Then fold any modifications back into `sails.config`
     */
    configure: function() {

      // Validate config
      // Ensure that secret is specified if a custom session store is used
      if (app.config.session) {
        if (!_.isObject(app.config.session)) {
          throw new Error('Invalid custom session store configuration!\n' +
            '\n' +
            'Basic usage ::\n' +
            '{ session: { adapter: "memory", secret: "someVerySecureString", /* ...if applicable: host, port, etc... */ } }' +
            '\n\nCustom usage ::\n' +
            '{ session: { store: { /* some custom connect session store instance */ }, secret: "someVerySecureString", /* ...custom settings.... */ } }'
          );
        }

      }

      // If session secret is undefined, set a secure, one-time use secret
      if (!app.config.session || !app.config.session.secret) {

        app.log.verbose('Session secret not defined-- automatically generating one for now...');

        if (app.config.environment === 'production') {
          app.log.warn('Session secret should be manually specified in production!');
          app.log.warn('Automatically generating one for now...');

          app.log.error('This generated session secret is NOT OK for production!');
          app.log.error('It will change each time the server starts and break multi-instance deployments.');
          app.log.blank();
          app.log.error('To set up a session secret, add or update it in `config/session.js`:');
          app.log.error('module.exports.session = { secret: "keyboardcat" }');
          app.log.blank();
        }

        app.config.session.secret = generateSecret();
      }

      // If secret _is_ defined, make sure it's a string
      else if (app.config.session.secret && !_.isString(app.config.session.secret)) {
        throw new Error('If provided, sails.config.session.secret should be a string.');
      }

      // Validate `routesDisabled`, if specified.
      if (app.config.session.routesDisabled && !_.isArray(app.config.session.routesDisabled)) {
        throw new Error('Invalid `sails.config.session.routesDisabled` configuration!\n' +
          '(must be an array of route address strings)'
        );
      }

      // Backwards-compatibility / shorthand notation
      // (allow mongo or redis session stores to be specified directly)
      if (app.config.session.adapter === 'redis') {
        app.config.session.adapter = 'connect-redis';
      }
      else if (app.config.session.adapter === 'mongo') {
        app.config.session.adapter = 'connect-mongo';
      }
    },

    /**
     * initialize() is run when the session hook is loaded.
     *
     * (Its primary responsibility is to create a session store instance
     *  and keep it around.)
     *
     * @api private
     */
    initialize: function(cb) {
      var sessionConfig = app.config.session;

      // Build `sails.hooks.session.routesDisabled`.
      // (only salient if `sails.config.session.routesDisabled` was specified)
      try {
        // Regex to check if the route is...a regex.
        var regExRoute = /^r\|(.*)\|(.*)$/;

        app.hooks.session.routesDisabled = _.reduce(sessionConfig.routesDisabled || [], function (memo, routeAddressStr){

          // Validate and parse route address.
          if (!_.isString(routeAddressStr)){
            throw new Error('Cannot parse route address (`'+routeAddressStr+'`). Must be a string.');
          }
          var addrPieces = routeAddressStr.split(/\s/);

          var method;
          var urlPattern;
          if (addrPieces.length === 1) {
            method = '';
            urlPattern = addrPieces[0];
          }
          else if (addrPieces.length === 2) {
            method = addrPieces[0];
            urlPattern = addrPieces[1];
          }
          else {
            throw new Error('Cannot parse route address (`'+routeAddressStr+'`). When split on whitespace, there are either too many or too few pieces (`'+addrPieces.length+'`).');
          }

          // Generate a regular expression from the URL pattern string.
          var urlPatternRegExp;

          // Perform the check
          var matches = urlPattern.match(regExRoute);

          // If it *is* a regex, create a RegExp object that Express can bind,
          // pull out the params, and wrap the handler in regexRouteWrapper
          if (matches) {
            urlPatternRegExp = new RegExp(matches[1]);
          } else {
            urlPatternRegExp = pathToRegexp(urlPattern, []);
          }

          memo.push({
            method: method,
            urlPatternRegExp: urlPatternRegExp
          });
          return memo;
        }, []);//</_.reduce()>

      } catch (e) {
        return cb(
          new Error('Failed to parse one of the route addresses provided in `sails.config.session.routesDisabled`.\n'+
          'If specified, this config must be an array of normal route address strings.\n'+
          'Error details:'+e.stack)
        );
      }

      // Intepret session adapter config and "new up" a session store
      if (_.isObject(sessionConfig) && !_.isObject(sessionConfig.store)) {

        // Unless the session is explicitly disabled, require the appropriate adapter
        if (sessionConfig.adapter) {

          // 'memory' is a special case
          if (sessionConfig.adapter === 'memory') {
            var MemoryStore = require('express-session').MemoryStore;
            sessionConfig.store = new MemoryStore();
          }
          // Try and load the specified adapter from the local sails project,
          // or catch and return error:
          else {

            var SessionAdapter;
            try {
              // Attempt to initialize the adapter using the express-session module
              SessionAdapter = require(path.resolve(app.config.appPath, 'node_modules', sessionConfig.adapter));
              try {
                var CustomStore = SessionAdapter(require('express-session'));
                sessionConfig.store = new CustomStore(sessionConfig);
              } catch (rawErr) {
                // If that fails, attempt to initialize the adapter using express
                // (required by older session adapters)
                try {
                  var CustomStore = SessionAdapter(require('express'));
                  sessionConfig.store = new CustomStore(sessionConfig);
                }
                catch (unused) {

                  // Failed attempting to initialize adapter; output a message w/ error info
                  // TODO: negotiate error and give better error msg depending on code
                  return cb(new Error(
                    'Encountered error in the installed version of `' + sessionConfig.adapter + '` (a session adapter).\n'+
                    'Raw error from the session adapter:\n'+
                    '---\n'+
                    (function _getAppropriateMessageFromRawSessionAdapterErr(){
                      if (_.isError(rawErr)) { return rawErr.stack; }
                      else if (_.isString(rawErr)) { return rawErr; }
                      else { return util.inspect(rawErr, { depth: null }); }
                    })()+'\n'+
                    '---\n'+
                    '\n'
                  ));

                }//</catch :: failed to instantiate session adapter by passing in express-session AND by passing express!>
              }//</catch :: failed to instantiate session adapter by passing in express-session>

            } catch(rawRequireErr) {

              // If an error occurred while attempting to require() the adapter, include
              // some (hopefully) helpful instructions on installing the adapter.
              return cb(new Error(
                // 'Could not require `' + sessionConfig.adapter + '` (a session adapter).\n'+
                'Do you have `' + sessionConfig.adapter + '` installed locally?\n'+
                'If not, try running the following command in your app\'s root directory:\n'+
                'npm install ' + sessionConfig.adapter + '\n'+
                '(Note: Make sure to install a Connect session adapter that is compatible with this version of Sails.)\n'+
                '\n'+
                'For debugging purposes, here is the error from attempting to run `require(\''+sessionConfig.adapter+'\')`:\n'+
                '---\n'+
                (function _getAppropriateMessageFromRawRequireErr(){
                  if (_.isError(rawRequireErr)) { return rawRequireErr.stack; }
                  else if (_.isString(rawRequireErr)) { return rawRequireErr; }
                  else { return util.inspect(rawRequireErr, { depth: null }); }
                })()+'\n'+
                '---\n'
              ));

            }//</catch :: require>
          }//</else>
        }//</if sessionConfig.adapter is truthy>
      }//</if sessionConfig is an object, but sessionConfig.store is NOT an object>

      // Expose hook as `sails.session`
      app.session = SessionHook;

      // Build and configure the raw session middleware.
      var opts = _.extend({
        resave: true,
        saveUninitialized: true
      }, app.config.session);

      var rawSessionMiddleware = require('express-session')(opts);

      // Now wrap up the raw middleware in our own req/res/next function, and expose
      // it privately so it can be used by the private Sails router and the HTTP session middleware.
      app._privateSessionMiddleware = function(req, res, next) {

        // If configured to do so (i.e. there is at least one entry in the `sails.hooks.session.routesDisabled` blacklist)
        // then check this request against each entry in the blacklist and skip running session middleware if this is a match.
        var isSessionDisabled = _.any(app.hooks.session.routesDisabled, function (disabledRouteInfo){

          // Figure out if the request's method matches.
          var isMethodExactMatch = req.method === disabledRouteInfo.method;
          var isMethodImplicitMatch = disabledRouteInfo.method === 'ALL' || (disabledRouteInfo.method === '' && _.contains(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], req.method));
          // If not, then skip this disabled route- it's not a match.
          if (!isMethodExactMatch && !isMethodImplicitMatch) {
            return;
          }

          // Then figure out if the request's url path matches.
          var isUrlPathMatch = req.path.match(disabledRouteInfo.urlPatternRegExp);
          return isUrlPathMatch;

        });//</_.any()>

        // If the session is disabled, then skip running the middleware.
        if (isSessionDisabled) {
          return next();
        }

        // Run the express session middleware that actually sets up the session.
        return rawSessionMiddleware(req, res, next);

      };

      return cb();
    },

    /**
     * Generate a cookie to represent a new session.
     *
     * @return {String}
     * @api private
     */

    generateNewSidCookie: function (){
      var sid = uid(24);
      var signedSid = 's:' + signCookie(sid, app.config.session.secret);
      var cookie = stringifyCookie(app.config.session.key, signedSid, {});
      return cookie;
    },

    /**
     * Parse and unsign (i.e. decrypt) the provided cookie to get the session id.
     *
     * (adapted from code in the `express-session`)
     * (TODO: pull out into separate module as part of jshttp/pillarjs)
     *
     * @param  {String} cookie
     * @return {String}                [sessionId]
     *
     * @throws {Error} If cookie cannot be parsed or unsigned
     */
    parseSessionIdFromCookie: function (cookie){

      // e.g. "lolcatparty"
      var sessionSecret = app.config.session.secret;

      // Parse cookie
      var parsedSidCookie = parseCookie(cookie)[app.config.session.key];

      if (typeof parsedSidCookie !== 'string') {
        throw (function createError(){
          var err = new Error('No sid cookie exists');
          err.status = 401;
          err.code = 'E_SESSION_PARSE_COOKIE';
          return err;
        })();
      }

      if (parsedSidCookie.substr(0, 2) !== 's:') {
        throw (function createError(){
          var err = new Error('Cookie unsigned');
          err.status = 401;
          err.code = 'E_SESSION_PARSE_COOKIE';
          return err;
        })();
      }

      // Unsign cookie
      var sessionId = unsignCookie(parsedSidCookie.slice(2), sessionSecret);

      if (sessionId === false) {
        throw (function createError(){
          var err = new Error('Cookie signature invalid');
          err.status = 401;
          err.code = 'E_SESSION_PARSE_COOKIE';
          return err;
        })();
      }

      return sessionId;
    },

    /**
     * @param {String} sessionId
     * @param {Function} cb
     *
     * @api private
     */
    get: function(sessionId, cb) {
      if (!_.isFunction(cb)) {
        throw new Error('Invalid usage :: `sails.hooks.session.get(sessionId, cb)`');
      }
      return getSession(sessionId, 'Session could not be loaded', cb);
    },

    /**
     * @param {String} sessionId
     * @param {} data
     * @param {Function} cb
     *
     * @api private
     */
    set: function(sessionId, data, cb) {
      if (!_.isFunction(cb)) {
        throw new Error('Invalid usage :: `sails.hooks.session.set(sessionId, data, cb)`');
      }
      return app.config.session.store.set(sessionId, data, function (err) {
        if (err) return cb(err);
        return getSession(sessionId, 'Session could not be saved', cb);
      });
    }
  };

  return SessionHook;
};
<|endoftext|>


<commit_before>import Vue from 'vue'
import Router from 'vue-router'

import Home from '../Home'
import Admin from '../Admin'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/admin',
      name: 'Admin',
      component: Admin
    }
  ]
})
<commit_msg>added a default route<commit_after>import Vue from 'vue'
import Router from 'vue-router'

import Home from '../Home'
import Admin from '../Admin'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/admin',
      name: 'Admin',
      component: Admin
    },
    {
      path: '*',
      name: 'default',
      component: Home
    }
  ]
})
<|endoftext|>


<commit_before>// Shuffle an array.
function fisherYates(myArray) {
    var i = myArray.length;
    if (i == 0) { return false; }
    while (--i) {
        var j = Math.floor(Math.random() * (i + 1));
        var tempi = myArray[i];
        var tempj = myArray[j];
        myArray[i] = tempj;
        myArray[j] = tempi;
   }
}

// Given an array of arrays, returns a single array with elements
// from each array shuffled evenly into it.
// WARNING: This will destructively modify the matrix array.
// IMPORTANT: The order of elements in subarrays is preserved.
function evenShuffle(arrayOfArrays) {
    fisherYates(arrayOfArrays);

    var longestArrayLength = 0;
    var totalLength = 0;
    for (var i = 0; i < arrayOfArrays.length; ++i) {
        if (arrayOfArrays[i].length > longestArrayLength)
            longestArrayLength = arrayOfArrays[i].length;
        totalLength += arrayOfArrays[i].length;
    }

    if (totalLength == 0) { return []; }

    var loopsPerIncrement = new Array(arrayOfArrays.length);
    for (var i = 0; i < arrayOfArrays.length; ++i) {
        loopsPerIncrement[i] = (arrayOfArrays[i].length + 0.0) / (longestArrayLength + 0.0)
    }

    var indexArray = new Array(arrayOfArrays.length);
    for (var i = 0; i < indexArray.length; ++i) {
        indexArray[i] = 0.0;
    }

    var shuffledArray = new Array(totalLength);
    for (var idx = 0; idx < totalLength;) {
        for (var j = 0; j < arrayOfArrays.length; ++j) {
            var oldi = indexArray[j];
            var newi = oldi + loopsPerIncrement[j];
            if (Math.floor(oldi) != Math.floor(newi)) {
                if (oldi < arrayOfArrays[j].length) {
                    shuffledArray[idx] = arrayOfArrays[j][Math.floor(oldi)];
                    ++idx;
                    if (! (idx < totalLength)) {
                        break; // The outer loop will now exit too.
                    }
                }
            }
            indexArray[j] = newi;
        }
    }

    return shuffledArray;
}

function latinSquare(arrayOfArrays, counter, extras) {
    var groupSize = null;
    for (var i = 0; i < arrayOfArrays.length; ++i) {
        if (groupSize == null) {
            groupSize = arrayOfArrays[i].length;
        }
        else if (groupSize != arrayOfArrays[i].length) {
            alert("Inconsistent group sizes.");
            return 1/0;
        }
    }

    var idx = counter % groupSize;
    var a = new Array(arrayOfArrays.length);
    for (var i = 0; i < arrayOfArrays.length; ++i) {
        a[i] = arrayOfArrays[i][idx];
        ++idx;
        if (idx >= groupSize)
            idx = 0;
    }

    if (extras != null) { extras['groupSize'] = groupSize; }
    return a;
}

function mungGroups(sentenceArray, counter, extras) {
    var nulls = filter(function (e) { return e.group == null; }, sentenceArray);
    var grouped = filter(function (e) { return e.group != null; }, sentenceArray);

    var hash = new Hashtable();
    for (var i = 0; i < grouped.length; ++i) {
        if (hash.get(grouped[i].group) == undefined) {
            hash.put(grouped[i].group, [grouped[i]]);
        }
        else
            hash.get(grouped[i].group).push(grouped[i]);
    }
    // Flatten the hash.
    var flat = new Array();
    hash.moveFirst();
    while (hash.next()) {
        flat.push(hash.getValue());
    }
    var es = {};
    var ls = flat.length > 0 ? latinSquare(flat, counter, es) : [];
    if (extras != null) { extras['groupSize'] = es['groupSize']; }
    return nulls.concat(ls);
}

function anyType(x) { return true; }
function lessThan0(x) { return typeof(x) == "number" && x < 0 ;}
function greaterThan0(x) { return typeof(x) == "number" && x > 0; }
function equalTo0(x) { return typeof(x) == "number" && x == 0; }
function startsWith(k) {
    return function(s) {
        if (typeof(s) != "string")
            return false;
        else {
            // Avoid searching through the whole string in cases where
            // it's not necessary.
            if (s.length == 0 && k.length == 0)
                return true;
            else if (s.charAt(0) != k.charAt(0))
                return false;
            else
                return s.indexOf(k) == 0;
        }
    }
}
function endsWith(k) {
    return function(s) {
        if (typeof(s) != "string")
            return false;
        else {
            // Avoid searching through the whole string in cases where
            // it's not necessary.
            if (s.length == 0 && k.length == 0)
                return true;
            else if (s.charAt(s.length - 1) != k.charAt(k.length - 1))
                return false
            else {
                var i = s.indexOf(k);
                return k != -1 && i == s.length - k.length;
            }
        }
    }
}
function not(pred) {
    return function(k) { return ! pred(k); }
}

function Seq(args) {
    this.args = args;

    this.run = function(arrays) {
        var totLength = 0;
        for (var i = 0; i < arrays.length; ++i)
            totLength += arrays[i].length;
        var a = new Array(totLength);
        var count = 0;
        for (var i = 0; i < arrays.length; ++i) {
            for (var j = 0; j < arrays[i].length; ++j) {
                a[count] = arrays[i][j];
                ++count;
            }
        }
        return a;
    }
}
function seq() { return new Seq(seq.arguments); }
function Randomize(x) {
    this.args = [x];

    this.run = function(arrays) {
        fisherYates(arrays[0]);
        return arrays[0];
    }
}
function randomize(x) { return new Randomize(x); }
function Shuffle(args) {
    this.args = args;

    this.run = function(arrays) {
        return evenShuffle(arrays);
    }
}
function shuffle() { return new Shuffle(shuffle.arguments); }
function rshuffle() { return new Shuffle(map(randomize, rshuffle.arguments)); }

function toPredicate(v) {
    if (typeof(v) == "function") {
        return v;
    }
    else if (typeof(v) == "object") {
        return function(x) {
            for (var i = 0; i < v.length; ++i) {
                if (v[i] == x)
                    return true;
            }
            return false;
        }
    }
    else if (typeof(v) == "string" || typeof(v) == "number") {
        return function(x) { return x == v; }
    }
    else {
        return 1/0;
    }
}

function runShuffleSequence(masterArray, ss) {
    if (typeof(ss) != "object") {
        alert("Bad shuffle sequence");
        return 1/0;
    }

    var arrays = new Array();
    for (var i = 0; i < ss.args.length; ++i) {
        if (typeof(ss.args[i]) == "object" && ss.ssType != undefined) {
            arrays.push(runShuffleSequence(masterArray, ss.args[i]));
        }
        else {
            var pred = toPredicate(ss.args[i]);
            var elems = filter(function (s) { return pred(s.type); }, masterArray);

            if (elems.length > 0)
                arrays.push(elems);
        }
    }

    if (arrays.length == 0)
        return []

    return ss.run(arrays);
}

<commit_msg>0.1.3.5<commit_after>// Shuffle an array.
function fisherYates(myArray) {
    var i = myArray.length;
    if (i == 0) { return false; }
    while (--i) {
        var j = Math.floor(Math.random() * (i + 1));
        var tempi = myArray[i];
        var tempj = myArray[j];
        myArray[i] = tempj;
        myArray[j] = tempi;
   }
}

// Given an array of arrays, returns a single array with elements
// from each array shuffled evenly into it.
// WARNING: This will destructively modify the matrix array.
// IMPORTANT: The order of elements in subarrays is preserved.
function evenShuffle(arrayOfArrays) {
    fisherYates(arrayOfArrays);

    var longestArrayLength = 0;
    var totalLength = 0;
    for (var i = 0; i < arrayOfArrays.length; ++i) {
        if (arrayOfArrays[i].length > longestArrayLength)
            longestArrayLength = arrayOfArrays[i].length;
        totalLength += arrayOfArrays[i].length;
    }

    if (totalLength == 0) { return []; }

    var loopsPerIncrement = new Array(arrayOfArrays.length);
    for (var i = 0; i < arrayOfArrays.length; ++i) {
        loopsPerIncrement[i] = (arrayOfArrays[i].length + 0.0) / (longestArrayLength + 0.0)
    }

    var indexArray = new Array(arrayOfArrays.length);
    for (var i = 0; i < indexArray.length; ++i) {
        indexArray[i] = 0.0;
    }

    var shuffledArray = new Array(totalLength);
    for (var idx = 0; idx < totalLength;) {
        for (var j = 0; j < arrayOfArrays.length; ++j) {
            var oldi = indexArray[j];
            var newi = oldi + loopsPerIncrement[j];
            if (Math.floor(oldi) != Math.floor(newi)) {
                if (oldi < arrayOfArrays[j].length) {
                    shuffledArray[idx] = arrayOfArrays[j][Math.floor(oldi)];
                    ++idx;
                    if (! (idx < totalLength)) {
                        break; // The outer loop will now exit too.
                    }
                }
            }
            indexArray[j] = newi;
        }
    }

    return shuffledArray;
}

function latinSquare(arrayOfArrays, counter, extras) {
    var groupSize = null;
    for (var i = 0; i < arrayOfArrays.length; ++i) {
        if (groupSize == null) {
            groupSize = arrayOfArrays[i].length;
        }
        else if (groupSize != arrayOfArrays[i].length) {
            alert("Inconsistent group sizes.");
            return 1/0;
        }
    }

    var idx = counter % groupSize;
    var a = new Array(arrayOfArrays.length);
    for (var i = 0; i < arrayOfArrays.length; ++i) {
        a[i] = arrayOfArrays[i][idx];
        ++idx;
        if (idx >= groupSize)
            idx = 0;
    }

    if (extras != null) { extras['groupSize'] = groupSize; }
    return a;
}

function mungGroups(sentenceArray, counter, extras) {
    var nulls = filter(function (e) { return e.group == null; }, sentenceArray);
    var grouped = filter(function (e) { return e.group != null; }, sentenceArray);

    var hash = new Hashtable();
    for (var i = 0; i < grouped.length; ++i) {
        if (hash.get(grouped[i].group) == undefined) {
            hash.put(grouped[i].group, [grouped[i]]);
        }
        else
            hash.get(grouped[i].group).push(grouped[i]);
    }
    // Flatten the hash.
    var flat = new Array();
    hash.moveFirst();
    while (hash.next()) {
        flat.push(hash.getValue());
    }
    var es = {};
    var ls = flat.length > 0 ? latinSquare(flat, counter, es) : [];
    if (extras != null) { extras['groupSize'] = es['groupSize']; }
    return nulls.concat(ls);
}

function anyType(x) { return true; }
function lessThan0(x) { return typeof(x) == "number" && x < 0 ;}
function greaterThan0(x) { return typeof(x) == "number" && x > 0; }
function equalTo0(x) { return typeof(x) == "number" && x == 0; }
function startsWith(k) {
    return function(s) {
        if (typeof(s) != "string")
            return false;
        else {
            // Avoid searching through the whole string in cases where
            // it's not necessary.
            if (s.length == 0 && k.length == 0)
                return true;
            else if (s.charAt(0) != k.charAt(0))
                return false;
            else
                return s.indexOf(k) == 0;
        }
    }
}
function endsWith(k) {
    return function(s) {
        if (typeof(s) != "string")
            return false;
        else {
            // Avoid searching through the whole string in cases where
            // it's not necessary.
            if (s.length == 0 && k.length == 0)
                return true;
            else if (s.charAt(s.length - 1) != k.charAt(k.length - 1))
                return false
            else {
                var i = s.indexOf(k);
                return k != -1 && i == s.length - k.length;
            }
        }
    }
}
function not(pred) {
    return function(k) { return ! pred(k); }
}

function Seq(args) {
    this.args = args;

    this.run = function(arrays) {
        var totLength = 0;
        for (var i = 0; i < arrays.length; ++i)
            totLength += arrays[i].length;
        var a = new Array(totLength);
        var count = 0;
        for (var i = 0; i < arrays.length; ++i) {
            for (var j = 0; j < arrays[i].length; ++j) {
                a[count] = arrays[i][j];
                ++count;
            }
        }
        return a;
    }
}
function seq() { return new Seq(seq.arguments); }
function Randomize(x) {
    this.args = [x];

    this.run = function(arrays) {
        fisherYates(arrays[0]);
        return arrays[0];
    }
}
function randomize(x) { return new Randomize(x); }
function Shuffle(args) {
    this.args = args;

    this.run = function(arrays) {
        return evenShuffle(arrays);
    }
}
function shuffle() { return new Shuffle(shuffle.arguments); }
function rshuffle() { return new Shuffle(map(randomize, rshuffle.arguments)); }

function toPredicate(v) {
    if (typeof(v) == "function") {
        return v;
    }
    else if (typeof(v) == "object") {
        return function(x) {
            for (var i = 0; i < v.length; ++i) {
                if (v[i] == x)
                    return true;
            }
            return false;
        }
    }
    else if (typeof(v) == "string" || typeof(v) == "number") {
        return function(x) { return x == v; }
    }
    else {
        return 1/0;
    }
}

function runShuffleSequence(masterArray, ss) {
    if (typeof(ss) != "object") {
        alert("Bad shuffle sequence");
        return 1/0;
    }

    var arrays = new Array();
    for (var i = 0; i < ss.args.length; ++i) {
        if (typeof(ss.args[i]) == "object") {
            arrays.push(runShuffleSequence(masterArray, ss.args[i]));
        }
        else {
            var pred = toPredicate(ss.args[i]);
            var elems = filter(function (s) { return pred(s.type); }, masterArray);

            if (elems.length > 0)
                arrays.push(elems);
        }
    }

    if (arrays.length == 0)
        return []

    return ss.run(arrays);
}
<|endoftext|>