<commit_before>import {inject, singleton} from 'aurelia-framework';
import {getLogger} from 'aurelia-logging';
import {EventAggregator} from 'aurelia-event-aggregator';
import * as config from 'environment';
import 'ms-signalr-client';

@inject(EventAggregator, getLogger('SocketService'))
export class SocketService {
    constructor(eventAggregator, logger) {
        this._logger = logger;
        this._eventAggregator = eventAggregator;
        this.connectionState = 4;
        this._connection = $.hubConnection(
            config.apiHostAddress,
            {
                //logging: config.debug
            });
        this._connection.stateChanged((state) => this._connectionStateChanged(state));
        this.hub = this._connection.createHubProxy('commonHub');
        this.lastStates = {};

        this.hub.on('sensorStatePush', state => {
      this._logger.debug('Received "sensorStatePush"', state, this.lastStates);
      var lastState = this.lastStates[`${state.clientId}_${state.sensorId}_${state.sensorType}`];

            if (!lastState || lastState.timestamp < state.timestamp) {
        this.lastStates[`${state.clientId}_${state.sensorId}_${state.sensorType}`] = state;
                this._eventAggregator.publish('socket.sensors', state);
            }
            else {
                this._logger.warn('Skipping state update for sensor as it arrived late', {
                    localState: lastState,
                    receivedState: state
                });
            }
        });

        this.hub.on('clientStatePush', state => {
            this._logger.debug('Received "clientStatePush"', state);
      var lastState = this.lastStates[`${state.clientId}`];

            if (!lastState || lastState.timestamp < state.timestamp) {
        this.lastStates[`${state.clientId}`] = state;
                this._eventAggregator.publish('socket.clients', state);
            }
            else {
                this._logger.warn('Skipping state update for client as it arrived late', {
                    localState: lastState,
                    receivedState: state
                });
            }
        });
    }

    start() {
        return this._connection.start({})
            .done((m) => {
                this.hub.invoke('requestInitialState');
            })
            .fail((e) => {
                this._logger.error('Failed to connect to hub', e);
                this._stateChanged();
            });
    }

    stop() {
        this._connection.stop();
    }

    _connectionStateChanged(state) {
        let connectionState = {
            0: 'connecting',
            1: 'connected',
            2: 'reconnecting',
            4: 'disconnected',
            5: 'faulted'
        }

        if (!state) {
            this._logger.info(`SignalR state changed from ${this.connectionState.name} to ${connectionState[5]}`);
            this.connectionState = { code: 5, name: connectionState[5] };
        }
        else {
            this._logger.info(`SignalR state changed from ${connectionState[state.oldState]} to ${connectionState[state.newState]}`);
            this.connectionState = { code: state.newState, name: connectionState[state.newState] };
        }
        this._eventAggregator.publish('socket.state', this.connectionState);
    }
}<commit_msg>Code formating<commit_after>import {inject, singleton} from 'aurelia-framework';
import {getLogger} from 'aurelia-logging';
import {EventAggregator} from 'aurelia-event-aggregator';
import * as config from 'environment';
import 'ms-signalr-client';

@inject(EventAggregator, getLogger('SocketService'))
export class SocketService {
  constructor(eventAggregator, logger) {
    this._logger = logger;
    this._eventAggregator = eventAggregator;
    this.connectionState = 4;
    this._connection = $.hubConnection(
      config.apiHostAddress,
      {
        //logging: config.debug
      });
    this._connection.stateChanged((state) => this._connectionStateChanged(state));
    this.hub = this._connection.createHubProxy('commonHub');
    this.lastStates = {};

    this.hub.on('sensorStatePush', state => {
      this._logger.debug('Received "sensorStatePush"', state);
      var lastState = this.lastStates[`${state.clientId}_${state.sensorId}_${state.sensorType}`];

      if (!lastState || lastState.timestamp < state.timestamp) {
        this.lastStates[`${state.clientId}_${state.sensorId}_${state.sensorType}`] = state;
        this._eventAggregator.publish('socket.sensors', state);
      }
      else {
        this._logger.warn('Skipping state update for sensor as it arrived late', {
          localState: lastState,
          receivedState: state
        });
      }
    });

    this.hub.on('clientStatePush', state => {
      this._logger.debug('Received "clientStatePush"', state);
      var lastState = this.lastStates[`${state.clientId}`];

      if (!lastState || lastState.timestamp < state.timestamp) {
        this.lastStates[`${state.clientId}`] = state;
        this._eventAggregator.publish('socket.clients', state);
      }
      else {
        this._logger.warn('Skipping state update for client as it arrived late', {
          localState: lastState,
          receivedState: state
        });
      }
    });
  }

  start() {
    return this._connection.start({})
      .done((m) => {
        this.hub.invoke('requestInitialState');
      })
      .fail((e) => {
        this._logger.error('Failed to connect to hub', e);
        this._stateChanged();
      });
  }

  stop() {
    this._connection.stop();
  }

  _connectionStateChanged(state) {
    let connectionState = {
      0: 'connecting',
      1: 'connected',
      2: 'reconnecting',
      4: 'disconnected',
      5: 'faulted'
    }

    if (!state) {
      this._logger.info(`SignalR state changed from ${this.connectionState.name} to ${connectionState[5]}`);
      this.connectionState = { code: 5, name: connectionState[5] };
    }
    else {
      this._logger.info(`SignalR state changed from ${connectionState[state.oldState]} to ${connectionState[state.newState]}`);
      this.connectionState = { code: state.newState, name: connectionState[state.newState] };
    }
    this._eventAggregator.publish('socket.state', this.connectionState);
  }
}
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import purebem from 'purebem';

import {
    firebaseRef,
    overlayAdd,
    overlayRemove
} from 'app/utils';

import {
    ClickOutside,
    NavLink,
    User
} from 'app/components';

const block = purebem.of('navigation');

const Navigation = React.createClass({

    contextTypes: {
        router: PropTypes.object
    },

    propTypes: {
        location: PropTypes.object.isRequired,
        params: PropTypes.object.isRequired
    },

    getInitialState() {
        return {
            isMenuExpanded: false,
            isUserExpanded: false
        };
    },

    componentDidUpdate(prevProps) {
        if (prevProps.location.pathname !== this.props.location.pathname) {
            this.handleMenuToggle(false);
        }
    },

    isLoggedIn() {
        return firebaseRef.getAuth() !== null;
    },

    isProject() {
        const route = this.props.location.pathname.split('/');
        const match = route.some(part => part === 'project');
        const { id } = this.props.params;

        return match === true && !!id;
    },

    handleMenuToggle(expanded=false) {
        switch (expanded) {
            case true:
                overlayAdd('navigation');
                break;
            default:
                overlayRemove();
        };

        this.setState({ isMenuExpanded: expanded });
    },

    handleUserToggle(expanded=false) {
        this.setState({ isUserExpanded: expanded });
    },

    renderUser() {
        if (!this.isLoggedIn()) {
            return null;
        }

        const authData = firebaseRef.getAuth();
        const userData = authData[authData.provider];
        const expanded = this.state.isUserExpanded;

        return (
            <User data={ userData }
                  isExpanded={ expanded }
                  onToggle={ this.handleUserToggle } />
        );
    },

    renderProfileNav() {
        if (!this.isLoggedIn() || this.isProject()) {
            return null;
        }

        return (

                <NavLink baseClass={ block('link') } to="/profile">My Profile</NavLink>
                <NavLink baseClass={ block('link') } to="/create">Create</NavLink>
                <NavLink baseClass={ block('link') } to="/search">Find</NavLink>

        );
    },

    renderProjectNav() {
        if (!this.isLoggedIn() || !this.isProject()) {
            return null;
        }

        const { id } = this.props.params;

        return (

                <NavLink baseClass={ block('link') } to={ `/project/${id}` }>Dashboard</NavLink>
                <NavLink baseClass={ block('link') } to={ `/project/${id}/entry` }>Add Bird</NavLink>
                <NavLink baseClass={ block('link') } to={ `/project/${id}/members` }>Members</NavLink>
                <NavLink baseClass={ block('link') } to={ `/project/${id}/rings` }>Rings</NavLink>
                <NavLink baseClass={ block('link') } to={ `/project/${id}/export` }>Data</NavLink>

        );
    },

    renderBurger() {
        if (!this.isLoggedIn()) {
            return null;
        }

        return (

 this.handleMenuToggle(true) }>

        );
    },

    renderMenu() {
        return (

                { this.renderProfileNav() }
                { this.renderProjectNav() }
                { this.renderUser() }

        );
    },

    renderMenuExpanded() {
        return (
            <ClickOutside onClick={ this.handleMenuToggle }>
                { this.renderMenu() }
            </ClickOutside>
        );
    },

    render() {
        const active = this.isLoggedIn();
        const expanded = this.state.isMenuExpanded;

        return (

                { this.renderBurger() }
                {
                    expanded
                        ? this.renderMenuExpanded()
                        : this.renderMenu()
                }

        );
    }

});

export default Navigation;
<commit_msg>rendering of menu<commit_after>import React, { PropTypes } from 'react';
import purebem from 'purebem';

import {
    firebaseRef,
    overlayAdd,
    overlayRemove
} from 'app/utils';

import {
    ClickOutside,
    NavLink,
    User
} from 'app/components';

const block = purebem.of('navigation');

const Navigation = React.createClass({

    contextTypes: {
        router: PropTypes.object
    },

    propTypes: {
        location: PropTypes.object.isRequired,
        params: PropTypes.object.isRequired
    },

    getInitialState() {
        return {
            isMenuExpanded: false,
            isUserExpanded: false
        };
    },

    componentDidUpdate(prevProps) {
        if (prevProps.location.pathname !== this.props.location.pathname) {
            this.handleMenuToggle(false);
        }
    },

    isLoggedIn() {
        return firebaseRef.getAuth() !== null;
    },

    isProject() {
        const route = this.props.location.pathname.split('/');
        const match = route.some(part => part === 'project');
        const { id } = this.props.params;

        return match === true && !!id;
    },

    handleMenuToggle(expanded=false) {
        switch (expanded) {
            case true:
                overlayAdd('navigation');
                break;
            default:
                overlayRemove();
        };

        this.setState({ isMenuExpanded: expanded });
    },

    handleUserToggle(expanded=false) {
        this.setState({ isUserExpanded: expanded });
    },

    renderUser() {
        if (!this.isLoggedIn()) {
            return null;
        }

        const authData = firebaseRef.getAuth();
        const userData = authData[authData.provider];
        const expanded = this.state.isUserExpanded;

        return (
            <User data={ userData }
                  isExpanded={ expanded }
                  onToggle={ this.handleUserToggle } />
        );
    },

    renderProfileNav() {
        if (!this.isLoggedIn() || this.isProject()) {
            return null;
        }

        return (

                <NavLink baseClass={ block('link') } to="/profile">My Profile</NavLink>
                <NavLink baseClass={ block('link') } to="/create">Create</NavLink>
                <NavLink baseClass={ block('link') } to="/search">Find</NavLink>

        );
    },

    renderProjectNav() {
        if (!this.isLoggedIn() || !this.isProject()) {
            return null;
        }

        const { id } = this.props.params;

        return (

                <NavLink baseClass={ block('link') } to={ `/project/${id}` }>Dashboard</NavLink>
                <NavLink baseClass={ block('link') } to={ `/project/${id}/entry` }>Add Bird</NavLink>
                <NavLink baseClass={ block('link') } to={ `/project/${id}/members` }>Members</NavLink>
                <NavLink baseClass={ block('link') } to={ `/project/${id}/rings` }>Rings</NavLink>
                <NavLink baseClass={ block('link') } to={ `/project/${id}/export` }>Data</NavLink>

        );
    },

    renderBurger() {
        if (!this.isLoggedIn()) {
            return null;
        }

        return (

 this.handleMenuToggle(true) }>

        );
    },

    renderMenu() {
        return (

                { this.renderProfileNav() }
                { this.renderProjectNav() }
                { this.renderUser() }

        );
    },

    render() {
        const active = this.isLoggedIn();
        const expanded = this.state.isMenuExpanded;

        return (

                { this.renderBurger() }
                <ClickOutside onClick={ () => expanded && this.handleMenuToggle() }>
                    { this.renderMenu() }
                </ClickOutside>

        );
    }

});

