<commit_before>import React from 'react';
import { Icon } from 'react-native-elements';
import {
  Text,
  View,
  TouchableOpacity,
} from 'react-native';
import PropTypes from 'prop-types';
import { NavButton } from 'react-native-nav';
import { Actions } from 'react-native-router-flux';
import { CachedImage } from 'react-native-img-cache';
import UserAvatar from 'react-native-user-avatar';
import { AppUtil } from 'roverz-chat';
import { AppStyles, AppColors } from '../../theme/';
import Group from '../../models/group';
import Network from '../../network';
import Application from '../../constants/config';

class ChatNavBar extends React.Component {
  constructor(props) {
    super(props);
    const obj = this.props.obj;
    this._net = new Network();
    this.displayName = obj.name;
    this.displayTitle = obj.title;
    this.roomType = obj.type;
    this.avatarUri = obj.avatar;
    this.state = {
      obj,
      displayName: this.displayName,
      displayTitle: this.displayTitle,
      avatarUri: this.avatarUri,
      showAvatar: true,
      roomType: this.roomType,
    };
    this.goToRoomInfo = this.goToRoomInfo.bind(this);
  }

  componentDidMount() {
  }

  setAvType() {
    if (this.state.roomType === 'private') {
      return 'lock';
    } else if (this.state.roomType === 'direct') {
      return 'perm-identity';
    }
    return 'supervisor-account';
  }

  _renderAvatar() {
    if (this.state.showAvatar) {
      return (
        <View
          style={{
            width: 36,
            height: 36,
            paddingHorizontal: 7,
            justifyContent: 'center',
            alignItems: 'center',
          }}
        >
          <CachedImage
            style={{
              width: 36,
              height: 36,
              borderRadius: 18,
              position: 'absolute',
              zIndex: 20,
              left: 0,
              top: 0,
            }}
            source={{ uri: this.avatarUri }}
            onError={() => { this._hideAvatarView(); }}
          />
          <UserAvatar
            name={AppUtil.avatarInitials(this.state.displayTitle ? this.state.displayTitle : this.state.displayName)}
            size={36}
            style={{
              position: 'absolute',
              zIndex: 10,
              left: -18,
              top: -18,
            }}
          />
        </View>
      );
    }
    return (
      <View
        style={{
          width: 36,
          height: 36,
          paddingHorizontal: 7,
          justifyContent: 'center',
          alignItems: 'center',
        }}
      >
        <UserAvatar
          name={AppUtil.avatarInitials(this.state.displayTitle ? this.state.displayTitle : this.state.displayName)}
          size={36}
          style={{
            position: 'absolute',
            zIndex: 20,
            left: -18,
            top: -18,
          }}
        />
      </View>
    );
  }

  _hideAvatarView() {
    this.setState({
      showAvatar: false,
    });
  }

  iconType() {
    switch (this.state.roomType) {
      case 'direct':
        return 'at';
      case 'public':
        return 'pound';
      case 'private':
        return 'lock';
      default:
        return 'pound';
    }
  }

  iconColor() {
    return 'rgba(255, 255, 255, 0.3)';
  }

  chooseAvIcon(icon) {
    return (
      <Icon
        name={icon}
        type="material-community"
        size={16}
        style={{ width: 20 }}
        color={this.iconColor()}
      />
    );
  }

  goToRoomInfo() {
    if (this.state.roomType !== 'direct') {
      Actions.roomInfo({
        group: this.state.obj,
        roomName: this.state.displayName,
        roomTitle: this.state.displayTitle,
        duration: 0,
      });
    } else {
      const user = this._net.chat.findUserByUserName(this.state.displayName);
      if (user) {
        Actions.memberDetail({ memberId: user._id, duration: 0 });
      }
    }
  }

  renderAvIcon() {
    switch (this.state.roomType) {
      case 'direct':
        return this.chooseAvIcon('at');
      case 'public':
        return this.chooseAvIcon('pound');
      case 'private':
        return this.chooseAvIcon('lock');
      default:
        return this.chooseAvIcon('pound');
    }
  }

  renderSearchIcon() {
    return (
      <NavButton
        style={{ width: 40, height: 50, justifyContent: 'center', alignItems: 'center' }}
        onPress={() => Actions.messageSearch({ group: this.state.obj })}
      >
        <Icon
          name="search"
          size={24}
          color={'#FFF'}
        />
      </NavButton>
    );
  }

  renderUploads() {
    return (
      <NavButton
        style={{ width: 40, height: 50, justifyContent: 'center', alignItems: 'center' }}
        onPress={() => Actions.photoBrowser({ group: this.state.obj })}
      >
        <Icon
          name="insert-photo"
          size={24}
          color={'#FFF'}
        />
      </NavButton>
    );
  }

  renderVideoConfIcon() {
    const gname = this.state.obj.name;
    const user = this._net.chat.getCurrentUser();
    return (
      <NavButton
        style={{ width: 40, height: 50, justifyContent: 'center', alignItems: 'center' }}
        onPress={() => {
          Actions.videoConference({
            instance: Application.instance,
            groupName: gname,
            userID: user ? user._id : 'unknown',
          });
        }}
      >
        <Icon
          name="videocam"
          size={32}
          color={'#FFF'}
        />
      </NavButton>
    );
  }

  render() {
    return (
      <View style={[AppStyles.navbar, AppStyles.navbarHeight, {
        position: 'absolute',
        top: 0,
        right: 0,
        left: 0,
        flex: 1,
        paddingLeft: 0,
        flexDirection: 'row',
        paddingRight: 10,
        alignItems: 'center',
        backgroundColor: AppColors.brand().secondary,
      }]}
      >
        <NavButton
          style={{ width: 35, paddingRight: 15, justifyContent: 'center', alignItems: 'flex-start' }}
          // onPress={() => { Actions.groups({ type: 'replace', duration: 0 }); }}
          onPress={() => { Actions.pop(); }}
        >
          <Icon
            name="keyboard-arrow-left"
            size={32}
            color={'#FFF'}
          />
        </NavButton>
        <TouchableOpacity
          style={{
            flex: 1,
            justifyContent: 'flex-start',
            flexDirection: 'row',
            alignItems: 'center',
          }}
          onPress={this.goToRoomInfo}
        >
          {this._renderAvatar()}
          <View style={{ flex: 1, zIndex: 200, flexDirection: 'column', justifyContent: 'center' }}>
            <View style={{ flexDirection: 'row' }}>
              {this.renderAvIcon()}
              <Text
                numberOfLines={1}
                style={[AppStyles.navbarTitle, {
                  textAlign: 'left',
                  flex: 1,
                  fontSize: 14,
                }]}
              >
                {this.state.displayName}
              </Text>
            </View>
            {(!!this.state.displayTitle &&
              <Text
                numberOfLines={1}
                style={[AppStyles.navbarTitle,
                { color: 'rgba(255,255,255,0.5)', fontSize: 12, marginBottom: 5, paddingLeft: 2, textAlign: 'left' }]}
              >{this.state.displayTitle}</Text>
            )}
          </View>
        </TouchableOpacity>
        {this.renderVideoConfIcon()}
      </View>
    );
  }
}

ChatNavBar.defaultProps = {
  obj: null,
};

ChatNavBar.propTypes = {
  obj: PropTypes.instanceOf(Group),
};

/* Export Component ==================================================================== */
export default ChatNavBar;
<commit_msg> added md5 hex functionality<commit_after>import React from 'react';
import { Icon } from 'react-native-elements';
import {
  Text,
  View,
  TouchableOpacity,
} from 'react-native';
import md5 from 'react-native-md5';
import PropTypes from 'prop-types';
import { NavButton } from 'react-native-nav';
import { Actions } from 'react-native-router-flux';
import { CachedImage } from 'react-native-img-cache';
import UserAvatar from 'react-native-user-avatar';
import { AppUtil } from 'roverz-chat';
import { AppStyles, AppColors } from '../../theme/';
import Group from '../../models/group';
import Network from '../../network';
import Application from '../../constants/config';

class ChatNavBar extends React.Component {
  constructor(props) {
    super(props);
    const obj = this.props.obj;
    this._net = new Network();
    this.displayName = obj.name;
    this.displayTitle = obj.title;
    this.roomType = obj.type;
    this.avatarUri = obj.avatar;
    this.state = {
      obj,
      displayName: this.displayName,
      displayTitle: this.displayTitle,
      avatarUri: this.avatarUri,
      showAvatar: true,
      roomType: this.roomType,
    };
    this.goToRoomInfo = this.goToRoomInfo.bind(this);
  }

  componentDidMount() {
  }

  setAvType() {
    if (this.state.roomType === 'private') {
      return 'lock';
    } else if (this.state.roomType === 'direct') {
      return 'perm-identity';
    }
    return 'supervisor-account';
  }

