<commit_before>import {VISITOR_KEYS} from "babel-types"

export const Tag = {push:{$:"push"},top:{$:"top"},Array:{$:"Array"}}

for(const i in VISITOR_KEYS) {
  Tag[i] = {$:i}
  for (const j of VISITOR_KEYS[i])
    Tag[j] = {$:j}
}

function isNode(node) {
  if (node == null)
    return false;
  return typeof node === 'object' && typeof node.type === 'string';
}

export function* produce(node,pos) {
  function* walk(value,pos) {
    if (Array.isArray(value)) {
      yield {enter: true, leave: false, value, pos, type: Tag.Array}
      for(const i of value)
        yield* walk(i,Tag.push)
      yield {enter: false, leave: true, value, pos, type: Tag.Array}
    } else if (isNode(value)) {
      const keys = VISITOR_KEYS[value.type]
      const type = Tag[value.type]
      if (keys.length) {
        yield {enter: true, leave: false, value, pos, type}
        for(const i of keys) {
          const v = value[i]
          if (v != null)
            yield* walk(value[i],Tag[i] || i)
        }
        yield {enter: false, leave: true, value, pos, type}
      } else {
        yield {enter: true, leave: true, value, pos, type}
      }
    }
  }
  yield* walk(node,pos || Tag.top)
}

export function consume(s) {
  const stack = [{}]
  for (const i of s) {
    if (i.type == null || !Tag[i.type.$])
      continue
    if (i.enter) {
      if (i.type === Tag.Array)
        stack.unshift([])
      else
        stack.unshift(i.value)
    }
    if (i.leave) {
      const value = stack.shift()
      if (i.pos === Tag.push) {
        stack[0].push(value)
      } else
        stack[0][i.pos.$] = value
    }
  }
  return stack[0]
}

<commit_msg>adjusting type in consumer<commit_after>import {VISITOR_KEYS} from "babel-types"

export const Tag = {push:{$:"push"},top:{$:"top"},Array:{$:"Array"}}

for(const i in VISITOR_KEYS) {
  Tag[i] = {$:i}
  for (const j of VISITOR_KEYS[i])
    Tag[j] = {$:j}
}

function isNode(node) {
  if (node == null)
    return false;
  return typeof node === 'object' && typeof node.type === 'string';
}

export function* produce(node,pos) {
  function* walk(value,pos) {
    if (Array.isArray(value)) {
      yield {enter: true, leave: false, value, pos, type: Tag.Array}
      for(const i of value)
        yield* walk(i,Tag.push)
      yield {enter: false, leave: true, value, pos, type: Tag.Array}
    } else if (isNode(value)) {
      const keys = VISITOR_KEYS[value.type]
      const type = Tag[value.type]
      if (keys.length) {
        yield {enter: true, leave: false, value, pos, type}
        for(const i of keys) {
          const v = value[i]
          if (v != null)
            yield* walk(value[i],Tag[i] || i)
        }
        yield {enter: false, leave: true, value, pos, type}
      } else {
        yield {enter: true, leave: true, value, pos, type}
      }
    }
  }
  yield* walk(node,pos || Tag.top)
}

export function consume(s) {
  const stack = [{}]
  for (const i of s) {
    if (i.type == null || !Tag[i.type.$])
      continue
    if (i.enter) {
      i.value.type = i.type.$
      if (i.type === Tag.Array)
        stack.unshift([])
      else
        stack.unshift(i.value)
    }
    if (i.leave) {
      const value = stack.shift()
      if (i.pos === Tag.push) {
        stack[0].push(value)
      } else
        stack[0][i.pos.$] = value
    }
  }
  return stack[0]
}

<|endoftext|>


<commit_before>// @flow
export {default as ChartData} from './chartdata/ChartData';
export {default as Svg} from './component/Svg';
export {default as Chart} from './component/Chart';

// Children
export {default as Axis} from './component/canvas/Axis'
export {default as Gridline} from './component/canvas/Gridline'
export {default as Line} from './component/canvas/Line'
export {default as Scatter} from './component/canvas/Scatter'
export {default as Column} from './component/canvas/Column'
<commit_msg>build: fix linting<commit_after>// @flow
export {default as ChartData} from './chartdata/ChartData';
export {default as Svg} from './component/Svg';
export {default as Chart} from './component/Chart';

// Children
export {default as Axis} from './component/canvas/Axis';
export {default as Gridline} from './component/canvas/Gridline';
export {default as Line} from './component/canvas/Line';
export {default as Scatter} from './component/canvas/Scatter';
export {default as Column} from './component/canvas/Column';
<|endoftext|>


<commit_before>var urls = require("urls"),
    urlPath = require("url_path"),
    sameOrigin = require("same_origin"),
    isString = require("is_string"),
    EventEmitter = require("event_emitter"),
    eventListener = require("event_listener"),
    environment = require("environment");

var page = new EventEmitter(),

    window = environment.window,
    location = window.location || {},
    navigator = window.navigator || {},

    pageListening = false,
    pageHtml5Mode = false,
    pageOrigin = location.origin,
    pageBase = "/",
    pageCurrentPath = location.pathname,
    pageHistory = [],

    supportsHtml5Mode = (function() {
        var userAgent = navigator.userAgent || "";
        if (
            (userAgent.indexOf("Android 2.") !== -1 || userAgent.indexOf("Android 4.0") !== -1) &&
            userAgent.indexOf("Mobile Safari") !== -1 &&
            userAgent.indexOf("Chrome") === -1
        ) {
            return false;
        }

        return (window.history && window.history.pushState != null);
    }());

page.init = page.listen = function() {
    if (pageListening === false) {
        pageListening = true;

        eventListener.on(window, "click", onclick);
        eventListener.on(window, "popstate", onpopstate);
        eventListener.on(window, "hashchange", onhashchange);

        page.emit("listen");
        page.go((pageHtml5Mode ? urlPath.relative(pageBase, location.pathname + location.search) : location.hash.slice(1)) || "/");
    }

    return page;
};

page.close = function() {
    if (pageListening === true) {
        pageListening = false;

        eventListener.off(window, "click", onclick);
        eventListener.off(window, "popstate", onpopstate);
        eventListener.off(window, "hashchange", onhashchange);

        page.emit("close");
    }

    return page;
};

page.html5Mode = function(value) {
    if (value != null && supportsHtml5Mode) {
        pageHtml5Mode = !!value;
    }
    return pageHtml5Mode;
};

page.base = function(value) {
    if (isString(value)) {
        pageBase = value;
    }
    return pageBase;
};

page.go = function(path) {
    var ctx = buildContext(path);

    replaceState(ctx, ctx.fullUrl.path);
    page.emit("request", ctx);

    return page;
};

page.hasHistory = function() {
    return pageHistory.length !== 0;
};

page.back = function(fallback) {
    var history = pageHistory,
        currentPath = pageCurrentPath,
        i = history.length,
        path;

    while (i--) {
        path = history[i];

        if (path !== currentPath) {
            history.length = i + 1;
            return page.go(path);
        }
    }

    if (isString(fallback)) {
        return page.go(fallback);
    } else {
        return false;
    }
};

page.reload = function() {
    var ctx = buildContext(pageCurrentPath);
    page.emit("request", ctx);
    return page;
};

function buildContext(path) {
    var ctx = {},
        fullUrl = urls.parse(pageOrigin + path, true);

    ctx.fullUrl = fullUrl;
    ctx.pathname = fullUrl.pathname;
    ctx.query = fullUrl.query;

    return ctx;
}

function replaceState(ctx, path) {
    pageHistory.push(pageCurrentPath);
    pageCurrentPath = path;

    if (pageHtml5Mode) {
        history.replaceState(ctx, ctx.fullUrl.path, urlPath.join(pageBase, path));
    } else {
        location.hash = path;
    }
}

function onpopstate(e) {
    if (pageHtml5Mode && e.state) {
        page.go(e.state.fullUrl.path);
    }
}

function onhashchange() {
    var path = location.hash.slice(1) || "/";

    if (!pageHtml5Mode && pageCurrentPath !== path) {
        page.go(path);
    }
}

function onclick(e) {
    var el, link;

    if (
        which(e) !== 1 ||
        e.metaKey || e.ctrlKey || e.shiftKey ||
        e.defaultPrevented
    ) {
        return;
    }

    el = e.target;
    link = el.getAttribute("href") || el.href;

    if (!link || el.target) {
        return;
    }
    if (link[0] === "#") {
        link = link.slice(1);
    }
    if (link && (link.indexOf("mailto:") > -1 || link.indexOf("tel:") > -1)) {
        return;
    }

    if (
        el.href && !sameOrigin.browser(el.href) ||
        (urlPath.isAbsoluteURL(link) && !sameOrigin.browser(link))
    ) {
        return;
    }

    e.preventDefault();
    page.go(urls.parse(link).path);
}

function which(e) {
    e = e || window.event;
    return e.which == null ? +e.button : +e.which;
}

module.exports = page;
<commit_msg>updates<commit_after>var urls = require("urls"),
    urlPath = require("url_path"),
    sameOrigin = require("same_origin"),
    isString = require("is_string"),
    EventEmitter = require("event_emitter"),
    eventListener = require("event_listener"),
    environment = require("environment");

var page = new EventEmitter(),

    window = environment.window,
    location = window.location || {},
    navigator = window.navigator || {},

    pageListening = false,
    pageHtml5Mode = false,
    pageOrigin = location.origin,
    pageBase = "/",
    pageCurrentPath = location.pathname,
    pageHistory = [],

    supportsHtml5Mode = (function() {
        var userAgent = navigator.userAgent || "";
        if (
            (userAgent.indexOf("Android 2.") !== -1 || userAgent.indexOf("Android 4.0") !== -1) &&
            userAgent.indexOf("Mobile Safari") !== -1 &&
            userAgent.indexOf("Chrome") === -1
        ) {
            return false;
        }

        return (window.history && window.history.pushState != null);
    }());