export default Navigation;
<|endoftext|>


<commit_before>import React from 'react'
import Fluxxor from 'fluxxor'
require("font-awesome-webpack");
import { Input, Button } from 'react-bootstrap'
import Color from '../services/linechartcolor.js'

var FluxMixin = Fluxxor.FluxMixin(React);

export default React.createClass({
  mixins: [FluxMixin],

  getInitialState: function() {
    return {
      hidden: false,
      value: ""
    }
  },

  show: function() {
    this.setState({ visible: true });
    document.addEventListener("hover", this.hide.bind(this));
  },

  hide: function() {
    document.removeEventListener("hover", this.hide.bind(this));
    this.setState({ visible: false });
  },

  handleClick: function() {
    this.getFlux().actions.addKeyword(this.props.chartID, this.state.value)
    this.setState({value: ""})
  },

  handleKeyDown: function(event) {
    if (event.which == 13) {
      this.getFlux().actions.addKeyword(this.props.chartID, event.target.value)
      this.setState({value: ""})
    }
  },

  handleChange: function(event) {
    this.setState({value: event.target.value})
  },

  render: function() {

    var ButtonStyle = {
      backgroundColor: '#e7e7e7',
      border: '0px'
    }

    var innerButton = <Button style={ButtonStyle} onClick={this.handleChange}></Button>;

    return (

            <Input type='text' maxLength="16" chartID={this.props.chartID} buttonBefore={innerButton} onKeyDown={this.handleKeyDown} />

    )
  }
})
<commit_msg>Fixed bug - keyword entry field now clears on enter.<commit_after>import React from 'react'
import Fluxxor from 'fluxxor'
require("font-awesome-webpack");
import { Input, Button } from 'react-bootstrap'
import Color from '../services/linechartcolor.js'

var FluxMixin = Fluxxor.FluxMixin(React);

export default React.createClass({
  mixins: [FluxMixin],

  getInitialState: function() {
    return {
      value: ""
    }
  },

  handleClick: function() {
    if (this.state.value.length > 0) {
      this.getFlux().actions.addKeyword(this.props.chartID, this.state.value)
      this.setState({value: ""})
    }
  },

  handleKeyUp: function(event) {
    if (event.which != 13) {
      this.setState({value: event.target.value})
    } else {
      if (this.state.value.length > 0) {
        this.getFlux().actions.addKeyword(this.props.chartID, this.state.value)
      }
    this.setState({value: ""})
    }
  },

  handleChange: function(event) {
    this.setState({value: event.target.value});
  },

  render: function() {
    var value = this.state.value
    var ButtonStyle = {
      backgroundColor: '#e7e7e7',
      border: '0px'
    }

    var innerButton = <Button style={ButtonStyle} onClick={this.handleClick}></Button>;

    return (

            <Input type='text' value={value} maxLength="16" chartID={this.props.chartID} buttonBefore={innerButton} onChange={this.handleChange} onKeyUp={this.handleKeyUp} />

    )
  }
})
<|endoftext|>


<commit_before>/* globals google */
import Ember from 'ember';
import helpers from 'ember-google-map/core/helpers';
import GoogleObjectMixin from 'ember-google-map/mixins/google-object';

var computed = Ember.computed;
var run = Ember.run;
var on = Ember.on;
var observer = Ember.observer;
var fmt = Ember.String.fmt;
var forEach = Ember.EnumerableUtils.forEach;
var getProperties = Ember.getProperties;
var get$ = Ember.get;
var dummyCircle;

var VALID_FIT_BOUND_TYPES = ['markers', 'infoWindows', 'circles', 'polylines', 'polygons'];

function getDummyCircle(center, radius) {
  if (radius == null) {
    radius = get$(center, 'radius');
  }
  if (!(center instanceof google.maps.LatLng)) {
    center = helpers._latLngToGoogle(center);
  }
  if (dummyCircle) {
    dummyCircle.setCenter(center);
    dummyCircle.setRadius(radius);
  }
  else {
    dummyCircle = new google.maps.Circle({center: center, radius: radius});
  }
  return dummyCircle;
}

function collectCoordsOf(type, array, items) {
  if (['markers', 'infoWindows'].indexOf(type) !== -1) {
    // handle simple types
    return array.reduce(function (previous, item) {
      var coords = getProperties(item, 'lat', 'lng');
      if (coords.lat != null && coords.lng != null) {
        previous.push(coords);
      }
      return previous;
    }, items || []);
  }
  else if (type === 'circles') {
    // handle circles
    return array.reduce(function (previous, item) {
      var opt = getProperties(item, 'lat', 'lng', 'radius'), bounds;
      if (opt.lat != null && opt.lng != null && opt.radius != null) {
        bounds = getDummyCircle(opt).getBounds();
        previous.push(helpers._latLngFromGoogle(bounds.getNorthEast()));
        previous.push(helpers._latLngFromGoogle(bounds.getSouthWest()));
      }
      return previous;
    }, items || []);
  }
  else if (['polylines', 'polygons']) {
    // handle complex types
    return array.reduce(function (previous, item) {
      return get$(item, '_path').reduce(function (previous, item) {
        var coords = getProperties(item, 'lat', 'lng');
        if (coords.lat != null && coords.lng != null) {
          previous.push(coords);
        }
        return previous;
      }, items || []);
    }, items || []);
  }
}

function obj(o) {
  return Ember.Object.create(o);
}

export var MAP_TYPES = Ember.A([
  obj({id: 'road', label: 'road'}),
  obj({id: 'satellite', label: 'satellite'}),
  obj({id: 'terrain', label: 'terrain'}),
  obj({id: 'hybrid', label: 'hybrid'})
]);

export var PLACE_TYPES = Ember.A([
  obj({id: helpers.PLACE_TYPE_ADDRESS, label: 'address'}),
  obj({id: helpers.PLACE_TYPE_LOCALITY, label: 'locality'}),
  obj({id: helpers.PLACE_TYPE_ADMIN_REGION, label: 'administrative region'}),
  obj({id: helpers.PLACE_TYPE_BUSINESS, label: 'business'})
]);

/**
 * @class GoogleMapComponent
 * @extends Ember.Component
 * @uses GoogleObjectMixin
 */