  _renderAvatar() {
    if (this.state.showAvatar) {
      return (
        <View
          style={{
            width: 36,
            height: 36,
            paddingHorizontal: 7,
            justifyContent: 'center',
            alignItems: 'center',
          }}
        >
          <CachedImage
            style={{
              width: 36,
              height: 36,
              borderRadius: 18,
              position: 'absolute',
              zIndex: 20,
              left: 0,
              top: 0,
            }}
            source={{ uri: this.avatarUri }}
            onError={() => { this._hideAvatarView(); }}
          />
          <UserAvatar
            name={AppUtil.avatarInitials(this.state.displayTitle ? this.state.displayTitle : this.state.displayName)}
            size={36}
            style={{
              position: 'absolute',
              zIndex: 10,
              left: -18,
              top: -18,
            }}
          />
        </View>
      );
    }
    return (
      <View
        style={{
          width: 36,
          height: 36,
          paddingHorizontal: 7,
          justifyContent: 'center',
          alignItems: 'center',
        }}
      >
        <UserAvatar
          name={AppUtil.avatarInitials(this.state.displayTitle ? this.state.displayTitle : this.state.displayName)}
          size={36}
          style={{
            position: 'absolute',
            zIndex: 20,
            left: -18,
            top: -18,
          }}
        />
      </View>
    );
  }

  _hideAvatarView() {
    this.setState({
      showAvatar: false,
    });
  }

  iconType() {
    switch (this.state.roomType) {
      case 'direct':
        return 'at';
      case 'public':
        return 'pound';
      case 'private':
        return 'lock';
      default:
        return 'pound';
    }
  }

  iconColor() {
    return 'rgba(255, 255, 255, 0.3)';
  }

  chooseAvIcon(icon) {
    return (
      <Icon
        name={icon}
        type="material-community"
        size={16}
        style={{ width: 20 }}
        color={this.iconColor()}
      />
    );
  }

  goToRoomInfo() {
    if (this.state.roomType !== 'direct') {
      Actions.roomInfo({
        group: this.state.obj,
        roomName: this.state.displayName,
        roomTitle: this.state.displayTitle,
        duration: 0,
      });
    } else {
      const user = this._net.chat.findUserByUserName(this.state.displayName);
      if (user) {
        Actions.memberDetail({ memberId: user._id, duration: 0 });
      }
    }
  }

  renderAvIcon() {
    switch (this.state.roomType) {
      case 'direct':
        return this.chooseAvIcon('at');
      case 'public':
        return this.chooseAvIcon('pound');
      case 'private':
        return this.chooseAvIcon('lock');
      default:
        return this.chooseAvIcon('pound');
    }
  }

  renderSearchIcon() {
    return (
      <NavButton
        style={{ width: 40, height: 50, justifyContent: 'center', alignItems: 'center' }}
        onPress={() => Actions.messageSearch({ group: this.state.obj })}
      >
        <Icon
          name="search"
          size={24}
          color={'#FFF'}
        />
      </NavButton>
    );
  }

  renderUploads() {
    return (
      <NavButton
        style={{ width: 40, height: 50, justifyContent: 'center', alignItems: 'center' }}
        onPress={() => Actions.photoBrowser({ group: this.state.obj })}
      >
        <Icon
          name="insert-photo"
          size={24}
          color={'#FFF'}
        />
      </NavButton>
    );
  }

  renderVideoConfIcon() {
    const gname = this.state.obj.name;
    const user = this._net.chat.getCurrentUser();
    return (
      <NavButton
        style={{ width: 40, height: 50, justifyContent: 'center', alignItems: 'center' }}
        onPress={() => {
          Actions.videoConference({
            instance: Application.instance,
            groupName: gname,
            userID: user ? md5.hex_md5(user._id) : '0',
          });
        }}
      >
        <Icon
          name="videocam"
          size={32}
          color={'#FFF'}
        />
      </NavButton>
    );
  }

  render() {
    return (
      <View style={[AppStyles.navbar, AppStyles.navbarHeight, {
        position: 'absolute',
        top: 0,
        right: 0,
        left: 0,
        flex: 1,
        paddingLeft: 0,
        flexDirection: 'row',
        paddingRight: 10,
        alignItems: 'center',
        backgroundColor: AppColors.brand().secondary,
      }]}
      >
        <NavButton
          style={{ width: 35, paddingRight: 15, justifyContent: 'center', alignItems: 'flex-start' }}
          // onPress={() => { Actions.groups({ type: 'replace', duration: 0 }); }}
          onPress={() => { Actions.pop(); }}
        >
          <Icon
            name="keyboard-arrow-left"
            size={32}
            color={'#FFF'}
          />
        </NavButton>
        <TouchableOpacity
          style={{
            flex: 1,
            justifyContent: 'flex-start',
            flexDirection: 'row',
            alignItems: 'center',
          }}
          onPress={this.goToRoomInfo}
        >
          {this._renderAvatar()}
          <View style={{ flex: 1, zIndex: 200, flexDirection: 'column', justifyContent: 'center' }}>
            <View style={{ flexDirection: 'row' }}>
              {this.renderAvIcon()}
              <Text
                numberOfLines={1}
                style={[AppStyles.navbarTitle, {
                  textAlign: 'left',
                  flex: 1,
                  fontSize: 14,
                }]}
              >
                {this.state.displayName}
              </Text>
            </View>
            {(!!this.state.displayTitle &&
              <Text
                numberOfLines={1}
                style={[AppStyles.navbarTitle,
                { color: 'rgba(255,255,255,0.5)', fontSize: 12, marginBottom: 5, paddingLeft: 2, textAlign: 'left' }]}
              >{this.state.displayTitle}</Text>
            )}
          </View>
        </TouchableOpacity>
        {this.renderVideoConfIcon()}
      </View>
    );
  }
}

ChatNavBar.defaultProps = {
  obj: null,
};

ChatNavBar.propTypes = {
  obj: PropTypes.instanceOf(Group),
};

/* Export Component ==================================================================== */
export default ChatNavBar;
<|endoftext|>


