<commit_before>
 /**
  * @namespace basis.router
  */

  var namespace = this.path;

  //
  // main part
  //

  var location = global.location;
  var document = global.document;
  var eventUtils = require('basis.dom.event');

  // documentMode logic from YUI to filter out IE8 Compat Mode which false positives
  var docMode = document.documentMode;
  var eventSupport = 'onhashchange' in global && (docMode === undefined || docMode > 7);

  var CHECK_INTERVAL = 50;

  var arrayFrom = basis.array.from;
  var routes = {};
  var matched = {};
  var started = false;
  var currentPath;
  var timer;

 /**
  * @class
  */
  var Route = basis.Token.subclass({
    className: namespace + '.Route',

    matched: null,
    params_: null,
    names_: null,

    init: function(names){
      basis.Token.prototype.init.call(this, null);

      this.matched = this.as(Boolean);
      this.names_ = Array.isArray(names) ? names : [];
      this.params_ = {};
    },
    param: function(nameOrIdx){
      var idx = typeof nameOrIdx == 'number' ? nameOrIdx : this.names_.indexOf(nameOrIdx);

      if (idx in this.params_ == false)
        this.params_[idx] = this.as(function(value){
          return value && value[idx];
        });

      return this.params_[idx];
    },
    set: function(value){
      if (value)
      {
        // make a copy of value, it also converts value to object (as value is array of matches)
        value = basis.object.slice(value);

        // extend object with named values
        for (var key in value)
          if (key in this.names_)
            value[this.names_[key]] = value[key];
      }

      basis.Token.prototype.set.call(this, value);
    }
  });

 /**
  * Convert string to regexp
  */
  function pathToRegExp(route){
    var value = String(route || '');
    var params = [];

    function findWord(offset){
      return value.substr(offset).match(/^\w+/);
    }

    function parse(offset, stopChar){
      var result = '';
      var res;

      for (var i = offset; i < value.length; i++)
      {
        var c = value.charAt(i);
        switch (c)
        {
          case stopChar:
            return {
              result: result,
              offset: i
            };

          case '\\':
            result += '\\' + value.charAt(++i);
            break;

          case '|':  // allow | inside braces
            result += stopChar != ')' ? '\\|' : '|';
            break;

          case '(':  // optional: (something) -> (?:something)?
            if (res = parse(i + 1, ')'))
            {
              i = res.offset;
              result += '(?:' + res.result + ')?';
            }
            else
            {
              result += '\\(';
            }

            break;

          case ':':  // named:   :name -> ([^/]+)
            if (res = findWord(i + 1))
            {
              i += res[0].length;
              result += '([^\/]+)';
              params.push(res[0]);
            }
            else
            {
              result += ':';
            }

            break;

          case '*':  // splat:   *name -> (.*?)
            if (res = findWord(i + 1))
            {
              i += res[0].length;
              result += '(.*?)';
              params.push(res[0]);
            }
            else
            {
              result += '\\*';
            }

            break;

          default:
            result += basis.string.forRegExp(c);
        }
      }

      return stopChar ? null : result;
    }

    var regexp = new RegExp('^' + parse(0) + '$', 'i');
    regexp.params = params;
    return regexp;
  }

  function startWatch(){
    if (eventSupport)
      eventUtils.addHandler(global, 'hashchange', checkUrl);
    else
      timer = setInterval(checkUrl, CHECK_INTERVAL);
  }
  function stopWatch(){
    if (eventSupport)
      eventUtils.removeHandler(global, 'hashchange', checkUrl);
    else
      clearInterval(timer);
  }

 /**
  * Start router
  */
  function start(){
    if (!started)
    {
      startWatch();
      started = true;

      /** @cut */ if (module.exports.debug)
      /** @cut */   basis.dev.log(namespace + ' started');

      checkUrl();
    }
  }

 /**
  * Stop router
  */
  function stop(){
    if (started)
    {
      stopWatch();
      started = false;

      /** @cut */ if (module.exports.debug)
      /** @cut */   basis.dev.log(namespace + ' stopped');
    }
  }

 /**
  * Process current location
  */
  function checkUrl(){
    var newPath = location.hash.substr(1) || '';

    if (newPath != currentPath)
    {
      var inserted = [];
      var deleted = [];
      /** @cut */ var log = [];

      currentPath = newPath;

      for (var path in routes)
      {
        var route = routes[path];
        var match = newPath.match(route.regexp);

        if (match)
        {
          if (!matched[path])
            inserted.push(route);

          match = arrayFrom(match, 1);
          matched[path] = match;
        }
        else
        {
          if (matched[path])
          {
            deleted.push(route);
            delete matched[path];
            route.token.set(null);
          }
        }
      }

      // callback off for previous matched
      for (var i = 0, route; route = deleted[i]; i++)
      {
        var callbacks = arrayFrom(route.callbacks);
        for (var j = 0, item; item = callbacks[j]; j++)
          if (item.callback.leave)
          {
            item.callback.leave.call(item.context);
            /** @cut */ log.push('\n', { type: 'leave', path: route.id, cb: item, route: route });
          }
      }

      // callback off for previous matched
      for (var i = 0, route; route = inserted[i]; i++)
      {
        var callbacks = arrayFrom(route.callbacks);
        for (var j = 0, item; item = callbacks[j]; j++)
          if (item.callback.enter)
          {
            item.callback.enter.call(item.context);
            /** @cut */ log.push('\n', { type: 'enter', path: route.id, cb: item, route: route });
          }
      }

      // callback for matched
      for (var path in matched)
      {
        var route = routes[path];
        var args = matched[path];
        var callbacks = arrayFrom(route.callbacks);

        for (var i = 0, item; item = callbacks[i]; i++)
          if (item.callback.match)
          {
            item.callback.match.apply(item.context, args);
            /** @cut */ log.push('\n', { type: 'match', path: route.id, cb: item, route: route, args: args });
          }

        route.token.set(args);
      }

      /** @cut */ if (module.exports.debug)
      /** @cut */   basis.dev.info.apply(basis.dev, [namespace + ': hash changed to "' + newPath + '"'].concat(log.length ? log : '\n<no matches>'));
    }
  }

 /**
  * Returns route
  */
  function get(path, autocreate){
    var route = path instanceof Route ? path : routes[path];

    if (!route && autocreate)
    {
      var regexp = Object.prototype.toString.call(path) == '[object RegExp]'
        ? path
        : pathToRegExp(path);

      route = routes[path] = {
        id: path,
        callbacks: [],
        token: new Route(regexp.params),
        regexp: regexp
      };

      if (typeof currentPath == 'string')
      {
        var match = currentPath.match(route.regexp);
        if (match)
        {
          match = arrayFrom(match, 1);
          matched[path] = match;
          route.token.set(match);
        }
      }
    }

    return route;
  }

 /**
  * Add path to be handled
  */
  function add(path, callback, context){
    var route = get(path, true);
    var config;
    /** @cut */ var log = [];

    config = {
      cb_: callback,
      context: context,
      callback: typeof callback != 'function' ? callback || {} : {
        match: callback
      }
    };

    route.callbacks.push(config);

    if (route.id in matched)
    {
      if (config.callback.enter)
      {
        config.callback.enter.call(context);
        /** @cut */ log.push('\n', { type: 'enter', path: route.id, cb: config, route: route });
      }

      if (config.callback.match)
      {
        config.callback.match.apply(context, matched[path]);
        /** @cut */ log.push('\n', { type: 'match', path: route.id, cb: config, route: route, args: matched[path] });
      }
    }

    /** @cut */ if (module.exports.debug)
    /** @cut */   basis.dev.info.apply(basis.dev, [namespace + ': add handler for route `' + path + '`'].concat(log.length ? log : '\n<no matches>'));

    return route.token;
  }

 /**
  * Remove handler for path
  */
  function remove(path, callback, context){
    var route = get(path);

    if (route)
    {
      for (var i = 0, cb; cb = route.callbacks[i]; i++)
        if (cb.cb_ === callback && cb.context === context)
        {
          var token = route.token;

          route.callbacks.splice(i, 1);

          if (!route.callbacks.length)
          {
            // check no attaches to route token
            if ((!token.handler || !token.handler.handler) && !token.matched.handler)
            {
              delete routes[route.id];
              delete matched[route.id];
            }
          }

          break;
        }
    }
  }

 /**
  * Navigate to specified path
  */
  function navigate(path, replace){
    if (replace)
      location.replace(location.pathname + '#' + path);
    else
      location.hash = path;

    if (started)
      checkUrl();
  }

  //
  // export names
  //

  module.exports = {
    debug: false,

    start: start,
    stop: stop,
    checkUrl: checkUrl,
    navigate: navigate,

    add: add,
    remove: remove,
    route: function(path){
      return get(path, true).token;
    }
  };