export default Ember.Component.extend(GoogleObjectMixin, {
  googleFQCN: 'google.maps.Map',

  classNames: ['google-map'],

  /**
   * Defines all properties bound to the google map object
   * @property googleProperties
   * @type {Object}
   */
  googleProperties: {
    zoom:      {event: 'zoom_changed', cast: helpers.cast.integer},
    type:      {
      name:       'mapTypeId',
      event:      'maptypeid_changed',
      toGoogle:   helpers._typeToGoogle,
      fromGoogle: helpers._typeFromGoogle
    },
    'lat,lng': {
      name:       'center',
      event:      'center_changed',
      toGoogle:   helpers._latLngToGoogle,
      fromGoogle: helpers._latLngFromGoogle
    }
    /**
     * available options (prepend with `gopt_` to use):
     * `backgroundColor`, `disableDefaultUI`, `disableDoubleClickZoom`, `draggable`, `keyboardShortcuts`,
     * `mapTypeControl`, `maxZoom`, `minZoom`, `overviewMapControl`, `panControl`, `rotateControl`, `scaleControl`,
     * `scrollwheel`, `streetViewControl`, `zoomControl`
     */
  },

  /**
   * @inheritDoc
   */
  googleEvents: {},

  /**
   * Our google map object
   * @property googleObject
   * @type {google.maps.Map}
   * @private
   */
  googleObject: null,

  /**
   * Always auto-fit bounds
   * @property alwaysAutoFitBounds
   * @type {boolean}
   */
  alwaysAutoFitBounds: false,

  /**
   * Auto fit bounds to type of items
   * @property autoFitBounds
   * @type {boolean|string}
   */
  autoFitBounds: false,

  /**
   * Fit bounds to view all coordinates
   * @property fitBoundsArray
   * @type {Array.<{lat: number, lng: number}>}
   */
  fitBoundsArray: computed(
    'autoFitBounds', '_markers.[]', '_infoWindow.[]', '_polylines.@each._path.[]',
    '_polygons.@each._path.[]', '_circles.[]',
    {
      get() {
        var auto, value;
        if (this._fixedFitBoundsArray) {
          value = this._fixedFitBoundsArray;
        }
        else {
          // here comes our computation
          auto = this.get('autoFitBounds');
          if (auto) {
            auto = auto === true ? VALID_FIT_BOUND_TYPES : auto.split(',');
            value = [];
            forEach(auto, function (type) {
              collectCoordsOf(type, this.get('_' + type), value);
            }, this);
          }
          else {
            value = null;
          }
        }
        return value;
      },
      set(key, value) {
        this._fixedFitBoundsArray = value;
      }
    }
  ),

  /**
   * Initial center's latitude of the map
   * @property lat
   * @type {Number}
   */
  lat: 0,

  /**
   * Initial center's longitude of the map
   * @property lng
   * @type {Number}
   */
  lng: 0,

  /**
   * Initial zoom of the map
   * @property zoom
   * @type {Number}
   * @default 5
   */
  zoom: 5,

  /**
   * Initial type of the map
   * @property type
   * @type {String}
   * @enum ['road', 'hybrid', 'terrain', 'satellite']
   * @default 'road'
   */
  type: 'road',

  /**
   * List of markers to handle/show on the map
   * @property markers
   * @type {Array.<{lat: Number, lng: Number, title: String}>}
   */
  markers: null,

  /**
   * The array controller holding the markers
   * @property _markers
   * @type {Ember.ArrayController}
   * @private
   */
  _markers: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/markers').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller to use for each marker
   * @property markerController
   * @type {String}
   * @default 'google-map/marker'
   */
  markerController: 'google-map/marker',

  /**
   * View to use for each marker
   * @property markerViewClass
   * @type {String}
   * @default 'google-map/marker'
   */
  markerViewClass: 'google-map/marker',

  /**
   * Info-window template name to use for each marker
   * @property markerInfoWindowTemplateName
   * @type {String}
   * @default 'google-map/info-window'
   */
  markerInfoWindowTemplateName: 'google-map/info-window',

  /**
   * Whether the markers have an info-window by default
   * @property markerHasInfoWindow
   * @type {Boolean}
   * @default true
   */
  markerHasInfoWindow: true,

  /**
   * List of polylines to handle/show on the map
   * @property polylines
   * @type {Array.<{path: Array.<{lat: Number, lng: Number}>>}
   */
  polylines: null,

  /**
   * The array controller holding the polylines
   * @property _polylines
   * @type {Ember.ArrayController}
   * @private
   */
  _polylines: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/polylines').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller to use for each polyline
   * @property polylineController
   * @type {String}
   * @default 'google-map/polyline'
   */
  polylineController: 'google-map/polyline',

  /**
   * Controller to use for each polyline's path
   * @property polylinePathController
   * @type {String}
   * @default 'google-map/polyline-path'
   */
  polylinePathController: 'google-map/polyline-path',

  /**
   * View to use for each polyline
   * @property polylineViewClass
   * @type {String}
   * @default 'google-map/polyline'
   */
  polylineViewClass: 'google-map/polyline',

  /**
   * List of polygons to handle/show on the map
   * @property polygons
   * @type {Array.<{path: Array.<{lat: Number, lng: Number}>>}
   */
  polygons: null,

  /**
   * The array controller holding the polygons
   * @property _polygons
   * @type {Ember.ArrayController}
   * @private
   */
  _polygons: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/polygons').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller to use for each polygon
   * @property polygonController
   * @type {String}
   * @default 'google-map/polygon'
   */
  polygonController: 'google-map/polygon',

  /**
   * Controller to use for each polygon's path
   * @property polygonPathController
   * @type {String}
   * @default 'google-map/polygon-path'
   */
  polygonPathController: 'google-map/polygon-path',

  /**
   * View to use for each polygon
   * @property polygonViewClass
   * @type {String}
   * @default 'google-map/polygon'
   */
  polygonViewClass: 'google-map/polygon',

  /**
   * List of circles to handle/show on the map
   * @property circles
   * @type {Array.<{lat: Number, lng: Number, radius: Number}>}
   */
  circles: null,

  /**
   * The array controller holding the circles
   * @property _circles
   * @type {Ember.ArrayController}
   * @private
   */
  _circles: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/circles').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller to use for each circle
   * @property circleController
   * @type {String}
   * @default 'google-map/circle'
   */
  circleController: 'google-map/circle',

  /**
   * View to use for each circle
   * @property circleViewClass
   * @type {String}
   * @default 'google-map/circle'
   */
  circleViewClass: 'google-map/circle',

  /**
   * Array of al info-windows to handle/show (independent from the markers' info-windows)
   * @property infoWindows
   * @type {Array.<{lat: Number, lng: Number, title: String, description: String}>}
   */
  infoWindows: null,

  /**
   * The array controller holding the info-windows
   * @property _infoWindows
   * @type {Ember.ArrayController}
   * @private
   */
  _infoWindows: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/info-windows').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller for each info-window
   * @property infoWindowController
   * @type {String}
   * @default 'google-map/info-window'
   */
  infoWindowController: 'google-map/info-window',

  /**
   * View for each info-window
   * @property infoWindowViewClass
   * @type {String}
   * @default 'google-map/info-window'
   */
  infoWindowViewClass: 'google-map/info-window',

  /**
   * Template for each info-window
   * @property infoWindowTemplateName
   * @type {String}
   * @default 'google-map/info-window'
   */
  infoWindowTemplateName: 'google-map/info-window',

  /**
   * The google map object
   * @property map
   * @type {google.maps.Map}
   */
  map: computed.oneWay('googleObject'),

  /**
   * Schedule an auto-fit of the bounds
   *
   * @method _scheduleAutoFitBounds
   */
  _scheduleAutoFitBounds: function () {
    run.schedule('afterRender', this, function () {
      run.debounce(this, '_fitBounds', 200);
    });
  },

  /**
   * Observes the length of the autoFitBounds array
   *
   * @method _observesAutoFitBoundLength
   * @private
   */
  _observesAutoFitBoundLength: on('init', observer('fitBoundsArray.length', function () {
    if (this.get('alwaysAutoFitBounds')) {
      this._scheduleAutoFitBounds();
    }
  })),

  /**
   * Fit the bounds to contain given coordinates
   *
   * @method _fitBounds
   */
  _fitBounds: function () {
    var map, bounds, coords;
    if (this.isDestroying || this.isDestroyed) {
      return;
    }
    map = this.get('googleObject');
    if (this._state !== 'inDOM' || !map) {
      this._scheduleAutoFitBounds(coords);
      return;
    }
    coords = this.get('fitBoundsArray');
    if (!coords) {
      return;
    }
    if (Ember.isArray(coords)) {
      // it's an array of lat,lng
      coords = coords.slice();
      if (coords.get('length')) {
        bounds = new google.maps.LatLngBounds(helpers._latLngToGoogle(coords.shift()));
        forEach(coords, function (point) {
          bounds.extend(helpers._latLngToGoogle(point));
        });
      }
      else {
        return;
      }
    }
    else {
      // it's a bound object
      bounds = helpers._boundsToGoogle(coords);
    }
    if (bounds) {
      // finally make our map to fit
      map.fitBounds(bounds);
    }
  },

  /**
   * Initialize the map
   */
  initGoogleMap: on('didInsertElement', function () {
    var canvas;
    this.destroyGoogleMap();
    if (helpers.hasGoogleLib()) {
      canvas = this.$('div.map-canvas')[0];
      this.createGoogleObject(canvas, null);
      this._scheduleAutoFitBounds();
    }
  }),

  /**
   * Destroy the map
   */
  destroyGoogleMap: on('willDestroyElement', function () {
    if (this.get('googleObject')) {
      Ember.debug(fmt('[google-map] destroying %@', this.get('googleName')));
      this.set('googleObject', null);
    }
  })
});
<commit_msg>[FIX] Fixed use of extended proto<commit_after>/* globals google */
import Ember from 'ember';
import helpers from 'ember-google-map/core/helpers';
import GoogleObjectMixin from 'ember-google-map/mixins/google-object';

var computed = Ember.computed;
var run = Ember.run;
var on = Ember.on;
var observer = Ember.observer;
var fmt = Ember.String.fmt;
var forEach = Ember.EnumerableUtils.forEach;
var getProperties = Ember.getProperties;
var get$ = Ember.get;
var dummyCircle;

var VALID_FIT_BOUND_TYPES = ['markers', 'infoWindows', 'circles', 'polylines', 'polygons'];

function getDummyCircle(center, radius) {
  if (radius == null) {
    radius = get$(center, 'radius');
  }
  if (!(center instanceof google.maps.LatLng)) {
    center = helpers._latLngToGoogle(center);
  }
  if (dummyCircle) {
    dummyCircle.setCenter(center);
    dummyCircle.setRadius(radius);
  }
  else {
    dummyCircle = new google.maps.Circle({center: center, radius: radius});
  }
  return dummyCircle;
}

function collectCoordsOf(type, array, items) {
  if (['markers', 'infoWindows'].indexOf(type) !== -1) {
    // handle simple types
    return array.reduce(function (previous, item) {
      var coords = getProperties(item, 'lat', 'lng');
      if (coords.lat != null && coords.lng != null) {
        previous.push(coords);
      }
      return previous;
    }, items || []);
  }
  else if (type === 'circles') {
    // handle circles
    return array.reduce(function (previous, item) {
      var opt = getProperties(item, 'lat', 'lng', 'radius'), bounds;
      if (opt.lat != null && opt.lng != null && opt.radius != null) {
        bounds = getDummyCircle(opt).getBounds();
        previous.push(helpers._latLngFromGoogle(bounds.getNorthEast()));
        previous.push(helpers._latLngFromGoogle(bounds.getSouthWest()));
      }
      return previous;
    }, items || []);
  }
  else if (['polylines', 'polygons']) {
    // handle complex types
    return array.reduce(function (previous, item) {
      return get$(item, '_path').reduce(function (previous, item) {
        var coords = getProperties(item, 'lat', 'lng');
        if (coords.lat != null && coords.lng != null) {
          previous.push(coords);
        }
        return previous;
      }, items || []);
    }, items || []);
  }
}

function obj(o) {
  return Ember.Object.create(o);
}

export var MAP_TYPES = Ember.A([
  obj({id: 'road', label: 'road'}),
  obj({id: 'satellite', label: 'satellite'}),
  obj({id: 'terrain', label: 'terrain'}),
  obj({id: 'hybrid', label: 'hybrid'})
]);

export var PLACE_TYPES = Ember.A([
  obj({id: helpers.PLACE_TYPE_ADDRESS, label: 'address'}),
  obj({id: helpers.PLACE_TYPE_LOCALITY, label: 'locality'}),
  obj({id: helpers.PLACE_TYPE_ADMIN_REGION, label: 'administrative region'}),
  obj({id: helpers.PLACE_TYPE_BUSINESS, label: 'business'})
]);

/**
 * @class GoogleMapComponent
 * @extends Ember.Component
 * @uses GoogleObjectMixin
 */