<commit_before>/* global history */
/**
 * Marionette Routing
 *
 * Copyright © 2015-2016 Luiz Américo Pereira Câmara. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import _ from 'underscore'
import Radio from 'backbone.radio'
import Cherrytree from 'cherrytreex'
import Route from './route'

let mnRouteMap = Object.create(null)
export const routerChannel = Radio.channel('router')
let router

export function createRouter (options) {
  if (router) {
    throw new Error('Instance of router already created')
  }
  router = Route.prototype.$router = new Cherrytree(options)
  return router
}

export function destroyRouter (instance) {
  router = null
  Route.prototype.$router = null
  mnRouteMap = Object.create(null)
  instance.destroy()
}

export function getMnRoutes (routes) {
  return routes.map(function (route) {
    return mnRouteMap[route.name]
  })
}

routerChannel.reply('transitionTo', function () {
  return router.transitionTo.apply(router, arguments)
})

routerChannel.reply('isActive', function () {
  return router.isActive.apply(router, arguments)
})

routerChannel.reply('generate', function () {
  return router.generate.apply(router, arguments)
})

routerChannel.reply('goBack', function () {
  // in wait of a better implementation
  history.back()
})

function getChangingIndex (prevRoutes, currentRoutes) {
  let index, prev, current
  const count = Math.max(prevRoutes.length, currentRoutes.length)
  for (index = 0; index < count; index++) {
    prev = prevRoutes[index]
    current = currentRoutes[index]
    if (!(prev && current) || (prev.name !== current.name) || !_.isEqual(prev.params, current.params)) {
      break
    }
  }
  return index
}

function findRouteConfig (routeName, index, routes) {
  let parentRoutes = routes.slice(0, index).reverse().map(function (route) {
    return mnRouteMap[route.name]
  })
  let config
  parentRoutes.some(function (route) {
    let childRoutes = _.result(route, 'childRoutes')
    config = childRoutes && childRoutes[routeName]
    if (_.isFunction(config) && !(config.prototype instanceof Route)) {
      config = config.call(route)
    }
    return config
  })
  return config
}

function createRouteInstance (options, config) {
  if (options.__esModule) options = options.default
  if (options.prototype instanceof Route) {
    return new options(undefined, config) // eslint-disable-line new-cap
  }
  let routeOptions = _.extend({}, options.routeOptions, _.pick(options, ['viewClass', 'viewOptions']))
  if (options.routeClass) {
    return new options.routeClass(routeOptions, config) // eslint-disable-line new-cap
  } else if (options.viewClass) {
    return new Route(routeOptions, config)
  }
}

function createMnRoute (route, index, routes) {
  let instanceConfig = {
    name: route.name,
    path: route.path,
    options: _.clone(route.options)
  }
  let instance = createRouteInstance(route.options, instanceConfig)
  if (!instance) {
    let routeConfig = findRouteConfig(route.name, index, routes)
    return Promise.resolve(routeConfig).then(function (options) {
      return options && createRouteInstance(options, instanceConfig)
    })
  }
  return instance
}

function getParentRegion (routes, route) {
  let region, parent
  let routeIndex = routes.indexOf(route) - 1
  while (routeIndex >= 0) {
    parent = routes[routeIndex]
    if (parent.view && parent.$config.options.outlet !== false) {
      region = parent.getOutlet()
      if (region) {
        return region
      } else {
        throw new Error(`No outlet region defined in ${parent.$config.name} route`)
      }
    }
    routeIndex--
  }
  return router.rootRegion
}

function renderViews (mnRoutes, activated, transition) {
  // ensure at least the target (last) route is rendered
  let renderCandidates = activated.length ? activated : mnRoutes.slice(-1)

  let renderQueue = renderCandidates.reduce(function (memo, mnRoute) {
    if (mnRoute.viewClass) {
      if (memo.length && memo[memo.length - 1].$config.options.outlet === false) {
        memo.pop()
      }
      memo.push(mnRoute)
    }
    return memo
  }, [])

  renderQueue.forEach(function (mnRoute) {
    let parentRegion = getParentRegion(mnRoutes, mnRoute)
    mnRoute.renderView(parentRegion, transition)
  })
}

function runAsyncMethod (transition, routes, method) {
  return routes.reduce(function (prevPromise, mnRoute) {
    routerChannel.trigger(`before:${method}`, transition, mnRoute)
    return prevPromise.then(function () {
      if (!transition.isCancelled) {
        return Promise.resolve(mnRoute[method](transition)).then(function () {
          if (!transition.isCancelled) {
            routerChannel.trigger(method, transition, mnRoute)
          }
        })
      }
      return Promise.resolve()
    })
  }, Promise.resolve())
}

function isActivatingRoute (route) {
  return this.activating && this.activating.indexOf(route) !== -1
}

function isTargetRoute (route) {
  return this.mnRoutes && this.mnRoutes.indexOf(route) === this.mnRoutes.length - 1
}

export const middleware = {
  next: function routeResolver (transition) {
    transition.isActivating = isActivatingRoute
    transition.isTarget = isTargetRoute

    routerChannel.trigger('before:transition', transition)

    if (transition.isCancelled) return

    let prevRoutes = transition.prev.routes
    let changingIndex = getChangingIndex(prevRoutes, transition.routes)
    let deactivated = []
    let routeIndex, routeInstance

    // deactivate previous routes
    for (routeIndex = prevRoutes.length - 1; routeIndex >= changingIndex; routeIndex--) {
      routeInstance = mnRouteMap[prevRoutes[routeIndex].name]
      if (routeInstance) {
        deactivated.push(routeInstance)
      }
    }

    let promise = runAsyncMethod(transition, deactivated, 'deactivate')

    // build route tree and creating instances if necessary
    let mnRoutes = transition.mnRoutes = []

    promise = promise.then(() => {
      return transition.routes.reduce(function (acc, route, i, routes) {
        return acc.then(function (res) {
          let instance = mnRouteMap[route.name]
          if (instance) {
            res.push(instance)
            return res
          } else {
            instance = createMnRoute(route, i, routes)
            return Promise.resolve(instance).then(function (mnRoute) {
              if (!mnRoute) {
                throw new Error(`Unable to create route ${route.name}: routeClass or viewClass must be defined`)
              }
              mnRouteMap[route.name] = mnRoute
              res.push(mnRoute)
              return res
            })
          }
        })
      }, Promise.resolve(mnRoutes))
    })

    // activate routes in order
    let activated

    promise = promise.then(function () {
      activated = transition.activating = mnRoutes.slice(changingIndex)
      return runAsyncMethod(transition, activated, 'activate')
    })

    promise.catch(() => {
      // catch errors occurred inside routing classes / methods
      // Should be handled in error event or in a transition.catch method
    })

    // render views
    return promise.then(function () {
      if (transition.isCancelled) return

      let loadPromise = mnRoutes.reduce(function (prevPromise, mnRoute) {
        let nextPromise = prevPromise
        if (_.isFunction(mnRoute.load)) {
          if (prevPromise) {
            return prevPromise.then(function () {
              return Promise.resolve(mnRoute.load(transition))
            }).catch(function () {
              return Promise.resolve(mnRoute.load(transition))
            })
          } else {
            return Promise.resolve(mnRoute.load(transition))
          }
        }
        return nextPromise
      }, undefined)

      if (loadPromise) {
        return new Promise(function (resolve) {
          loadPromise.then(function () {
            renderViews(mnRoutes, activated, transition)
            resolve()
          }).catch(function () {
            renderViews(mnRoutes, activated, transition)
            resolve()
          })
        })
      } else {
        renderViews(mnRoutes, activated, transition)
      }
    })
  },

  done: function (transition) {
    router.state.mnRoutes = transition.mnRoutes
    routerChannel.trigger('transition', transition)
    transition.activating = []
  },

  error: function (transition, err) {
    transition.activating = []
    if (err.type !== 'TransitionCancelled' && err.type !== 'TransitionRedirected') {
      routerChannel.trigger('transition:error', transition, err)
    }
  }
}
<commit_msg>Reduce number of promises when running lifecycle methods<commit_after>/* global history */
/**
 * Marionette Routing
 *
 * Copyright © 2015-2016 Luiz Américo Pereira Câmara. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import _ from 'underscore'
import Radio from 'backbone.radio'
import Cherrytree from 'cherrytreex'
import Route from './route'

let mnRouteMap = Object.create(null)
export const routerChannel = Radio.channel('router')
let router

export function createRouter (options) {
  if (router) {
    throw new Error('Instance of router already created')
  }
  router = Route.prototype.$router = new Cherrytree(options)
  return router
}

export function destroyRouter (instance) {
  router = null
  Route.prototype.$router = null
  mnRouteMap = Object.create(null)
  instance.destroy()
}

export function getMnRoutes (routes) {
  return routes.map(function (route) {
    return mnRouteMap[route.name]
  })
}

routerChannel.reply('transitionTo', function () {
  return router.transitionTo.apply(router, arguments)
})

routerChannel.reply('isActive', function () {
  return router.isActive.apply(router, arguments)
})

routerChannel.reply('generate', function () {
  return router.generate.apply(router, arguments)
})

routerChannel.reply('goBack', function () {
  // in wait of a better implementation
  history.back()
})

function getChangingIndex (prevRoutes, currentRoutes) {
  let index, prev, current
  const count = Math.max(prevRoutes.length, currentRoutes.length)
  for (index = 0; index < count; index++) {
    prev = prevRoutes[index]
    current = currentRoutes[index]
    if (!(prev && current) || (prev.name !== current.name) || !_.isEqual(prev.params, current.params)) {
      break
    }
  }
  return index
}

function findRouteConfig (routeName, index, routes) {
  let parentRoutes = routes.slice(0, index).reverse().map(function (route) {
    return mnRouteMap[route.name]
  })
  let config
  parentRoutes.some(function (route) {
    let childRoutes = _.result(route, 'childRoutes')
    config = childRoutes && childRoutes[routeName]
    if (_.isFunction(config) && !(config.prototype instanceof Route)) {
      config = config.call(route)
    }
    return config
  })
  return config
}

function createRouteInstance (options, config) {
  if (options.__esModule) options = options.default
  if (options.prototype instanceof Route) {
    return new options(undefined, config) // eslint-disable-line new-cap
  }
  let routeOptions = _.extend({}, options.routeOptions, _.pick(options, ['viewClass', 'viewOptions']))
  if (options.routeClass) {
    return new options.routeClass(routeOptions, config) // eslint-disable-line new-cap
  } else if (options.viewClass) {
    return new Route(routeOptions, config)
  }
}

function createMnRoute (route, index, routes) {
  let instanceConfig = {
    name: route.name,
    path: route.path,
    options: _.clone(route.options)
  }
  let instance = createRouteInstance(route.options, instanceConfig)
  if (!instance) {
    let routeConfig = findRouteConfig(route.name, index, routes)
    return Promise.resolve(routeConfig).then(function (options) {
      return options && createRouteInstance(options, instanceConfig)
    })
  }
  return instance
}

function getParentRegion (routes, route) {
  let region, parent
  let routeIndex = routes.indexOf(route) - 1
  while (routeIndex >= 0) {
    parent = routes[routeIndex]
    if (parent.view && parent.$config.options.outlet !== false) {
      region = parent.getOutlet()
      if (region) {
        return region
      } else {
        throw new Error(`No outlet region defined in ${parent.$config.name} route`)
      }
    }
    routeIndex--
  }
  return router.rootRegion
}

function renderViews (mnRoutes, activated, transition) {
  // ensure at least the target (last) route is rendered
  let renderCandidates = activated.length ? activated : mnRoutes.slice(-1)

  let renderQueue = renderCandidates.reduce(function (memo, mnRoute) {
    if (mnRoute.viewClass) {
      if (memo.length && memo[memo.length - 1].$config.options.outlet === false) {
        memo.pop()
      }
      memo.push(mnRoute)
    }
    return memo
  }, [])

  renderQueue.forEach(function (mnRoute) {
    let parentRegion = getParentRegion(mnRoutes, mnRoute)
    mnRoute.renderView(parentRegion, transition)
  })
}

const resolved = Promise.resolve()

function runAsyncMethod (transition, routes, method) {
  return routes.reduce(function (prevPromise, mnRoute) {
    routerChannel.trigger(`before:${method}`, transition, mnRoute)
    return prevPromise.then(function () {
      if (!transition.isCancelled) {
        return Promise.resolve(mnRoute[method](transition)).then(function () {
          if (!transition.isCancelled) {
            routerChannel.trigger(method, transition, mnRoute)
          }
        })
      }
    })
  }, resolved)
}

function isActivatingRoute (route) {
  return this.activating && this.activating.indexOf(route) !== -1
}

function isTargetRoute (route) {
  return this.mnRoutes && this.mnRoutes.indexOf(route) === this.mnRoutes.length - 1
}

export const middleware = {
  next: function routeResolver (transition) {
    transition.isActivating = isActivatingRoute
    transition.isTarget = isTargetRoute

    routerChannel.trigger('before:transition', transition)

    if (transition.isCancelled) return

    let prevRoutes = transition.prev.routes
    let changingIndex = getChangingIndex(prevRoutes, transition.routes)
    let deactivated = []
    let routeIndex, routeInstance

    // deactivate previous routes
    for (routeIndex = prevRoutes.length - 1; routeIndex >= changingIndex; routeIndex--) {
      routeInstance = mnRouteMap[prevRoutes[routeIndex].name]
      if (routeInstance) {
        deactivated.push(routeInstance)
      }
    }

    let promise = runAsyncMethod(transition, deactivated, 'deactivate')

    // build route tree and creating instances if necessary
    let mnRoutes = transition.mnRoutes = []

    promise = promise.then(() => {
      return transition.routes.reduce(function (acc, route, i, routes) {
        return acc.then(function (res) {
          let instance = mnRouteMap[route.name]
          if (instance) {
            res.push(instance)
            return res
          } else {
            instance = createMnRoute(route, i, routes)
            return Promise.resolve(instance).then(function (mnRoute) {
              if (!mnRoute) {
                throw new Error(`Unable to create route ${route.name}: routeClass or viewClass must be defined`)
              }
              mnRouteMap[route.name] = mnRoute
              res.push(mnRoute)
              return res
            })
          }
        })
      }, Promise.resolve(mnRoutes))
    })

    // activate routes in order
    let activated

    promise = promise.then(function () {
      activated = transition.activating = mnRoutes.slice(changingIndex)
      return runAsyncMethod(transition, activated, 'activate')
    })

    promise.catch(() => {
      // catch errors occurred inside routing classes / methods
      // Should be handled in error event or in a transition.catch method
    })

    // render views
    return promise.then(function () {
      if (transition.isCancelled) return

      let loadPromise = mnRoutes.reduce(function (prevPromise, mnRoute) {
        let nextPromise = prevPromise
        if (_.isFunction(mnRoute.load)) {
          if (prevPromise) {
            return prevPromise.then(function () {
              return Promise.resolve(mnRoute.load(transition))
            }).catch(function () {
              return Promise.resolve(mnRoute.load(transition))
            })
          } else {
            return Promise.resolve(mnRoute.load(transition))
          }
        }
        return nextPromise
      }, undefined)

      if (loadPromise) {
        return new Promise(function (resolve) {
          loadPromise.then(function () {
            renderViews(mnRoutes, activated, transition)
            resolve()
          }).catch(function () {
            renderViews(mnRoutes, activated, transition)
            resolve()
          })
        })
      } else {
        renderViews(mnRoutes, activated, transition)
      }
    })
  },

  done: function (transition) {
    router.state.mnRoutes = transition.mnRoutes
    routerChannel.trigger('transition', transition)
    transition.activating = []
  },

  error: function (transition, err) {
    transition.activating = []
    if (err.type !== 'TransitionCancelled' && err.type !== 'TransitionRedirected') {
      routerChannel.trigger('transition:error', transition, err)
    }
  }
}
<|endoftext|>


<commit_before><commit_msg>Update impress.js submodule<commit_after><|endoftext|>


<commit_before>define(function(require) {

  var _ = require('underscore');
  var Backbone = require('backbone');
  var rsSync = require('rs-adapter');

  var Doc = Backbone.Model.extend({

    defaults: {
      title: '',
      content: '',
      lastEdited: undefined
    },

    sync: rsSync,

    isEmpty: function() {
      // Contenteditable never is really empty
      return this.get('content').match(/^(<\/{0,1}div>|
|\s| )*?$/) !== null;
    },

    updateLastEdited: function(doc) {
      // only update lastEdited if you didn't switch the document
      if ( !doc.changed.id ) doc.set( 'lastEdited', new Date().getTime() );
    },

    updateTitle: function(doc) {
      // Title consists of the first 40 characters of the first not empty line
      var title = doc.get('content')
        .match(/^(
|<\/div>|
|\s| )*([^<]{0,40}).*?(
|<\/div>|
|$)/)[2]
        .replace(/ /gi,'');
      doc.set( 'title', title );
    },

    getUrl: function() {
      var url = this.get('title')
        .toLowerCase()
        .replace(/\s| /g, '-')
        .replace(/"|’|'|\//g, '');
      return '!' + encodeURI(url) + '-(' + this.id + ')';
    },

    getOpacity: function() {
      // Time passed since this document was edited the last time in milliseconds
      var diff = new Date().getTime() - this.get('lastEdited');
      // The older the document the smaller the opacity
      // but the opacity is allway between 0.4 and 1
      // For documents older than 2 weeks the opacity won't change anymore
      var limit = 14 * 86400000;
      var opacity = diff > limit ? 0.4 : Math.round( (0.4 + ((limit - diff) / limit) * 0.6) * 100 ) / 100;
      return opacity;
    }

  });

  return Doc;
});
<commit_msg>don't display commas in urls<commit_after>define(function(require) {

  var _ = require('underscore');
  var Backbone = require('backbone');
  var rsSync = require('rs-adapter');

  var Doc = Backbone.Model.extend({

    defaults: {
      title: '',
      content: '',
      lastEdited: undefined
    },

    sync: rsSync,

    isEmpty: function() {
      // Contenteditable never is really empty
      return this.get('content').match(/^(<\/{0,1}div>|
|\s| )*?$/) !== null;
    },

    updateLastEdited: function(doc) {
      // only update lastEdited if you didn't switch the document
      if ( !doc.changed.id ) doc.set( 'lastEdited', new Date().getTime() );
    },

    updateTitle: function(doc) {
      // Title consists of the first 40 characters of the first not empty line
      var title = doc.get('content')
        .match(/^(
|<\/div>|
|\s| )*([^<]{0,40}).*?(
|<\/div>|
|$)/)[2]
        .replace(/ /gi,'');
      doc.set( 'title', title );
    },

    getUrl: function() {
      var url = this.get('title')
        .toLowerCase()
        .replace(/\s| /g, '-')
        .replace(/"|’|'|,|\//g, '');
      return '!' + encodeURI(url) + '-(' + this.id + ')';
    },

    getOpacity: function() {
      // Time passed since this document was edited the last time in milliseconds
      var diff = new Date().getTime() - this.get('lastEdited');
      // The older the document the smaller the opacity
      // but the opacity is allway between 0.4 and 1
      // For documents older than 2 weeks the opacity won't change anymore
      var limit = 14 * 86400000;
      var opacity = diff > limit ? 0.4 : Math.round( (0.4 + ((limit - diff) / limit) * 0.6) * 100 ) / 100;
      return opacity;
    }

  });

  return Doc;
});
<|endoftext|>


<commit_before>idrinth.raids = {
    script: null,
    list: { },
    joined: { },
    interval: null,
    requested: 0,
    clearInterval: function () {
        try {
            window.clearInterval ( idrinth.raids.interval );
        } catch ( e ) {
            idrinth.raids.interval = null;
        }
    },
    restartInterval: function () {
        this.clearInterval ();
        idrinth.raids.interval = window.setInterval ( idrinth.raids.join.process, 1500 );
    },
    import: function ( id ) {
        'use strict';
        if ( !idrinth.platform ) {
            return;
        }
        var getImportLink = function ( toImport ) {
            return 'raid-service/' + ( toImport === '' ? '_' : toImport ) + '/';
        };
        idrinth.core.ajax.runHome (
                getImportLink ( id ),
                function ( responseText ) {
                    'use strict';
                    var delHandler = function ( key ) {
                        if ( key in idrinth.raids.list ) {
                            delete idrinth.raids.list[key];
                        }
                        if ( key in idrinth.raids.joined ) {
                            delete idrinth.raids.joined[key];
                        }
                        if ( document.getElementById ( 'idrinth-raid-link-' + key ) ) {
                            idrinth.ui.removeElement ( 'idrinth-raid-link-' + key );
                        }
                    };
                    var list = JSON.parse ( responseText );
                    for (var key in list) {
                        if ( list[key].delete ) {
                            delHandler ( key );
                        } else {//worst case: overwriting itself
                            idrinth.raids.list[key] = list[key];
                        }
                    }
                },
                function ( ) {
                },
                function ( ) {
                },
                idrinth.raids.knowRaids ()
                );
    },
    knowRaids: function () {
        return ( ( Object.keys ( idrinth.raids.joined ) ).concat ( Object.keys ( idrinth.raids.list ) ) ).join ();
    },
    clearAll: function () {
        this.clearInterval ( );
        while ( document.getElementById ( "idrinth-raid-link-list" ).firstChild ) {
            idrinth.ui.removeElement ( document.getElementById ( "idrinth-raid-link-list" ).firstChild.id );
        }
        idrinth.raids.list = { };
        idrinth.raids.joined = { };
        idrinth.raids.restartInterval ();
    },
    join: {
        data: {
            prefix: null,
            tag: null
        },
        getServerLink: function ( key ) {
            var getLink = function ( list, key, prefix, tag ) {
                var build = function ( data, tag, prefix ) {
                    try {
                        return prefix +
                                tag + 'action_type=raidhelp&' +
                                tag + 'raid_id=' + data.raidId + '&' +
                                tag + 'difficulty=' + data.difficulty + '&' +
                                tag + 'hash=' + data.hash +
                                ( idrinth.settings.isWorldServer ? '&' + tag + 'serverid=' + 2 : '' );
                    } catch ( e1 ) {
                        return false;
                    }
                };
                if ( list[key] ) {
                    var link = build ( list[key], tag, prefix );
                    if ( link ) {
                        return link;
                    }
                }
            };
            var makePrefix = function () {
                if ( idrinth.raids.join.data.prefix === null ) {
                    var sites = {
                        armorgames: 'http://50.18.191.15/armor/raidjoin.php?user_id=###id###&auth_token=###token###&',
                        kongregate: 'http://50.18.191.15/kong/raidjoin.php?kongregate_username=###name###&kongregate_user_id=###id###&kongregate_game_auth_token=###token###&',
                        newgrounds: 'https://newgrounds.com/portal/view/609826?',
                        dawnofthedragons: 'https://web1.dawnofthedragons.com/live_iframe/raidjoin.php?',
                        facebook: 'https://web1.dawnofthedragons.com/live_iframe/raidjoin.php?'
                    };
                    idrinth.raids.join.data.prefix = ( ( ( sites[idrinth.platform].replace (
                            '###id###', idrinth.user.id
                            ) ).replace (
                            '###token###', idrinth.user.token
                            ) ).replace (
                            '###name###', idrinth.user.name
                            ) );
                }
                return idrinth.raids.join.data.prefix;
            };
            var makeTag = function () {
                if ( idrinth.raids.join.data.tag === null ) {
                    var sites = {
                        armorgames: 'ar_',
                        kongregate: 'kv_',
                        newgrounds: 'ng_',
                        facebook: '',
                        dawnofthedragons: ''
                    };
                    idrinth.raids.join.data.tag = sites[idrinth.platform];
                }
                return idrinth.raids.join.data.tag;
            };
            var prefix = makePrefix ();
            var tag = makeTag ();
            var link = getLink ( idrinth.raids.list, key, prefix, tag );
            if ( link ) {
                return link;
            }
            link = getLink ( idrinth.raids.joined, key, prefix, tag );
            if ( link ) {
                return link;
            }
            return prefix;
        },
        messages: {
            log: function ( string, key ) {
                var message = ( string.replace ( '#name#', idrinth.raids.list[key].name ) ).replace ( '#raid#', idrinth.raids.list[key].raid );
                idrinth.core.log ( message );
                var li = document.createElement ( 'li' );
                var ul = document.getElementById ( 'idrinth-joined-raids' ).getElementsByTagName ( 'ul' )[0];
                li.appendChild ( document.createTextNode ( ( new Date () ).toLocaleTimeString () + ' ' + message ) );
                if ( !ul.firstChild ) {
                    ul.appendChild ( li );
                } else {
                    if ( ul.childNodes.length > 9 ) {
                        ul.removeChild ( ul.lastChild );
                    }
                    ul.insertBefore ( li, ul.firstChild );
                }
            },
            addToJoined: function ( key ) {
                if ( key && idrinth.raids.list.hasOwnProperty ( key ) ) {
                    idrinth.raids.joined[ key ] = idrinth.raids.list[ key ];
                    delete idrinth.raids.list[ key ];
                }
            },
            success: function ( key ) {
                'use strict';
                idrinth.raids.join.messages.log ( 'Joined #name#\'s #raid#.', key );
                idrinth.ui.removeElement ( 'idrinth-raid-link-' + key );
                this.addToJoined ( key );
            },
            failed: function ( key ) {
                'use strict';
                idrinth.raids.join.messages.log ( 'Could not join #name#\'s #raid#', key );
            },
            trying: function ( key ) {
                'use strict';
                ( ( function ( key ) {
                    window.setTimeout ( function () {
                        var id = 'idrinth-raid-link-' + key;
                        if ( document.getElementById ( id ) ) {
                            idrinth.ui.removeElement ( id );
                        }
                    }, 300 );
                } ) ( key ) );
                if ( idrinth.raids.list[key] ) {
                    idrinth.raids.join.messages.log ( 'Trying to join #name#\'s #raid#', key );
                }
                this.addToJoined ( key );
            }
        },
        process: function ( ) {
            'use strict';
            var join = function ( ) {
                'use strict';
                var getServerMethods = function () {
                    var byAjax = function ( key ) {
                        'use strict';
                        idrinth.core.ajax.run (
                                idrinth.raids.join.getServerLink ( key ),
                                function ( ) {
                                    idrinth.raids.join.messages.success ( key );
                                },
                                function ( ) {
                                    idrinth.raids.join.messages.failed ( key );
                                },
                                function ( ) {
                                    idrinth.raids[key].joined = false;
                                    idrinth.raids.join.messages.failed ( key );
                                }
                        );
                    };
                    var byFrame = function ( key ) {
                        'use strict';
                        var exist = document.getElementsByClassName ( 'idrinth-join-frame' ).length;
                        if ( exist >= idrinth.settings.windows ) {
                            idrinth.raids.list[key].joined = false;
                            return;
                        }
                        var frame = idrinth.ui.buildElement ( {
                            type: 'iframe',
                            css: 'idrinth-join-frame',
                            id: 'join-' + key,
                            attributes: [
                                {
                                    name: 'src',
                                    value: idrinth.raids.join.getServerLink ( key )
                                },
                                {
                                    name: 'sandbox',
                                    value: 'allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts'
                                },
                                {
                                    name: 'style',
                                    value: 'top:' + exist + 'px;'
                                },
                                {
                                    name: 'onload',
                                    value: 'try{event.stopPropagation();}catch(e){}window.setTimeout(){function(){idrinth.ui.removeElement(\'' + key + '\');},1234);'
                                },
                                {
                                    name: 'onunload',
                                    value: 'try{event.stopPropagation();}catch(e){}'
                                }
                            ]
                        } );
                        ( ( function ( key ) {
                            return window.setTimeout ( function () {
                                idrinth.ui.removeElement ( 'join-' + key );
                            }, 30000 );
                        } ) ( key ) );
                        idrinth.ui.body.appendChild ( frame );
                        idrinth.raids.join.messages.trying ( key );
                    };
                    var postLink = function ( key ) {
                        'use strict';
                        if ( !document.getElementById ( 'idrinth-raid-link-' + key ) ) {
                            var span = document.createElement ( 'span' );
                            span.id = 'idrinth-raid-link-' + key;
                            span.setAttribute ( 'data-clipboard-text', idrinth.raids.join.getServerLink ( key ) );
                            span.appendChild ( document.createTextNode ( idrinth.raids.list[key].name + '\'s ' + idrinth.raids.list[key].raid ) );
                            document.getElementById ( 'idrinth-raid-link-list' ).appendChild ( span );
                        }
                    };
                    var options = [ postLink ];
                    if ( idrinth.platform === 'armorgames' || idrinth.platform === 'kongregate' ) {
                        options.push ( byAjax );
                    } else if ( idrinth.platform === 'facebook' || idrinth.platform === 'dawnofthedragons' ) {
                        options.push ( byFrame );
                    }
                    return options;
                };
                var reachedMax = function ( amount ) {
                    return amount > 99 || ( ( idrinth.platform === 'facebook' || idrinth.platform === 'dawnofthedragons' ) && amount >= idrinth.settings.windows );
                };
                var added = 0;
                var options = getServerMethods ();
                for (var key in idrinth.raids.list) {
                    if ( !idrinth.raids.list[key].joined && !idrinth.settings.bannedRaids[idrinth.raids.list[key].boss] ) {
                        added++;
                        for (var count = 0; count < options.length; count++) {
                            options[count] ( key );
                        }
                    }
                    if ( reachedMax ( added ) ) {
                        return true;
                    }
                }
                return false;
            };
            if ( !join ( ) && Date.now ( ) - 60000 > idrinth.raids.requested ) {
                idrinth.raids.requested = Date.now ( );
                idrinth.raids.import ( idrinth.settings.raids ? idrinth.settings.favs : '-1' );
            }
        }
    },
    start: function ( ) {
        'use strict';
        idrinth.raids.restartInterval ();
    }
};
<commit_msg>using correct property for join-check<commit_after>idrinth.raids = {
    script: null,
    list: { },
    joined: { },
    interval: null,
    requested: 0,
    clearInterval: function () {
        try {
            window.clearInterval ( idrinth.raids.interval );
        } catch ( e ) {
            idrinth.raids.interval = null;
        }
    },
    restartInterval: function () {
        this.clearInterval ();
        idrinth.raids.interval = window.setInterval ( idrinth.raids.join.process, 1500 );
    },
    import: function ( id ) {
        'use strict';
        if ( !idrinth.platform ) {
            return;
        }
        var getImportLink = function ( toImport ) {
            return 'raid-service/' + ( toImport === '' ? '_' : toImport ) + '/';
        };
        idrinth.core.ajax.runHome (
                getImportLink ( id ),
                function ( responseText ) {
                    'use strict';
                    var delHandler = function ( key ) {
                        if ( key in idrinth.raids.list ) {
                            delete idrinth.raids.list[key];
                        }
                        if ( key in idrinth.raids.joined ) {
                            delete idrinth.raids.joined[key];
                        }
                        if ( document.getElementById ( 'idrinth-raid-link-' + key ) ) {
                            idrinth.ui.removeElement ( 'idrinth-raid-link-' + key );
                        }
                    };
                    var list = JSON.parse ( responseText );
                    for (var key in list) {
                        if ( list[key].delete ) {
                            delHandler ( key );
                        } else {//worst case: overwriting itself
                            idrinth.raids.list[key] = list[key];
                        }
                    }
                },
                function ( ) {
                },
                function ( ) {
                },
                idrinth.raids.knowRaids ()
                );
    },
    knowRaids: function () {
        return ( ( Object.keys ( idrinth.raids.joined ) ).concat ( Object.keys ( idrinth.raids.list ) ) ).join ();
    },
    clearAll: function () {
        this.clearInterval ( );
        while ( document.getElementById ( "idrinth-raid-link-list" ).firstChild ) {
            idrinth.ui.removeElement ( document.getElementById ( "idrinth-raid-link-list" ).firstChild.id );
        }
        idrinth.raids.list = { };
        idrinth.raids.joined = { };
        idrinth.raids.restartInterval ();
    },
    join: {
        data: {
            prefix: null,
            tag: null
        },
        getServerLink: function ( key ) {
            var getLink = function ( list, key, prefix, tag ) {
                var build = function ( data, tag, prefix ) {
                    try {
                        return prefix +
                                tag + 'action_type=raidhelp&' +
                                tag + 'raid_id=' + data.raidId + '&' +
                                tag + 'difficulty=' + data.difficulty + '&' +
                                tag + 'hash=' + data.hash +
                                ( idrinth.settings.isWorldServer ? '&' + tag + 'serverid=' + 2 : '' );
                    } catch ( e1 ) {
                        return false;
                    }
                };
                if ( list[key] ) {
                    var link = build ( list[key], tag, prefix );
                    if ( link ) {
                        return link;
                    }
                }
            };
            var makePrefix = function () {
                if ( idrinth.raids.join.data.prefix === null ) {
                    var sites = {
                        armorgames: 'http://50.18.191.15/armor/raidjoin.php?user_id=###id###&auth_token=###token###&',
                        kongregate: 'http://50.18.191.15/kong/raidjoin.php?kongregate_username=###name###&kongregate_user_id=###id###&kongregate_game_auth_token=###token###&',
                        newgrounds: 'https://newgrounds.com/portal/view/609826?',
                        dawnofthedragons: 'https://web1.dawnofthedragons.com/live_iframe/raidjoin.php?',
                        facebook: 'https://web1.dawnofthedragons.com/live_iframe/raidjoin.php?'
                    };
                    idrinth.raids.join.data.prefix = ( ( ( sites[idrinth.platform].replace (
                            '###id###', idrinth.user.id
                            ) ).replace (
                            '###token###', idrinth.user.token
                            ) ).replace (
                            '###name###', idrinth.user.name
                            ) );
                }
                return idrinth.raids.join.data.prefix;
            };
            var makeTag = function () {
                if ( idrinth.raids.join.data.tag === null ) {
                    var sites = {
                        armorgames: 'ar_',
                        kongregate: 'kv_',
                        newgrounds: 'ng_',
                        facebook: '',
                        dawnofthedragons: ''
                    };
                    idrinth.raids.join.data.tag = sites[idrinth.platform];
                }
                return idrinth.raids.join.data.tag;
            };
            var prefix = makePrefix ();
            var tag = makeTag ();
            var link = getLink ( idrinth.raids.list, key, prefix, tag );
            if ( link ) {
                return link;
            }
            link = getLink ( idrinth.raids.joined, key, prefix, tag );
            if ( link ) {
                return link;
            }
            return prefix;
        },
        messages: {
            log: function ( string, key ) {
                var message = ( string.replace ( '#name#', idrinth.raids.list[key].name ) ).replace ( '#raid#', idrinth.raids.list[key].raid );
                idrinth.core.log ( message );
                var li = document.createElement ( 'li' );
                var ul = document.getElementById ( 'idrinth-joined-raids' ).getElementsByTagName ( 'ul' )[0];
                li.appendChild ( document.createTextNode ( ( new Date () ).toLocaleTimeString () + ' ' + message ) );
                if ( !ul.firstChild ) {
                    ul.appendChild ( li );
                } else {
                    if ( ul.childNodes.length > 9 ) {
                        ul.removeChild ( ul.lastChild );
                    }
                    ul.insertBefore ( li, ul.firstChild );
                }
            },
            addToJoined: function ( key ) {
                if ( key && idrinth.raids.list.hasOwnProperty ( key ) ) {
                    idrinth.raids.joined[ key ] = idrinth.raids.list[ key ];
                    delete idrinth.raids.list[ key ];
                }
            },
            success: function ( key ) {
                'use strict';
                idrinth.raids.join.messages.log ( 'Joined #name#\'s #raid#.', key );
                idrinth.ui.removeElement ( 'idrinth-raid-link-' + key );
                this.addToJoined ( key );
            },
            failed: function ( key ) {
                'use strict';
                idrinth.raids.join.messages.log ( 'Could not join #name#\'s #raid#', key );
            },
            trying: function ( key ) {
                'use strict';
                ( ( function ( key ) {
                    window.setTimeout ( function () {
                        var id = 'idrinth-raid-link-' + key;
                        if ( document.getElementById ( id ) ) {
                            idrinth.ui.removeElement ( id );
                        }
                    }, 300 );
                } ) ( key ) );
                if ( idrinth.raids.list[key] ) {
                    idrinth.raids.join.messages.log ( 'Trying to join #name#\'s #raid#', key );
                }
                this.addToJoined ( key );
            }
        },
        process: function ( ) {
            'use strict';
            var join = function ( ) {
                'use strict';
                var getServerMethods = function () {
                    var byAjax = function ( key ) {
                        'use strict';
                        idrinth.core.ajax.run (
                                idrinth.raids.join.getServerLink ( key ),
                                function ( ) {
                                    idrinth.raids.join.messages.success ( key );
                                },
                                function ( ) {
                                    idrinth.raids.join.messages.failed ( key );
                                },
                                function ( ) {
                                    idrinth.raids[key].joined = false;
                                    idrinth.raids.join.messages.failed ( key );
                                }
                        );
                    };
                    var byFrame = function ( key ) {
                        'use strict';
                        var exist = document.getElementsByClassName ( 'idrinth-join-frame' ).length;
                        if ( exist >= idrinth.settings.windows ) {
                            idrinth.raids.list[key].joined = false;
                            return;
                        }
                        var frame = idrinth.ui.buildElement ( {
                            type: 'iframe',
                            css: 'idrinth-join-frame',
                            id: 'join-' + key,
                            attributes: [
                                {
                                    name: 'src',
                                    value: idrinth.raids.join.getServerLink ( key )
                                },
                                {
                                    name: 'sandbox',
                                    value: 'allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts'
                                },
                                {
                                    name: 'style',
                                    value: 'top:' + exist + 'px;'
                                },
                                {
                                    name: 'onload',
                                    value: 'try{event.stopPropagation();}catch(e){}window.setTimeout(){function(){idrinth.ui.removeElement(\'' + key + '\');},1234);'
                                },
                                {
                                    name: 'onunload',
                                    value: 'try{event.stopPropagation();}catch(e){}'
                                }
                            ]
                        } );
                        ( ( function ( key ) {
                            return window.setTimeout ( function () {
                                idrinth.ui.removeElement ( 'join-' + key );
                            }, 30000 );
                        } ) ( key ) );
                        idrinth.ui.body.appendChild ( frame );
                        idrinth.raids.join.messages.trying ( key );
                    };
                    var postLink = function ( key ) {
                        'use strict';
                        if ( !document.getElementById ( 'idrinth-raid-link-' + key ) ) {
                            var span = document.createElement ( 'span' );
                            span.id = 'idrinth-raid-link-' + key;
                            span.setAttribute ( 'data-clipboard-text', idrinth.raids.join.getServerLink ( key ) );
                            span.appendChild ( document.createTextNode ( idrinth.raids.list[key].name + '\'s ' + idrinth.raids.list[key].raid ) );
                            document.getElementById ( 'idrinth-raid-link-list' ).appendChild ( span );
                        }
                    };
                    var options = [ postLink ];
                    if ( idrinth.platform === 'armorgames' || idrinth.platform === 'kongregate' ) {
                        options.push ( byAjax );
                    } else if ( idrinth.platform === 'facebook' || idrinth.platform === 'dawnofthedragons' ) {
                        options.push ( byFrame );
                    }
                    return options;
                };
                var reachedMax = function ( amount ) {
                    return amount > 99 || ( ( idrinth.platform === 'facebook' || idrinth.platform === 'dawnofthedragons' ) && amount >= idrinth.settings.windows );
                };
                var added = 0;
                var options = getServerMethods ();
                for (var key in idrinth.raids.list) {
                    var raid = idrinth.raids.list[key];
                    if ( !raid.joined ) {
                        added++;
                        options[0] ( key );//post link
                        if ( !idrinth.settings.bannedRaids[raid.raid] ) {
                            for (var count = 1; count < options.length; count++) {
                                options[count] ( key );
                            }
                        }
                    }
                    if ( reachedMax ( added ) ) {
                        return true;
                    }
                }
                return false;
            };
            if ( !join ( ) && Date.now ( ) - 60000 > idrinth.raids.requested ) {
                idrinth.raids.requested = Date.now ( );
                idrinth.raids.import ( idrinth.settings.raids ? idrinth.settings.favs : '-1' );
            }
        }
    },
    start: function ( ) {
        'use strict';
        idrinth.raids.restartInterval ();
    }
};
<|endoftext|>


<commit_before>// adopted from: spawn-commands <https://github.com/jonschlinkert/spawn-commands>
// Copyright (c) 2014-2015, Jon Schlinkert.

'use strict'

var iterate = require('../async/iterate').each
var forEach = require('../collection/forEach')
var child = require('child_process')

// cmds: arrary/object of objects {cmd: 'something', args: ['some', 'things']}
// cb: callback [function]

function commands (cmds, cb) {
  if (arguments.length === 1) cb = function () {}

  iterate(cmds, function (cmd, idx, next) {
    child.spawn(cmd.cmd, cmd.args, {stdio: 'inherit'})
      .on('error', next)
      .on('close', next)
  }, cb)
}

commands.sync = function (cmds) {
  cmds = Array.isArray(cmds) ? cmds : [cmds]

  forEach(cmds, function (cmd) {
    child.spawnSync(cmd.cmd, cmd.args, {stdio: 'inherit'})
  })
}

module.exports = commands
<commit_msg>update cli/spawn-commands<commit_after>// adopted from: spawn-commands <https://github.com/jonschlinkert/spawn-commands>
// Copyright (c) 2014-2015, Jon Schlinkert.

'use strict'

var serial = require('../async/iterate').each
var concurrent = require('../async/concurrent').each
var forEach = require('../collection/forEach')
var extend = require('../object/extend')
var child = require('child_process')

// cmds: arrary/object of objects {cmd: 'something', args: ['some', 'things']}
// cb: callback [function]

function defs (opts) {
  opts = opts || {}

  return extend({
    stdio: 'inherit',
    concurrent: false
  }, opts)
}

function commands (cmds, opts, cb) {
  cmds = Array.isArray(cmds) ? cmds : [cmds]

  if (arguments.length === 1) {
    cb = function () {}
    opts = defs()
  } else if (arguments.length === 2) {
    if (typeof opts === 'function') {
      cb = opts
      opts = defs()
    } else {
      cb = function () {}
      opts = defs(opts)
    }
  } else {
    opts = defs(opts)
  }

  var iterate = opts.concurrent ? concurrent : serial

  iterate(cmds, function (cmd, idx, next) {
    child.spawn(cmd.cmd, cmd.args, opts)
      .on('error', next)
      .on('close', next)
  }, cb)
}

commands.sync = function (cmds) {
  cmds = Array.isArray(cmds) ? cmds : [cmds]

  forEach(cmds, function (cmd) {
    child.spawnSync(cmd.cmd, cmd.args, opts)
  })
}

module.exports = commands
<|endoftext|>


<commit_before>'use strict';

angular.module('hyphe.service_hyphe_api', [])

  .factory('api', ['serverURL', '$http', function(surl, $http) {
    var api = {}
    ,HYPHE_API = {
      WEBENTITIES:{
        GET: 'store.get_webentities'
        ,GET_LINKS: 'store.get_webentities_network_json'
        ,CREATE_BY_LRU: 'store.declare_webentity_by_lru'
        ,CREATE_BY_LRUS: 'store.declare_webentity_by_lrus'
        ,MERGE: 'store.merge_webentity_into_another'
      }
      ,WEBENTITY:{
        STARTPAGE:{
          ADD:'store.add_webentity_startpage'
          ,REMOVE:'store.rm_webentity_startpage'
        }

        ,PREFIX:{
          ADD:'store.add_webentity_lruprefix'
          ,REMOVE:'store.rm_webentity_lruprefix'
        }

        ,GET_PAGES:'store.get_webentity_pages'
        ,GET_SUBWEBENTITIES:'store.get_webentity_subwebentities'
        ,GET_PARENTWEBENTITIES:'store.get_webentity_parentwebentities'

        ,SET_NAME:'store.rename_webentity'
        ,SET_STATUS: 'store.set_webentity_status'
        ,SET_HOMEPAGE: 'store.set_webentity_homepage'
        ,SET_TAG_VALUES: 'store.set_webentity_tag_values'

        ,CRAWL:'crawl_webentity'

        ,FETCH_BY_URL: 'store.get_webentity_for_url'
        ,FETCH_BY_PREFIX_LRU: 'store.get_webentity_by_lruprefix'
        ,FETCH_BY_PREFIX_URL: 'store.get_webentity_by_lruprefix_as_url'
      }
      ,PREFIX:{
        GET_PARENTWEBENTITIES:'store.get_lru_definedprefixes'
      }
      ,PAGES:{
        DECLARE:'declare_pages'
      }
      ,PAGE:{
        DECLARE:'declare_page'
      }
      ,CRAWLJOBS:{
        GET:'listjobs'
      }
      ,CRAWLJOB:{
        CANCEL:'crawl.cancel'
      }
      ,STATUS:{
        GET:'get_status'
      }

      ,URL_LOOKUP:'lookup_httpstatus'
      ,RESET:'reinitialize'
    }

    api.getWebentities = buildApiCall(
        HYPHE_API.WEBENTITIES.GET
        ,function(settings){
          return [
            settings.id_list                // List of webentities
            ,settings.light || false        // Mode light
            ,settings.semiLight || false    // Mode semi-light
          ]}
      )

    api.getLruParentWebentities = buildApiCall(
        HYPHE_API.PREFIX.GET_PARENTWEBENTITIES
        ,function(settings){
          return [
            settings.lru
          ]}
      )

    api.declareWebentity = buildApiCall(
        HYPHE_API.WEBENTITIES.CREATE_BY_LRUS
        ,function(settings){
          return [
              settings.prefixes             // LRU list
              ,settings.name || ''          // Name
              ,'IN'                         // Status
              ,settings.startPages || []    // Start pages
            ]}
      )

    api.urlLookup = buildApiCall(
        HYPHE_API.URL_LOOKUP
        ,function(settings){
          return [
              settings.url
              ,settings.timeout || 5
            ]}
      )

    api.addStartPage = buildApiCall(
        HYPHE_API.WEBENTITY.STARTPAGE.ADD
        ,function(settings){
          return [
              settings.webentityId
              ,settings.url
            ]}
      )

    api.removeStartPage = buildApiCall(
        HYPHE_API.WEBENTITY.STARTPAGE.REMOVE
        ,function(settings){
          return [
              settings.webentityId
              ,settings.url
            ]}
      )

    api.addPrefix = buildApiCall(
        HYPHE_API.WEBENTITY.PREFIX.ADD
        ,function(settings){
          return [
              settings.webentityId
              ,settings.lru
            ]}
      )

    api.removePrefix = buildApiCall(
        HYPHE_API.WEBENTITY.PREFIX.REMOVE
        ,function(settings){
          return [
              settings.webentityId
              ,settings.lru
            ]}
      )

    api.webentitiesMerge = buildApiCall(
        HYPHE_API.WEBENTITIES.MERGE
        ,function(settings){

          // Default settings
          if(settings.mergeTags === undefined)
            settings.mergeTags = true
          if(settings.mergeStartPages === undefined)
            settings.mergeStartPages = true

          return [
              settings.oldWebentityId
              ,settings.goodWebentityId
              ,settings.mergeTags             // Include tags
              ,settings.mergeStartPages       // Include Home and Startpages as Startpages
            ]}
      )

    api.crawl = buildApiCall(
        HYPHE_API.WEBENTITY.CRAWL
        ,function(settings){
          return [
            settings.webentityId
            ,settings.depth
            ,false
            ,false
            ,settings.cautious || false
          ]}
      )

    api.globalStatus = buildApiCall(
        HYPHE_API.STATUS.GET
        ,function(settings){
            return []
          }
      )

    api.getCrawlJobs = buildApiCall(
        HYPHE_API.CRAWLJOBS.GET
        ,function(settings){
          return [
            settings.id_list    // List of crawl jobs
          ]}
      )

    api.abortCrawlJobs = buildApiCall(
        HYPHE_API.CRAWLJOB.CANCEL
        ,function(settings){
          return [
            settings.id
          ]}
      )

    function buildApiCall(pseudo_route, params){
      return function(settings, successCallback, errorCallback){
        var s // settings
        if(typeof(settings) == 'object'){
          s = settings
        } else if(typeof(settings) == 'function'){
          s = settings()
        } else {
          s = {}
        }

        // Abort
        if(s._API_ABORT_QUERY){
          return false
        }

        errorCallback = errorCallback || rpcError
        $http({
          method: 'POST'
          ,url: surl
          ,data: JSON.stringify({ //JSON RPC
              'method' : pseudo_route,
              'params' : params(s),
            })
          ,headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
          .success(function(data, status, headers, config){
              var target = (data[0] || {}).result
              if(target){
                successCallback(target)
              } else {
                console.log('data', data, 'errorCallback', errorCallback)
                errorCallback(data, status, headers, config)
              }
            })
          .error(function(data, status, headers, config){
            errorCallback(data, status, headers, config)
          })

        return true
      }
    }

    return api

    function rpcError(data, status, headers, config) {
      // called asynchronously if an error occurs
      // or server returns response with an error status.
      console.log('RPC Error', data, status, headers, config)
    }
  }])<commit_msg>api lookup to default<commit_after>'use strict';

angular.module('hyphe.service_hyphe_api', [])

  .factory('api', ['serverURL', '$http', function(surl, $http) {
    var api = {}
    ,HYPHE_API = {
      WEBENTITIES:{
        GET: 'store.get_webentities'
        ,GET_LINKS: 'store.get_webentities_network_json'
        ,CREATE_BY_LRU: 'store.declare_webentity_by_lru'
        ,CREATE_BY_LRUS: 'store.declare_webentity_by_lrus'
        ,MERGE: 'store.merge_webentity_into_another'
      }
      ,WEBENTITY:{
        STARTPAGE:{
          ADD:'store.add_webentity_startpage'
          ,REMOVE:'store.rm_webentity_startpage'
        }

        ,PREFIX:{
          ADD:'store.add_webentity_lruprefix'
          ,REMOVE:'store.rm_webentity_lruprefix'
        }

        ,GET_PAGES:'store.get_webentity_pages'
        ,GET_SUBWEBENTITIES:'store.get_webentity_subwebentities'
        ,GET_PARENTWEBENTITIES:'store.get_webentity_parentwebentities'

        ,SET_NAME:'store.rename_webentity'
        ,SET_STATUS: 'store.set_webentity_status'
        ,SET_HOMEPAGE: 'store.set_webentity_homepage'
        ,SET_TAG_VALUES: 'store.set_webentity_tag_values'

        ,CRAWL:'crawl_webentity'

        ,FETCH_BY_URL: 'store.get_webentity_for_url'
        ,FETCH_BY_PREFIX_LRU: 'store.get_webentity_by_lruprefix'
        ,FETCH_BY_PREFIX_URL: 'store.get_webentity_by_lruprefix_as_url'
      }
      ,PREFIX:{
        GET_PARENTWEBENTITIES:'store.get_lru_definedprefixes'
      }
      ,PAGES:{
        DECLARE:'declare_pages'
      }
      ,PAGE:{
        DECLARE:'declare_page'
      }
      ,CRAWLJOBS:{
        GET:'listjobs'
      }
      ,CRAWLJOB:{
        CANCEL:'crawl.cancel'
      }
      ,STATUS:{
        GET:'get_status'
      }

      ,URL_LOOKUP:'lookup_httpstatus'
      ,RESET:'reinitialize'
    }

    api.getWebentities = buildApiCall(
        HYPHE_API.WEBENTITIES.GET
        ,function(settings){
          return [
            settings.id_list                // List of webentities
            ,settings.light || false        // Mode light
            ,settings.semiLight || false    // Mode semi-light
          ]}
      )

    api.getLruParentWebentities = buildApiCall(
        HYPHE_API.PREFIX.GET_PARENTWEBENTITIES
        ,function(settings){
          return [
            settings.lru
          ]}
      )

    api.declareWebentity = buildApiCall(
        HYPHE_API.WEBENTITIES.CREATE_BY_LRUS
        ,function(settings){
          return [
              settings.prefixes             // LRU list
              ,settings.name || ''          // Name
              ,'IN'                         // Status
              ,settings.startPages || []    // Start pages
            ]}
      )

    api.urlLookup = buildApiCall(
        HYPHE_API.URL_LOOKUP
        ,function(settings){
          return [
              settings.url
              ,settings.timeout
            ]}
      )

    api.addStartPage = buildApiCall(
        HYPHE_API.WEBENTITY.STARTPAGE.ADD
        ,function(settings){
          return [
              settings.webentityId
              ,settings.url
            ]}
      )

    api.removeStartPage = buildApiCall(
        HYPHE_API.WEBENTITY.STARTPAGE.REMOVE
        ,function(settings){
          return [
              settings.webentityId
              ,settings.url
            ]}
      )

    api.addPrefix = buildApiCall(
        HYPHE_API.WEBENTITY.PREFIX.ADD
        ,function(settings){
          return [
              settings.webentityId
              ,settings.lru
            ]}
      )

    api.removePrefix = buildApiCall(
        HYPHE_API.WEBENTITY.PREFIX.REMOVE
        ,function(settings){
          return [
              settings.webentityId
              ,settings.lru
            ]}
      )

    api.webentitiesMerge = buildApiCall(
        HYPHE_API.WEBENTITIES.MERGE
        ,function(settings){

          // Default settings
          if(settings.mergeTags === undefined)
            settings.mergeTags = true
          if(settings.mergeStartPages === undefined)
            settings.mergeStartPages = true

          return [
              settings.oldWebentityId
              ,settings.goodWebentityId
              ,settings.mergeTags             // Include tags
              ,settings.mergeStartPages       // Include Home and Startpages as Startpages
            ]}
      )

    api.crawl = buildApiCall(
        HYPHE_API.WEBENTITY.CRAWL
        ,function(settings){
          return [
            settings.webentityId
            ,settings.depth
            ,false
            ,false
            ,settings.cautious || false
          ]}
      )

    api.globalStatus = buildApiCall(
        HYPHE_API.STATUS.GET
        ,function(settings){
            return []
          }
      )

    api.getCrawlJobs = buildApiCall(
        HYPHE_API.CRAWLJOBS.GET
        ,function(settings){
          return [
            settings.id_list    // List of crawl jobs
          ]}
      )

    api.abortCrawlJobs = buildApiCall(
        HYPHE_API.CRAWLJOB.CANCEL
        ,function(settings){
          return [
            settings.id
          ]}
      )

    function buildApiCall(pseudo_route, params){
      return function(settings, successCallback, errorCallback){
        var s // settings
        if(typeof(settings) == 'object'){
          s = settings
        } else if(typeof(settings) == 'function'){
          s = settings()
        } else {
          s = {}
        }

        // Abort
        if(s._API_ABORT_QUERY){
          return false
        }

        errorCallback = errorCallback || rpcError
        $http({
          method: 'POST'
          ,url: surl
          ,data: JSON.stringify({ //JSON RPC
              'method' : pseudo_route,
              'params' : params(s),
            })
          ,headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        })
          .success(function(data, status, headers, config){
              var target = (data[0] || {}).result
              if(target){
                successCallback(target)
              } else {
                console.log('data', data, 'errorCallback', errorCallback)
                errorCallback(data, status, headers, config)
              }
            })
          .error(function(data, status, headers, config){
            errorCallback(data, status, headers, config)
          })

        return true
      }
    }

    return api

    function rpcError(data, status, headers, config) {
      // called asynchronously if an error occurs
      // or server returns response with an error status.
      console.log('RPC Error', data, status, headers, config)
    }
  }])<|endoftext|>