<commit_msg>basis.router: additional parameter for route function to get transformed value w/o as method<commit_after>
 /**
  * @namespace basis.router
  */

  var namespace = this.path;

  //
  // main part
  //

  var location = global.location;
  var document = global.document;
  var eventUtils = require('basis.dom.event');

  // documentMode logic from YUI to filter out IE8 Compat Mode which false positives
  var docMode = document.documentMode;
  var eventSupport = 'onhashchange' in global && (docMode === undefined || docMode > 7);

  var CHECK_INTERVAL = 50;

  var arrayFrom = basis.array.from;
  var routes = {};
  var matched = {};
  var started = false;
  var currentPath;
  var timer;

 /**
  * @class
  */
  var Route = basis.Token.subclass({
    className: namespace + '.Route',

    matched: null,
    params_: null,
    names_: null,

    init: function(names){
      basis.Token.prototype.init.call(this, null);

      this.matched = this.as(Boolean);
      this.names_ = Array.isArray(names) ? names : [];
      this.params_ = {};
    },
    param: function(nameOrIdx){
      var idx = typeof nameOrIdx == 'number' ? nameOrIdx : this.names_.indexOf(nameOrIdx);

      if (idx in this.params_ == false)
        this.params_[idx] = this.as(function(value){
          return value && value[idx];
        });

      return this.params_[idx];
    },
    set: function(value){
      if (value)
      {
        // make a copy of value, it also converts value to object (as value is array of matches)
        value = basis.object.slice(value);

        // extend object with named values
        for (var key in value)
          if (key in this.names_)
            value[this.names_[key]] = value[key];
      }

      basis.Token.prototype.set.call(this, value);
    }
  });

 /**
  * Convert string to regexp
  */
  function pathToRegExp(route){
    var value = String(route || '');
    var params = [];

    function findWord(offset){
      return value.substr(offset).match(/^\w+/);
    }

    function parse(offset, stopChar){
      var result = '';
      var res;

      for (var i = offset; i < value.length; i++)
      {
        var c = value.charAt(i);
        switch (c)
        {
          case stopChar:
            return {
              result: result,
              offset: i
            };

          case '\\':
            result += '\\' + value.charAt(++i);
            break;

          case '|':  // allow | inside braces
            result += stopChar != ')' ? '\\|' : '|';
            break;

          case '(':  // optional: (something) -> (?:something)?
            if (res = parse(i + 1, ')'))
            {
              i = res.offset;
              result += '(?:' + res.result + ')?';
            }
            else
            {
              result += '\\(';
            }

            break;

          case ':':  // named:   :name -> ([^/]+)
            if (res = findWord(i + 1))
            {
              i += res[0].length;
              result += '([^\/]+)';
              params.push(res[0]);
            }
            else
            {
              result += ':';
            }

            break;

          case '*':  // splat:   *name -> (.*?)
            if (res = findWord(i + 1))
            {
              i += res[0].length;
              result += '(.*?)';
              params.push(res[0]);
            }
            else
            {
              result += '\\*';
            }

            break;

          default:
            result += basis.string.forRegExp(c);
        }
      }

      return stopChar ? null : result;
    }

    var regexp = new RegExp('^' + parse(0) + '$', 'i');
    regexp.params = params;
    return regexp;
  }

  function startWatch(){
    if (eventSupport)
      eventUtils.addHandler(global, 'hashchange', checkUrl);
    else
      timer = setInterval(checkUrl, CHECK_INTERVAL);
  }
  function stopWatch(){
    if (eventSupport)
      eventUtils.removeHandler(global, 'hashchange', checkUrl);
    else
      clearInterval(timer);
  }

 /**
  * Start router
  */
  function start(){
    if (!started)
    {
      startWatch();
      started = true;

      /** @cut */ if (module.exports.debug)
      /** @cut */   basis.dev.log(namespace + ' started');

      checkUrl();
    }
  }

 /**
  * Stop router
  */
  function stop(){
    if (started)
    {
      stopWatch();
      started = false;

      /** @cut */ if (module.exports.debug)
      /** @cut */   basis.dev.log(namespace + ' stopped');
    }
  }

 /**
  * Process current location
  */
  function checkUrl(){
    var newPath = location.hash.substr(1) || '';

    if (newPath != currentPath)
    {
      var inserted = [];
      var deleted = [];
      /** @cut */ var log = [];

      currentPath = newPath;

      for (var path in routes)
      {
        var route = routes[path];
        var match = newPath.match(route.regexp);

        if (match)
        {
          if (!matched[path])
            inserted.push(route);

          match = arrayFrom(match, 1);
          matched[path] = match;
        }
        else
        {
          if (matched[path])
          {
            deleted.push(route);
            delete matched[path];
            route.token.set(null);
          }
        }
      }

      // callback off for previous matched
      for (var i = 0, route; route = deleted[i]; i++)
      {
        var callbacks = arrayFrom(route.callbacks);
        for (var j = 0, item; item = callbacks[j]; j++)
          if (item.callback.leave)
          {
            item.callback.leave.call(item.context);
            /** @cut */ log.push('\n', { type: 'leave', path: route.id, cb: item, route: route });
          }
      }

      // callback off for previous matched
      for (var i = 0, route; route = inserted[i]; i++)
      {
        var callbacks = arrayFrom(route.callbacks);
        for (var j = 0, item; item = callbacks[j]; j++)
          if (item.callback.enter)
          {
            item.callback.enter.call(item.context);
            /** @cut */ log.push('\n', { type: 'enter', path: route.id, cb: item, route: route });
          }
      }

      // callback for matched
      for (var path in matched)
      {
        var route = routes[path];
        var args = matched[path];
        var callbacks = arrayFrom(route.callbacks);

        for (var i = 0, item; item = callbacks[i]; i++)
          if (item.callback.match)
          {
            item.callback.match.apply(item.context, args);
            /** @cut */ log.push('\n', { type: 'match', path: route.id, cb: item, route: route, args: args });
          }

        route.token.set(args);
      }

      /** @cut */ if (module.exports.debug)
      /** @cut */   basis.dev.info.apply(basis.dev, [namespace + ': hash changed to "' + newPath + '"'].concat(log.length ? log : '\n<no matches>'));
    }
  }

 /**
  * Returns route
  */
  function get(path, autocreate){
    var route = path instanceof Route ? path : routes[path];

    if (!route && autocreate)
    {
      var regexp = Object.prototype.toString.call(path) == '[object RegExp]'
        ? path
        : pathToRegExp(path);

      route = routes[path] = {
        id: path,
        callbacks: [],
        token: new Route(regexp.params),
        regexp: regexp
      };

      if (typeof currentPath == 'string')
      {
        var match = currentPath.match(route.regexp);
        if (match)
        {
          match = arrayFrom(match, 1);
          matched[path] = match;
          route.token.set(match);
        }
      }
    }

    return route;
  }

 /**
  * Add path to be handled
  */
  function add(path, callback, context){
    var route = get(path, true);
    var config;
    /** @cut */ var log = [];

    config = {
      cb_: callback,
      context: context,
      callback: typeof callback != 'function' ? callback || {} : {
        match: callback
      }
    };

    route.callbacks.push(config);

    if (route.id in matched)
    {
      if (config.callback.enter)
      {
        config.callback.enter.call(context);
        /** @cut */ log.push('\n', { type: 'enter', path: route.id, cb: config, route: route });
      }

      if (config.callback.match)
      {
        config.callback.match.apply(context, matched[path]);
        /** @cut */ log.push('\n', { type: 'match', path: route.id, cb: config, route: route, args: matched[path] });
      }
    }

    /** @cut */ if (module.exports.debug)
    /** @cut */   basis.dev.info.apply(basis.dev, [namespace + ': add handler for route `' + path + '`'].concat(log.length ? log : '\n<no matches>'));

    return route.token;
  }

 /**
  * Remove handler for path
  */
  function remove(path, callback, context){
    var route = get(path);

    if (route)
    {
      for (var i = 0, cb; cb = route.callbacks[i]; i++)
        if (cb.cb_ === callback && cb.context === context)
        {
          var token = route.token;

          route.callbacks.splice(i, 1);

          if (!route.callbacks.length)
          {
            // check no attaches to route token
            if ((!token.handler || !token.handler.handler) && !token.matched.handler)
            {
              delete routes[route.id];
              delete matched[route.id];
            }
          }

          break;
        }
    }
  }

 /**
  * Navigate to specified path
  */
  function navigate(path, replace){
    if (replace)
      location.replace(location.pathname + '#' + path);
    else
      location.hash = path;

    if (started)
      checkUrl();
  }

  //
  // export names
  //

  module.exports = {
    debug: false,

    start: start,
    stop: stop,
    checkUrl: checkUrl,
    navigate: navigate,

    add: add,
    remove: remove,
    route: function(path, transformer){
      var route = get(path, true).token;
      return transformer
        ? route.as(transformer)
        : route;
    }
  };
<|endoftext|>


<commit_before>/**
 * WordPress dependencies
 */
import { visitAdminPage } from '@wordpress/e2e-test-utils';

describe( 'Site Kit set up flow for the first time', () => {
	it( 'renders a splash page for proxy set up when no GCP credentials are provided', async () => {
		await visitAdminPage( 'admin.php', 'page=googlesitekit-splash' );

		await page.waitForSelector( '.googlesitekit-start-setup' );

		await expect( page ).toMatchElement( '.googlesitekit-setup__title', { text: 'Sign in with Google to set up Site Kit' } );
		await expect( page ).toMatchElement( '.googlesitekit-start-setup', { text: 'Start setup' } );
		await expect( page ).toMatchElement( '.googlesitekit-start-setup', { href: /^https:\/\/sitekit.withgoogle.com\/site-management\/setup\/\?/i } );
	} );
} );

<commit_msg>Update e2e tests for splash screen.<commit_after>/**
 * WordPress dependencies
 */
import { visitAdminPage } from '@wordpress/e2e-test-utils';

describe( 'Site Kit set up flow for the first time', () => {
	it( 'renders a splash page for proxy set up when no GCP credentials are provided', async () => {
		await visitAdminPage( 'admin.php', 'page=googlesitekit-splash' );

		await page.waitForSelector( '.googlesitekit-start-setup' );

		await expect( page ).toMatchElement( '.googlesitekit-setup__title', { text: 'Set up Site Kit' } );
		await expect( page ).toMatchElement( '.googlesitekit-start-setup', { text: 'Sign in with Google' } );
		await expect( page ).toMatchElement( '.googlesitekit-start-setup', { href: /^https:\/\/sitekit.withgoogle.com\/site-management\/setup\/\?/i } );
	} );
} );