export default Ember.Component.extend(GoogleObjectMixin, {
  googleFQCN: 'google.maps.Map',

  classNames: ['google-map'],

  /**
   * Defines all properties bound to the google map object
   * @property googleProperties
   * @type {Object}
   */
  googleProperties: {
    zoom:      {event: 'zoom_changed', cast: helpers.cast.integer},
    type:      {
      name:       'mapTypeId',
      event:      'maptypeid_changed',
      toGoogle:   helpers._typeToGoogle,
      fromGoogle: helpers._typeFromGoogle
    },
    'lat,lng': {
      name:       'center',
      event:      'center_changed',
      toGoogle:   helpers._latLngToGoogle,
      fromGoogle: helpers._latLngFromGoogle
    }
    /**
     * available options (prepend with `gopt_` to use):
     * `backgroundColor`, `disableDefaultUI`, `disableDoubleClickZoom`, `draggable`, `keyboardShortcuts`,
     * `mapTypeControl`, `maxZoom`, `minZoom`, `overviewMapControl`, `panControl`, `rotateControl`, `scaleControl`,
     * `scrollwheel`, `streetViewControl`, `zoomControl`
     */
  },

  /**
   * @inheritDoc
   */
  googleEvents: {},

  /**
   * Our google map object
   * @property googleObject
   * @type {google.maps.Map}
   * @private
   */
  googleObject: null,

  /**
   * Always auto-fit bounds
   * @property alwaysAutoFitBounds
   * @type {boolean}
   */
  alwaysAutoFitBounds: false,

  /**
   * Auto fit bounds to type of items
   * @property autoFitBounds
   * @type {boolean|string}
   */
  autoFitBounds: false,

  /**
   * Fit bounds to view all coordinates
   * @property fitBoundsArray
   * @type {Array.<{lat: number, lng: number}>}
   */
  fitBoundsArray: computed(
    'autoFitBounds', '_markers.[]', '_infoWindow.[]', '_polylines.@each._path.[]',
    '_polygons.@each._path.[]', '_circles.[]',
    {
      get() {
        var auto, value;
        if (this._fixedFitBoundsArray) {
          value = this._fixedFitBoundsArray;
        }
        else {
          // here comes our computation
          auto = this.get('autoFitBounds');
          if (auto) {
            auto = auto === true ? VALID_FIT_BOUND_TYPES : auto.split(',');
            value = [];
            forEach(auto, function (type) {
              collectCoordsOf(type, this.get('_' + type), value);
            }, this);
          }
          else {
            value = null;
          }
        }
        return value;
      },
      set(key, value) {
        this._fixedFitBoundsArray = value;
      }
    }
  ),

  /**
   * Initial center's latitude of the map
   * @property lat
   * @type {Number}
   */
  lat: 0,

  /**
   * Initial center's longitude of the map
   * @property lng
   * @type {Number}
   */
  lng: 0,

  /**
   * Initial zoom of the map
   * @property zoom
   * @type {Number}
   * @default 5
   */
  zoom: 5,

  /**
   * Initial type of the map
   * @property type
   * @type {String}
   * @enum ['road', 'hybrid', 'terrain', 'satellite']
   * @default 'road'
   */
  type: 'road',

  /**
   * List of markers to handle/show on the map
   * @property markers
   * @type {Array.<{lat: Number, lng: Number, title: String}>}
   */
  markers: null,

  /**
   * The array controller holding the markers
   * @property _markers
   * @type {Ember.ArrayController}
   * @private
   */
  _markers: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/markers').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller to use for each marker
   * @property markerController
   * @type {String}
   * @default 'google-map/marker'
   */
  markerController: 'google-map/marker',

  /**
   * View to use for each marker
   * @property markerViewClass
   * @type {String}
   * @default 'google-map/marker'
   */
  markerViewClass: 'google-map/marker',

  /**
   * Info-window template name to use for each marker
   * @property markerInfoWindowTemplateName
   * @type {String}
   * @default 'google-map/info-window'
   */
  markerInfoWindowTemplateName: 'google-map/info-window',

  /**
   * Whether the markers have an info-window by default
   * @property markerHasInfoWindow
   * @type {Boolean}
   * @default true
   */
  markerHasInfoWindow: true,

  /**
   * List of polylines to handle/show on the map
   * @property polylines
   * @type {Array.<{path: Array.<{lat: Number, lng: Number}>>}
   */
  polylines: null,

  /**
   * The array controller holding the polylines
   * @property _polylines
   * @type {Ember.ArrayController}
   * @private
   */
  _polylines: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/polylines').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller to use for each polyline
   * @property polylineController
   * @type {String}
   * @default 'google-map/polyline'
   */
  polylineController: 'google-map/polyline',

  /**
   * Controller to use for each polyline's path
   * @property polylinePathController
   * @type {String}
   * @default 'google-map/polyline-path'
   */
  polylinePathController: 'google-map/polyline-path',

  /**
   * View to use for each polyline
   * @property polylineViewClass
   * @type {String}
   * @default 'google-map/polyline'
   */
  polylineViewClass: 'google-map/polyline',

  /**
   * List of polygons to handle/show on the map
   * @property polygons
   * @type {Array.<{path: Array.<{lat: Number, lng: Number}>>}
   */
  polygons: null,

  /**
   * The array controller holding the polygons
   * @property _polygons
   * @type {Ember.ArrayController}
   * @private
   */
  _polygons: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/polygons').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller to use for each polygon
   * @property polygonController
   * @type {String}
   * @default 'google-map/polygon'
   */
  polygonController: 'google-map/polygon',

  /**
   * Controller to use for each polygon's path
   * @property polygonPathController
   * @type {String}
   * @default 'google-map/polygon-path'
   */
  polygonPathController: 'google-map/polygon-path',

  /**
   * View to use for each polygon
   * @property polygonViewClass
   * @type {String}
   * @default 'google-map/polygon'
   */
  polygonViewClass: 'google-map/polygon',

  /**
   * List of circles to handle/show on the map
   * @property circles
   * @type {Array.<{lat: Number, lng: Number, radius: Number}>}
   */
  circles: null,

  /**
   * The array controller holding the circles
   * @property _circles
   * @type {Ember.ArrayController}
   * @private
   */
  _circles: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/circles').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller to use for each circle
   * @property circleController
   * @type {String}
   * @default 'google-map/circle'
   */
  circleController: 'google-map/circle',

  /**
   * View to use for each circle
   * @property circleViewClass
   * @type {String}
   * @default 'google-map/circle'
   */
  circleViewClass: 'google-map/circle',

  /**
   * Array of al info-windows to handle/show (independent from the markers' info-windows)
   * @property infoWindows
   * @type {Array.<{lat: Number, lng: Number, title: String, description: String}>}
   */
  infoWindows: null,

  /**
   * The array controller holding the info-windows
   * @property _infoWindows
   * @type {Ember.ArrayController}
   * @private
   */
  _infoWindows: computed({
    get () {
      return this.container.lookupFactory('controller:google-map/info-windows').create({
        parentController: this
      });
    }
  }),

  /**
   * Controller for each info-window
   * @property infoWindowController
   * @type {String}
   * @default 'google-map/info-window'
   */
  infoWindowController: 'google-map/info-window',

  /**
   * View for each info-window
   * @property infoWindowViewClass
   * @type {String}
   * @default 'google-map/info-window'
   */
  infoWindowViewClass: 'google-map/info-window',

  /**
   * Template for each info-window
   * @property infoWindowTemplateName
   * @type {String}
   * @default 'google-map/info-window'
   */
  infoWindowTemplateName: 'google-map/info-window',

  /**
   * The google map object
   * @property map
   * @type {google.maps.Map}
   */
  map: computed.oneWay('googleObject'),

  /**
   * Schedule an auto-fit of the bounds
   *
   * @method _scheduleAutoFitBounds
   */
  _scheduleAutoFitBounds: function () {
    run.schedule('afterRender', this, function () {
      run.debounce(this, '_fitBounds', 200);
    });
  },

  /**
   * Observes the length of the autoFitBounds array
   *
   * @method _observesAutoFitBoundLength
   * @private
   */
  _observesAutoFitBoundLength: on('init', observer('fitBoundsArray.length', function () {
    if (this.get('alwaysAutoFitBounds')) {
      this._scheduleAutoFitBounds();
    }
  })),

  /**
   * Fit the bounds to contain given coordinates
   *
   * @method _fitBounds
   */
  _fitBounds: function () {
    var map, bounds, coords;
    if (this.isDestroying || this.isDestroyed) {
      return;
    }
    map = this.get('googleObject');
    if (this._state !== 'inDOM' || !map) {
      this._scheduleAutoFitBounds(coords);
      return;
    }
    coords = this.get('fitBoundsArray');
    if (!coords) {
      return;
    }
    if (Ember.isArray(coords)) {
      // it's an array of lat,lng
      coords = coords.slice();
      if (get$(coords, 'length')) {
        bounds = new google.maps.LatLngBounds(helpers._latLngToGoogle(coords.shift()));
        forEach(coords, function (point) {
          bounds.extend(helpers._latLngToGoogle(point));
        });
      }
      else {
        return;
      }
    }
    else {
      // it's a bound object
      bounds = helpers._boundsToGoogle(coords);
    }
    if (bounds) {
      // finally make our map to fit
      map.fitBounds(bounds);
    }
  },

  /**
   * Initialize the map
   */
  initGoogleMap: on('didInsertElement', function () {
    var canvas;
    this.destroyGoogleMap();
    if (helpers.hasGoogleLib()) {
      canvas = this.$('div.map-canvas')[0];
      this.createGoogleObject(canvas, null);
      this._scheduleAutoFitBounds();
    }
  }),

  /**
   * Destroy the map
   */
  destroyGoogleMap: on('willDestroyElement', function () {
    if (this.get('googleObject')) {
      Ember.debug(fmt('[google-map] destroying %@', this.get('googleName')));
      this.set('googleObject', null);
    }
  })
});
<|endoftext|>


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

var mongoose = require('mongoose')
var Articulo = mongoose.model('Articulo')

exports.dameArticulos= function(req, res){
	Articulo.find(function(error, data){
		if (error) return res.status(500).send(err.message);
		return res.status(200).jsonp(data);
	});
};

exports.dameArticulosFecha= function(req, res){
	var dia=req.params.dia;
	var mes=req.params.mes;
	var ano =req.params.ano;
	var fecha = new date(ano, mes, dia);
	Articulo.find({"createdAt" : { $gte : fecha }}).exec(function(error, data){
		if (error) return res.status(500).send(err.message);
		return res.status(200).jsonp(data);
	});
};

exports.nuevo=function(req,res){
	var datos = req.body;
	console.log('Añadir a: -> ' + req.params.id);
	//console.log ('Datos pasados ->');
	//console.log(datos);

	articulo = new Articulo(datos);
	articulo.save(function(err, object){
		if (err){
			//console.log("ERROR -> Al crear el articulo")
			//console.log(err.message);
			return res.status(500).send(err.message);
		}else{
			console.log("Articulo creado");
			return res.status(200).send('Correcto');
		}

	});
};<commit_msg>fecha3<commit_after>
/*!
 * Module dependencies.
 */

var mongoose = require('mongoose')
var Articulo = mongoose.model('Articulo')

exports.dameArticulos= function(req, res){
	Articulo.find(function(error, data){
		if (error) return res.status(500).send(err.message);
		return res.status(200).jsonp(data);
	});
};

exports.dameArticulosFecha= function(req, res){
	var dia=req.params.dia;
	var mes=req.params.mes;
	var ano =req.params.ano;
	var fecha = new Date(ano, mes, dia);
	Articulo.find({"createdAt" : { $gte : fecha }}).exec(function(error, data){
		if (error) return res.status(500).send(err.message);
		return res.status(200).jsonp(data);
	});
};

exports.nuevo=function(req,res){
	var datos = req.body;
	console.log('Añadir a: -> ' + req.params.id);
	//console.log ('Datos pasados ->');
	//console.log(datos);

	articulo = new Articulo(datos);
	articulo.save(function(err, object){
		if (err){
			//console.log("ERROR -> Al crear el articulo")
			//console.log(err.message);
			return res.status(500).send(err.message);
		}else{
			console.log("Articulo creado");
			return res.status(200).send('Correcto');
		}

	});
};<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { compose, lifecycle } from 'recompose';
import { reduxForm, Field } from 'redux-form';

import user from 'features/user/actions';
import Spinner from 'common/components/Spinner';

import {
  requiredValid,
  emailValid,
  minLengthValid,
  confirmPasswordValid,
} from 'common/validations';

import Input from './Input';

import { Form, SubmitButton, ApiLink, ValidationMessage } from './styles';

FormView.propTypes = {
  loginSelected: PropTypes.bool.isRequired,
  registerSelected: PropTypes.bool.isRequired,
  resetSelected: PropTypes.bool.isRequired,
  handleSubmit: PropTypes.func.isRequired,
  submitting: PropTypes.bool.isRequired,
  error: PropTypes.array,
};

FormView.defaultProps = {
  error: [],
};