page.init = page.listen = function() {
    if (pageListening === false) {
        pageListening = true;

        eventListener.on(window, "click", onclick);
        eventListener.on(window, "popstate", onpopstate);
        eventListener.on(window, "hashchange", onhashchange);

        page.emit("listen");
        page.go((pageHtml5Mode ? urlPath.relative(pageBase, location.pathname + location.search) : location.hash.slice(1)) || "/");
    }

    return page;
};

page.close = function() {
    if (pageListening === true) {
        pageListening = false;

        eventListener.off(window, "click", onclick);
        eventListener.off(window, "popstate", onpopstate);
        eventListener.off(window, "hashchange", onhashchange);

        page.emit("close");
    }

    return page;
};

page.html5Mode = function(value) {
    if (value != null && supportsHtml5Mode) {
        pageHtml5Mode = !!value;
    }
    return pageHtml5Mode;
};

page.base = function(value) {
    if (isString(value)) {
        pageBase = value;
    }
    return pageBase;
};

page.go = function(path) {
    var ctx = buildContext(path);

    replaceState(ctx, ctx.fullUrl.path);
    page.emit("request", ctx);

    return page;
};

page.hasHistory = function() {
    return pageHistory.length !== 0;
};

page.back = function(fallback) {
    var history = pageHistory,
        currentPath = pageCurrentPath,
        i = history.length,
        path;

    while (i--) {
        path = history[i];

        if (path !== currentPath) {
            history.length = i + 1;
            return page.go(path);
        }
    }

    if (isString(fallback)) {
        return page.go(fallback);
    } else {
        return false;
    }
};

page.reload = function() {
    var ctx = buildContext(pageCurrentPath);
    page.emit("request", ctx);
    return page;
};

function end() {
    this.forceEnd = true;
}

function buildContext(path) {
    var ctx = {},
        fullUrl = urls.parse(pageOrigin + path, true);

    ctx.forceEnd = false;
    ctx.fullUrl = fullUrl;
    ctx.pathname = fullUrl.pathname;
    ctx.query = fullUrl.query;
    ctx.end = end;

    return ctx;
}

function replaceState(ctx, path) {
    pageHistory.push(pageCurrentPath);
    pageCurrentPath = path;

    if (pageHtml5Mode) {
        history.replaceState(ctx, ctx.fullUrl.path, urlPath.join(pageBase, path));
    } else {
        location.hash = path;
    }
}

function onpopstate(e) {
    if (pageHtml5Mode && e.state) {
        page.go(e.state.fullUrl.path);
    }
}

function onhashchange() {
    var path = location.hash.slice(1) || "/";

    if (!pageHtml5Mode && pageCurrentPath !== path) {
        page.go(path);
    }
}

function onclick(e) {
    var el, link;

    if (
        which(e) !== 1 ||
        e.metaKey || e.ctrlKey || e.shiftKey ||
        e.defaultPrevented
    ) {
        return;
    }

    el = e.target;
    link = el.getAttribute("href") || el.href;

    if (!link || el.target) {
        return;
    }
    if (link[0] === "#") {
        link = link.slice(1);
    }
    if (link && (link.indexOf("mailto:") > -1 || link.indexOf("tel:") > -1)) {
        return;
    }

    if (
        el.href && !sameOrigin.browser(el.href) ||
        (urlPath.isAbsoluteURL(link) && !sameOrigin.browser(link))
    ) {
        return;
    }

    e.preventDefault();
    page.go(urls.parse(link).path);
}

function which(e) {
    e = e || window.event;
    return e.which == null ? +e.button : +e.which;
}

module.exports = page;
<|endoftext|>


<commit_before>import i18next from './i18next';

export default i18next;
<commit_msg>fix #873<commit_after>import i18next from './i18next';

export default i18next;

export const changeLanguage = i18next.changeLanguage.bind(i18next);
export const cloneInstance = i18next.cloneInstance.bind(i18next);
export const createInstance = i18next.createInstance.bind(i18next);
export const dir = i18next.dir.bind(i18next);
export const exists = i18next.exists.bind(i18next);
export const getFixedT = i18next.getFixedT.bind(i18next);
export const init = i18next.init.bind(i18next);
export const loadLanguages = i18next.loadLanguages.bind(i18next);
export const loadNamespaces = i18next.loadNamespaces.bind(i18next);
export const loadResources = i18next.loadResources.bind(i18next);
export const off = i18next.off.bind(i18next);
export const on = i18next.on.bind(i18next);
export const setDefaultNamespace = i18next.setDefaultNamespace.bind(i18next);
export const t = i18next.t.bind(i18next);
export const use = i18next.use.bind(i18next);<|endoftext|>


<commit_before>import { mergeObjects, deepClone } from './util'
import devtoolMiddleware from './middlewares/devtool'
import createLogger from './middlewares/logger'
import override from './override'

let Vue

export class Store {

  /**
   * @param {Object} options
   *        - {Object} state
   *        - {Object} actions
   *        - {Object} mutations
   *        - {Array} middlewares
   *        - {Boolean} strict
   */

  constructor ({
    state = {},
    mutations = {},
    modules = {},
    middlewares = [],
    strict = false
  } = {}) {
    this._dispatching = false
    this._rootMutations = this._mutations = mutations
    this._modules = modules
    // bind dispatch to self
    const dispatch = this.dispatch
    this.dispatch = (...args) => {
      dispatch.apply(this, args)
    }
    // use a Vue instance to store the state tree
    this._vm = new Vue({
      data: state
    })
    this._setupModuleState(state, modules)
    this._setupModuleMutations(modules)
    this._setupMiddlewares(middlewares, state)
    // add extra warnings in strict mode
    if (strict) {
      this._setupMutationCheck()
    }
  }

  /**
   * Getter for the entire state tree.
   * Read only.
   *
   * @return {Object}
   */

  get state () {
    return this._vm._data
  }

  set state (v) {
    throw new Error('[vuex] Vuex root state is read only.')
  }

  /**
   * Dispatch an action.
   *
   * @param {String} type
   */

  dispatch (type, ...payload) {
    const mutation = this._mutations[type]
    const prevSnapshot = this._prevSnapshot
    const state = this.state
    let snapshot, clonedPayload
    if (mutation) {
      this._dispatching = true
      // apply the mutation
      if (Array.isArray(mutation)) {
        mutation.forEach(m => m(state, ...payload))
      } else {
        mutation(state, ...payload)
      }
      this._dispatching = false
      // invoke middlewares
      if (this._needSnapshots) {
        snapshot = this._prevSnapshot = deepClone(state)
        clonedPayload = deepClone(payload)
      }
      this._middlewares.forEach(m => {
        if (m.onMutation) {
          if (m.snapshot) {
            m.onMutation({ type, payload: clonedPayload }, snapshot, prevSnapshot)
          } else {
            m.onMutation({ type, payload }, state)
          }
        }
      })
    } else {
      console.warn(`[vuex] Unknown mutation: ${type}`)
    }
  }

  /**
   * Watch state changes on the store.
   * Same API as Vue's $watch, except when watching a function,
   * the function gets the state as the first argument.
   *
   * @param {String|Function} expOrFn
   * @param {Function} cb
   * @param {Object} [options]
   */

  watch (expOrFn, cb, options) {
    return this._vm.$watch(() => {
      return typeof expOrFn === 'function'
        ? expOrFn(this.state)
        : this._vm.$get(expOrFn)
    }, cb, options)
  }

  /**
   * Hot update actions and mutations.
   *
   * @param {Object} options
   *        - {Object} [mutations]
   *        - {Object} [modules]
   */

  hotUpdate ({ mutations, modules } = {}) {
    this._rootMutations = this._mutations = mutations || this._rootMutations
    this._setupModuleMutations(modules || this._modules)
  }

  /**
   * Attach sub state tree of each module to the root tree.
   *
   * @param {Object} state
   * @param {Object} modules
   */

  _setupModuleState (state, modules) {
    const { setPath } = Vue.parsers.path
    Object.keys(modules).forEach(key => {
      setPath(state, key, modules[key].state)
    })
  }

  /**
   * Bind mutations for each module to its sub tree and
   * merge them all into one final mutations map.
   *
   * @param {Object} modules
   */

  _setupModuleMutations (modules) {
    this._modules = modules
    const { getPath } = Vue.parsers.path
    const allMutations = [this._rootMutations]
    Object.keys(modules).forEach(key => {
      const module = modules[key]
      // bind mutations to sub state tree
      const mutations = {}
      Object.keys(module.mutations).forEach(name => {
        const original = module.mutations[name]
        mutations[name] = (state, ...args) => {
          original(getPath(state, key), ...args)
        }
      })
      allMutations.push(mutations)
    })
    this._mutations = mergeObjects(allMutations)
  }

  /**
   * Setup mutation check: if the vuex instance's state is mutated
   * outside of a mutation handler, we throw en error. This effectively
   * enforces all mutations to the state to be trackable and hot-reloadble.
   * However, this comes at a run time cost since we are doing a deep
   * watch on the entire state tree, so it is only enalbed with the
   * strict option is set to true.
   */

  _setupMutationCheck () {
    // a hack to get the watcher constructor from older versions of Vue
    // mainly because the public $watch method does not allow sync
    // watchers.
    const unwatch = this._vm.$watch('__vuex__', a => a)
    const Watcher = this._vm._watchers[0].constructor
    unwatch()
    /* eslint-disable no-new */
    new Watcher(this._vm, '$data', () => {
      if (!this._dispatching) {
        throw new Error(
          '[vuex] Do not mutate vuex store state outside mutation handlers.'
        )
      }
    }, { deep: true, sync: true })
    /* eslint-enable no-new */
  }

  /**
   * Setup the middlewares. The devtools middleware is always
   * included, since it does nothing if no devtool is detected.
   *
   * A middleware can demand the state it receives to be
   * "snapshots", i.e. deep clones of the actual state tree.
   *
   * @param {Array} middlewares
   * @param {Object} state
   */

  _setupMiddlewares (middlewares, state) {
    this._middlewares = [devtoolMiddleware].concat(middlewares)
    this._needSnapshots = middlewares.some(m => m.snapshot)
    if (this._needSnapshots) {
      console.log(
        '[vuex] One or more of your middlewares are taking state snapshots ' +
        'for each mutation. Make sure to use them only during development.'
      )
    }
    const initialSnapshot = this._prevSnapshot = this._needSnapshots
      ? deepClone(state)
      : null
    // call init hooks
    this._middlewares.forEach(m => {
      if (m.onInit) {
        m.onInit(m.snapshot ? initialSnapshot : state)
      }
    })
  }
}