<|endoftext|>


<commit_before>'use strict';

describe('test.partial.js', function () {
  beforeEach(function () {
    const write = context.db.bulkDocs({ docs: [
      { _id: 'a', type: 'x', hello: 'world' },
      { _id: 'a', type: 'y', hello: 'world' }
    ]});
    const index = context.db.createIndex({
      index: {
        fields: ['hello'],
        partial_filter_selector: { type: 'x' }
      },
      ddoc: 'test-partial',
      name: 'type-x'
    });
    return Promise.all([write, index]);
  });
  it('should apply the partial filter', function () {
    return context.db.find({
      selector: { hello: 'world' },
      use_index: ['_design/test-partial', 'type-x']
    }).then(function (result) {
      result.docs.should.have.length(1);
      const [{ _id: id, type, hello }] = result.docs;
      id.should.equal('a');
      type.should.equal('x');
      hello.should.equal('world');
    });
  });
});
<commit_msg>test(#8522): add failing test for partial index<commit_after>'use strict';

describe('test.partial.js', function () {
  beforeEach(function () {
    const write = context.db.bulkDocs({ docs: [
      { _id: 'a', type: 'x', hello: 'world' },
      { _id: 'b', type: 'y', hello: 'world' }
    ]});
    const index = context.db.createIndex({
      index: {
        fields: ['hello'],
        partial_filter_selector: { type: 'x' }
      },
      ddoc: 'test-partial',
      name: 'type-x'
    });
    return Promise.all([write, index]);
  });

  it('should write the partial filter to the ddoc', function () {
    return context.db.get('_design/test-partial').then(function (result) {
      const map = result.views['type-x'].map;
      map.should.have.property('partial_filter_selector');
      map.partial_filter_selector.should.deep.equal({
        type: {
          '$eq': 'x'
        }
      });
    });
  });

  it('should apply the partial filter', function () {
    return context.db.find({
      selector: { hello: 'world' },
      use_index: ['_design/test-partial', 'type-x']
    }).then(function (result) {
      result.docs.should.have.length(1);
      const [{ _id: id, type, hello }] = result.docs;
      id.should.equal('a');
      type.should.equal('x');
      hello.should.equal('world');
    });
  });
});
<|endoftext|>


<commit_before>/* @flow */
import * as Constants from '../constants/devices'
import {devicesTab, loginTab} from '../constants/tabs'
import engine from '../engine'
import {navigateBack, navigateTo, switchTab} from './router'
import type {AsyncAction} from '../constants/types/flux'
import type {incomingCallMapType, login_deprovision_rpc, revoke_revokeDevice_rpc, device_deviceHistoryList_rpc, login_paperKey_rpc} from '../constants/types/flow-types'
import {setRevokedSelf} from './login'

export function loadDevices () : AsyncAction {
  return function (dispatch) {
    dispatch({
      type: Constants.loadingDevices,
      payload: null
    })

    const params : device_deviceHistoryList_rpc = {
      method: 'device.deviceHistoryList',
      param: {},
      incomingCallMap: {},
      callback: (error, devices) => {
        // Flow is weird here, we have to give it true or false directly instead of just giving it !!error
        if (error) {
          dispatch({
            type: Constants.showDevices,
            payload: error,
            error: true
          })
        } else {
          dispatch({
            type: Constants.showDevices,
            payload: devices,
            error: false
          })
        }
        // dispatch()
      }
    }

    engine.rpc(params)
  }
}

export function generatePaperKey () : AsyncAction {
  return function (dispatch) {
    dispatch({
      type: Constants.paperKeyLoading,
      payload: null
    })

    const incomingMap : incomingCallMapType = {
      'keybase.1.loginUi.promptRevokePaperKeys': (param, response) => {
        response.result(false)
      },
      'keybase.1.secretUi.getPassphrase': (param, response) => {
        console.log(param)
      },
      'keybase.1.loginUi.displayPaperKeyPhrase': ({phrase: paperKey}, response) => {
        dispatch({
          type: Constants.paperKeyLoaded,
          payload: paperKey
        })
        response.result()
      }
    }

    const params : login_paperKey_rpc = {
      method: 'login.paperKey',
      param: {},
      incomingCallMap: incomingMap,
      callback: (error, paperKey) => {
        if (error) {
          dispatch({
            type: Constants.paperKeyLoaded,
            payload: error,
            error: true
          })
        }
      }
    }

    engine.rpc(params)
  }
}

export function removeDevice (deviceID: string, name: string, currentDevice: boolean): AsyncAction {
  return (dispatch, getState) => {
    if (currentDevice) {
      // Revoking the current device uses the "deprovision" RPC instead.
      const username = getState().config.username
      if (!username) {
        console.warn('No username in removeDevice')
        return
      }
      const params: login_deprovision_rpc = {
        method: 'login.deprovision',
        param: {username, doRevoke: true},
        incomingCallMap: {},
        callback: error => {
          dispatch({
            type: Constants.deviceRemoved,
            payload: error,
            error: !!error
          })
          if (!error) {
            dispatch(loadDevices())
            dispatch(setRevokedSelf(name))
            dispatch(navigateTo('', loginTab))
            dispatch(switchTab(loginTab))
          }
        }
      }
      engine.rpc(params)
    } else {
      const params: revoke_revokeDevice_rpc = {
        method: 'revoke.revokeDevice',
        param: {deviceID, force: false},
        incomingCallMap: {},
        callback: error => {
          dispatch({
            type: Constants.deviceRemoved,
            payload: error,
            error: !!error
          })
          if (!error) {
            dispatch(loadDevices())
            dispatch(navigateBack(devicesTab))
          }
        }
      }
      engine.rpc(params)
    }
  }
}
<commit_msg>Go all the way back to the refreshed devices list after a revoke<commit_after>/* @flow */
import * as Constants from '../constants/devices'
import {devicesTab, loginTab} from '../constants/tabs'
import engine from '../engine'
import {navigateBack, navigateTo, navigateUp, switchTab} from './router'
import Immutable from 'immutable'
import type {AsyncAction} from '../constants/types/flux'
import type {incomingCallMapType, login_deprovision_rpc, revoke_revokeDevice_rpc, device_deviceHistoryList_rpc, login_paperKey_rpc} from '../constants/types/flow-types'
import {setRevokedSelf} from './login'

export function loadDevices () : AsyncAction {
  return function (dispatch) {
    dispatch({
      type: Constants.loadingDevices,
      payload: null
    })

    const params : device_deviceHistoryList_rpc = {
      method: 'device.deviceHistoryList',
      param: {},
      incomingCallMap: {},
      callback: (error, devices) => {
        // Flow is weird here, we have to give it true or false directly instead of just giving it !!error
        if (error) {
          dispatch({
            type: Constants.showDevices,
            payload: error,
            error: true
          })
        } else {
          dispatch({
            type: Constants.showDevices,
            payload: devices,
            error: false
          })
        }
        // dispatch()
      }
    }

    engine.rpc(params)
  }
}

export function generatePaperKey () : AsyncAction {
  return function (dispatch) {
    dispatch({
      type: Constants.paperKeyLoading,
      payload: null
    })

    const incomingMap : incomingCallMapType = {
      'keybase.1.loginUi.promptRevokePaperKeys': (param, response) => {
        response.result(false)
      },
      'keybase.1.secretUi.getPassphrase': (param, response) => {
        console.log(param)
      },
      'keybase.1.loginUi.displayPaperKeyPhrase': ({phrase: paperKey}, response) => {
        dispatch({
          type: Constants.paperKeyLoaded,
          payload: paperKey
        })
        response.result()
      }
    }

    const params : login_paperKey_rpc = {
      method: 'login.paperKey',
      param: {},
      incomingCallMap: incomingMap,
      callback: (error, paperKey) => {
        if (error) {
          dispatch({
            type: Constants.paperKeyLoaded,
            payload: error,
            error: true
          })
        }
      }
    }

    engine.rpc(params)
  }
}

export function removeDevice (deviceID: string, name: string, currentDevice: boolean): AsyncAction {
  return (dispatch, getState) => {
    if (currentDevice) {
      // Revoking the current device uses the "deprovision" RPC instead.
      const username = getState().config.username
      if (!username) {
        console.warn('No username in removeDevice')
        return
      }
      const params: login_deprovision_rpc = {
        method: 'login.deprovision',
        param: {username, doRevoke: true},
        incomingCallMap: {},
        callback: error => {
          dispatch({
            type: Constants.deviceRemoved,
            payload: error,
            error: !!error
          })
          if (!error) {
            dispatch(loadDevices())
            dispatch(setRevokedSelf(name))
            dispatch(navigateTo('', loginTab))
            dispatch(switchTab(loginTab))
          }
        }
      }
      engine.rpc(params)
    } else {
      const params: revoke_revokeDevice_rpc = {
        method: 'revoke.revokeDevice',
        param: {deviceID, force: false},
        incomingCallMap: {},
        callback: error => {
          dispatch({
            type: Constants.deviceRemoved,
            payload: error,
            error: !!error
          })
          if (!error) {
            dispatch(loadDevices())
            dispatch(navigateUp(devicesTab, Immutable.Map({path: 'root'})))
          }
        }
      }
      engine.rpc(params)
    }
  }
}
<|endoftext|>


<commit_before>angular.module('run.controller', [])

.controller('RunController', function($scope, $timeout, $location, Geo){
  $scope.raceStarted = 0;
  $scope.startTime;
  $scope.userLocation;
  $scope.destination;

  var tick = function() {
    $scope.time = Math.floor((Date.now() - $scope.startTime)/1000);
    $timeout(tick, 100)
  }

  $scope.startRun = function() {
    $scope.startTime = Date.now();
    $scope.raceStarted = true;
    tick();
  }

  $scope.currentCoords = {
    lat: null,
    lng: null
  };
  // $scope.getCurrentCoords = function() {
  //   console.log('ran');
  //   Geo.getCurrentCoords(function(coordsObj) {
  //     $scope.currentCoords = coordsObj;
  //     console.log('$scope.currentCoords.lat: ', $scope.currentCoords.lat);
  //     console.log('$scope.currentCoords.lng: ', $scope.currentCoords.lng);
  //   });
  // };

  $scope.makeInitialMap = function($scope) {
    console.log('in controller');
    Geo.makeInitialMap($scope);
  };

  $scope.makeInitialMap($scope);

  $scope.updateCurrentPosition = function($scope, $location) {
    Geo.updateCurrentPosition($scope);
    $scope.checkIfFinished($location);
  };

  $scope.checkIfFinished = function($location) {
    if ($scope.destination && $scope.userLocation) {
      var currLat = $scope.destination.lat;
      var currLng = $scope.destination.lng;
      var destLat = $scope.userLocation.lat;
      var destLng = $scope.userLocation.lng;
      var distRemaining = Math.sqrt(Math.pow((currLat - destLat), 2) + Math.pow((currLng - destLng) , 2));

      if (distRemaining < 0.0008) {
        $location.path('/finish');
        clearInterval($scope.geoUpdater);
      }
    }
  }

  // Determine user location and update map each second

  $scope.geoUpdater = setInterval(function() {$scope.updateCurrentPosition($scope, $location)}, 1000);

  // Stop geotracker upon canceling run
  $scope.stopGeoUpdater = function() {
    clearInterval($scope.geoUpdater);
  };
})
<commit_msg>Tighten up success radius and fix userLocation/destination<commit_after>angular.module('run.controller', [])

.controller('RunController', function($scope, $timeout, $location, Geo){
  $scope.raceStarted = 0;
  $scope.startTime;
  $scope.userLocation;
  $scope.destination;

  var tick = function() {
    $scope.time = Math.floor((Date.now() - $scope.startTime)/1000);
    $timeout(tick, 100)
  }

  $scope.startRun = function() {
    $scope.startTime = Date.now();
    $scope.raceStarted = true;
    tick();
  }

  // $scope.getCurrentCoords = function() {
  //   console.log('ran');
  //   Geo.getCurrentCoords(function(coordsObj) {
  //     $scope.currentCoords = coordsObj;
  //     console.log('$scope.currentCoords.lat: ', $scope.currentCoords.lat);
  //     console.log('$scope.currentCoords.lng: ', $scope.currentCoords.lng);
  //   });
  // };

  $scope.makeInitialMap = function($scope) {
    Geo.makeInitialMap($scope);
  };

  $scope.makeInitialMap($scope);

  $scope.updateCurrentPosition = function($scope, $location) {
    Geo.updateCurrentPosition($scope);
    $scope.checkIfFinished($location);
  };

  $scope.checkIfFinished = function($location) {
    if ($scope.destination && $scope.userLocation) {
      var currLat = $scope.userLocation.lat;
      var currLng = $scope.userLocation.lng;
      var destLat = $scope.destination.lat;
      var destLng = $scope.destination.lng;
      var distRemaining = Math.sqrt(Math.pow((currLat - destLat), 2) + Math.pow((currLng - destLng) , 2));

      if (distRemaining < 0.0004) {
        $location.path('/finish');
        clearInterval($scope.geoUpdater);
      }
    }
  }

  // Determine user location and update map each second

  $scope.geoUpdater = setInterval(function() {$scope.updateCurrentPosition($scope, $location)}, 1000);

  // Stop geotracker upon canceling run
  $scope.stopGeoUpdater = function() {
    clearInterval($scope.geoUpdater);
  };
})
<|endoftext|>


<commit_before>(function() {
  'use strict';

  angular.module('app.services')
    .factory('Language', LanguageFactory);

  /** @ngInject */
  function LanguageFactory($http, $q, gettextCatalog, lodash) {
    var availableAvailable = $q.defer();
    var service = {
      available: {
        'en': 'English',  // not translated on purpose
      },
      ready: availableAvailable.promise,
      browser: browser,
      onLogin: onLogin,
      onReload: onReload,
      chosen: {
        code: null,
      },
      save: save,
      user_href: null,
      setLocale: setLocale,
    };

    init();

    return service;

    function init() {
      $http.get('gettext/json/available_languages.json')
      .then(function(response) {
        lodash.extend(service.available, response.data);
        availableAvailable.resolve(service.available);
      });
    }

    // returns a list of user's preferred languages, in order
    function browser() {
      var ary = [];

      // the standard
      if (lodash.isArray(window.navigator.languages)) {
        ary = lodash.slice(window.navigator.languages);
      }

      // IE 11 and older browers
      if (window.navigator.language) {
        ary.push(window.navigator.language);
      }

      // IE<11
      if (window.navigator.userLanguage) {
        ary.push(window.navigator.userLanguage);
      }

      return lodash.uniq(ary);
    }

    function setLocale(code) {
      gettextCatalog.loadAndSet(code);

      return code;
    }

    function getLocale(data) {
      return data
        && data.settings
        && data.settings.ui_self_service
        && data.settings.ui_self_service.display
        && data.settings.ui_self_service.display.locale;
    }

    function setUser(data) {
      service.user_href = data.identity.user_href.replace(/^.*?\/api\//, '/api/');
    }

    function onLogin(data) {
      setUser(data);

      var code = 'en';
      if (!service.chosen.code || (service.chosen.code === '_user_')) {
        code = getLocale(data);
      } else {
        code = service.chosen.code;
        save(code);
      }

      setLocale(code);
    }

    function onReload(data) {
      setUser(data);

      var code = getLocale(data);
      setLocale(code);
    }

    function save(code) {
      if (!service.user_href) {
        console.error('Trying to save language selection without a valid user_href');

        return;
      }

      if (code === '_browser_') {
        code = null;
      }

      return $http.post(service.user_href, {
        action: 'edit',
        resource: {
          settings: {
            ui_self_service: {
              display: {
                locale: code,
              },
            },
          },
        },
      });
    }
  }
})();
<commit_msg>Language.match - use to match browser preference and available languages for Browser Default<commit_after>(function() {
  'use strict';

  angular.module('app.services')
    .factory('Language', LanguageFactory);

  /** @ngInject */
  function LanguageFactory($http, $q, gettextCatalog, lodash) {
    var availableAvailable = $q.defer();
    var service = {
      available: {
        'en': 'English',  // not translated on purpose
      },
      ready: availableAvailable.promise,
      browser: browser,
      onLogin: onLogin,
      onReload: onReload,
      chosen: {
        code: null,
      },
      save: save,
      match: match,
      user_href: null,
      setLocale: setLocale,
    };

    init();

    return service;

    function init() {
      $http.get('gettext/json/available_languages.json')
      .then(function(response) {
        lodash.extend(service.available, response.data);
        availableAvailable.resolve(service.available);
      });
    }

    // returns a list of user's preferred languages, in order
    function browser() {
      var ary = [];

      // the standard
      if (lodash.isArray(window.navigator.languages)) {
        ary = lodash.slice(window.navigator.languages);
      }

      // IE 11 and older browers
      if (window.navigator.language) {
        ary.push(window.navigator.language);
      }

      // IE<11
      if (window.navigator.userLanguage) {
        ary.push(window.navigator.userLanguage);
      }

      return lodash.uniq(ary);
    }

    function setLocale(code) {
      if (!code || (code === '_browser_')) {
        code = service.match(service.available, service.browser());
      }

      gettextCatalog.loadAndSet(code);

      return code;
    }

    function getLocale(data) {
      return data
        && data.settings
        && data.settings.ui_self_service
        && data.settings.ui_self_service.display
        && data.settings.ui_self_service.display.locale;
    }

    function setUser(data) {
      service.user_href = data.identity.user_href.replace(/^.*?\/api\//, '/api/');
    }

    function onLogin(data) {
      setUser(data);

      var code = 'en';
      if (!service.chosen.code || (service.chosen.code === '_user_')) {
        code = getLocale(data);
      } else {
        code = service.chosen.code;
        save(code);
      }

      setLocale(code);
    }

    function onReload(data) {
      setUser(data);

      var code = getLocale(data);
      setLocale(code);
    }

    function save(code) {
      if (!service.user_href) {
        console.error('Trying to save language selection without a valid user_href');

        return;
      }

      if (code === '_browser_') {
        code = null;
      }

      return $http.post(service.user_href, {
        action: 'edit',
        resource: {
          settings: {
            ui_self_service: {
              display: {
                locale: code,
              },
            },
          },
        },
      });
    }

    // returns the best match from available
    function match(available, requested) {
      var shorten = function(str) {
        return {
          orig: str,
          short: str.replace(/[-_].*$/, ''),
        };
      };

      var short = {
        available: lodash.keys(available).map(shorten),
        requested: requested.map(shorten),
      };

      for (var k in short.requested) {
        /* jshint -W089, -W083 */
        var r = short.requested[k];

        var match = lodash.find(short.available, function(a) {
          // try exact match first
          return a.orig.toLowerCase() === r.orig.toLowerCase();
        }) || lodash.find(short.available, function(a) {
          // lowercase, only language code match second
          return a.short.toLowerCase() === r.short.toLowerCase();
        });

        if (match) {
          return match.orig;
        }
      }

      return 'en';
    }
  }
})();
<|endoftext|>


<commit_before>/**
 * Created by justin on 2014-11-29.
 */

var
    StringStream = require('string-stream'),
    batcher = require('win-common')().batcher;

module.exports = function (bucketName, provider) {
  var s = {};
  provider = provider || new AWS.S3({params: {Bucket: bucketName}});

  // technically there is a way to promisfy all in one go, but as can be seen here
  // we do not want all the methods promisified...  (getObject for one...)
  // http://stackoverflow.com/questions/26475486/how-do-i-promisify-the-aws-javascript-sdk
  provider.deleteBucket = p.promisify(provider.deleteBucket);
  provider.createBucket = p.promisify(provider.createBucket);
  provider.putObject = p.promisify(provider.putObject);
  provider.listBuckets = p.promisify(provider.listBuckets);
  provider.deleteObjects = p.promisify(provider.deleteObjects);
  //provider.getObject = p.promisify(provider.getObject);

  s.destroy = function () {
    s.emptyBucket().then(function (test) {
      return provider.deleteBucket().then(function () {
        s._bucketName = null;
      });
    });
  };

  s.emptyBucket = function() {
    return s.ready().then(function () {
      return s.list()
    })
      .then(function (allObjects) {
        log('Deleting:', allObjects.length, 'objects from bucket:', bucketName);
        return p.all(batcher.chunk(allObjects, 1000, function (chunk) {
              return provider.deleteObjects({
                Delete: {
                  Objects: _.map(chunk, function (x) {
                    return {Key: x.Key}
                  })
                }
              });
            }
          )
        )
      })
  };

  s.ready = function () {
    if (s._bucketName) {
      return p.resolve(s._bucketName);
    }
    else if (s._async) {
      return s._async;
    }
    else {
      console.log('creating bucket...', bucketName);
      return s._async = provider.createBucket().then(function (data) {
        s._bucketName = bucketName;
        s._async = null;
      });
    }
  };

  s.write = function (params) {
    return s.ready().then(function () {
      var key = params.key || s.genKey(params.suffix);
      return provider.putObject({
        Key: key,
        Body: params.data
      }).then(function () {
        return key;
      });
    });
  };

  s.read = function (key) {
    return s.ready().then(function () {
      return provider.getObject({
        Key: key
      }).createReadStream();
    });
  };

  s.genKey = function (suffix) {
    return new Date().toISOString() + '-' + (suffix || Math.floor(Math.random() * 99999));
  };

  s.listBuckets = function () {
    return provider.listBuckets().then(function (data) {
      return data.Buckets;
    });
  };

  s.readString = function (key) {
    return s.read(key).then(function (fileStream) {
      var deferred = p.defer();
      var ss = new StringStream('');
      fileStream.pipe(ss);
      ss.on('end', function () {
        deferred.resolve(ss.toString());
      });
      fileStream.on('error', function (err) {
        deferred.resolve(err);
      });
      return deferred.promise;
    });
  };

  /**
   *
   * @param prefix Only download files that start with this prefix
   * @param marker Only download files after this file (the same thing as s3 api marker.)
   * @returns {*}
   */
  s.list = function (prefix, marker) {
    return s.ready().then(function () {
      return listAllObjects(prefix, marker);
    });
  };

  /***
   * Write the file to S3 if it doesnt already exist.  If file does exist, this does nothing and resolves.
   * @param filePath
   * @param key
   */
  s.writeFile = function(filePath, key) {
    return s.list(key).then(function(results) {
      if (!results || !results.length) {
        return s.write({
          data: fs.createReadStream(filePath),
          key: key
        });
      }
      return key;
    });
  };

  s.writeBlobs = function(blobs) {
    return p.map(blobs, function(blob) {
      return s.write(blob);
    });
  };

  s.readBlobs = function(blobs) {
    return p.map(blobs, function(key) {
      return s.readString(key);
    })
    .then(function(data) {
      return _.map(blobs, function(key, idx) {
        return {
          key: key,
          data: data[idx]
        };
      });
    });
  };

  function listAllObjects(prefix, marker) {
    var allKeys = [], deferred = p.defer();

    function listAllKeys(marker, prefix) {
      provider.listObjects({Prefix: prefix, Marker: marker}, function (err, data) {
        if (err) {
          deferred.reject(err);
          return;
        }
        allKeys.push(data.Contents);
        if (data.IsTruncated)
          listAllKeys(data.Contents.slice(-1)[0].Key, prefix);
        else
          deferred.resolve(_.flatten(allKeys));
      });
    }

    listAllKeys(marker, prefix);
    return deferred.promise;
  }

  return s;
};

<commit_msg>Added maxCount param to storage.list() API.<commit_after>/**
 * Created by justin on 2014-11-29.
 */

var
    StringStream = require('string-stream'),
    batcher = require('win-common')().batcher;

module.exports = function (bucketName, provider) {
  var s = {};
  provider = provider || new AWS.S3({params: {Bucket: bucketName}});

  // technically there is a way to promisfy all in one go, but as can be seen here
  // we do not want all the methods promisified...  (getObject for one...)
  // http://stackoverflow.com/questions/26475486/how-do-i-promisify-the-aws-javascript-sdk
  provider.deleteBucket = p.promisify(provider.deleteBucket);
  provider.createBucket = p.promisify(provider.createBucket);
  provider.putObject = p.promisify(provider.putObject);
  provider.listBuckets = p.promisify(provider.listBuckets);
  provider.deleteObjects = p.promisify(provider.deleteObjects);
  //provider.getObject = p.promisify(provider.getObject);

  s.destroy = function () {
    s.emptyBucket().then(function (test) {
      return provider.deleteBucket().then(function () {
        s._bucketName = null;
      });
    });
  };

  s.emptyBucket = function() {
    return s.ready().then(function () {
      return s.list()
    })
    .then(function (allObjects) {
      log('Deleting:', allObjects.length, 'objects from bucket:', bucketName);
      return p.all(batcher.chunk(allObjects, 1000, function (chunk) {
            return provider.deleteObjects({
              Delete: {
                Objects: _.map(chunk, function (x) {
                  return {Key: x.Key}
                })
              }
            });
          }
        )
      )
    })
  };

  s.ready = function () {
    if (s._bucketName) {
      return p.resolve(s._bucketName);
    }
    else if (s._async) {
      return s._async;
    }
    else {
      console.log('creating bucket...', bucketName);
      return s._async = provider.createBucket().then(function (data) {
        s._bucketName = bucketName;
        s._async = null;
      });
    }
  };

  s.write = function (params) {
    return s.ready().then(function () {
      var key = params.key || s.genKey(params.suffix);
      return provider.putObject({
        Key: key,
        Body: params.data
      }).then(function () {
        return key;
      });
    });
  };

  s.read = function (key) {
    return s.ready().then(function () {
      return provider.getObject({
        Key: key
      }).createReadStream();
    });
  };

  s.genKey = function (suffix) {
    return new Date().toISOString() + '-' + (suffix || Math.floor(Math.random() * 99999));
  };

  s.listBuckets = function () {
    return provider.listBuckets().then(function (data) {
      return data.Buckets;
    });
  };

  s.readString = function (key) {
    return s.read(key).then(function (fileStream) {
      var deferred = p.defer();
      var ss = new StringStream('');
      fileStream.pipe(ss);
      ss.on('end', function () {
        deferred.resolve(ss.toString());
      });
      fileStream.on('error', function (err) {
        deferred.resolve(err);
      });
      return deferred.promise;
    });
  };

  /**
   *
   * @param prefix Only download files that start with this prefix
   * @param marker Only download files after this file (the same thing as s3 api marker.)
   * @param maxCount Will only return up to this amount (it could exceed it by up to 999 at maximum, but no more.)
   * @returns {*}
   */
  s.list = function (prefix, marker, maxCount) {
    return s.ready().then(function () {
      return listAllObjects(prefix, marker, maxCount);
    });
  };

  /***
   * Write the file to S3 if it doesnt already exist.  If file does exist, this does nothing and resolves.
   * @param filePath
   * @param key
   */
  s.writeFile = function(filePath, key) {
    return s.list(key).then(function(results) {
      if (!results || !results.length) {
        return s.write({
          data: fs.createReadStream(filePath),
          key: key
        });
      }
      return key;
    });
  };

  s.writeBlobs = function(blobs) {
    return p.map(blobs, function(blob) {
      return s.write(blob);
    });
  };

  s.readBlobs = function(blobs) {
    return p.map(blobs, function(key) {
      return s.readString(key);
    })
    .then(function(data) {
      return _.map(blobs, function(key, idx) {
        return {
          key: key,
          data: data[idx]
        };
      });
    });
  };

  function listAllObjects(prefix, marker, maxCount) {
    var allKeys = [], deferred = p.defer();
    maxCount = maxCount || 100000;

    function listAllKeys(marker, prefix) {
      provider.listObjects({Prefix: prefix, Marker: marker}, function (err, data) {
        if (err) {
          deferred.reject(err);
          return;
        }
        allKeys.push(data.Contents);
        if (data.IsTruncated && _.flatten(allKeys).length < maxCount)
          listAllKeys(data.Contents.slice(-1)[0].Key, prefix);
        else
          deferred.resolve(_.flatten(allKeys));
      });
    }

    listAllKeys(marker, prefix);
    return deferred.promise;
  }

  return s;
};

<|endoftext|>


<commit_before>'use strict';

angular.module('nightOwlApp')
  .service('userInfo', function () {
    // AngularJS will instantiate a singleton by calling "new" on this function
  });
<commit_msg>client: user-info: Implement service<commit_after>'use strict';

angular.module('nightOwlApp')
  .service('userInfo', function () {
    var userInfo = {};

    return userInfo;
  });
<|endoftext|>


<commit_before>define(["libs/sjcl", "cryptoWorker/minimalHelper"], function (sjcl, chelper) {
	"use strict";

	function transformSymData(data) {
		if (!data.key || !data.message) {
			throw new Error("need message and key!");
		}

		data.key = chelper.hex2bits(data.key);
	}

	function handleSym(data) {
		transformSymData(data);

		var config = {};
		if (data.iv) {
			config.iv = data.iv;
		}

		if (data.encrypt) {
			return sjcl.json._encrypt(data.key, data.message, config);
		} else {
			config.raw = 1;
			return sjcl.decrypt(data.key, data.message, config);
		}
	}

	function privKey(exponent, curve) {
		return new sjcl.ecc.ecdsa.secretKey(curve, exponent);
	}

	function sign(exponent, curve, toSign) {
		var privateKey = privKey(exponent, curve);

		toSign = chelper.hex2bits(toSign);

		return privateKey.sign(toSign);
	}

	function unKem(exponent, curve, tag) {
		var privateKey = privKey(exponent, curve);

		tag = chelper.hex2bits(tag);

		return privateKey.unkem(tag);
	}

	function publicKey(point, curve) {
		return new sjcl.ecc.ecdsa.publicKey(curve, point);
	}

	function verify(point, curve, hash, signature) {
		var pubKey = publicKey(point, curve);

		hash = chelper.hex2bits(hash);
		signature = chelper.hex2bits(signature);

		return pubKey.verify(hash, signature);
	}

	function kem(point, curve) {
		var pubKey = publicKey(point, curve);

		var keyData = pubKey.kem();
		return {
			key: chelper.bits2hex(keyData.key),
			tag: chelper.bits2hex(keyData.tag)
		};
	}

	function transformAsymData(data) {
		if (data.curve) {
			data.curve = chelper.getCurve(data.curve);
		}

		if (data.exponent) {
			data.exponent = new sjcl.bn(data.exponent);
		}

		if (data.point) {
			var x =	new data.curve.field(data.point.x);
			var y = new data.curve.field(data.point.y);
			data.point = new sjcl.ecc.point(data.curve, x, y);
		}
	}

	function handleHash(data) {
		var text = data.toHash;

		var i, h = new sjcl.hash.sha256(), PART = 8 * 50;
		for (i = 0; i < text.length / PART; i+= 1) {
			h.update(sjcl.codec.base64.toBits(text.substr(i*PART, PART)));
		}

		return chelper.bits2hex(h.finalize());
	}

	function handleAsym(data) {
		transformAsymData(data);

		var curve = data.curve;

		if (data.generate) {
			var crypt = data.crypt;
			if (crypt) {
				sjcl.ecc.elGamal.generateKeys(curve);
			} else {
				sjcl.ecc.ecdsa.generateKeys(curve);
			}
		} else {
			var action = data.action;

			switch(action) {
				case "sign":
					return sign(data.exponent, curve, data.toSign);
				case "decrypt":
					return unKem(action, data.exponent, curve, data.tag);
				case "verify":
					return verify(data.point, curve, data.hash, data.signature);
				case "kem":
					return kem(data.point, curve);
			}
		}
	}

	return function (event) {
		if (event.data.randomNumber) {
			sjcl.random.addEntropy(event.data.randomNumber, event.data.entropy, "adding entropy");
			return "entropy";
		}

		var asym = event.data.asym;
		var isHash = event.data.isHash;

		try {
			if (isHash) {
				return handleHash(event.data);
			}

			if (asym) {
				return handleAsym(event.data);
			}

			return handleSym(event.data);
		} catch (e) {
			return false;
		}
	};
});<commit_msg>do not encode and decode json.<commit_after>define(["libs/sjcl", "cryptoWorker/minimalHelper"], function (sjcl, chelper) {
	"use strict";

	function transformSymData(data) {
		if (!data.key || !data.message) {
			throw new Error("need message and key!");
		}

		data.key = chelper.hex2bits(data.key);
	}

	function handleSym(data) {
		transformSymData(data);

		var config = {};
		if (data.iv) {
			config.iv = data.iv;
		}

		if (data.encrypt) {
			return sjcl.json._encrypt(data.key, data.message, config);
		} else {
			config.raw = 1;
			return sjcl.json._decrypt(data.key, data.message, config);
		}
	}

	function privKey(exponent, curve) {
		return new sjcl.ecc.ecdsa.secretKey(curve, exponent);
	}

	function sign(exponent, curve, toSign) {
		var privateKey = privKey(exponent, curve);

		toSign = chelper.hex2bits(toSign);

		return privateKey.sign(toSign);
	}

	function unKem(exponent, curve, tag) {
		var privateKey = privKey(exponent, curve);

		tag = chelper.hex2bits(tag);

		return privateKey.unkem(tag);
	}

	function publicKey(point, curve) {
		return new sjcl.ecc.ecdsa.publicKey(curve, point);
	}

	function verify(point, curve, hash, signature) {
		var pubKey = publicKey(point, curve);

		hash = chelper.hex2bits(hash);
		signature = chelper.hex2bits(signature);

		return pubKey.verify(hash, signature);
	}

	function kem(point, curve) {
		var pubKey = publicKey(point, curve);

		var keyData = pubKey.kem();
		return {
			key: chelper.bits2hex(keyData.key),
			tag: chelper.bits2hex(keyData.tag)
		};
	}

	function transformAsymData(data) {
		if (data.curve) {
			data.curve = chelper.getCurve(data.curve);
		}

		if (data.exponent) {
			data.exponent = new sjcl.bn(data.exponent);
		}

		if (data.point) {
			var x =	new data.curve.field(data.point.x);
			var y = new data.curve.field(data.point.y);
			data.point = new sjcl.ecc.point(data.curve, x, y);
		}
	}

	function handleHash(data) {
		var text = data.toHash;

		var i, h = new sjcl.hash.sha256(), PART = 8 * 50;
		for (i = 0; i < text.length / PART; i+= 1) {
			h.update(sjcl.codec.base64.toBits(text.substr(i*PART, PART)));
		}

		return chelper.bits2hex(h.finalize());
	}

	function handleAsym(data) {
		transformAsymData(data);

		var curve = data.curve;

		if (data.generate) {
			var crypt = data.crypt;
			if (crypt) {
				sjcl.ecc.elGamal.generateKeys(curve);
			} else {
				sjcl.ecc.ecdsa.generateKeys(curve);
			}
		} else {
			var action = data.action;

			switch(action) {
				case "sign":
					return sign(data.exponent, curve, data.toSign);
				case "decrypt":
					return unKem(action, data.exponent, curve, data.tag);
				case "verify":
					return verify(data.point, curve, data.hash, data.signature);
				case "kem":
					return kem(data.point, curve);
			}
		}
	}

	return function (event) {
		if (event.data.randomNumber) {
			sjcl.random.addEntropy(event.data.randomNumber, event.data.entropy, "adding entropy");
			return "entropy";
		}

		var asym = event.data.asym;
		var isHash = event.data.isHash;

		try {
			if (isHash) {
				return handleHash(event.data);
			}

			if (asym) {
				return handleAsym(event.data);
			}

			return handleSym(event.data);
		} catch (e) {
			return false;
		}
	};
});<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
  CHECK_SESSION
} from '../../modules/Sign/actions';
import {
  FETCH_USER
} from '../../modules/Flass/User/UserActions';

const { shape, object, func, bool } = PropTypes;

const propTypes = {
  checkSession: func.isRequired,
  sessionValid: bool.isRequired
};
const defaultProps = {};

export default function(ComposedComponent) {
  class Authentication extends Component {
    static contextTypes = {
      router: shape({
        history: object.isRequired
      })
    };

    componentDidMount() {
      this.props.checkSession();
    }

    componentWillReceiveProps(nextProps) {
      if (!nextProps.sessionValid) {
        this.context.router.history.push('/user/login');
      }
    }

    render() {
      return <ComposedComponent { ...this.props } />;
    }
  }

  function mapStateToProps(state) {
    const { sessionValid } = state.sign;
    return { sessionValid };
  }

  function mapDispatchToProps(dispatch) {
    return bindActionCreators({
      checkSession: () => ({
        type: CHECK_SESSION
      }),
      fetchUser: () => ({
        type: FETCH_USER
      })
    }, dispatch);
  }

  Authentication.propTypes = propTypes;
  Authentication.defaultProps = defaultProps;

  return connect(mapStateToProps, mapDispatchToProps)(Authentication);
}
<commit_msg>세션 체크 버그 수정<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
  CHECK_SESSION
} from '../../modules/Sign/actions';
import {
  FETCH_USER
} from '../../modules/Flass/User/UserActions';

const { shape, object, func, bool } = PropTypes;

const propTypes = {
  checkSession: func.isRequired,
  sessionValid: bool.isRequired
};
const defaultProps = {};

export default function(ComposedComponent) {
  class Authentication extends Component {
    static contextTypes = {
      router: shape({
        history: object.isRequired
      })
    };

    componentWillMount() {
      const { sessionValid } = this.props;
      if (!sessionValid) {
        this.context.router.history.push('/user/login');
      }
    }

    componentDidMount() {
      this.props.checkSession();
    }

    componentWillReceiveProps(nextProps) {
      if (!nextProps.sessionValid) {
        this.context.router.history.push('/user/login');
      }
    }

    render() {
      return <ComposedComponent { ...this.props } />;
    }
  }

  function mapStateToProps(state) {
    const { sessionValid } = state.sign;
    return { sessionValid };
  }

  function mapDispatchToProps(dispatch) {
    return bindActionCreators({
      checkSession: () => ({
        type: CHECK_SESSION
      }),
      fetchUser: () => ({
        type: FETCH_USER
      })
    }, dispatch);
  }

  Authentication.propTypes = propTypes;
  Authentication.defaultProps = defaultProps;

  return connect(mapStateToProps, mapDispatchToProps)(Authentication);
}
<|endoftext|>


<commit_before>"use strict";
var MapController = function($scope, $location, analytics, config, mapTooltipFactory, navigation) {

	var MIN_TIME_BETWEEN_UPDATES = 100;

	var activeMarker = null;
	var defaultMarker = null;
	var hoverMarker = null;
	var lastMarkerUpdateTime = null;
	var socket = null;

	$scope.mapOptions = null;
	$scope.markers = [];

	$scope.markerActivate = function(marker) {
		activeMarker = mapTooltipFactory.create(marker);
		marker.setIcon(hoverMarker);
	};

	$scope.markerDeactivate = function(marker) {
		if (activeMarker) {
			activeMarker.destroy();
			activeMarker = null;
		}
		marker.setIcon(defaultMarker);
	};

	$scope.markerClicked = function(marker) {
		navigation.toEntry(marker.hikeData.string_id);
	};

	$scope.updateMarkers = function(event) {
		if (lastMarkerUpdateTime &&
				event.type !== "map-idle" &&
				event.timestamp - lastMarkerUpdateTime < MIN_TIME_BETWEEN_UPDATES) {
			// Recently updated, ignore this update request
			return;
		}

		lastMarkerUpdateTime = event.timestamp;
		var mapBounds = $scope.map.getBounds();
		var northEast = mapBounds.getNorthEast();
		var northEastLatLng = {
			latitude: northEast.lat(),
			longitude: northEast.lng()
		};
		var southWest = mapBounds.getSouthWest();
		var southWestLatLng = {
			latitude: southWest.lat(),
			longitude: southWest.lng()
		};
		socket.emit("get-hikes-in-bounds", { ne: northEastLatLng, sw: southWestLatLng });
	};

	var initIcons = function() {
		defaultMarker = {
			path: google.maps.SymbolPath.CIRCLE,
			fillOpacity: 1,
			fillColor: "#FF6262",
			strokeWeight: 1.0,
			scale: 4
		};
		hoverMarker = {
			path: google.maps.SymbolPath.CIRCLE,
			fillOpacity: 1,
			fillColor: "#FFFF33",
			strokeWeight: 1.0,
			scale: 5
		};
	};

	var initMapOptions = function() {
		// Default to a central view of the US
		var centerLatLng = new google.maps.LatLng(39.833333, -98.583333);
		var zoomLevel = 4;

		// If the url parameters lat / lng are set, zoom in there
		var urlParams = $location.search();
		var latString = urlParams.lat;
		var lngString = urlParams.lng;
		if ($.isNumeric(latString) && $.isNumeric(lngString)) {
			var lat = Number(latString);
			var lng = Number(lngString);
			centerLatLng = new google.maps.LatLng(lat, lng);
			zoomLevel = 12;
		}

		// else if we can guess the user's location, zoom into this location
		else if (google.loader.ClientLocation) {
			var clientLocation = google.loader.ClientLocation;
			centerLatLng = new google.maps.LatLng(clientLocation.latitude, clientLocation.longitude);
			zoomLevel = 7;
		}

		$scope.mapOptions = {
			zoom: zoomLevel,
			center: centerLatLng,
			mapTypeId: google.maps.MapTypeId.TERRAIN
		};
	};

	var initSocketIo = function() {
		socket = io.connect(config.socketIoPath);
		socket.on("get-hikes-in-bounds", function (data) {
			mergeMarkers(data);
		});
	};

	var compareLatLng = function(a, b) {
		if			(a.lat() < b.lat())		{	return -1;}
		else if (a.lat() > b.lat())		{	return 1;	}
		else if (a.lng() < b.lng())		{	return -1;}
		else if (a.lng() > b.lng())		{	return 1;	}
		else													{	return 0;	}
	};

	var mergeMarkers = function(newMarkers) {
		var i = 0;
		var j = 0;
		var mergedMarkers = [];
		while (i !== newMarkers.length || j !== $scope.markers.length) {
			var newLatLng = null;
			var oldMarker = null;
			var oldLatLng = null;

			if (i < newMarkers.length) {
				newLatLng = new google.maps.LatLng(newMarkers[i].latitude, newMarkers[i].longitude);
			}

			if (j < $scope.markers.length) {
				oldMarker = $scope.markers[j];
				oldLatLng = oldMarker.getPosition();
			}

			if (!oldLatLng || (newLatLng && compareLatLng(newLatLng, oldLatLng) < 0)) {
				// This is a brand new marker, add it
				var marker = new google.maps.Marker({
					icon: defaultMarker,
					map: $scope.map,
					position: newLatLng,
					hikeData: newMarkers[i]
				});
				mergedMarkers.push(marker);
				i++;
			} else if (!newLatLng || (oldLatLng && compareLatLng(newLatLng, oldLatLng) > 0)) {
				// The old marker is no longer in use, remove it
				oldMarker.setMap(null);
				j++;
			} else {
				// Use the existing marker
				mergedMarkers.push(oldMarker);
				i++;
				j++;
			}
		}
		$scope.markers = mergedMarkers;
	};

	// Init
	initIcons();
	initMapOptions();
	initSocketIo();
	$scope.htmlReady();
};

MapController.$inject = ["$scope", "$location", "analytics", "config", "mapTooltipFactory", "navigation"];<commit_msg>Delay rerendering of google maps marker and tooltip until mouse is surely moused out.<commit_after>"use strict";
var MapController = function($scope, $location, $timeout, analytics, config, mapTooltipFactory, navigation) {

	var MIN_TIME_BETWEEN_UPDATES = 100;

	var activeMarker = null;
	var defaultMarker = null;
	var hoverMarker = null;
	var lastMarkerUpdateTime = null;
	var socket = null;

	$scope.mapOptions = null;
	$scope.markers = [];

	$scope.markerActivate = function(marker) {
		var tooltip = mapTooltipFactory.create(marker)
		marker.tooltips.push(tooltip);
		marker.setIcon(hoverMarker);
	};

	$scope.markerDeactivate = function(marker) {
		$timeout(function() {
			var tooltip = marker.tooltips.pop();
			if (tooltip) {
				tooltip.destroy();
			}
			if (marker.tooltips.length === 0) {
				marker.setIcon(defaultMarker);
			}
		}, 200)
	};

	$scope.markerClicked = function(marker) {
		navigation.toEntry(marker.hikeData.string_id);
	};

	$scope.updateMarkers = function(event) {
		if (lastMarkerUpdateTime &&
				event.type !== "map-idle" &&
				event.timestamp - lastMarkerUpdateTime < MIN_TIME_BETWEEN_UPDATES) {
			// Recently updated, ignore this update request
			return;
		}

		lastMarkerUpdateTime = event.timestamp;
		var mapBounds = $scope.map.getBounds();
		var northEast = mapBounds.getNorthEast();
		var northEastLatLng = {
			latitude: northEast.lat(),
			longitude: northEast.lng()
		};
		var southWest = mapBounds.getSouthWest();
		var southWestLatLng = {
			latitude: southWest.lat(),
			longitude: southWest.lng()
		};
		socket.emit("get-hikes-in-bounds", { ne: northEastLatLng, sw: southWestLatLng });
	};

	var initIcons = function() {
		defaultMarker = {
			path: google.maps.SymbolPath.CIRCLE,
			fillOpacity: 1,
			fillColor: "#FF6262",
			strokeWeight: 1.0,
			scale: 4
		};
		hoverMarker = {
			path: google.maps.SymbolPath.CIRCLE,
			fillOpacity: 1,
			fillColor: "#FFFF33",
			strokeWeight: 1.0,
			scale: 5
		};
	};

	var initMapOptions = function() {
		// Default to a central view of the US
		var centerLatLng = new google.maps.LatLng(39.833333, -98.583333);
		var zoomLevel = 4;

		// If the url parameters lat / lng are set, zoom in there
		var urlParams = $location.search();
		var latString = urlParams.lat;
		var lngString = urlParams.lng;
		if ($.isNumeric(latString) && $.isNumeric(lngString)) {
			var lat = Number(latString);
			var lng = Number(lngString);
			centerLatLng = new google.maps.LatLng(lat, lng);
			zoomLevel = 12;
		}

		// else if we can guess the user's location, zoom into this location
		else if (google.loader.ClientLocation) {
			var clientLocation = google.loader.ClientLocation;
			centerLatLng = new google.maps.LatLng(clientLocation.latitude, clientLocation.longitude);
			zoomLevel = 7;
		}

		$scope.mapOptions = {
			zoom: zoomLevel,
			center: centerLatLng,
			mapTypeId: google.maps.MapTypeId.TERRAIN
		};
	};

	var initSocketIo = function() {
		socket = io.connect(config.socketIoPath);
		socket.on("get-hikes-in-bounds", function (data) {
			mergeMarkers(data);
		});
	};

	var compareLatLng = function(a, b) {
		if			(a.lat() < b.lat())		{	return -1;}
		else if (a.lat() > b.lat())		{	return 1;	}
		else if (a.lng() < b.lng())		{	return -1;}
		else if (a.lng() > b.lng())		{	return 1;	}
		else													{	return 0;	}
	};

	var mergeMarkers = function(newMarkers) {
		var i = 0;
		var j = 0;
		var mergedMarkers = [];
		while (i !== newMarkers.length || j !== $scope.markers.length) {
			var newLatLng = null;
			var oldMarker = null;
			var oldLatLng = null;

			if (i < newMarkers.length) {
				newLatLng = new google.maps.LatLng(newMarkers[i].latitude, newMarkers[i].longitude);
			}

			if (j < $scope.markers.length) {
				oldMarker = $scope.markers[j];
				oldLatLng = oldMarker.getPosition();
			}

			if (!oldLatLng || (newLatLng && compareLatLng(newLatLng, oldLatLng) < 0)) {
				// This is a brand new marker, add it
				var marker = new google.maps.Marker({
					icon: defaultMarker,
					map: $scope.map,
					position: newLatLng,
					hikeData: newMarkers[i],
					tooltips: []
				});
				mergedMarkers.push(marker);
				i++;
			} else if (!newLatLng || (oldLatLng && compareLatLng(newLatLng, oldLatLng) > 0)) {
				// The old marker is no longer in use, remove it
				oldMarker.setMap(null);
				j++;
			} else {
				// Use the existing marker
				mergedMarkers.push(oldMarker);
				i++;
				j++;
			}
		}
		$scope.markers = mergedMarkers;
	};

	// Init
	initIcons();
	initMapOptions();
	initSocketIo();
	$scope.htmlReady();
};

MapController.$inject = ["$scope", "$location", "$timeout", "analytics", "config", "mapTooltipFactory", "navigation"];<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Card, CardHeader, CardText } from 'material-ui/Card';
import IconButton from 'material-ui/IconButton';
import Clear from 'material-ui/svg-icons/content/clear';
import {
  propTypes as routerPropTypes,
  withRouter,
} from 'react-router-dom';