function FormView({
  loginSelected,
  registerSelected,
  resetSelected,
  handleSubmit,
  submitting,
  error,
}) {
  const mainInputText =
    (loginSelected && 'Username or Email') || (registerSelected && 'Username') || 'Email';

  return (
    <Form onSubmit={handleSubmit} autoComplete="on">
      <Field
        label={`Enter ${!resetSelected ? 'username' : 'email'}`}
        name={!resetSelected ? 'username' : 'email'}
        component={Input}
        placeholder={mainInputText}
        validate={!resetSelected ? [requiredValid] : [requiredValid, emailValid]}
      />
      <Field
        label="Enter email"
        name="email"
        component={Input}
        type="email"
        placeholder="Email"
        validate={registerSelected ? [requiredValid, emailValid] : []}
        isHidden={loginSelected || resetSelected}
      />
      <Field
        label="Enter account password"
        name="password"
        component={Input}
        type="password"
        placeholder="Password"
        validate={!resetSelected ? [requiredValid, minLengthValid] : []}
        isHidden={resetSelected}
      />
      <Field
        label="Confirm account password"
        name="confirmPassword"
        component={Input}
        type="password"
        placeholder="Confirm Password"
        validate={registerSelected ? [requiredValid, minLengthValid, confirmPasswordValid] : []}
        isHidden={loginSelected || resetSelected}
      />
      <Field
        label="WaniKani V1 API Key"
        name="apiKey"
        component={Input}
        placeholder="WaniKani V1 API Key"
        validate={registerSelected ? [requiredValid] : []}
        isHidden={loginSelected || resetSelected}
      >
        <ApiLink
          title="Find WK API Key"
          name="HELP"
          color="black"
          href="https://www.wanikani.com/settings/account#public-api-key"
          isHidden={loginSelected || resetSelected}
          tabIndex={loginSelected || resetSelected ? -1 : 0}
          external
        />
      </Field>
      {error.length > 0 && <ValidationMessage>{error}</ValidationMessage>}
      <SubmitButton
        type="submit"
        lang="ja"
        title={
          (submitting && 'Submitting...') ||
          (registerSelected && 'Register') ||
          (loginSelected && "Let's Go!") ||
          (resetSelected && 'Submit')
        }
      >
        {(submitting && '送信している...') ||
          (registerSelected && '登録する') ||
          (loginSelected && '行こう') ||
          (resetSelected && '送信する')}
      </SubmitButton>
      {registerSelected && submitting && <Spinner />}
    </Form>
  );
}

const enhance = compose(
  reduxForm({
    form: 'multiLogin',
    onSubmit: (values, dispatch, props) => {
      const { loginSelected, registerSelected, resetSelected, ...form } = props;
      const { username, email, password, apiKey } = values;

      if (registerSelected) {
        dispatch(
          user.register.request(
            {
              username,
              email,
              password,
              api_key: apiKey,
            },
            { form }
          )
        );
      }

      if (loginSelected) {
        dispatch(user.login.request({ username, password }, { form }));
      }

      if (resetSelected) {
        dispatch(user.resetPassword.request({ email }, { form }));
      }
    },
  }),
  lifecycle({
    componentDidUpdate(prevProps) {
      // reset form if user changes panel and there are lingering general submission errors
      if (prevProps.activePanel !== this.props.activePanel && this.props.error) {
        this.props.reset();
      }
    },
  })
);

export default enhance(FormView);
<commit_msg>feat: update WK api key link<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { compose, lifecycle } from 'recompose';
import { reduxForm, Field } from 'redux-form';

import user from 'features/user/actions';
import Spinner from 'common/components/Spinner';

import {
  requiredValid,
  emailValid,
  minLengthValid,
  confirmPasswordValid,
} from 'common/validations';

import Input from './Input';

import { Form, SubmitButton, ApiLink, ValidationMessage } from './styles';

FormView.propTypes = {
  loginSelected: PropTypes.bool.isRequired,
  registerSelected: PropTypes.bool.isRequired,
  resetSelected: PropTypes.bool.isRequired,
  handleSubmit: PropTypes.func.isRequired,
  submitting: PropTypes.bool.isRequired,
  error: PropTypes.array,
};

FormView.defaultProps = {
  error: [],
};

function FormView({
  loginSelected,
  registerSelected,
  resetSelected,
  handleSubmit,
  submitting,
  error,
}) {
  const mainInputText = (loginSelected && 'Username or Email') || (registerSelected && 'Username') || 'Email';

  return (
    <Form onSubmit={handleSubmit} autoComplete="on">
      <Field
        label={`Enter ${!resetSelected ? 'username' : 'email'}`}
        name={!resetSelected ? 'username' : 'email'}
        component={Input}
        placeholder={mainInputText}
        validate={!resetSelected ? [requiredValid] : [requiredValid, emailValid]}
      />
      <Field
        label="Enter email"
        name="email"
        component={Input}
        type="email"
        placeholder="Email"
        validate={registerSelected ? [requiredValid, emailValid] : []}
        isHidden={loginSelected || resetSelected}
      />
      <Field
        label="Enter account password"
        name="password"
        component={Input}
        type="password"
        placeholder="Password"
        validate={!resetSelected ? [requiredValid, minLengthValid] : []}
        isHidden={resetSelected}
      />
      <Field
        label="Confirm account password"
        name="confirmPassword"
        component={Input}
        type="password"
        placeholder="Confirm Password"
        validate={registerSelected ? [requiredValid, minLengthValid, confirmPasswordValid] : []}
        isHidden={loginSelected || resetSelected}
      />
      <Field
        label="WaniKani V1 API Key"
        name="apiKey"
        component={Input}
        placeholder="WaniKani V1 API Key"
        validate={registerSelected ? [requiredValid] : []}
        isHidden={loginSelected || resetSelected}
      >
        <ApiLink
          title="Find WK API Key"
          name="HELP"
          color="black"
          href="https://www.wanikani.com/settings/personal_access_tokens"
          isHidden={loginSelected || resetSelected}
          tabIndex={loginSelected || resetSelected ? -1 : 0}
          external
        />
      </Field>
      {error.length > 0 && <ValidationMessage>{error}</ValidationMessage>}
      <SubmitButton
        type="submit"
        lang="ja"
        title={
          (submitting && 'Submitting...')
          || (registerSelected && 'Register')
          || (loginSelected && "Let's Go!")
          || (resetSelected && 'Submit')
        }
      >
        {(submitting && '送信している...')
          || (registerSelected && '登録する')
          || (loginSelected && '行こう')
          || (resetSelected && '送信する')}
      </SubmitButton>
      {registerSelected && submitting && <Spinner />}
    </Form>
  );
}

const enhance = compose(
  reduxForm({
    form: 'multiLogin',
    onSubmit: (values, dispatch, props) => {
      const { loginSelected, registerSelected, resetSelected, ...form } = props;
      const { username, email, password, apiKey } = values;

      if (registerSelected) {
        dispatch(
          user.register.request(
            {
              username,
              email,
              password,
              api_key: apiKey,
            },
            { form }
          )
        );
      }

      if (loginSelected) {
        dispatch(user.login.request({ username, password }, { form }));
      }

      if (resetSelected) {
        dispatch(user.resetPassword.request({ email }, { form }));
      }
    },
  }),
  lifecycle({
    componentDidUpdate(prevProps) {
      // reset form if user changes panel and there are lingering general submission errors
      if (prevProps.activePanel !== this.props.activePanel && this.props.error) {
        this.props.reset();
      }
    },
  })
);

export default enhance(FormView);
<|endoftext|>


<commit_before>
$ = require("jquery");
var Book =  AV.Object.extend("book");
var User = AV.User.current();
var GeoCoding = require("./geocoding");

var fetchBookInfo=function(isbn,callback,error_callback) {
  var error_callback=error_callback||function(data){console.log(data)};
  $.ajax({
             timeout:3000,
             url:"http://api.douban.com/v2/book/isbn/"+isbn,
             dataType:"jsonp",
             jsonp:"callback",
             success: callback,
             error: error_callback
        });
};

var fakeBookList = function(isbn,locationArray)
{
  var error_callback=function(data){console.log(data)};
  var success_callback=function(data){console.log(data)};
  var queryUserBookCallback = function(result)
  {
    if(result){
       error_callback("BOOK_ALREADY_EXISTS");
       return;
    }
    var bookInfoCallback = function(infodata){
      if(infodata && infodata.title){
          var newbook = new Book();
          newbook.set("detail",infodata);
          newbook.set("title",infodata.title);
          newbook.set("author",infodata.author);
          newbook.set("isbn",isbn);
          newbook.set("owner",User);
          newbook.set("location",new AV.GeoPoint({latitude:locationArray[0], longitude: locationArray[1]}));
          newbook.save(null, {
            success: success_callback,
            error: function(newbook, error) {
              error_callback(error.description);
            }
          });
      } else{
        error_callback("BOOK_INFO_NOT_FOUND");
        return;
      }
    }
    fetchBookInfo(isbn,bookInfoCallback)
  }
  queryUserBook(isbn,queryUserBookCallback);
}

var addBook = function(isbn,infodata,success_callback,error_callback) {
  error_callback=error_callback||function(data){console.log(data)};
  var queryUserBookCallback = function(result){
    if(result){
       error_callback("BOOK_ALREADY_EXISTS");
       return;
    }
      var newbook = new Book();
      newbook.set("detail",infodata);
      newbook.set("title",infodata.title);
      newbook.set("author",infodata.author);
      newbook.set("isbn",isbn);
      newbook.set("owner",User);
      console.log(newbook);
      newbook.save(null, {
        success: success_callback,
        error: function(newbook, error) {
          error_callback(error.description);
        }
      });
      var locationCallback = function(location){
        var streetnameCallback = function(streetname){
           newbook.set("location",new AV.GeoPoint({latitude: location.coords.latitude, longitude: location.coords.longitude}));
           if(streetname.result && streetname.result.addressComponent)
           {
            newbook.set("streetname",streetname.result.addressComponent);
           }
           newbook.save();
        }
        GeoCoding.geoDecodingGPS(location.coords.latitude,location.coords.longitude,streetnameCallback);
      }
    navigator.geolocation.getCurrentPosition(locationCallback);
  }
  queryUserBook(isbn,queryUserBookCallback);
}

var queryUserBook = function(isbn,callback){
  var query = new AV.Query(Book);
  query.equalTo("owner", User);
  query.equalTo("isbn", isbn);
  query.find({
      success: function(results){
        if(results.length){
          callback(results[0]);
        }else{
          callback(false);
        }
      },
      error : function(err){
        callback(false);
      }
    })
}

var removeBook = function(bookobj,success_callback,error_callback){
  error_callback=error_callback || function(data){console.log(data)};
      bookobj.destroy({
        success:success_callback,
        error:error_callback
    });
}

var listNearBook = function(GeoPoint,callback){
  var filterCallback = function (results){
    var symbol = {};
    var res = [];
    for (var idx in results){
      var isbn = results[idx].get("isbn")
      if(isbn && !symbol[isbn]){
          symbol[isbn] = true;
          res.push(results[idx]);
      }
    }
  callback(res);
  }
  var query = new AV.Query(Book);
  query.descending("createdAt");
  query.withinKilometers("location", GeoPoint,5);
  query.include("owner");
  query.notEqualTo("owner", User);
  query.limit(100);
  query.find({
  success: filterCallback
  });
}

var listBookByUser = function(userObj,callback){
  var query = new AV.Query(Book);
  query.equalTo("owner", userObj);
  query.descending("createdAt");
  query.find({
      success: function(results){
        callback(results);
      },
      error: function(err){
        console.log(err);
      }
    });
}

var listUserByBook = function(bookObj,callback)
{
  function queryCallback(results)
  {
    var ownerList = [];
    for (var idx in results){
      ownerList.push(results[idx].get("owner"));
    }
    callback(ownerList);
  }

   var query = new AV.Query(Book);
   query.descending("createdAt");
   query.include("owner");
   query.select("owner");
   query.equalTo("isbn",bookObj.get("isbn"));
   query.find({
    success: queryCallback
    });
}