function install (_Vue) {
  Vue = _Vue
  override(Vue)
}

export {
  install,
  createLogger
}

// also export the default
export default {
  Store,
  install,
  createLogger
}
<commit_msg>add replace state method<commit_after>import { mergeObjects, deepClone } from './util'
import devtoolMiddleware from './middlewares/devtool'
import createLogger from './middlewares/logger'
import override from './override'

let Vue

export class Store {

  /**
   * @param {Object} options
   *        - {Object} state
   *        - {Object} actions
   *        - {Object} mutations
   *        - {Array} middlewares
   *        - {Boolean} strict
   */

  constructor ({
    state = {},
    mutations = {},
    modules = {},
    middlewares = [],
    strict = false
  } = {}) {
    this._dispatching = false
    this._rootMutations = this._mutations = mutations
    this._modules = modules
    // bind dispatch to self
    const dispatch = this.dispatch
    this.dispatch = (...args) => {
      dispatch.apply(this, args)
    }
    // use a Vue instance to store the state tree
    this._vm = new Vue({
      data: state
    })
    this._setupModuleState(state, modules)
    this._setupModuleMutations(modules)
    this._setupMiddlewares(middlewares, state)
    // add extra warnings in strict mode
    if (strict) {
      this._setupMutationCheck()
    }
  }

  /**
   * Getter for the entire state tree.
   * Read only.
   *
   * @return {Object}
   */

  get state () {
    return this._vm._data
  }

  set state (v) {
    throw new Error('[vuex] Vuex root state is read only.')
  }

  /**
   * Dispatch an action.
   *
   * @param {String} type
   */

  dispatch (type, ...payload) {
    const mutation = this._mutations[type]
    const prevSnapshot = this._prevSnapshot
    const state = this.state
    let snapshot, clonedPayload
    if (mutation) {
      this._dispatching = true
      // apply the mutation
      if (Array.isArray(mutation)) {
        mutation.forEach(m => m(state, ...payload))
      } else {
        mutation(state, ...payload)
      }
      this._dispatching = false
      // invoke middlewares
      if (this._needSnapshots) {
        snapshot = this._prevSnapshot = deepClone(state)
        clonedPayload = deepClone(payload)
      }
      this._middlewares.forEach(m => {
        if (m.onMutation) {
          if (m.snapshot) {
            m.onMutation({ type, payload: clonedPayload }, snapshot, prevSnapshot)
          } else {
            m.onMutation({ type, payload }, state)
          }
        }
      })
    } else {
      console.warn(`[vuex] Unknown mutation: ${type}`)
    }
  }

  /**
   * Watch state changes on the store.
   * Same API as Vue's $watch, except when watching a function,
   * the function gets the state as the first argument.
   *
   * @param {String|Function} expOrFn
   * @param {Function} cb
   * @param {Object} [options]
   */

  watch (expOrFn, cb, options) {
    return this._vm.$watch(() => {
      return typeof expOrFn === 'function'
        ? expOrFn(this.state)
        : this._vm.$get(expOrFn)
    }, cb, options)
  }

  /**
   * Hot update actions and mutations.
   *
   * @param {Object} options
   *        - {Object} [mutations]
   *        - {Object} [modules]
   */

  hotUpdate ({ mutations, modules } = {}) {
    this._rootMutations = this._mutations = mutations || this._rootMutations
    this._setupModuleMutations(modules || this._modules)
  }

  /**
   * Replace entire state tree.
   */

  replaceState (newState) {
    const state = this._vm._data
    const clone = deepClone(newState)
    Object.keys(clone).forEach(key => {
      state[key] = clone[key]
    })
  }

  /**
   * Attach sub state tree of each module to the root tree.
   *
   * @param {Object} state
   * @param {Object} modules
   */

  _setupModuleState (state, modules) {
    const { setPath } = Vue.parsers.path
    Object.keys(modules).forEach(key => {
      setPath(state, key, modules[key].state)
    })
  }

  /**
   * Bind mutations for each module to its sub tree and
   * merge them all into one final mutations map.
   *
   * @param {Object} modules
   */

  _setupModuleMutations (modules) {
    this._modules = modules
    const { getPath } = Vue.parsers.path
    const allMutations = [this._rootMutations]
    Object.keys(modules).forEach(key => {
      const module = modules[key]
      // bind mutations to sub state tree
      const mutations = {}
      Object.keys(module.mutations).forEach(name => {
        const original = module.mutations[name]
        mutations[name] = (state, ...args) => {
          original(getPath(state, key), ...args)
        }
      })
      allMutations.push(mutations)
    })
    this._mutations = mergeObjects(allMutations)
  }

  /**
   * Setup mutation check: if the vuex instance's state is mutated
   * outside of a mutation handler, we throw en error. This effectively
   * enforces all mutations to the state to be trackable and hot-reloadble.
   * However, this comes at a run time cost since we are doing a deep
   * watch on the entire state tree, so it is only enalbed with the
   * strict option is set to true.
   */

  _setupMutationCheck () {
    // a hack to get the watcher constructor from older versions of Vue
    // mainly because the public $watch method does not allow sync
    // watchers.
    const unwatch = this._vm.$watch('__vuex__', a => a)
    const Watcher = this._vm._watchers[0].constructor
    unwatch()
    /* eslint-disable no-new */
    new Watcher(this._vm, '$data', () => {
      if (!this._dispatching) {
        throw new Error(
          '[vuex] Do not mutate vuex store state outside mutation handlers.'
        )
      }
    }, { deep: true, sync: true })
    /* eslint-enable no-new */
  }

  /**
   * Setup the middlewares. The devtools middleware is always
   * included, since it does nothing if no devtool is detected.
   *
   * A middleware can demand the state it receives to be
   * "snapshots", i.e. deep clones of the actual state tree.
   *
   * @param {Array} middlewares
   * @param {Object} state
   */

  _setupMiddlewares (middlewares, state) {
    this._middlewares = [devtoolMiddleware].concat(middlewares)
    this._needSnapshots = middlewares.some(m => m.snapshot)
    if (this._needSnapshots) {
      console.log(
        '[vuex] One or more of your middlewares are taking state snapshots ' +
        'for each mutation. Make sure to use them only during development.'
      )
    }
    const initialSnapshot = this._prevSnapshot = this._needSnapshots
      ? deepClone(state)
      : null
    // call init hooks
    this._middlewares.forEach(m => {
      if (m.onInit) {
        m.onInit(m.snapshot ? initialSnapshot : state)
      }
    })
  }
}

function install (_Vue) {
  Vue = _Vue
  override(Vue)
}

export {
  install,
  createLogger
}

// also export the default
export default {
  Store,
  install,
  createLogger
}
<|endoftext|>


<commit_before>/**
 * Created by oleg on 08.07.15.
 */
goog.require('goog.base');
goog.require('Syncer');

/**
 * @param {Array.<models.bitbucket.Branch|models.bitbucket.PullRequest>} elements
 */
var showList = function(elements) {
	var makeLi = function(ul, name, clickListener) {
		var li = document.createElement('li');
		li.onclick = clickListener;
		li.appendChild(document.createTextNode(name));
		ul.appendChild(li);
	};

	var ul = document.getElementById('content');
	makeLi(ul, 'back', function() {
		while (ul.lastChild) {
			ul.removeChild(ul.lastChild);
		}
		ul.setAttribute('display', 'none');
	});
	elements.forEach(function(element) {
		makeLi(ul, element.name || element.title, function() {
			window.open(element.links.html.href);
		});
	});
	ul.style.display = 'block';
};

var goto = function(url) {
	window.open(url);
};

var init = function() {
	var syncer = new Syncer;

	chrome.tabs.getSelected(function(tab) {
		var url = tab.url;
		syncer.setUrl(url);
	});

	document.getElementById('redmine').onclick = syncer.goToRedmineTicket.bind(syncer);
	document.getElementById('bit-pull').onclick = function() {
		syncer.getBitbucketPullRequests().then(function(pulls) {
			if (pulls.length === 1) {
				goto(pulls[0].links.html.href);
			} else {
				showList(pulls);
			}
		});
	};
	document.getElementById('bit-branch').onclick = function() {
		syncer.getBitbucketBranches().then(showList);
	};

	chrome.extension.onMessage.addListener(function(request, sender) {
		if (request.action == "get-branches") {
			console.log(request.source);
		}
	});
};

window.addEventListener('load', init);
<commit_msg>refactoring index.js<commit_after>/**
 * Created by oleg on 08.07.15.
 */
goog.require('goog.base');
goog.require('Syncer');

/**
 * @param {Array.<models.bitbucket.Branch|models.bitbucket.PullRequest>} elements
 */
var showList = function(elements) {
	var makeLi = function(ul, name, clickListener) {
		var li = document.createElement('li');
		li.onclick = clickListener;
		li.appendChild(document.createTextNode(name));
		ul.appendChild(li);
	};

	var ul = document.getElementById('content');
	makeLi(ul, 'back', function() {
		while (ul.lastChild) {
			ul.removeChild(ul.lastChild);
		}
		ul.setAttribute('display', 'none');
	});
	elements.forEach(function(element) {
		makeLi(ul, element.name || element.title, function() {
			window.open(element.links.html.href);
		});
	});
	ul.style.display = 'block';
};

var goto = function(url) {
	window.open(url);
};

var init = function() {
	var syncer = new Syncer;
	syncer.on('load', function() {
		document.getElementById('redmine').onclick = syncer.goToRedmineTicket.bind(syncer);
		document.getElementById('bit-pull').onclick = function() {
			syncer.getBitbucketPullRequests().then(function(pulls) {
				if (pulls.length === 1) {
					goto(pulls[0].links.html.href);
				} else {
					showList(pulls);
				}
			});
		};
		document.getElementById('bit-branch').onclick = function() {
			syncer.getBitbucketBranches().then(showList);
		};
	});

	chrome.extension.onMessage.addListener(function(request, sender) {
		if (request.action == "get-branches") {
			console.log(request.source);
		}
	});
};