import {
  setDisplayMode,
  setComposeState,
} from '../actions/ui';
import { postListing, loadListings, updateListing } from '../actions/listings';
import { postSeek, loadSeeks } from '../actions/seeks';
import ComposeForm from '../components/ComposeForm';
import SeekComposeForm from '../components/SeekComposeForm';
import RedirectToCas from '../components/RedirectToCas';

const overlayStyle = {
  position: 'fixed',
  bottom: '0',
  zIndex: '99',
  right: '5%',
  width: '40vw',
  minWidth: '16rem',
};

const showStyle = {};
const hideStyle = { display: 'none' };

class ComposeOverlay extends Component {
  static propTypes = {
    ...routerPropTypes,
    dispatch: PropTypes.func.isRequired,
    history: PropTypes.shape({
      push: PropTypes.func.isRequired,
    }).isRequired,
    user: PropTypes.shape({
      loggedIn: PropTypes.bool.isRequired,
    }).isRequired,
    currentUserLoading: PropTypes.bool.isRequired,
    mode: PropTypes.string.isRequired,
    // eslint-disable-next-line react/forbid-prop-types
    refreshQuery: PropTypes.object,
  };

  static defaultProps = {
    refreshQuery: { query: '' },
  }

  state = {
    mode: this.props.mode,
    expanded: true,
  }