var AddStreetNameToAllBooks = function()
{
  function queryCallback(results)
  {
    for (var idx in results){
      function temp(){
        var newbook=results[idx];
        var streetnameCallback = function(streetname){
           if(streetname.result && streetname.result.addressComponent)
           {
            newbook.set("streetname",streetname.result.addressComponent);
           }
           newbook.save({success:function(n){console.log(n.get("title")+" succ");}});
        }
        GeoCoding.geoDecodingGeoPoint(newbook.get("location"),streetnameCallback);
        }
        temp();
    }
  }

   var query = new AV.Query(Book);
   query.doesNotExist("streetname");
   query.find({
    success: queryCallback
    });
}
//exports.fakeBookList  = fakeBookList ;
//exports.AddStreetNameToAllBooks = AddStreetNameToAllBooks;
exports.fetchBookInfo = fetchBookInfo;
exports.addBook  = addBook ;
exports.removeBook  = removeBook ;
exports.listNearBook  = listNearBook ;
exports.listBookByUser   = listBookByUser  ;
exports.listUserByBook   = listUserByBook  ;<commit_msg>Revert "fixed 啊"<commit_after>
$ = require("jquery");
var Book =  AV.Object.extend("book");
var User = AV.User.current();
var GeoCoding = require("./geocoding");

var fetchBookInfo=function(isbn,callback,error_callback)
var error_callback=error_callback||function(data){console.log(data)};
{
   $.ajax({
             timeout:3000,
             url:"http://api.douban.com/v2/book/isbn/"+isbn,
             dataType:"jsonp",
             jsonp:"callback",
             success: callback,
             error: error_callback
        });
};

var fakeBookList = function(isbn,locationArray)
{
  var error_callback=function(data){console.log(data)};
  var success_callback=function(data){console.log(data)};
  var queryUserBookCallback = function(result)
  {
    if(result){
       error_callback("BOOK_ALREADY_EXISTS");
       return;
    }
    var bookInfoCallback = function(infodata){
      if(infodata && infodata.title){
          var newbook = new Book();
          newbook.set("detail",infodata);
          newbook.set("title",infodata.title);
          newbook.set("author",infodata.author);
          newbook.set("isbn",isbn);
          newbook.set("owner",User);
          newbook.set("location",new AV.GeoPoint({latitude:locationArray[0], longitude: locationArray[1]}));
          newbook.save(null, {
            success: success_callback,
            error: function(newbook, error) {
              error_callback(error.description);
            }
          });
      } else{
        error_callback("BOOK_INFO_NOT_FOUND");
        return;
      }
    }
    fetchBookInfo(isbn,bookInfoCallback)
  }
  queryUserBook(isbn,queryUserBookCallback);
}

var addBook = function(isbn,infodata,success_callback,error_callback) {
  error_callback=error_callback||function(data){console.log(data)};
  var queryUserBookCallback = function(result){
    if(result){
       error_callback("BOOK_ALREADY_EXISTS");
       return;
    }
      var newbook = new Book();
      newbook.set("detail",infodata);
      newbook.set("title",infodata.title);
      newbook.set("author",infodata.author);
      newbook.set("isbn",isbn);
      newbook.set("owner",User);
      console.log(newbook);
      newbook.save(null, {
        success: success_callback,
        error: function(newbook, error) {
          error_callback(error.description);
        }
      });
      var locationCallback = function(location){
        var streetnameCallback = function(streetname){
           newbook.set("location",new AV.GeoPoint({latitude: location.coords.latitude, longitude: location.coords.longitude}));
           if(streetname.result && streetname.result.addressComponent)
           {
            newbook.set("streetname",streetname.result.addressComponent);
           }
           newbook.save();
        }
        GeoCoding.geoDecodingGPS(location.coords.latitude,location.coords.longitude,streetnameCallback);
      }
    navigator.geolocation.getCurrentPosition(locationCallback);
  }
  queryUserBook(isbn,queryUserBookCallback);
}

var queryUserBook = function(isbn,callback){
  var query = new AV.Query(Book);
  query.equalTo("owner", User);
  query.equalTo("isbn", isbn);
  query.find({
      success: function(results){
        if(results.length){
          callback(results[0]);
        }else{
          callback(false);
        }
      },
      error : function(err){
        callback(false);
      }
    })
}

var removeBook = function(bookobj,success_callback,error_callback){
  error_callback=error_callback || function(data){console.log(data)};
      bookobj.destroy({
        success:success_callback,
        error:error_callback
    });
}

var listNearBook = function(GeoPoint,callback){
  var filterCallback = function (results){
    var symbol = {};
    var res = [];
    for (var idx in results){
      var isbn = results[idx].get("isbn")
      if(isbn && !symbol[isbn]){
          symbol[isbn] = true;
          res.push(results[idx]);
      }
    }
  callback(res);
  }
  var query = new AV.Query(Book);
  query.descending("createdAt");
  query.withinKilometers("location", GeoPoint,5);
  query.include("owner");
  query.notEqualTo("owner", User);
  query.limit(100);
  query.find({
  success: filterCallback
  });
}

var listBookByUser = function(userObj,callback){
  var query = new AV.Query(Book);
  query.equalTo("owner", userObj);
  query.descending("createdAt");
  query.find({
      success: function(results){
        callback(results);
      },
      error: function(err){
        console.log(err);
      }
    });
}

var listUserByBook = function(bookObj,callback)
{
  function queryCallback(results)
  {
    var ownerList = [];
    for (var idx in results){
      ownerList.push(results[idx].get("owner"));
    }
    callback(ownerList);
  }

   var query = new AV.Query(Book);
   query.descending("createdAt");
   query.include("owner");
   query.select("owner");
   query.equalTo("isbn",bookObj.get("isbn"));
   query.find({
    success: queryCallback
    });
}

var AddStreetNameToAllBooks = function()
{
  function queryCallback(results)
  {
    for (var idx in results){
      function temp(){
        var newbook=results[idx];
        var streetnameCallback = function(streetname){
           if(streetname.result && streetname.result.addressComponent)
           {
            newbook.set("streetname",streetname.result.addressComponent);
           }
           newbook.save({success:function(n){console.log(n.get("title")+" succ");}});
        }
        GeoCoding.geoDecodingGeoPoint(newbook.get("location"),streetnameCallback);
        }
        temp();
    }
  }

   var query = new AV.Query(Book);
   query.doesNotExist("streetname");
   query.find({
    success: queryCallback
    });
}
//exports.fakeBookList  = fakeBookList ;
//exports.AddStreetNameToAllBooks = AddStreetNameToAllBooks;
exports.fetchBookInfo = fetchBookInfo;
exports.addBook  = addBook ;
exports.removeBook  = removeBook ;
exports.listNearBook  = listNearBook ;
exports.listBookByUser   = listBookByUser  ;
exports.listUserByBook   = listUserByBook  ;<|endoftext|>


<commit_before>'use strict';
/*
 * Controller for the logout button on the tab bar and side-menu
 * Basically, it closes the PeerJS connection and retuns you to
 * the login screen
 */

angular.module('logout', ['peerhandler'])

    .controller('LogoutCtrl', function($scope, $state, $localStorage,  peerFactory, socketFactory, apiFactory) {
        $scope.logout = function() {

            apiFactory.auth.logout()
                .then(function () {
                    apiFactory.deleteApiToken();

                    var number = $localStorage.user.phoneNumber;

                    // Remove everything except user number so it doesn't have to be typed in every time
                    $localStorage.$reset({
                            user: {
                                phoneNumber: number
                            }
                    })

                    if (peerFactory.isConnected()) {
                        peerFactory.disconnectFromPeerJS();
                    }

                    socketFactory.disconnectFromServer();

                    $state.go('login');
                })
                .catch(function (error) {
                    console.log(error);
                })

        };
});

<commit_msg>Always log out no matter what the api returns<commit_after>'use strict';
/*
 * Controller for the logout button on the tab bar and side-menu
 * Basically, it closes the PeerJS connection and retuns you to
 * the login screen
 */

angular.module('logout', ['peerhandler'])

    .controller('LogoutCtrl', function($scope, $state, $localStorage,  peerFactory, socketFactory, apiFactory) {
        $scope.logout = function() {

            apiFactory.auth.logout()
                .then(function (results) {
                    console.log(results);
                })
                .catch(function (error) {
                    console.log(error);
                })

                apiFactory.deleteApiToken();

                var number = $localStorage.user.phoneNumber;

                // Remove everything except user number so it doesn't have to be typed in every time
                $localStorage.$reset({
                        user: {
                            phoneNumber: number
                        }
                })

                if (peerFactory.isConnected()) {
                    peerFactory.disconnectFromPeerJS();
                }

                socketFactory.disconnectFromServer();

                $state.go('login');
        };
});

<|endoftext|>


<commit_before>import AvailableNetworks from './networks'

let $window = typeof window !== 'undefined' ? window : null

export function mockWindow (self) {
  $window = self || window // mock window for unit testing
}