window.addEventListener('load', init);
<|endoftext|>


<commit_before>import {spawn} from 'cross-spawn'
import commandConvert from './command'
import varValueConvert from './variable'

module.exports = crossEnv

const envSetterRegex = /(\w+)=('(.*)'|"(.*)"|(.*))/

function crossEnv(args, options = {}) {
  const [envSetters, command, commandArgs] = parseCommand(args)
  if (command) {
    const proc = spawn(
      // run `path.normalize` for command(on windows)
      commandConvert(command, true),
      // by default normalize is `false`, so not run for cmd args
      commandArgs.map(commandConvert),
      {
        stdio: 'inherit',
        shell: options.shell,
        env: getEnvVars(envSetters),
      },
    )
    process.on('SIGTERM', () => proc.kill('SIGTERM'))
    process.on('SIGINT', () => proc.kill('SIGINT'))
    process.on('SIGBREAK', () => proc.kill('SIGBREAK'))
    process.on('SIGHUP', () => proc.kill('SIGHUP'))
    proc.on('exit', process.exit)
    return proc
  }
  return null
}

function parseCommand(args) {
  const envSetters = {}
  let command = null
  let commandArgs = []
  for (let i = 0; i < args.length; i++) {
    const match = envSetterRegex.exec(args[i])
    if (match) {
      let value

      if (typeof match[3] !== 'undefined') {
        value = match[3]
      } else if (typeof match[4] === 'undefined') {
        value = match[5]
      } else {
        value = match[4]
      }

      envSetters[match[1]] = value
    } else {
      // No more env setters, the rest of the line must be the command and args
      command = args[i]
      commandArgs = args.slice(i + 1)
      break
    }
  }

  return [envSetters, command, commandArgs]
}

function getEnvVars(envSetters) {
  const envVars = Object.assign({}, process.env)
  if (process.env.APPDATA) {
    envVars.APPDATA = process.env.APPDATA
  }
  Object.keys(envSetters).forEach(varName => {
    envVars[varName] = varValueConvert(envSetters[varName], varName)
  })
  return envVars
}
<commit_msg>fix: Don't pass fn reference(`commandConvert`) to `commandArgs.map` (#135)<commit_after>import {spawn} from 'cross-spawn'
import commandConvert from './command'
import varValueConvert from './variable'

module.exports = crossEnv

const envSetterRegex = /(\w+)=('(.*)'|"(.*)"|(.*))/

function crossEnv(args, options = {}) {
  const [envSetters, command, commandArgs] = parseCommand(args)
  if (command) {
    const proc = spawn(
      // run `path.normalize` for command(on windows)
      commandConvert(command, true),
      // by default normalize is `false`, so not run for cmd args
      commandArgs.map(arg => commandConvert(arg)),
      {
        stdio: 'inherit',
        shell: options.shell,
        env: getEnvVars(envSetters),
      },
    )
    process.on('SIGTERM', () => proc.kill('SIGTERM'))
    process.on('SIGINT', () => proc.kill('SIGINT'))
    process.on('SIGBREAK', () => proc.kill('SIGBREAK'))
    process.on('SIGHUP', () => proc.kill('SIGHUP'))
    proc.on('exit', process.exit)
    return proc
  }
  return null
}

function parseCommand(args) {
  const envSetters = {}
  let command = null
  let commandArgs = []
  for (let i = 0; i < args.length; i++) {
    const match = envSetterRegex.exec(args[i])
    if (match) {
      let value

      if (typeof match[3] !== 'undefined') {
        value = match[3]
      } else if (typeof match[4] === 'undefined') {
        value = match[5]
      } else {
        value = match[4]
      }

      envSetters[match[1]] = value
    } else {
      // No more env setters, the rest of the line must be the command and args
      command = args[i]
      commandArgs = args.slice(i + 1)
      break
    }
  }

  return [envSetters, command, commandArgs]
}

function getEnvVars(envSetters) {
  const envVars = Object.assign({}, process.env)
  if (process.env.APPDATA) {
    envVars.APPDATA = process.env.APPDATA
  }
  Object.keys(envSetters).forEach(varName => {
    envVars[varName] = varValueConvert(envSetters[varName], varName)
  })
  return envVars
}
<|endoftext|>


<commit_before>/* eslint-disable react/jsx-filename-extension */

import React              from 'react';
import ReactDOM           from 'react-dom';

import App                from './App.jsx';
import {Auth0Provider}    from './react-auth0-spa';
import config             from './auth_config.json';
import history            from './history';
import * as serviceWorker from './serviceWorker';

// style
import './index.css';

const onRedirectCallback = appState => {
  history.push(appState && appState.targetUrl ?
    appState.targetUrl :
    window.location.pathname);
};