  handleRequestClose = event => this.props.dispatch(setComposeState(false))

  handleSubmitListing = (data) => {
    this.props.dispatch(postListing({
      ...data,
      price: data.price ? Math.round(parseFloat(data.price) * 100) : 0,
    }));
    this.props.dispatch(loadListings());
    this.props.history.push('/listings');
    this.handleRequestClose();
  }

  handleSubmitSeek = (data) => {
    this.props.dispatch(postSeek({
      ...data,
      price: data.price ? Math.round(parseFloat(data.price) * 100) : 0,
    }));
    this.props.dispatch(loadSeeks());
    this.props.history.push('/seeks');
    this.handleRequestClose();
  }

  handleEditListing = (data) => {
    this.props.dispatch(updateListing({
      ...data,
      price: data.price ? Math.round(parseFloat(data.price) * 100) : 0,
    }, this.props.refreshQuery));
    this.handleRequestClose();
  }

  handleToggle = (event, isInputChecked) => {
    this.props.dispatch(setDisplayMode(isInputChecked ? 'seeks' : 'listings'));
  }

  handleExpandChange = (expanded) => {
    this.setState({ expanded });
  }

  render() {
    if (!this.props.currentUserLoading && !this.props.user.loggedIn) {
      return <RedirectToCas />;
    }

    return (

        <Card expanded={this.state.expanded} onExpandChange={this.handleExpandChange}>
          <CardHeader title={this.props.isEdit ? 'Edit' : 'Compose'} actAsExpander>
            <IconButton
              onTouchTap={this.handleRequestClose}
              style={{ float: 'right', marginTop: '-15px', marginRight: '-15px' }}
            >
              <Clear />
            </IconButton>
          </CardHeader>
          <CardText style={this.state.expanded ? showStyle : hideStyle}>
            { (this.state.mode === 'listings') ?
              <ComposeForm
                onSubmit={this.props.isEdit ? this.handleEditListing : this.handleSubmitListing}
                initialValues={
                  this.props.isEdit ?
                  { ...this.props.listing, price: this.props.listing.price / 100 } : {}
                }
              /> :
                  <SeekComposeForm onSubmit={this.handleSubmitSeek} />
            }
          </CardText>
        </Card>

    );
  }
}