export default {
  name: 'ShareNetwork',

  props: {
    /**
     * Name of the network to display.
     */
    network: {
      type: String,
      required: true
    },

    /**
     * URL of the content to share.
     */
    url: {
      type: String,
      required: true
    },

    /**
     * Title of the content to share.
     */
    title: {
      type: String,
      required: true
    },

    /**
     * Description of the content to share.
     */
    description: {
      type: String,
      default: ''
    },

    /**
     * Quote content, used for Facebook.
     */
    quote: {
      type: String,
      default: ''
    },

    /**
     * Hashtags, used for Twitter and Facebook.
     */
    hashtags: {
      type: String,
      default: ''
    },

    /**
     * Twitter user, used for Twitter
     * @var string
     */
    twitterUser: {
      type: String,
      default: ''
    },

    /**
     * Media to share, used for Pinterest
     */
    media: {
      type: String,
      default: ''
    },

    /**
     * HTML tag used by the Network component.
     */
    tag: {
      type: String,
      default: 'a'
    },

    /**
     * Properties to configure the popup window.
     */
    popup: {
      type: Object,
      default: () => ({
        width: 626,
        height: 436
      })
    }
  },

  data () {
    return {
      popupTop: 0,
      popupLeft: 0,
      popupWindow: undefined,
      popupInterval: null
    }
  },

  computed: {
    /**
     * List of available networks
     */
    networks () {
      return this.$SocialSharing
        ? this.$SocialSharing.options.networks
        : AvailableNetworks
    },

    /**
     * Formatted network name.
     */
    key () {
      return this.network.toLowerCase()
    },

    /**
     * Network sharing raw sharing link.
     */
    rawLink () {
      const ua = navigator.userAgent.toLowerCase()

      /**
       * On IOS, SMS sharing link need a special formatting
       * Source: https://weblog.west-wind.com/posts/2013/Oct/09/Prefilling-an-SMS-on-Mobile-Devices-with-the-sms-Uri-Scheme#Body-only
       */
      if (this.key === 'sms' && (ua.indexOf('iphone') > -1 || ua.indexOf('ipad') > -1)) {
        return this.networks[this.key].replace(':?', ':&')
      }

      return this.networks[this.key]
    },

    /**
     * Create the url for sharing.
     */
    shareLink () {
      let link = this.rawLink

      /**
       * Twitter sharing shouldn't include empty parameter
       * Source: https://github.com/nicolasbeauvais/vue-social-sharing/issues/143
       */
      if (this.key === 'twitter') {
        if (!this.hashtags.length) link = link.replace('&hashtags=@h', '')
        if (!this.twitterUser.length) link = link.replace('@tu', '')
      }

      return link
        .replace(/@tu/g, '&via=' + encodeURIComponent(this.twitterUser))
        .replace(/@u/g, encodeURIComponent(this.url))
        .replace(/@t/g, encodeURIComponent(this.title))
        .replace(/@d/g, encodeURIComponent(this.description))
        .replace(/@q/g, encodeURIComponent(this.quote))
        .replace(/@h/g, this.encodedHashtags)
        .replace(/@m/g, encodeURIComponent(this.media))
    },

    /**
     * Encoded hashtags for the current social network.
     */
    encodedHashtags () {
      if (this.key === 'facebook' && this.hashtags.length) {
        return '%23' + this.hashtags.split(',')[0]
      }

      return this.hashtags
    }
  },

  render: function (createElement) {
    if (!this.networks.hasOwnProperty(this.key)) {
      throw new Error('Network ' + this.key + ' does not exist')
    }

    const node = {
      class: 'share-network-' + this.key,
      on: {
        click: () => this[this.rawLink.substring(0, 4) === 'http' ? 'share' : 'touch']()
      }
    }

    if (this.tag === 'a') node.attrs = { href: '#' }

    return createElement(this.tag, node, this.$slots.default)
  },

  methods: {
    /**
     * Center the popup on multi-screens
     * http://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen/32261263
     */
    resizePopup () {
      const width = $window.innerWidth || (document.documentElement.clientWidth || $window.screenX)
      const height = $window.innerHeight || (document.documentElement.clientHeight || $window.screenY)
      const systemZoom = width / $window.screen.availWidth

      this.popupLeft = (width - this.popup.width) / 2 / systemZoom + ($window.screenLeft !== undefined ? $window.screenLeft : $window.screenX)
      this.popupTop = (height - this.popup.height) / 2 / systemZoom + ($window.screenTop !== undefined ? $window.screenTop : $window.screenY)
    },

    /**
     * Shares URL in specified network.
     */
    share () {
      this.resizePopup()

      // If a popup window already exist, we close it and trigger a change event.
      if (this.popupWindow && this.popupInterval) {
        clearInterval(this.popupInterval)

        // Force close (for Facebook)
        this.popupWindow.close()

        this.emit('change')
      }

      this.popupWindow = $window.open(
        this.shareLink,
        'sharer-' + this.key,
        ',height=' + this.popup.height +
        ',width=' + this.popup.width +
        ',left=' + this.popupLeft +
        ',top=' + this.popupTop +
        ',screenX=' + this.popupLeft +
        ',screenY=' + this.popupTop
      )

      // If popup are prevented (AdBlocker, Mobile App context..), popup.window stays undefined and we can't display it
      if (!this.popupWindow) return

      this.popupWindow.focus()

      // Create an interval to detect popup closing event
      this.popupInterval = setInterval(() => {
        if (!this.popupWindow || this.popupWindow.closed) {
          clearInterval(this.popupInterval)

          this.popupWindow = null

          this.emit('close')
        }
      }, 500)

      this.emit('open')
    },

    /**
     * Touches network and emits click event.
     */
    touch () {
      window.open(this.shareLink, '_blank')

      this.emit('open')
    },

    emit (name) {
      this.$root.$emit('share_network_' + name, this.key, this.url)
      this.$emit(name, this.key, this.url)
    }
  }
}
<commit_msg>Update share-network.js (#264)<commit_after>import AvailableNetworks from './networks'

let $window = typeof window !== 'undefined' ? window : null

export function mockWindow (self) {
  $window = self || window // mock window for unit testing
}

export default {
  name: 'ShareNetwork',

  props: {
    /**
     * Name of the network to display.
     */
    network: {
      type: String,
      required: true
    },

    /**
     * URL of the content to share.
     */
    url: {
      type: String,
      required: true
    },

    /**
     * Title of the content to share.
     */
    title: {
      type: String,
      required: true
    },

    /**
     * Description of the content to share.
     */
    description: {
      type: String,
      default: ''
    },

    /**
     * Quote content, used for Facebook.
     */
    quote: {
      type: String,
      default: ''
    },

    /**
     * Hashtags, used for Twitter and Facebook.
     */
    hashtags: {
      type: String,
      default: ''
    },

    /**
     * Twitter user, used for Twitter
     * @var string
     */
    twitterUser: {
      type: String,
      default: ''
    },

    /**
     * Media to share, used for Pinterest
     */
    media: {
      type: String,
      default: ''
    },

    /**
     * HTML tag used by the Network component.
     */
    tag: {
      type: String,
      default: 'a'
    },

    /**
     * Properties to configure the popup window.
     */
    popup: {
      type: Object,
      default: () => ({
        width: 626,
        height: 436
      })
    }
  },

  data () {
    return {
      popupTop: 0,
      popupLeft: 0,
      popupWindow: undefined,
      popupInterval: null
    }
  },

  computed: {
    /**
     * List of available networks
     */
    networks () {
      return this.$SocialSharing
        ? this.$SocialSharing.options.networks
        : AvailableNetworks
    },

    /**
     * Formatted network name.
     */
    key () {
      return this.network.toLowerCase()
    },

    /**
     * Network sharing raw sharing link.
     */
    rawLink () {
      const ua = navigator.userAgent.toLowerCase()

      /**
       * On IOS, SMS sharing link need a special formatting
       * Source: https://weblog.west-wind.com/posts/2013/Oct/09/Prefilling-an-SMS-on-Mobile-Devices-with-the-sms-Uri-Scheme#Body-only
       */
      if (this.key === 'sms' && (ua.indexOf('iphone') > -1 || ua.indexOf('ipad') > -1)) {
        return this.networks[this.key].replace(':?', ':&')
      }

      return this.networks[this.key]
    },

    /**
     * Create the url for sharing.
     */
    shareLink () {
      let link = this.rawLink

      /**
       * Twitter sharing shouldn't include empty parameter
       * Source: https://github.com/nicolasbeauvais/vue-social-sharing/issues/143
       */
      if (this.key === 'twitter') {
        if (!this.hashtags.length) link = link.replace('&hashtags=@h', '')
        if (!this.twitterUser.length) link = link.replace('@tu', '')
      }

      return link
        .replace(/@tu/g, '&via=' + encodeURIComponent(this.twitterUser))
        .replace(/@u/g, encodeURIComponent(this.url))
        .replace(/@t/g, encodeURIComponent(this.title))
        .replace(/@d/g, encodeURIComponent(this.description))
        .replace(/@q/g, encodeURIComponent(this.quote))
        .replace(/@h/g, this.encodedHashtags)
        .replace(/@m/g, encodeURIComponent(this.media))
    },

    /**
     * Encoded hashtags for the current social network.
     */
    encodedHashtags () {
      if (this.key === 'facebook' && this.hashtags.length) {
        return '%23' + this.hashtags.split(',')[0]
      }

      return this.hashtags
    }
  },

  render: function (createElement) {
    if (!this.networks.hasOwnProperty(this.key)) {
      throw new Error('Network ' + this.key + ' does not exist')
    }

    const node = {
      class: 'share-network-' + this.key,
      on: {
        click: () => this[this.rawLink.substring(0, 4) === 'http' ? 'share' : 'touch']()
      }
    }

    if (this.tag === 'a') node.attrs = { href: 'javascript:void(0)' }

    return createElement(this.tag, node, this.$slots.default)
  },

  methods: {
    /**
     * Center the popup on multi-screens
     * http://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen/32261263
     */
    resizePopup () {
      const width = $window.innerWidth || (document.documentElement.clientWidth || $window.screenX)
      const height = $window.innerHeight || (document.documentElement.clientHeight || $window.screenY)
      const systemZoom = width / $window.screen.availWidth

      this.popupLeft = (width - this.popup.width) / 2 / systemZoom + ($window.screenLeft !== undefined ? $window.screenLeft : $window.screenX)
      this.popupTop = (height - this.popup.height) / 2 / systemZoom + ($window.screenTop !== undefined ? $window.screenTop : $window.screenY)
    },

    /**
     * Shares URL in specified network.
     */
    share () {
      this.resizePopup()

      // If a popup window already exist, we close it and trigger a change event.
      if (this.popupWindow && this.popupInterval) {
        clearInterval(this.popupInterval)

        // Force close (for Facebook)
        this.popupWindow.close()

        this.emit('change')
      }

      this.popupWindow = $window.open(
        this.shareLink,
        'sharer-' + this.key,
        ',height=' + this.popup.height +
        ',width=' + this.popup.width +
        ',left=' + this.popupLeft +
        ',top=' + this.popupTop +
        ',screenX=' + this.popupLeft +
        ',screenY=' + this.popupTop
      )

      // If popup are prevented (AdBlocker, Mobile App context..), popup.window stays undefined and we can't display it
      if (!this.popupWindow) return

      this.popupWindow.focus()

      // Create an interval to detect popup closing event
      this.popupInterval = setInterval(() => {
        if (!this.popupWindow || this.popupWindow.closed) {
          clearInterval(this.popupInterval)

          this.popupWindow = null

          this.emit('close')
        }
      }, 500)

      this.emit('open')
    },

    /**
     * Touches network and emits click event.
     */
    touch () {
      window.open(this.shareLink, '_blank')

      this.emit('open')
    },

    emit (name) {
      this.$root.$emit('share_network_' + name, this.key, this.url)
      this.$emit(name, this.key, this.url)
    }
  }
}
<|endoftext|>


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

(function(shared, scope, testing) {

  // TODO: SimpleLength(simpleLength), SimpleLength(cssString)
  function SimpleLength(value, type) {
    if (arguments.length == 2 && shared.LengthValue.LengthType.indexOf(type) >= 0) {
      this.type = type;
      if (typeof value == 'number') {
        this.value = value;
      } else if (typeof value == 'string') {
        var nValue = Number.parseFloat(value);
        if (!isNaN(nValue)) {
          this.value = nValue;
        }
      }
    }
    if (this.value == undefined) {
      throw new TypeError('Value of SimpleLength must be a number or a numeric string.');
    }

    this.cssString = this.value + shared.LengthValue.cssStringTypeRepresentation(this.type);
  }

  SimpleLength.prototype = Object.create(shared.LengthValue.prototype);

  SimpleLength.prototype.multiply = function(multiplier) {
    return new SimpleLength((this.value * multiplier), this.type);
  };

  SimpleLength.prototype.divide = function(divider) {
    return new SimpleLength((this.value / divider), this.type);
  };

  SimpleLength.prototype._addSimpleLengths = function(addedLength) {
    if (!(addedLength instanceof SimpleLength)) {
      throw new TypeError('Objects not of type simple length');
    }
    if (this.type != addedLength.type) {
      throw new TypeError('SimpleLength units are not the same');
    }
    return new SimpleLength((this.value + addedLength.value), this.type);
  };

  SimpleLength.prototype._subtractSimpleLengths = function(subtractedLength) {
    if (!(subtractedLength instanceof SimpleLength)) {
      throw new TypeError('Objects not of type simple length');
    }
    if (this.type != subtractedLength.type) {
      throw new TypeError('SimpleLength units are not the same');
    }
    return new SimpleLength((this.value - subtractedLength.value), this.type);
  };

  SimpleLength.prototype._asCalcLength = function() {
    var calcDictionary = {};

    //Set calcDictionary field to the Length type inside the SimpleLength object that called the function
    calcDictionary[this.type] = this.value;

    return new CalcLength(calcDictionary);
  }

  SimpleLength.prototype.equals = function(other) {
    if (!(other instanceof SimpleLength)) {
      return false;
    }
    if (!(this.type == other.type && this.value == other.value)) {
      return false;
    }
    return true;
  };

  scope.SimpleLength = SimpleLength;
  if (TYPED_OM_TESTING)
    testing.SimpleLength = SimpleLength;

})(baseClasses, window, typedOMTesting);
<commit_msg>Fixed formatting issues found using gjslint for the SimpleLength class<commit_after>// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//     You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//     See the License for the specific language governing permissions and
// limitations under the License.

(function(shared, scope, testing) {

  // TODO: SimpleLength(simpleLength), SimpleLength(cssString)
  function SimpleLength(value, type) {
    if (arguments.length == 2 && shared.LengthValue.LengthType.indexOf(type) >= 0) {
      this.type = type;
      if (typeof value == 'number') {
        this.value = value;
      } else if (typeof value == 'string') {
        var nValue = Number.parseFloat(value);
        if (!isNaN(nValue)) {
          this.value = nValue;
        }
      }
    }
    if (this.value == undefined) {
      throw new TypeError('Value of SimpleLength must be a number or a numeric string.');
    }

    this.cssString = this.value + shared.LengthValue.cssStringTypeRepresentation(this.type);
  }

  SimpleLength.prototype = Object.create(shared.LengthValue.prototype);

  SimpleLength.prototype.multiply = function(multiplier) {
    return new SimpleLength((this.value * multiplier), this.type);
  };

  SimpleLength.prototype.divide = function(divider) {
    return new SimpleLength((this.value / divider), this.type);
  };

  SimpleLength.prototype._addSimpleLengths = function(addedLength) {
    if (!(addedLength instanceof SimpleLength)) {
      throw new TypeError('Objects not of type simple length');
    }
    if (this.type != addedLength.type) {
      throw new TypeError('SimpleLength units are not the same');
    }
    return new SimpleLength((this.value + addedLength.value), this.type);
  };

  SimpleLength.prototype._subtractSimpleLengths = function(subtractedLength) {
    if (!(subtractedLength instanceof SimpleLength)) {
      throw new TypeError('Objects not of type simple length');
    }
    if (this.type != subtractedLength.type) {
      throw new TypeError('SimpleLength units are not the same');
    }
    return new SimpleLength((this.value - subtractedLength.value), this.type);
  };

  SimpleLength.prototype._asCalcLength = function() {
    var calcDictionary = {};

    //Set calcDictionary field to the Length type inside the SimpleLength object that called the function
    calcDictionary[this.type] = this.value;

    return new CalcLength(calcDictionary);
  };

  SimpleLength.prototype.equals = function(other) {
    if (!(other instanceof SimpleLength)) {
      return false;
    }
    if (!(this.type == other.type && this.value == other.value)) {
      return false;
    }
    return true;
  };

  scope.SimpleLength = SimpleLength;
  if (TYPED_OM_TESTING)
    testing.SimpleLength = SimpleLength;

})(baseClasses, window, typedOMTesting);
<|endoftext|>


<commit_before>import { isWhitespaceChar, isSymbolChar } from './utils';

function _parse_list(state) {
  state.position++; // (
  const list = [];
  while (state.input[state.position] !== ')') {
    list.push(_parse(state));
  }
  state.position++; // )
  return list;
}

function _parse_string(state) {
  const token = state.input[state.position];
  state.position++;
  let str = "";

  while (state.input[state.position] !== token) {
    str += state.input[state.position];
    state.position++;
  }

  return token + str + token;
}

function _parse_symbol(state) {
  let symbol = "";
  while (isSymbolChar(state.input[state.position])) {
    symbol += state.input[state.position];
    state.position++;
  }
  return symbol;
}

function _parse(state) {
  while (isWhitespaceChar(state.input[state.position])) {
    state.position++;
  }
  const ch = state.input[state.position];

  if (ch === '(') {
    return _parse_list(state);
  }

  if (ch === '"' || ch === "'") {
    return _parse_string(state);
  }

  return _parse_symbol(state);
}

export function parse(input) {
  return _parse({
    input,
    position: 0
  });
}
<commit_msg>fixes for parse tests<commit_after>import { isWhitespaceChar, isSymbolChar } from './utils';

function _parse_list(state) {
  state.position++; // (
  const list = [];
  while (state.input[state.position] !== ')') {
    list.push(_parse(state));
  }
  state.position++; // )
  return list;
}

function _parse_string(state) {
  const token = state.input[state.position];
  state.position++; // move past opening token
  let str = "";

  while (state.input[state.position] !== token) {
    str += state.input[state.position];
    state.position++;
  }

  state.position++; // move past closing token
  return token + str + token;
}

function _parse_symbol(state) {
  let symbol = "";
  while (isSymbolChar(state.input[state.position])) {
    symbol += state.input[state.position];
    state.position++;
  }
  return symbol;
}

function _parse(state) {
  while (isWhitespaceChar(state.input[state.position])) {
    state.position++;
  }
  const ch = state.input[state.position];

  if (ch === '(') {
    return _parse_list(state);
  }

  if (ch === '"' || ch === "'") {
    return _parse_string(state);
  }

  return _parse_symbol(state);
}

export function parse(input = "()") {
  return _parse({
    input,
    position: 0
  });
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Link } from 'react-router'
import { Person } from 'blockstack-profiles'

import AddressBar from '../components/AddressBar'
import { IdentityItem } from '../components/index'
import { IdentityActions } from '../store/identities'
import { AccountActions } from '../store/account'

function mapStateToProps(state) {
  return {
    localIdentities: state.identities.localIdentities,
    lastNameLookup: state.identities.lastNameLookup,
    identityAddresses: state.account.identityAccount.addresses,
    addressLookupUrl: state.settings.api.addressLookupUrl || ''
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(Object.assign({}, IdentityActions, AccountActions), dispatch)
}

class IdentityPage extends Component {
  static propTypes = {
    localIdentities: PropTypes.object.isRequired,
    createNewIdentity: PropTypes.func.isRequired,
    refreshIdentities: PropTypes.func.isRequired,
    addressLookupUrl: PropTypes.string.isRequired,
    lastNameLookup: PropTypes.array.isRequired
  }

  constructor(props) {
    super(props)

    this.state = {
      localIdentities: this.props.localIdentities
    }
  }

  componentWillMount() {
    this.props.refreshIdentities(
      this.props.identityAddresses,
      this.props.addressLookupUrl,
      this.props.localIdentities,
      this.props.lastNameLookup
    )
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      localIdentities: nextProps.localIdentities
    })
  }

  render() {
    return (

                  Profiles

                  Utility

              <AddressBar placeholder="Search for people" />

My Profiles

                {Object.keys(this.state.localIdentities).map((domainName) => {
                  const identity = this.state.localIdentities[domainName],
                        person = new Person(identity.profile)
                  if (identity.domainName) {
                    return (
                      <IdentityItem key={identity.domainName}
                        label={identity.domainName}
                        pending={!identity.registered}
                        avatarUrl={person.avatarUrl() || ''}
                        url={`/profile/local/${identity.domainName}`} />
                    )
                  }
                })}
                {Object.keys(this.state.localIdentities).map((domainName) => {
                  const identity = this.state.localIdentities[domainName],
                        person = new Person(identity.profile)
                  if (identity.domainName) {
                    return (
                      <IdentityItem key={identity.domainName}
                        label={identity.domainName}
                        pending={!identity.registered}
                        avatarUrl={person.avatarUrl() || ''}
                        url={`/profile/local/${identity.domainName}`} />
                    )
                  }
                })}
                {Object.keys(this.state.localIdentities).map((domainName) => {
                  const identity = this.state.localIdentities[domainName],
                        person = new Person(identity.profile)
                  if (identity.domainName) {
                    return (
                      <IdentityItem key={identity.domainName}
                        label={identity.domainName}
                        pending={!identity.registered}
                        avatarUrl={person.avatarUrl() || ''}
                        url={`/profile/local/${identity.domainName}`} />
                    )
                  }
                })}
                {Object.keys(this.state.localIdentities).map((domainName) => {
                  const identity = this.state.localIdentities[domainName],
                        person = new Person(identity.profile)
                  if (identity.domainName) {
                    return (
                      <IdentityItem key={identity.domainName}
                        label={identity.domainName}
                        pending={!identity.registered}
                        avatarUrl={person.avatarUrl() || ''}
                        url={`/profile/local/${identity.domainName}`} />
                    )
                  }
                })}
                {Object.keys(this.state.localIdentities).map((domainName) => {
                  const identity = this.state.localIdentities[domainName],
                        person = new Person(identity.profile)
                  if (identity.domainName) {
                    return (
                      <IdentityItem key={identity.domainName}
                        label={identity.domainName}
                        pending={!identity.registered}
                        avatarUrl={person.avatarUrl() || ''}
                        url={`/profile/local/${identity.domainName}`} />
                    )
                  }
                })}

              <Link to="/names/register" className="btn btn-blue btn-lg" role="button" >
                +
              </Link>

    )
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(IdentityPage)<commit_msg>removed multiple profile cards from identitypage.js<commit_after>import React, { Component, PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Link } from 'react-router'
import { Person } from 'blockstack-profiles'

import AddressBar from '../components/AddressBar'
import { IdentityItem } from '../components/index'
import { IdentityActions } from '../store/identities'
import { AccountActions } from '../store/account'

function mapStateToProps(state) {
  return {
    localIdentities: state.identities.localIdentities,
    lastNameLookup: state.identities.lastNameLookup,
    identityAddresses: state.account.identityAccount.addresses,
    addressLookupUrl: state.settings.api.addressLookupUrl || ''
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(Object.assign({}, IdentityActions, AccountActions), dispatch)
}

class IdentityPage extends Component {
  static propTypes = {
    localIdentities: PropTypes.object.isRequired,
    createNewIdentity: PropTypes.func.isRequired,
    refreshIdentities: PropTypes.func.isRequired,
    addressLookupUrl: PropTypes.string.isRequired,
    lastNameLookup: PropTypes.array.isRequired
  }

  constructor(props) {
    super(props)

    this.state = {
      localIdentities: this.props.localIdentities
    }
  }

  componentWillMount() {
    this.props.refreshIdentities(
      this.props.identityAddresses,
      this.props.addressLookupUrl,
      this.props.localIdentities,
      this.props.lastNameLookup
    )
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      localIdentities: nextProps.localIdentities
    })
  }

  render() {
    return (

                  Profiles

                  Utility

              <AddressBar placeholder="Search for people" />

My Profiles

                {Object.keys(this.state.localIdentities).map((domainName) => {
                  const identity = this.state.localIdentities[domainName],
                        person = new Person(identity.profile)
                  if (identity.domainName) {
                    return (
                      <IdentityItem key={identity.domainName}
                        label={identity.domainName}
                        pending={!identity.registered}
                        avatarUrl={person.avatarUrl() || ''}
                        url={`/profile/local/${identity.domainName}`} />
                    )
                  }
                })}

              <Link to="/names/register" className="btn btn-blue btn-lg" role="button" >
                +
              </Link>

    )
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(IdentityPage)<|endoftext|>