ReactDOM.render(
  <Auth0Provider
    domain={config.domain}
    client_id={config.clientId}
    redirect_uri={window.location.href}
    audience={config.audience}
    onRedirectCallback={onRedirectCallback}
  >
    <App />
  </Auth0Provider>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
<commit_msg>Get rid of the ?code url parameter after authentication - not really nice, but works!<commit_after>/* eslint-disable react/jsx-filename-extension */

import React              from 'react';
import ReactDOM           from 'react-dom';

import App                from './App.jsx';
import {Auth0Provider}    from './react-auth0-spa';
import config             from './auth_config.json';
import history            from './history';
import * as serviceWorker from './serviceWorker';

// style
import './index.css';

const onRedirectCallback = appState => {
  if(window.location.search.startsWith('?code=')) {
    const newHref = `${window.location.protocol}//${window.location.host}` +
      `${window.location.pathname}#${appState.targetUrl}`;

    window.location.href = newHref;

    return;
  }

  history.push(appState && appState.targetUrl ?
    appState.targetUrl :
    window.location.pathname);
};

ReactDOM.render(
  <Auth0Provider
    domain={config.domain}
    client_id={config.clientId}
    redirect_uri={window.location.href}
    audience={config.audience}
    onRedirectCallback={onRedirectCallback}
  >
    <App />
  </Auth0Provider>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
<|endoftext|>


<commit_before>import Firebase from 'firebase';

class ReduxOnFire {
    constructor(config) {
        this.firebaseApp = Firebase.initializeApp(config);
        this.firebaseAuth = Firebase.auth();
        this.firebaseAuthFacebook = new Firebase.auth.FacebookAuthProvider();
        this.firebaseAuthGoogle = new Firebase.auth.GoogleAuthProvider();
        this.firebaseStorage = Firebase.storage();
        this.firebaseDatabase = Firebase.database();
        this.dispatch = null;
        this.getState = null;
    }

    watchAuth() {
        this.firebaseAuth.onAuthStateChanged((result) => {
            if (result) {
                this.dispatch({
                    type: 'USER_LOGGED',
                    result: result
                });
            } else {
                this.dispatch({ type: 'USER_LOGGED_OUT' });
            }
        });
    }

    signup(email, password) {
        this.dispatch({ type: 'SIGNUP_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.createUserWithEmailAndPassword(email, password)
                .then(result => {
                    this.dispatch({
                        type: 'SIGNUP_SUCCESS',
                        result: result
                    });

                    resolve(result);

                    let user = this.firebaseAuth.currentUser;
                    if (!user.emailVerified) { user.sendEmailVerification(); }
                })
                .catch(error => {
                    this.dispatch({
                        type: 'SIGNUP_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    login(email, password) {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithEmailAndPassword(email, password)
                .then(result => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch(error => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    passwordReset(email) {
        return new Promise((resolve, reject) => {
            this.firebaseAuth.sendPasswordResetEmail(email)
                .then(() => {
                    this.dispatch({ type: 'PASSWORD_RESET_SUCCESS' });

                    resolve();
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'PASSWORD_RESET_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    facebook() {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithPopup(this.firebaseAuthFacebook)
                .then((result) => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    google() {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithPopup(this.firebaseAuthGoogle)
                .then((result) => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    logout() {
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signOut()
                .then(() => {
                    this.dispatch({ type: 'LOGOUT_SUCCESS' });

                    resolve();
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGOUT_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    watchRecords(recordsName, returnId) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_REQUEST' });
        this.firebaseDatabase.ref(recordsName).on('value',
            (result) => {
                let array = result.val();
                if (returnId) {
                    array = [];
                    result.forEach((child) => {
                        let element = child.val();
                        element.id = child.key;
                        array.push(element);
                    });
                }

                this.dispatch({
                    type: 'GET_' + actionName + '_SUCCESS',
                    [recordsName]: array
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FAILED',
                    error: error
                });
            }
        );
    }

    watchRecordsOrdered(recordsName, returnId, criteria, reverse) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_REQUEST' });
        this.firebaseDatabase.ref(recordsName).orderByChild(criteria).on('value',
            (result) => {
                let array = result.val();
                if (returnId) {
                    array = [];
                    result.forEach((child) => {
                        let element = child.val();
                        element.id = child.key;
                        array.push(element);
                    });
                }

                this.dispatch({
                    type: 'GET_' + actionName + '_SUCCESS',
                    [recordsName]: reverse ? array.reverse() : array
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FAILED',
                    error: error
                });
            }
        );
    }

    getRecordsFiltered(recordsName, filter) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_FILTERED_REQUEST' });
        this.firebaseDatabase.ref(recordsName).once('value',
            (result) => {
                let array = [];
                result.forEach((child) => {
                    let element = child.val();
                    element.id = child.key;
                    array.push(element);
                });
                this.dispatch({
                    type: 'GET_' + actionName + '_FILTERED_SUCCESS',
                    [recordsName]: filter(array)
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FILTERED_FAILED',
                    error: error
                });
            }
        );
    }

    getRecordById(recordName, recordId) {
        let actionName = recordName.toUpperCase();
        this.dispatch({ type: 'GET_SINGLE_' + actionName + '_REQUEST' });

        const record = this.getState()[recordName].all.filter(value => {
            return value.id == recordId ? true : false
        });

        if (record.length == 1) {
            this.dispatch({
                type: 'GET_SINGLE_' + actionName + '_CACHED',
                [recordName]: record[0]
            });
        } else {
            this.firebaseDatabase.ref(recordName).child(recordId).once('value',
            (snapshot) => {
                this.dispatch({
                    type: 'GET_SINGLE_' + actionName + '_SUCCESS',
                    [recordName]: snapshot.val()
                });
            },
            (error) => {
                this.dispatch({ type: 'GET_SINGLE_' + actionName + '_FAILED' });
            });
        }
    }

    getRecordByContent(recordName, recordContent) {
        let actionName = recordName.toUpperCase();
        return {
            type: 'GET_' + actionName,
            [recordName]: recordContent
        }
    }

    addRecordKey(recordName) {
        var actionName = recordName.toUpperCase();
        var reference = this.firebaseDatabase.ref().child(recordName).push().key;
        var initialDB = {
            number: '0/2016'
        }

        return this.firebaseDatabase.ref().child(recordName + '/' + reference).update(
            initialDB,
            (error) => {
                if (error) {
                    console.log(error);
                } else {
                    return dispatch({
                        type: 'ADD_' + actionName,
                        reference: reference
                    });
                }
            }
        );
    }

    addRecordWithContent(recordName, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'ADD_' + actionName + '_REQUEST'});
        var reference = this.firebaseDatabase.ref().child(recordName).push().key;
        return this.firebaseDatabase.ref().child(recordName + '/' + reference).update(
            recordContent,
            (error) => {
                if (error) {
                    return dispatch({type: 'ADD_' + actionName + '_FAILED', notification: notificationFailed});
                } else {
                    return dispatch({type: 'ADD_' + actionName + '_SUCCESS', notification: notificationSuccess});
                };
            }
        );
    }

    updateRecord(recordName, recordId, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'UPDATE_' + actionName + '_REQUEST'});

        if (recordId == null) {
            var reference = this.firebaseDatabase.ref().child(recordName);
        } else {
            var reference = this.firebaseDatabase.ref().child(recordName + '/' + recordId);
        }

        return reference.update(
            recordContent,
            (error) => {
                if (error) {
                    if (notificationFailed) {
                        this.dispatch({
                            type: 'UPDATE_' + actionName + '_FAILED',
                            notification: notificationFailed
                        });
                    }
                } else {
                    if (notificationSuccess) {
                        this.dispatch({
                            type: 'UPDATE_' + actionName + '_SUCCESS',
                            [recordName]: recordContent,
                            notification: notificationSuccess
                        });
                    }
                };
            }
        );
    }

    setRecord(recordName, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'SET_' + actionName + '_REQUEST'});
        var reference = this.firebaseDatabase.ref().child(recordName);
        return reference.set(
            recordContent,
            (error) => {
                if (error) {
                    if (notificationFailed) {
                        this.dispatch({
                            type: 'SET_' + actionName + '_FAILED',
                            notification: notificationFailed
                        });
                    }
                } else {
                    if (notificationSuccess) {
                        this.dispatch({
                            type: 'SET_' + actionName + '_SUCCESS',
                            [recordName]: recordContent,
                            notification: notificationSuccess
                        });
                    }
                };
            }
        );
    }

    cloneRecord(recordName, recordId, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'CLONE_' + actionName + '_REQUEST'})
        const record = this.getState()[recordName].all.filter(value => {
            return value.id == recordId ? true : false
        });

        if(record.length == 1) {
            var reference = this.firebaseDatabase.ref(recordName).push().key;
            return this.firebaseDatabase.ref(recordName).child(reference).update(
                record[0],
                (error) => {
                    if (error) {
                        return dispatch({type: 'CLONE_' + actionName + '_FAILED', notification: notificationFailed});
                    } else {
                        return dispatch({type: 'CLONE_' + actionName + '_SUCCESS', notification: notificationSuccess});
                    };
                }
            );
        } else {
            this.firebaseDatabase.ref(recordName).child(recordId).once('value').then((snapshot) => {
                var reference = this.firebaseDatabase.ref(recordName).push().key;
                return this.firebaseDatabase.ref(recordName).child(reference).update(
                    snapshot.val(),
                    (error) => {
                        if (error) {
                            return dispatch({type: 'CLONE_' + actionName + '_FAILED', notification: notificationFailed});
                        } else {
                            return dispatch({type: 'CLONE_' + actionName + '_SUCCESS', notification: notificationSuccess});
                        };
                    }
                );
            });
        }
    }

    deleteRecord(recordName, recordId) {
        let actionName = recordName.toUpperCase();
        this.firebaseDatabase.ref().child(recordName + '/' + recordId).remove();
        return {
            type: 'DELETE_' + actionName,
            id: recordId
        }
    }

    addNotification(notification) {
        const newNotification = Object.assign({}, notification);
        newNotification.id = new Date().getTime();
        this.dispatch({
            type: 'ADD_NOTIFICATION',
            newNotification
        });

        if (newNotification.removeAfter) {
            setTimeout(() => {
                this.dispatch({
                    type: 'REMOVE_NOTIFICATION',
                    id: newNotification.id,
                });
            }, newNotification.removeAfter);
        }
    }

    removeNotification(id) {
        this.dispatch({
            type: 'REMOVE_NOTIFICATION',
            id: id
        });
    }

    clearNotifications() {
        this.dispatch({
            type: 'CLEAR_NOTIFICATIONS'
        });
    }

}

export default ReduxOnFire;
<commit_msg>REMOVED: cloneRecord API<commit_after>import Firebase from 'firebase';

class ReduxOnFire {
    constructor(config) {
        this.firebaseApp = Firebase.initializeApp(config);
        this.firebaseAuth = Firebase.auth();
        this.firebaseAuthFacebook = new Firebase.auth.FacebookAuthProvider();
        this.firebaseAuthGoogle = new Firebase.auth.GoogleAuthProvider();
        this.firebaseStorage = Firebase.storage();
        this.firebaseDatabase = Firebase.database();
        this.dispatch = null;
        this.getState = null;
    }

    watchAuth() {
        this.firebaseAuth.onAuthStateChanged((result) => {
            if (result) {
                this.dispatch({
                    type: 'USER_LOGGED',
                    result: result
                });
            } else {
                this.dispatch({ type: 'USER_LOGGED_OUT' });
            }
        });
    }

    signup(email, password) {
        this.dispatch({ type: 'SIGNUP_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.createUserWithEmailAndPassword(email, password)
                .then(result => {
                    this.dispatch({
                        type: 'SIGNUP_SUCCESS',
                        result: result
                    });

                    resolve(result);

                    let user = this.firebaseAuth.currentUser;
                    if (!user.emailVerified) { user.sendEmailVerification(); }
                })
                .catch(error => {
                    this.dispatch({
                        type: 'SIGNUP_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    login(email, password) {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithEmailAndPassword(email, password)
                .then(result => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch(error => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    passwordReset(email) {
        return new Promise((resolve, reject) => {
            this.firebaseAuth.sendPasswordResetEmail(email)
                .then(() => {
                    this.dispatch({ type: 'PASSWORD_RESET_SUCCESS' });

                    resolve();
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'PASSWORD_RESET_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    facebook() {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithPopup(this.firebaseAuthFacebook)
                .then((result) => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    google() {
        this.dispatch({ type: 'LOGIN_REQUEST' });
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signInWithPopup(this.firebaseAuthGoogle)
                .then((result) => {
                    this.dispatch({
                        type: 'LOGIN_SUCCESS',
                        result: result
                    });

                    resolve(result);
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGIN_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    logout() {
        return new Promise((resolve, reject) => {
            this.firebaseAuth.signOut()
                .then(() => {
                    this.dispatch({ type: 'LOGOUT_SUCCESS' });

                    resolve();
                })
                .catch((error) => {
                    this.dispatch({
                        type: 'LOGOUT_FAILED',
                        error: error
                    });

                    reject(error);
                });
        });
    }

    watchRecords(recordsName, returnId) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_REQUEST' });
        this.firebaseDatabase.ref(recordsName).on('value',
            (result) => {
                let array = result.val();
                if (returnId) {
                    array = [];
                    result.forEach((child) => {
                        let element = child.val();
                        element.id = child.key;
                        array.push(element);
                    });
                }

                this.dispatch({
                    type: 'GET_' + actionName + '_SUCCESS',
                    [recordsName]: array
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FAILED',
                    error: error
                });
            }
        );
    }

    watchRecordsOrdered(recordsName, returnId, criteria, reverse) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_REQUEST' });
        this.firebaseDatabase.ref(recordsName).orderByChild(criteria).on('value',
            (result) => {
                let array = result.val();
                if (returnId) {
                    array = [];
                    result.forEach((child) => {
                        let element = child.val();
                        element.id = child.key;
                        array.push(element);
                    });
                }

                this.dispatch({
                    type: 'GET_' + actionName + '_SUCCESS',
                    [recordsName]: reverse ? array.reverse() : array
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FAILED',
                    error: error
                });
            }
        );
    }

    getRecordsFiltered(recordsName, filter) {
        let actionName = recordsName.toUpperCase();
        this.dispatch({ type: 'GET_' + actionName + '_FILTERED_REQUEST' });
        this.firebaseDatabase.ref(recordsName).once('value',
            (result) => {
                let array = [];
                result.forEach((child) => {
                    let element = child.val();
                    element.id = child.key;
                    array.push(element);
                });
                this.dispatch({
                    type: 'GET_' + actionName + '_FILTERED_SUCCESS',
                    [recordsName]: filter(array)
                });
            },
            (error) => {
                this.dispatch({
                    type: 'GET_' + actionName + '_FILTERED_FAILED',
                    error: error
                });
            }
        );
    }

    getRecordById(recordName, recordId) {
        let actionName = recordName.toUpperCase();
        this.dispatch({ type: 'GET_SINGLE_' + actionName + '_REQUEST' });

        const record = this.getState()[recordName].all.filter(value => {
            return value.id == recordId ? true : false
        });

        if (record.length == 1) {
            this.dispatch({
                type: 'GET_SINGLE_' + actionName + '_CACHED',
                [recordName]: record[0]
            });
        } else {
            this.firebaseDatabase.ref(recordName).child(recordId).once('value',
            (snapshot) => {
                this.dispatch({
                    type: 'GET_SINGLE_' + actionName + '_SUCCESS',
                    [recordName]: snapshot.val()
                });
            },
            (error) => {
                this.dispatch({ type: 'GET_SINGLE_' + actionName + '_FAILED' });
            });
        }
    }

    getRecordByContent(recordName, recordContent) {
        let actionName = recordName.toUpperCase();
        return {
            type: 'GET_' + actionName,
            [recordName]: recordContent
        }
    }

    addRecordKey(recordName) {
        var actionName = recordName.toUpperCase();
        var reference = this.firebaseDatabase.ref().child(recordName).push().key;
        var initialDB = {
            number: '0/2016'
        }

        return this.firebaseDatabase.ref().child(recordName + '/' + reference).update(
            initialDB,
            (error) => {
                if (error) {
                    console.log(error);
                } else {
                    return dispatch({
                        type: 'ADD_' + actionName,
                        reference: reference
                    });
                }
            }
        );
    }

    addRecordWithContent(recordName, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'ADD_' + actionName + '_REQUEST'});
        var reference = this.firebaseDatabase.ref().child(recordName).push().key;
        return this.firebaseDatabase.ref().child(recordName + '/' + reference).update(
            recordContent,
            (error) => {
                if (error) {
                    return dispatch({type: 'ADD_' + actionName + '_FAILED', notification: notificationFailed});
                } else {
                    return dispatch({type: 'ADD_' + actionName + '_SUCCESS', notification: notificationSuccess});
                };
            }
        );
    }

    updateRecord(recordName, recordId, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'UPDATE_' + actionName + '_REQUEST'});

        if (recordId == null) {
            var reference = this.firebaseDatabase.ref().child(recordName);
        } else {
            var reference = this.firebaseDatabase.ref().child(recordName + '/' + recordId);
        }

        return reference.update(
            recordContent,
            (error) => {
                if (error) {
                    if (notificationFailed) {
                        this.dispatch({
                            type: 'UPDATE_' + actionName + '_FAILED',
                            notification: notificationFailed
                        });
                    }
                } else {
                    if (notificationSuccess) {
                        this.dispatch({
                            type: 'UPDATE_' + actionName + '_SUCCESS',
                            [recordName]: recordContent,
                            notification: notificationSuccess
                        });
                    }
                };
            }
        );
    }

    setRecord(recordName, recordContent, notificationFailed, notificationSuccess) {
        var actionName = recordName.toUpperCase();
        this.dispatch({type: 'SET_' + actionName + '_REQUEST'});
        var reference = this.firebaseDatabase.ref().child(recordName);
        return reference.set(
            recordContent,
            (error) => {
                if (error) {
                    if (notificationFailed) {
                        this.dispatch({
                            type: 'SET_' + actionName + '_FAILED',
                            notification: notificationFailed
                        });
                    }
                } else {
                    if (notificationSuccess) {
                        this.dispatch({
                            type: 'SET_' + actionName + '_SUCCESS',
                            [recordName]: recordContent,
                            notification: notificationSuccess
                        });
                    }
                };
            }
        );
    }

    deleteRecord(recordName, recordId) {
        let actionName = recordName.toUpperCase();
        this.firebaseDatabase.ref().child(recordName + '/' + recordId).remove();
        return {
            type: 'DELETE_' + actionName,
            id: recordId
        }
    }

    addNotification(notification) {
        const newNotification = Object.assign({}, notification);
        newNotification.id = new Date().getTime();
        this.dispatch({
            type: 'ADD_NOTIFICATION',
            newNotification
        });

        if (newNotification.removeAfter) {
            setTimeout(() => {
                this.dispatch({
                    type: 'REMOVE_NOTIFICATION',
                    id: newNotification.id,
                });
            }, newNotification.removeAfter);
        }
    }

    removeNotification(id) {
        this.dispatch({
            type: 'REMOVE_NOTIFICATION',
            id: id
        });
    }

    clearNotifications() {
        this.dispatch({
            type: 'CLEAR_NOTIFICATIONS'
        });
    }

}

export default ReduxOnFire;
<|endoftext|>


<commit_before>import parser from 'minimist'
import pkginfo from 'pkginfo'
import path from 'path'
import { spawn } from 'child_process'

class Commander {
  constructor() {
    this.details = {
      options: [],
      commands: []
    }

    this.option('help', 'Output usage information')
    this.command('help', 'Display help')
  }

  option (name, description, init, defaultValue) {
    let usage = []

    switch (name.constructor) {
      case String:
        usage[0] = name.charAt(0)
        usage[1] = name

        break
      case Array:
        usage = usage.concat(name)
        break
      default:
        throw new Error('Invalid name for option')
    }

    if (usage.length > 0 && usage[0].length > 1) {
      throw new Error('Short version of option is longer than 1 char')
    }

    let optionDetails = {
      defaultValue,
      usage,
      description
    }

    if (defaultValue) {
      let initFunction = typeof init === 'function'
      optionDetails.init = initFunction ? init : this.handleType(defaultValue)[1]
    }

    this.details.options.push(optionDetails)
    return this
  }

  command (usage, description) {
    this.details.commands.push({
      usage,
      description
    })

    return this
  }

  handleType (value) {
    const type = value.constructor

    switch (type) {
      case String:
        return ['[value]', toString]
        break
      case Array:
        return ['<list>']
        break
      case Number:
        return ['<n>', parseInt]
        break
      default:
        return false
    }
  }

  setProperties (option) {
    let value = false

    for (let name of option.usage) {
      let fromArgs = this.args[name]

      if (fromArgs) {
        value = fromArgs
      }
    }

    for (let name of option.usage) {
      let propVal = value || option.defaultValue,
          condition = true

      if (option.init) {
        if (option.init === toString) {
          condition = propVal.constructor === Number
        }

        if (condition) {
          propVal = option.init(propVal)
        }
      }

      if (propVal) this[name] = propVal
    }
  }

  generateDetails (kind) {
    const items = this.details[kind]
    let parts = []

    for (let item in items) {
      let usage = items[item].usage,
          initial = items[item].defaultValue

      if (usage.constructor === Array) {
        usage = `-${usage[0]}, --${usage[1]}`
        usage += initial ? ' ' + this.handleType(initial)[0] : ''
      }

      items[item].usage = usage
    }

    const longest = items.sort((a, b) => {
      return b.usage.length - a.usage.length
    })[0].usage.length

    for (let item of items) {
      let usage = item.usage,
          difference = longest - usage.length

      usage += ' '.repeat(difference)
      parts.push('  ' + usage + '  ' + item.description)
    }

    return parts
  }

  renderHelp () {
    const binary = path.basename(this.args._[0])

    let details = [
      '',
      `Usage: ${binary} [options] [command]`,
      '',
      '',
      'Commands:',
      ''
    ]

    const commands = this.generateDetails('commands'),
          options = this.generateDetails('options')

    details = details.concat(
      commands,
      [
        '',
        'Options:',
        ''
      ],
      options,
      ''
    )

    console.log(details.join('\n  '))

    /*
    if (this.child) {
      this.child.kill('SIGINT')
    }*/

    process.exit()
  }

  runCommand (name) {
    const full = path.basename(this.args._[0]) + '-' + name

    let args = process.argv,
        i = 0

    while (i < 3) {
      args.shift()
      i++
    }

    this.child = spawn(full, args, {
      stdio: 'inherit',
      detached: true
    })

    this.child.on('error', err => {
      throw err
    })
  }

  parse (argv) {
    this.args = parser(argv.slice(1))
    const subCommand = this.args._[1] || false

    for (let command of this.details.commands) {
      if (command.usage !== subCommand) {
        continue
      }

      return this.runCommand(subCommand)
    }

    const parent = module.parent

    pkginfo(parent)
    const version = parent.exports.version

    if (version) {
      this.option('version', 'Output the version number', version)

      if (this.args.v || this.args.version) {
        console.log(version)
        process.exit()
      }
    }

    if (this.args._[1] == 'help' || this.args.h || this.args.help) {
      this.renderHelp()
    }

    for (let option of this.details.options) {
      this.setProperties(option)
    }

    const args = this.args
    args._.shift()

    this.raw = args
  }
}

export default new Commander
<commit_msg>Do not show dash in binary<commit_after>import parser from 'minimist'
import pkginfo from 'pkginfo'
import path from 'path'
import { spawn } from 'child_process'

class Commander {
  constructor() {
    this.details = {
      options: [],
      commands: []
    }

    this.option('help', 'Output usage information')
    this.command('help', 'Display help')
  }

  option (name, description, init, defaultValue) {
    let usage = []

    switch (name.constructor) {
      case String:
        usage[0] = name.charAt(0)
        usage[1] = name

        break
      case Array:
        usage = usage.concat(name)
        break
      default:
        throw new Error('Invalid name for option')
    }

    if (usage.length > 0 && usage[0].length > 1) {
      throw new Error('Short version of option is longer than 1 char')
    }

    let optionDetails = {
      defaultValue,
      usage,
      description
    }

    if (defaultValue) {
      let initFunction = typeof init === 'function'
      optionDetails.init = initFunction ? init : this.handleType(defaultValue)[1]
    }

    this.details.options.push(optionDetails)
    return this
  }

  command (usage, description) {
    this.details.commands.push({
      usage,
      description
    })

    return this
  }

  handleType (value) {
    const type = value.constructor

    switch (type) {
      case String:
        return ['[value]', toString]
        break
      case Array:
        return ['<list>']
        break
      case Number:
        return ['<n>', parseInt]
        break
      default:
        return false
    }
  }

  setProperties (option) {
    let value = false

    for (let name of option.usage) {
      let fromArgs = this.args[name]

      if (fromArgs) {
        value = fromArgs
      }
    }

    for (let name of option.usage) {
      let propVal = value || option.defaultValue,
          condition = true

      if (option.init) {
        if (option.init === toString) {
          condition = propVal.constructor === Number
        }

        if (condition) {
          propVal = option.init(propVal)
        }
      }

      if (propVal) this[name] = propVal
    }
  }

  generateDetails (kind) {
    const items = this.details[kind]
    let parts = []

    for (let item in items) {
      let usage = items[item].usage,
          initial = items[item].defaultValue

      if (usage.constructor === Array) {
        usage = `-${usage[0]}, --${usage[1]}`
        usage += initial ? ' ' + this.handleType(initial)[0] : ''
      }

      items[item].usage = usage
    }

    const longest = items.sort((a, b) => {
      return b.usage.length - a.usage.length
    })[0].usage.length

    for (let item of items) {
      let usage = item.usage,
          difference = longest - usage.length

      usage += ' '.repeat(difference)
      parts.push('  ' + usage + '  ' + item.description)
    }

    return parts
  }

  renderHelp () {
    const binary = path.basename(this.args._[0]).replace('-', ' ')

    let details = [
      '',
      `Usage: ${binary} [options] [command]`,
      '',
      '',
      'Commands:',
      ''
    ]

    const commands = this.generateDetails('commands'),
          options = this.generateDetails('options')

    details = details.concat(
      commands,
      [
        '',
        'Options:',
        ''
      ],
      options,
      ''
    )

    console.log(details.join('\n  '))
    process.exit()
  }

  runCommand (name) {
    const full = path.basename(this.args._[0]) + '-' + name

    let args = process.argv,
        i = 0

    while (i < 3) {
      args.shift()
      i++
    }

    this.child = spawn(full, args, {
      stdio: 'inherit',
      detached: true
    })

    this.child.on('error', err => {
      throw err
    })
  }

  parse (argv) {
    this.args = parser(argv.slice(1))
    const subCommand = this.args._[1] || false

    for (let command of this.details.commands) {
      if (command.usage !== subCommand) {
        continue
      }

      return this.runCommand(subCommand)
    }

    const parent = module.parent

    pkginfo(parent)
    const version = parent.exports.version

    if (version) {
      this.option('version', 'Output the version number', version)

      if (this.args.v || this.args.version) {
        console.log(version)
        process.exit()
      }
    }

    if (this.args._[1] == 'help' || this.args.h || this.args.help) {
      this.renderHelp()
    }

    for (let option of this.details.options) {
      this.setProperties(option)
    }

    const args = this.args
    args._.shift()

    this.raw = args
  }
}

export default new Commander
<|endoftext|>


<commit_before>var isArray = require('isarray');
var _superagent, _urls = {};

var _assignurl = function(status, body, method) {
  return function(url) {
    _urls[url] = {
      status: status,
      body: body
    }

    if (method) {
      _urls[url].method = method;
    }
  };
};

var mockagent = {
  target: function(superagent) {
    _superagent = superagent;
    _superagent.Request.prototype._oldEnd = superagent.Request.prototype.end;

    _superagent.Request.prototype.end = function(fn) {

      var urlObj = _urls[this.url];

      if (! urlObj || (urlObj.method && urlObj.method !== this.method)) {
        return this._oldEnd(fn);
      }

      var body = urlObj.body;
      var res = { method: urlObj.method };

      if (typeof body === 'object') {
        body = JSON.stringify(body);
      }

      if (typeof urlObj.status === 'function') {
        res = urlObj.status.bind(this)(res);
      } else {
        res = {
          xhr: {
            status: urlObj.status,
            responseText: body
          }
        };
      }

      setTimeout(function() {
        if (res && res.xhr && res.xhr.status > 299) {
          // Status code is not in the 200 range, return response as err
          return fn(res, null);
        }

        fn(null, res);
      });
    };

  },

  url: function(url, status, body, method) {
    var assignurl = _assignurl(status, body, method);

    if (isArray(url)) {
      url.forEach(assignurl);
    } else {
      assignurl(url);
    }
  },

  get: function(url, status, body) {
    this.url(url, status, body, 'GET');
  },

  put: function(url, status, body) {
    this.url(url, status, body, 'PUT');
  },

  post: function(url, status, body) {
    this.url(url, status, body, 'POST');
  },

  del: function(url, status, body) {
    this.url(url, status, body, 'DELETE');
  },

  patch: function(url, status, body) {
    this.url(url, status, body, 'PATCH');
  },

  head: function(url, status, body) {
    this.url(url, status, body, 'HEAD');
  },

  options: function(url, status, body) {
    this.url(url, status, body, 'OPTIONS');
  },

  releaseTarget: function() {
    _superagent.Request.prototype.end = _superagent.Request.prototype._oldEnd;
    delete _superagent.Request.prototype._oldEnd;
  }
};

module.exports = mockagent;
<commit_msg>Correct in code comment<commit_after>var isArray = require('isarray');
var _superagent, _urls = {};

var _assignurl = function(status, body, method) {
  return function(url) {
    _urls[url] = {
      status: status,
      body: body
    }

    if (method) {
      _urls[url].method = method;
    }
  };
};

var mockagent = {
  target: function(superagent) {
    _superagent = superagent;
    _superagent.Request.prototype._oldEnd = superagent.Request.prototype.end;

    _superagent.Request.prototype.end = function(fn) {

      var urlObj = _urls[this.url];

      if (! urlObj || (urlObj.method && urlObj.method !== this.method)) {
        return this._oldEnd(fn);
      }

      var body = urlObj.body;
      var res = { method: urlObj.method };

      if (typeof body === 'object') {
        body = JSON.stringify(body);
      }

      if (typeof urlObj.status === 'function') {
        res = urlObj.status.bind(this)(res);
      } else {
        res = {
          xhr: {
            status: urlObj.status,
            responseText: body
          }
        };
      }

      setTimeout(function() {
        if (res && res.xhr && res.xhr.status > 299) {
          // Status code is in the 200 range, return response successfully
          return fn(res, null);
        }

        fn(null, res);
      });
    };

  },

  url: function(url, status, body, method) {
    var assignurl = _assignurl(status, body, method);

    if (isArray(url)) {
      url.forEach(assignurl);
    } else {
      assignurl(url);
    }
  },

  get: function(url, status, body) {
    this.url(url, status, body, 'GET');
  },

  put: function(url, status, body) {
    this.url(url, status, body, 'PUT');
  },

  post: function(url, status, body) {
    this.url(url, status, body, 'POST');
  },

  del: function(url, status, body) {
    this.url(url, status, body, 'DELETE');
  },

  patch: function(url, status, body) {
    this.url(url, status, body, 'PATCH');
  },

  head: function(url, status, body) {
    this.url(url, status, body, 'HEAD');
  },

  options: function(url, status, body) {
    this.url(url, status, body, 'OPTIONS');
  },

  releaseTarget: function() {
    _superagent.Request.prototype.end = _superagent.Request.prototype._oldEnd;
    delete _superagent.Request.prototype._oldEnd;
  }
};

module.exports = mockagent;
<|endoftext|>


<commit_before>import rsvp from 'rsvp';

class FirebaseReporting {
  constructor(config) {
    this.firebase = config.firebase;
    this.paths = {
      data: config.dataPath || 'data',
      reporting: config.reportingPath || 'reporting'
    };
    this.filters = config.filters || [];
    this.queryFilter = [];
    this.queryData = {};
    this.rules = {};
    this.evaluators = {};

    this.initializeRules(config.metrics);
  }

  addEvaluator(name, method) {
    this.evaluators[name] = method;
  }

  initializeRules(rules) {
    this.rules = rules;
    this.evaluators = {};
    this.addEvaluator('max', (newVal, oldVal) => newVal > oldVal ? newVal : null);
    this.addEvaluator('min', (newVal, oldVal) => newVal < oldVal ? newVal : null);
    this.addEvaluator('first', () => null);
    this.addEvaluator('last', (newVal) => newVal);
    this.addEvaluator('sum', (newVal, oldVal) => oldVal + newVal);
    this.addEvaluator('diff', (newVal, oldVal) => oldVal - newVal);
    this.addEvaluator('multi', (newVal, oldVal) => oldVal * newVal);
    this.addEvaluator('div', (newVal, oldVal) => oldVal / newVal);
  }

  setQueryFilter(filter, data) {
    this.queryFilter = filter;
    this.queryData = data;
  }

  saveMetrics(data) {
    const promises = [];
    for (var key in data) {
      if (this.rules[key]) {
        // need to store metrics for data
        this.rules[key].forEach((metric) => {
          if (this.evaluators[metric]) {
            // run metric for each filter
            this.filters.forEach((filter) => {
              promises.push(this._calculateMetricValue(key, data[key], metric, this.evaluators[metric], filter, data));
            });
          }
        });
      }
    }
    return rsvp.all(promises);
  }

  getMetrics() {
    const promise = new rsvp.Promise((resolve, reject) => {
      const promises = [];
      const metrics = {};
      for (var key in this.rules) {
        metrics[key] = {};
        this.rules[key].forEach((metric) => {
          if (this.evaluators[metric]) {
            promises.push(this._captureMetricValue(key, metric, metrics));
          } else {
            metrics[key][metric] = null;
          }
        });
      }
      return rsvp.all(promises).then(() => {
        resolve(metrics);
      }).catch(reject);
    });
    return promise;
  }

  getTopMetrics(stat, evalName, total) {
    return this._getGlobalMetrics(stat, evalName, 'last', total);
  }

  getBottomMetrics(stat, evalName, total) {
    return this._getGlobalMetrics(stat, evalName, 'first', total);
  }

  getAllMetrics(stat, evalName) {
    return this._getGlobalMetrics(stat, evalName, 'all');
  }

  getTotal(prop, comparision, value, otherValue) {
    const promise = new rsvp.Promise((resolve) => {
      let query = this.refData();
      if (prop) {
        query = query.orderByChild(prop);
        switch (comparision) {
          case 'lesser':
            query = query.endAt(value);
            break;
          case 'greater':
            query = query.startAt(value);
            break;
          case 'between':
            query = query.startAt(value).endAt(otherValue);
            break;
          case 'equal':
            query = query.startAt(value).endAt(value);
            break;
        }
      }
      query.once('value', (snapshot) => {
        resolve(snapshot.numChildren());
      });
    });
    return promise;
  }

  getTotalUsers(stat, evalName, comparision, value, otherValue) {
    const promise = new rsvp.Promise((resolve) => {
      let query = this.refUserReporting();
      if (stat) {
        const key = this._getStatKey(stat, evalName);
        query = query.orderByChild(key);
        switch (comparision) {
          case 'lesser':
            query = query.endAt(value);
            break;
          case 'greater':
            query = query.startAt(value);
            break;
          case 'between':
            query = query.startAt(value).endAt(otherValue);
            break;
          case 'equal':
            query = query.startAt(value).endAt(value);
            break;
        }
      }
      query.once('value', (snapshot) => {
        resolve(snapshot.numChildren());
      });
    });
    return promise;
  }

  _getGlobalMetrics(stat, evalName, type, total) {
    total = total || 1;
    const key = this._getStatKey(stat, evalName);
    const values = [];
    let query;
    if (type === 'last') {
      query = this.refUserReporting().orderByChild(key).limitToLast(total);
    } else if (type === 'first') {
      query = this.refUserReporting().orderByChild(key).limitToFirst(total);
    } else {
      query = this.refUserReporting().orderByChild(key);
    }
    const promise = new rsvp.Promise((resolve) => {
      query.on('child_added', (snapshot) => {
        values.push(snapshot.child(key).val());
        if (values.length === total) {
          done();
        }
      });

      const done = () => {
        clearTimeout(timeout);
        query.off('child_added');
        values.sort((a, b) => b - a);
        resolve(values);
      };
      const timeout = setTimeout(done, 5000);
    });
    return promise;
  }

  _captureMetricValue(stat, evaluatorName, metrics) {
    const key = this._getStatKey(stat, evaluatorName);
    const ref = this.refCurrentUserReporting().child(key);
    const promise = new rsvp.Promise((resolve) => {
      ref.once('value', (snapshot) => {
        const val = snapshot.val();
        if (metrics) {
          metrics[stat][evaluatorName] = val;
        }
        resolve(val);
      });
    });
    return promise;
  }

  _calculateMetricValue(stat, newVal, evaluatorName, evaluator, filter, filterData) {
    const key = this._getStatKey(stat, evaluatorName, filter, filterData);
    const ref = this.refCurrentUserReporting().child(key);
    const promise = new rsvp.Promise((resolve, reject) => {
      ref.once('value', (snapshot) => {
        const oldVal = snapshot.val();
        if (typeof oldVal === 'undefined') {
          ref.set(newVal).then(resolve).catch(reject);
        } else {
          const evalVal = evaluator(newVal, oldVal);
          if (typeof evalVal !== 'undefined' && evalVal !== null) {
            ref.set(evalVal).then(resolve).catch(reject);
          } else {
            resolve();
          }
        }
      });
    });
    return promise;
  }

  _getStatKey(stat, evalName, filter, filterData) {
    let prefix = '';
    (filter || this.queryFilter).forEach((key) => {
      if (filterData) {
        prefix += filterData[key] + '~~';
      } else {
        prefix += this.queryData[key] + '~~';
      }
    });
    return prefix + stat + '~~' + evalName;
  }

  refData() {
    return this.firebase.database.ref(this.paths.data);
  }

  refUserReporting() {
    return this.firebase.database.ref(this.paths.reporting).child('users');
  }

  refCurrentUserReporting() {
    const currentUser = this.firebase.auth().currentUser;
    if (currentUser) {
      return this.refUserReporting().child(currentUser.uid);
    } else {
      return this.refUserReporting().child('unknown');
    }
  }
}

module.exports = FirebaseReporting;
<commit_msg>use transaction to set metrics<commit_after>import rsvp from 'rsvp';

class FirebaseReporting {
  constructor(config) {
    this.firebase = config.firebase;
    this.paths = {
      data: config.dataPath || 'data',
      reporting: config.reportingPath || 'reporting'
    };
    this.filters = config.filters || [];
    this.queryFilter = [];
    this.queryData = {};
    this.rules = {};
    this.evaluators = {};

    this.initializeRules(config.metrics);
  }

  addEvaluator(name, method) {
    this.evaluators[name] = method;
  }

  initializeRules(rules) {
    this.rules = rules;
    this.evaluators = {};
    this.addEvaluator('max', (newVal, oldVal) => newVal > oldVal ? newVal : null);
    this.addEvaluator('min', (newVal, oldVal) => newVal < oldVal ? newVal : null);
    this.addEvaluator('first', () => null);
    this.addEvaluator('last', (newVal) => newVal);
    this.addEvaluator('sum', (newVal, oldVal) => oldVal + newVal);
    this.addEvaluator('diff', (newVal, oldVal) => oldVal - newVal);
    this.addEvaluator('multi', (newVal, oldVal) => oldVal * newVal);
    this.addEvaluator('div', (newVal, oldVal) => oldVal / newVal);
  }

  setQueryFilter(filter, data) {
    this.queryFilter = filter;
    this.queryData = data;
  }

  saveMetrics(data) {
    const promises = [];
    for (var key in data) {
      if (this.rules[key]) {
        // need to store metrics for data
        this.rules[key].forEach((metric) => {
          if (this.evaluators[metric]) {
            // run metric for each filter
            this.filters.forEach((filter) => {
              promises.push(this._calculateMetricValue(key, data[key], metric, this.evaluators[metric], filter, data));
            });
          }
        });
      }
    }
    return rsvp.all(promises);
  }

  getMetrics() {
    const promise = new rsvp.Promise((resolve, reject) => {
      const promises = [];
      const metrics = {};
      for (var key in this.rules) {
        metrics[key] = {};
        this.rules[key].forEach((metric) => {
          if (this.evaluators[metric]) {
            promises.push(this._captureMetricValue(key, metric, metrics));
          } else {
            metrics[key][metric] = null;
          }
        });
      }
      return rsvp.all(promises).then(() => {
        resolve(metrics);
      }).catch(reject);
    });
    return promise;
  }

  getTopMetrics(stat, evalName, total) {
    return this._getGlobalMetrics(stat, evalName, 'last', total);
  }

  getBottomMetrics(stat, evalName, total) {
    return this._getGlobalMetrics(stat, evalName, 'first', total);
  }

  getAllMetrics(stat, evalName) {
    return this._getGlobalMetrics(stat, evalName, 'all');
  }

  getTotal(prop, comparision, value, otherValue) {
    const promise = new rsvp.Promise((resolve) => {
      let query = this.refData();
      if (prop) {
        query = query.orderByChild(prop);
        switch (comparision) {
          case 'lesser':
            query = query.endAt(value);
            break;
          case 'greater':
            query = query.startAt(value);
            break;
          case 'between':
            query = query.startAt(value).endAt(otherValue);
            break;
          case 'equal':
            query = query.startAt(value).endAt(value);
            break;
        }
      }
      query.once('value', (snapshot) => {
        resolve(snapshot.numChildren());
      });
    });
    return promise;
  }

  getTotalUsers(stat, evalName, comparision, value, otherValue) {
    const promise = new rsvp.Promise((resolve) => {
      let query = this.refUserReporting();
      if (stat) {
        const key = this._getStatKey(stat, evalName);
        query = query.orderByChild(key);
        switch (comparision) {
          case 'lesser':
            query = query.endAt(value);
            break;
          case 'greater':
            query = query.startAt(value);
            break;
          case 'between':
            query = query.startAt(value).endAt(otherValue);
            break;
          case 'equal':
            query = query.startAt(value).endAt(value);
            break;
        }
      }
      query.once('value', (snapshot) => {
        resolve(snapshot.numChildren());
      });
    });
    return promise;
  }

  _getGlobalMetrics(stat, evalName, type, total) {
    total = total || 1;
    const key = this._getStatKey(stat, evalName);
    const values = [];
    let query;
    if (type === 'last') {
      query = this.refUserReporting().orderByChild(key).limitToLast(total);
    } else if (type === 'first') {
      query = this.refUserReporting().orderByChild(key).limitToFirst(total);
    } else {
      query = this.refUserReporting().orderByChild(key);
    }
    const promise = new rsvp.Promise((resolve) => {
      query.on('child_added', (snapshot) => {
        values.push(snapshot.child(key).val());
        if (values.length === total) {
          done();
        }
      });

      const done = () => {
        clearTimeout(timeout);
        query.off('child_added');
        values.sort((a, b) => b - a);
        resolve(values);
      };
      const timeout = setTimeout(done, 5000);
    });
    return promise;
  }

  _captureMetricValue(stat, evaluatorName, metrics) {
    const key = this._getStatKey(stat, evaluatorName);
    const ref = this.refCurrentUserReporting().child(key);
    const promise = new rsvp.Promise((resolve) => {
      ref.once('value', (snapshot) => {
        const val = snapshot.val();
        if (metrics) {
          metrics[stat][evaluatorName] = val;
        }
        resolve(val);
      });
    });
    return promise;
  }

  _calculateMetricValue(stat, newVal, evaluatorName, evaluator, filter, filterData) {
    const key = this._getStatKey(stat, evaluatorName, filter, filterData);
    const ref = this.refCurrentUserReporting().child(key);
    return ref.transaction((oldVal) => {
      if (typeof oldVal === 'undefined') {
        return newVal;
      } else {
        const evalVal = evaluator(newVal, oldVal);
        if (typeof evalVal !== 'undefined' && evalVal !== null) {
          return evalVal;
        } else {
          return oldVal;
        }
      }
    });
  }

  _getStatKey(stat, evalName, filter, filterData) {
    let prefix = '';
    (filter || this.queryFilter).forEach((key) => {
      if (filterData) {
        prefix += filterData[key] + '~~';
      } else {
        prefix += this.queryData[key] + '~~';
      }
    });
    return prefix + stat + '~~' + evalName;
  }

  refData() {
    return this.firebase.database.ref(this.paths.data);
  }

  refUserReporting() {
    return this.firebase.database.ref(this.paths.reporting).child('users');
  }

  refCurrentUserReporting() {
    const currentUser = this.firebase.auth().currentUser;
    if (currentUser) {
      return this.refUserReporting().child(currentUser.uid);
    } else {
      return this.refUserReporting().child('unknown');
    }
  }
}

module.exports = FirebaseReporting;
<|endoftext|>