const mapStateToProps = state => ({
  user: state.currentUser,
  form: state.form,
  mode: state.composeState.mode,
  currentUserLoading: state.currentUserLoading,
  isEdit: state.composeState.isEdit,
  listing: state.composeState.listing,
  seek: state.composeState.seek,
  refreshQuery: state.composeState.refreshQuery,
});

export default withRouter(connect(mapStateToProps)(ComposeOverlay));
<commit_msg>Fix indent<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Card, CardHeader, CardText } from 'material-ui/Card';
import IconButton from 'material-ui/IconButton';
import Clear from 'material-ui/svg-icons/content/clear';
import {
  propTypes as routerPropTypes,
  withRouter,
} from 'react-router-dom';

import {
  setDisplayMode,
  setComposeState,
} from '../actions/ui';
import { postListing, loadListings, updateListing } from '../actions/listings';
import { postSeek, loadSeeks } from '../actions/seeks';
import ComposeForm from '../components/ComposeForm';
import SeekComposeForm from '../components/SeekComposeForm';
import RedirectToCas from '../components/RedirectToCas';

const overlayStyle = {
  position: 'fixed',
  bottom: '0',
  zIndex: '99',
  right: '5%',
  width: '40vw',
  minWidth: '16rem',
};

const showStyle = {};
const hideStyle = { display: 'none' };

class ComposeOverlay extends Component {
  static propTypes = {
    ...routerPropTypes,
    dispatch: PropTypes.func.isRequired,
    history: PropTypes.shape({
      push: PropTypes.func.isRequired,
    }).isRequired,
    user: PropTypes.shape({
      loggedIn: PropTypes.bool.isRequired,
    }).isRequired,
    currentUserLoading: PropTypes.bool.isRequired,
    mode: PropTypes.string.isRequired,
    // eslint-disable-next-line react/forbid-prop-types
    refreshQuery: PropTypes.object,
  };

  static defaultProps = {
    refreshQuery: { query: '' },
  }

  state = {
    mode: this.props.mode,
    expanded: true,
  }

  handleRequestClose = event => this.props.dispatch(setComposeState(false))

  handleSubmitListing = (data) => {
    this.props.dispatch(postListing({
      ...data,
      price: data.price ? Math.round(parseFloat(data.price) * 100) : 0,
    }));
    this.props.dispatch(loadListings());
    this.props.history.push('/listings');
    this.handleRequestClose();
  }

  handleSubmitSeek = (data) => {
    this.props.dispatch(postSeek({
      ...data,
      price: data.price ? Math.round(parseFloat(data.price) * 100) : 0,
    }));
    this.props.dispatch(loadSeeks());
    this.props.history.push('/seeks');
    this.handleRequestClose();
  }

  handleEditListing = (data) => {
    this.props.dispatch(updateListing({
      ...data,
      price: data.price ? Math.round(parseFloat(data.price) * 100) : 0,
    }, this.props.refreshQuery));
    this.handleRequestClose();
  }

  handleToggle = (event, isInputChecked) => {
    this.props.dispatch(setDisplayMode(isInputChecked ? 'seeks' : 'listings'));
  }

  handleExpandChange = (expanded) => {
    this.setState({ expanded });
  }

  render() {
    if (!this.props.currentUserLoading && !this.props.user.loggedIn) {
      return <RedirectToCas />;
    }

    return (

        <Card expanded={this.state.expanded} onExpandChange={this.handleExpandChange}>
          <CardHeader title={this.props.isEdit ? 'Edit' : 'Compose'} actAsExpander>
            <IconButton
              onTouchTap={this.handleRequestClose}
              style={{ float: 'right', marginTop: '-15px', marginRight: '-15px' }}
            >
              <Clear />
            </IconButton>
          </CardHeader>
          <CardText style={this.state.expanded ? showStyle : hideStyle}>
            { (this.state.mode === 'listings') ?
              <ComposeForm
                onSubmit={this.props.isEdit ? this.handleEditListing : this.handleSubmitListing}
                initialValues={
                  this.props.isEdit ?
                  { ...this.props.listing, price: this.props.listing.price / 100 } : {}
                }
              /> :
              <SeekComposeForm onSubmit={this.handleSubmitSeek} />
            }
          </CardText>
        </Card>

    );
  }
}

const mapStateToProps = state => ({
  user: state.currentUser,
  form: state.form,
  mode: state.composeState.mode,
  currentUserLoading: state.currentUserLoading,
  isEdit: state.composeState.isEdit,
  listing: state.composeState.listing,
  seek: state.composeState.seek,
  refreshQuery: state.composeState.refreshQuery,
});

export default withRouter(connect(mapStateToProps)(ComposeOverlay));
<|endoftext|>