<commit_before>/* global $, Hogan, Bloodhound, Countable */

import outdent from 'outdent'

import Active from '../Active'
import DataModel from '../DataModel'
import GlobalUI from '../GlobalUI'
import Router from '../Router'
import Util from '../Util'

const InfoBox = {
  isOpen: false,
  changing: false,
  selectingPermission: false,
  changePermissionText: "
As the creator, you can change the permission of this map, and the permission of all the topics and synapses you have authority to change will change as well.
",
  nameHTML: outdent`
    {{name}}`,
  descHTML: outdent`
    {{desc}}`,
  userImageUrl: '',
  init: function(serverData) {
    var self = InfoBox

    $('.mapInfoIcon').click(self.toggleBox)
    $('.mapInfoBox').click(function(event) {
      event.stopPropagation()
    })
    $('body').click(self.close)

    self.attachEventListeners()

    self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html())

    self.userImageUrl = serverData['user.png']

    var querystring = window.location.search.replace(/^\?/, '')
    if (querystring === 'new') {
      self.open()
      $('.mapInfoBox').addClass('mapRequestTitle')
      $('#mapInfoName').trigger('click')
      $('#mapInfoName textarea').focus()
      $('#mapInfoName textarea').select()
    }
  },
  toggleBox: function(event) {
    var self = InfoBox

    if (self.isOpen) self.close()
    else self.open()

    event.stopPropagation()
  },
  open: function() {
    var self = InfoBox
    $('.mapInfoIcon div').addClass('hide')
    if (!self.isOpen && !self.changing) {
      self.changing = true
      $('.mapInfoBox').fadeIn(200, function() {
        self.changing = false
        self.isOpen = true
      })
    }
  },
  close: function() {
    var self = InfoBox

    $('.mapInfoIcon div').removeClass('hide')
    if (!self.changing) {
      self.changing = true
      $('.mapInfoBox').fadeOut(200, function() {
        self.changing = false
        self.isOpen = false
        self.hidePermissionSelect()
        $('.mapContributors .tip').hide()
      })
    }
  },
  load: function() {
    var self = InfoBox

    var map = Active.Map

    var obj = map.pick('permission', 'topic_count', 'synapse_count')

    var isCreator = map.authorizePermissionChange(Active.Mapper)
    var canEdit = map.authorizeToEdit(Active.Mapper)
    var relevantPeople = map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
    var shareable = map.get('permission') !== 'private'

    obj['name'] = canEdit ? Hogan.compile(self.nameHTML).render({id: map.id, name: map.get('name')}) : map.get('name')
    obj['desc'] = canEdit ? Hogan.compile(self.descHTML).render({id: map.id, desc: map.get('desc')}) : map.get('desc')
    obj['map_creator_tip'] = isCreator ? self.changePermissionText : ''

    obj['contributor_count'] = relevantPeople.length
    obj['contributors_class'] = relevantPeople.length > 1 ? 'multiple' : ''
    obj['contributors_class'] += relevantPeople.length === 2 ? ' mTwo' : ''
    obj['contributor_image'] = relevantPeople.length > 0 ? relevantPeople.models[0].get('image') : self.userImageUrl
    obj['contributor_list'] = self.createContributorList()

    obj['user_name'] = isCreator ? 'You' : map.get('user_name')
    obj['created_at'] = map.get('created_at_clean')
    obj['updated_at'] = map.get('updated_at_clean')

    var classes = isCreator ? 'yourMap' : ''
    classes += canEdit ? ' canEdit' : ''
    classes += shareable ? ' shareable' : ''
    $('.mapInfoBox').removeClass('shareable yourMap canEdit')
      .addClass(classes)
      .html(self.generateBoxHTML.render(obj))

    self.attachEventListeners()
  },
  attachEventListeners: function() {
    var self = InfoBox

    $('.mapInfoBox.canEdit .best_in_place').best_in_place()

    // because anyone who can edit the map can change the map title
    var bipName = $('.mapInfoBox .best_in_place_name')
    bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function() {
      var $el = bipName.find('textarea')
      var el = $el[0]

      $el.attr('maxlength', '140')

      $('.mapInfoName').append('

')

      var callback = function(data) {
        $('.nameCounter.forMap').html(data.all + '/140')
      }
      Countable.live(el, callback)
    })
    bipName.unbind('best_in_place:deactivate').bind('best_in_place:deactivate', function() {
      $('.nameCounter.forMap').remove()
    })

    $('.mapInfoName .best_in_place_name').unbind('ajax:success').bind('ajax:success', function() {
      var name = $(this).html()
      Active.Map.set('name', name)
      Active.Map.trigger('saved')
      // mobile menu
      $('#header_content').html(name)
      $('.mapInfoBox').removeClass('mapRequestTitle')
      document.title = `${name} | Metamaps`
      window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
    })

    $('.mapInfoDesc .best_in_place_desc').unbind('ajax:success').bind('ajax:success', function() {
      var desc = $(this).html()
      Active.Map.set('desc', desc)
      Active.Map.trigger('saved')
    })

    $('.mapInfoDesc .best_in_place_desc, .mapInfoName .best_in_place_name').unbind('keypress').keypress(function(e) {
      const ENTER = 13
      if (e.which === ENTER) {
        $(this).data('bestInPlaceEditor').update()
      }
    })

    $('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
    // .yourMap in the unbind/bind is just a namespace for the events
    // not a reference to the class .yourMap on the .mapInfoBox
    $('.mapInfoBox.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)

    $('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)

    $('.mapContributors span, #mapContribs').unbind().click(function(event) {
      $('.mapContributors .tip').toggle()
      event.stopPropagation()
    })
    $('.mapContributors .tip').unbind().click(function(event) {
      event.stopPropagation()
    })
    $('.mapContributors .tip li a').click(Router.intercept)

    $('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function() {
      $('.mapContributors .tip').hide()
    })

    self.addTypeahead()
  },
  addTypeahead: function() {
    var self = InfoBox

    if (!Active.Map) return

    // for autocomplete
    var collaborators = {
      name: 'collaborators',
      limit: 9999,
      display: function(s) { return s.label },
      templates: {
        notFound: function(s) {
          return Hogan.compile($('#collaboratorSearchTemplate').html()).render({
            value: 'No results',
            label: 'No results',
            rtype: 'noresult',
            profile: self.userImageUrl
          })
        },
        suggestion: function(s) {
          return Hogan.compile($('#collaboratorSearchTemplate').html()).render(s)
        }
      },
      source: new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/search/mappers?term=%QUERY',
          wildcard: '%QUERY'
        }
      })
    }

    // for adding map collaborators, who will have edit rights
    if (Active.Mapper && Active.Mapper.id === Active.Map.get('user_id')) {
      $('.collaboratorSearchField').typeahead(
        {
          highlight: false
        },
        [collaborators]
      )
      $('.collaboratorSearchField').bind('typeahead:select', self.handleResultClick)
      $('.mapContributors .removeCollaborator').click(function() {
        self.removeCollaborator(parseInt($(this).data('id')))
      })
    }
  },
  removeCollaborator: function(collaboratorId) {
    var self = InfoBox
    DataModel.Collaborators.remove(DataModel.Collaborators.get(collaboratorId))
    var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
    $.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
    self.updateNumbers()
  },
  addCollaborator: function(newCollaboratorId) {
    var self = InfoBox

    if (DataModel.Collaborators.get(newCollaboratorId)) {
      GlobalUI.notifyUser('That user already has access')
      return
    }

    function callback(mapper) {
      DataModel.Collaborators.add(mapper)
      var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
      $.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
      var name = DataModel.Collaborators.get(newCollaboratorId).get('name')
      GlobalUI.notifyUser(name + ' will be notified')
      self.updateNumbers()
    }

    $.getJSON('/users/' + newCollaboratorId + '.json', callback)
  },
  handleResultClick: function(event, item) {
    var self = InfoBox

    self.addCollaborator(item.id)
    $('.collaboratorSearchField').typeahead('val', '')
  },
  updateNameDescPerm: function(name, desc, perm) {
    $('.mapInfoBox').removeClass('mapRequestTitle')
    $('.mapInfoName .best_in_place_name').html(name)
    $('.mapInfoDesc .best_in_place_desc').html(desc)
    $('.mapInfoBox .mapPermission').removeClass('commons public private').addClass(perm)
  },
  createContributorList: function() {
    var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
    var activeMapperIsCreator = Active.Mapper && Active.Mapper.id === Active.Map.get('user_id')
    var string = ''
    string += '
'

    relevantPeople.each(function(m) {
      var isCreator = Active.Map.get('user_id') === m.get('id')
      string += '
' + '' + m.get('name')
      if (isCreator) string += ' (creator)'
      string += ''
      if (activeMapperIsCreator && !isCreator) string += ''
      string += '
'
    })

    string += '
'

    if (activeMapperIsCreator) {
      string += '
<input class="collaboratorSearchField" placeholder="Add a collaborator"></input>
'
    }
    return string
  },
  updateNumbers: function() {
    if (!Active.Map) return

    const self = InfoBox

    var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators

    let contributorsClass = ''
    if (relevantPeople.length === 2) {
      contributorsClass = 'multiple mTwo'
    } else if (relevantPeople.length > 2) {
      contributorsClass = 'multiple'
    }

    let contributorsImage = self.userImageUrl
    if (relevantPeople.length > 0) {
      // get the first contributor and use their image
      contributorsImage = relevantPeople.models[0].get('image')
    }
    $('.mapContributors img').attr('src', contributorsImage).removeClass('multiple mTwo').addClass(contributorsClass)
    $('.mapContributors span').text(relevantPeople.length)
    $('.mapContributors .tip').html(self.createContributorList())
    self.addTypeahead()
    $('.mapContributors .tip').unbind().click(function(event) {
      event.stopPropagation()
    })
    $('.mapTopics').text(DataModel.Topics.length)
    $('.mapSynapses').text(DataModel.Synapses.length)

    $('.mapEditedAt').html('Last edited: ' + Util.nowDateFormatted())
  },
  onPermissionClick: function(event) {
    var self = InfoBox

    if (!self.selectingPermission) {
      self.selectingPermission = true
      $(this).addClass('minimize') // this line flips the drop down arrow to a pull up arrow
      if ($(this).hasClass('commons')) {
        $(this).append('

')
      } else if ($(this).hasClass('public')) {
        $(this).append('

')
      } else if ($(this).hasClass('private')) {
        $(this).append('

')
      }
      $('.mapPermission .permissionSelect li').click(self.selectPermission)
      event.stopPropagation()
    }
  },
  hidePermissionSelect: function() {
    var self = InfoBox

    self.selectingPermission = false
    $('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
    $('.mapPermission .permissionSelect').remove()
  },
  selectPermission: function(event) {
    var self = InfoBox

    self.selectingPermission = false
    var permission = $(this).attr('class')
    Active.Map.save({
      permission: permission
    })
    Active.Map.updateMapWrapper()
    const shareable = permission === 'private' ? '' : 'shareable'
    $('.mapPermission').removeClass('commons public private minimize').addClass(permission)
    $('.mapPermission .permissionSelect').remove()
    $('.mapInfoBox').removeClass('shareable').addClass(shareable)
    event.stopPropagation()
  },
  deleteActiveMap: function() {
    var confirmString = 'Are you sure you want to delete this map? '
    confirmString += 'This action is irreversible. It will not delete the topics and synapses on the map.'

    var doIt = window.confirm(confirmString)
    var map = Active.Map
    var mapper = Active.Mapper
    var authorized = map.authorizePermissionChange(mapper)

    if (doIt && authorized) {
      InfoBox.close()
      DataModel.Maps.Active.remove(map)
      DataModel.Maps.Featured.remove(map)
      DataModel.Maps.Mine.remove(map)
      DataModel.Maps.Shared.remove(map)
      map.destroy()
      Router.home()
      GlobalUI.notifyUser('Map eliminated!')
    } else if (!authorized) {
      window.alert("Hey now. We can't just go around willy nilly deleting other people's maps now can we? Run off and find something constructive to do, eh?")
    }
  }
}

export default InfoBox
<commit_msg>remove exclamation mark<commit_after>/* global $, Hogan, Bloodhound, Countable */

import outdent from 'outdent'

import Active from '../Active'
import DataModel from '../DataModel'
import GlobalUI from '../GlobalUI'
import Router from '../Router'
import Util from '../Util'

const InfoBox = {
  isOpen: false,
  changing: false,
  selectingPermission: false,
  changePermissionText: "
As the creator, you can change the permission of this map, and the permission of all the topics and synapses you have authority to change will change as well.
",
  nameHTML: outdent`
    {{name}}`,
  descHTML: outdent`
    {{desc}}`,
  userImageUrl: '',
  init: function(serverData) {
    var self = InfoBox

    $('.mapInfoIcon').click(self.toggleBox)
    $('.mapInfoBox').click(function(event) {
      event.stopPropagation()
    })
    $('body').click(self.close)

    self.attachEventListeners()

    self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html())

    self.userImageUrl = serverData['user.png']

    var querystring = window.location.search.replace(/^\?/, '')
    if (querystring === 'new') {
      self.open()
      $('.mapInfoBox').addClass('mapRequestTitle')
      $('#mapInfoName').trigger('click')
      $('#mapInfoName textarea').focus()
      $('#mapInfoName textarea').select()
    }
  },
  toggleBox: function(event) {
    var self = InfoBox

    if (self.isOpen) self.close()
    else self.open()

    event.stopPropagation()
  },
  open: function() {
    var self = InfoBox
    $('.mapInfoIcon div').addClass('hide')
    if (!self.isOpen && !self.changing) {
      self.changing = true
      $('.mapInfoBox').fadeIn(200, function() {
        self.changing = false
        self.isOpen = true
      })
    }
  },
  close: function() {
    var self = InfoBox

    $('.mapInfoIcon div').removeClass('hide')
    if (!self.changing) {
      self.changing = true
      $('.mapInfoBox').fadeOut(200, function() {
        self.changing = false
        self.isOpen = false
        self.hidePermissionSelect()
        $('.mapContributors .tip').hide()
      })
    }
  },
  load: function() {
    var self = InfoBox

    var map = Active.Map

    var obj = map.pick('permission', 'topic_count', 'synapse_count')

    var isCreator = map.authorizePermissionChange(Active.Mapper)
    var canEdit = map.authorizeToEdit(Active.Mapper)
    var relevantPeople = map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
    var shareable = map.get('permission') !== 'private'

    obj['name'] = canEdit ? Hogan.compile(self.nameHTML).render({id: map.id, name: map.get('name')}) : map.get('name')
    obj['desc'] = canEdit ? Hogan.compile(self.descHTML).render({id: map.id, desc: map.get('desc')}) : map.get('desc')
    obj['map_creator_tip'] = isCreator ? self.changePermissionText : ''

    obj['contributor_count'] = relevantPeople.length
    obj['contributors_class'] = relevantPeople.length > 1 ? 'multiple' : ''
    obj['contributors_class'] += relevantPeople.length === 2 ? ' mTwo' : ''
    obj['contributor_image'] = relevantPeople.length > 0 ? relevantPeople.models[0].get('image') : self.userImageUrl
    obj['contributor_list'] = self.createContributorList()

    obj['user_name'] = isCreator ? 'You' : map.get('user_name')
    obj['created_at'] = map.get('created_at_clean')
    obj['updated_at'] = map.get('updated_at_clean')

    var classes = isCreator ? 'yourMap' : ''
    classes += canEdit ? ' canEdit' : ''
    classes += shareable ? ' shareable' : ''
    $('.mapInfoBox').removeClass('shareable yourMap canEdit')
      .addClass(classes)
      .html(self.generateBoxHTML.render(obj))

    self.attachEventListeners()
  },
  attachEventListeners: function() {
    var self = InfoBox

    $('.mapInfoBox.canEdit .best_in_place').best_in_place()

    // because anyone who can edit the map can change the map title
    var bipName = $('.mapInfoBox .best_in_place_name')
    bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function() {
      var $el = bipName.find('textarea')
      var el = $el[0]

      $el.attr('maxlength', '140')

      $('.mapInfoName').append('

')

      var callback = function(data) {
        $('.nameCounter.forMap').html(data.all + '/140')
      }
      Countable.live(el, callback)
    })
    bipName.unbind('best_in_place:deactivate').bind('best_in_place:deactivate', function() {
      $('.nameCounter.forMap').remove()
    })

    $('.mapInfoName .best_in_place_name').unbind('ajax:success').bind('ajax:success', function() {
      var name = $(this).html()
      Active.Map.set('name', name)
      Active.Map.trigger('saved')
      // mobile menu
      $('#header_content').html(name)
      $('.mapInfoBox').removeClass('mapRequestTitle')
      document.title = `${name} | Metamaps`
      window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
    })

    $('.mapInfoDesc .best_in_place_desc').unbind('ajax:success').bind('ajax:success', function() {
      var desc = $(this).html()
      Active.Map.set('desc', desc)
      Active.Map.trigger('saved')
    })

    $('.mapInfoDesc .best_in_place_desc, .mapInfoName .best_in_place_name').unbind('keypress').keypress(function(e) {
      const ENTER = 13
      if (e.which === ENTER) {
        $(this).data('bestInPlaceEditor').update()
      }
    })

    $('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
    // .yourMap in the unbind/bind is just a namespace for the events
    // not a reference to the class .yourMap on the .mapInfoBox
    $('.mapInfoBox.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)

    $('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)

    $('.mapContributors span, #mapContribs').unbind().click(function(event) {
      $('.mapContributors .tip').toggle()
      event.stopPropagation()
    })
    $('.mapContributors .tip').unbind().click(function(event) {
      event.stopPropagation()
    })
    $('.mapContributors .tip li a').click(Router.intercept)

    $('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function() {
      $('.mapContributors .tip').hide()
    })

    self.addTypeahead()
  },
  addTypeahead: function() {
    var self = InfoBox

    if (!Active.Map) return

    // for autocomplete
    var collaborators = {
      name: 'collaborators',
      limit: 9999,
      display: function(s) { return s.label },
      templates: {
        notFound: function(s) {
          return Hogan.compile($('#collaboratorSearchTemplate').html()).render({
            value: 'No results',
            label: 'No results',
            rtype: 'noresult',
            profile: self.userImageUrl
          })
        },
        suggestion: function(s) {
          return Hogan.compile($('#collaboratorSearchTemplate').html()).render(s)
        }
      },
      source: new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/search/mappers?term=%QUERY',
          wildcard: '%QUERY'
        }
      })
    }

    // for adding map collaborators, who will have edit rights
    if (Active.Mapper && Active.Mapper.id === Active.Map.get('user_id')) {
      $('.collaboratorSearchField').typeahead(
        {
          highlight: false
        },
        [collaborators]
      )
      $('.collaboratorSearchField').bind('typeahead:select', self.handleResultClick)
      $('.mapContributors .removeCollaborator').click(function() {
        self.removeCollaborator(parseInt($(this).data('id')))
      })
    }
  },
  removeCollaborator: function(collaboratorId) {
    var self = InfoBox
    DataModel.Collaborators.remove(DataModel.Collaborators.get(collaboratorId))
    var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
    $.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
    self.updateNumbers()
  },
  addCollaborator: function(newCollaboratorId) {
    var self = InfoBox

    if (DataModel.Collaborators.get(newCollaboratorId)) {
      GlobalUI.notifyUser('That user already has access')
      return
    }

    function callback(mapper) {
      DataModel.Collaborators.add(mapper)
      var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
      $.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
      var name = DataModel.Collaborators.get(newCollaboratorId).get('name')
      GlobalUI.notifyUser(name + ' will be notified')
      self.updateNumbers()
    }

    $.getJSON('/users/' + newCollaboratorId + '.json', callback)
  },
  handleResultClick: function(event, item) {
    var self = InfoBox

    self.addCollaborator(item.id)
    $('.collaboratorSearchField').typeahead('val', '')
  },
  updateNameDescPerm: function(name, desc, perm) {
    $('.mapInfoBox').removeClass('mapRequestTitle')
    $('.mapInfoName .best_in_place_name').html(name)
    $('.mapInfoDesc .best_in_place_desc').html(desc)
    $('.mapInfoBox .mapPermission').removeClass('commons public private').addClass(perm)
  },
  createContributorList: function() {
    var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
    var activeMapperIsCreator = Active.Mapper && Active.Mapper.id === Active.Map.get('user_id')
    var string = ''
    string += '
'

    relevantPeople.each(function(m) {
      var isCreator = Active.Map.get('user_id') === m.get('id')
      string += '
' + '' + m.get('name')
      if (isCreator) string += ' (creator)'
      string += ''
      if (activeMapperIsCreator && !isCreator) string += ''
      string += '
'
    })

    string += '
'

    if (activeMapperIsCreator) {
      string += '
<input class="collaboratorSearchField" placeholder="Add a collaborator"></input>
'
    }
    return string
  },
  updateNumbers: function() {
    if (!Active.Map) return

    const self = InfoBox

    var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators

    let contributorsClass = ''
    if (relevantPeople.length === 2) {
      contributorsClass = 'multiple mTwo'
    } else if (relevantPeople.length > 2) {
      contributorsClass = 'multiple'
    }

    let contributorsImage = self.userImageUrl
    if (relevantPeople.length > 0) {
      // get the first contributor and use their image
      contributorsImage = relevantPeople.models[0].get('image')
    }
    $('.mapContributors img').attr('src', contributorsImage).removeClass('multiple mTwo').addClass(contributorsClass)
    $('.mapContributors span').text(relevantPeople.length)
    $('.mapContributors .tip').html(self.createContributorList())
    self.addTypeahead()
    $('.mapContributors .tip').unbind().click(function(event) {
      event.stopPropagation()
    })
    $('.mapTopics').text(DataModel.Topics.length)
    $('.mapSynapses').text(DataModel.Synapses.length)

    $('.mapEditedAt').html('Last edited: ' + Util.nowDateFormatted())
  },
  onPermissionClick: function(event) {
    var self = InfoBox

    if (!self.selectingPermission) {
      self.selectingPermission = true
      $(this).addClass('minimize') // this line flips the drop down arrow to a pull up arrow
      if ($(this).hasClass('commons')) {
        $(this).append('

')
      } else if ($(this).hasClass('public')) {
        $(this).append('

')
      } else if ($(this).hasClass('private')) {
        $(this).append('

')
      }
      $('.mapPermission .permissionSelect li').click(self.selectPermission)
      event.stopPropagation()
    }
  },
  hidePermissionSelect: function() {
    var self = InfoBox

    self.selectingPermission = false
    $('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
    $('.mapPermission .permissionSelect').remove()
  },
  selectPermission: function(event) {
    var self = InfoBox

    self.selectingPermission = false
    var permission = $(this).attr('class')
    Active.Map.save({
      permission: permission
    })
    Active.Map.updateMapWrapper()
    const shareable = permission === 'private' ? '' : 'shareable'
    $('.mapPermission').removeClass('commons public private minimize').addClass(permission)
    $('.mapPermission .permissionSelect').remove()
    $('.mapInfoBox').removeClass('shareable').addClass(shareable)
    event.stopPropagation()
  },
  deleteActiveMap: function() {
    var confirmString = 'Are you sure you want to delete this map? '
    confirmString += 'This action is irreversible. It will not delete the topics and synapses on the map.'

    var doIt = window.confirm(confirmString)
    var map = Active.Map
    var mapper = Active.Mapper
    var authorized = map.authorizePermissionChange(mapper)

    if (doIt && authorized) {
      InfoBox.close()
      DataModel.Maps.Active.remove(map)
      DataModel.Maps.Featured.remove(map)
      DataModel.Maps.Mine.remove(map)
      DataModel.Maps.Shared.remove(map)
      map.destroy()
      Router.home()
      GlobalUI.notifyUser('Map eliminated')
    } else if (!authorized) {
      window.alert("Hey now. We can't just go around willy nilly deleting other people's maps now can we? Run off and find something constructive to do, eh?")
    }
  }
}

export default InfoBox
<|endoftext|>


<commit_before>/*
 * Diaspora
 * @author LoeiFy
 * @url http://lorem.in
 */

var home = location.href;

var D = {

    L: function(url, f) {
		$.ajax({
			type: 'GET',
			url: url,
			timeout: 7000,
			success: function(data) {f(data)},
			error: function() {window.location.href = url}
		})
    },

    P: function() {
		return !!('ontouchstart' in window);
	},

    PS: function() {
        history.replaceState({u: home, t: document.title}, document.title, home);
		window.addEventListener('popstate', function(e) {
			var state = e.state;

			if (!state) return;

			document.title = state.t;

			if (state.u == home) {
                $('#preview').css('position', 'fixed')
                setTimeout(function() {
                    $('#preview').removeClass('show')
                    $('#container').show()
                    window.scrollTo(0, parseInt($('#container').data('scroll')))
                    setTimeout(function() {
                        $('#preview').html('')
                    }, 300)
                }, 0)
			} else {
			}
		})
    },

	HS: function(tag, flag) {
		$(tag).on('click', function(e) {
			e.preventDefault();

			var url = $(this).attr('href'), title = $(this).text(),
                state = {t: title, u: url};

            D.L(url, function(data) {

                switch (flag) {

                    case 'push':
                        history.pushState(state, title, url)
                    break;

                    case 'replace':
				        history.replaceState(state, title, url)
                    break;

                }

                document.title = title;

                $('#preview').html($(data).filter('#single'))

                setTimeout(function() {
                    $('#preview').addClass('show')
                    $('#container').data('scroll', window.scrollY)
                    setTimeout(function() {
                        $('#container').hide()
                        setTimeout(function() {
                            $('#preview').css({
                                'position': 'static',
                                'overflow-y': 'auto'
                            })
                        }, 500)
                    }, 300)
                }, 0)

            })

		})
	}

}

$(function($) {

    D.PS()

    D.HS('.inner', 'push')

    //$('#preview').height(window.innerHeight)

    var loader = function() {
        var w = window.innerWidth;
        var css = '<style id="loaderstyle">@-moz-keyframes loader{0%{background-position:0 0}100%{background-position:'+ w +'px 0}}@-webkit-keyframes loader{0%{background-position:0 0}100%{background-position:'+ w +'px 0}}></style>';
        $('#loaderstyle').remove()
        $('head').append(css)
    }

    loader()

    //$('.loader').addClass('loading')

    $(window).on('resize', function() {
        $('.loader').removeClass('loading')
        loader()
        setTimeout(function() {$('.loader').addClass('loading')}, 0)
    })

    CBFimage({id: 'cover', cache: true})

})
<commit_msg>state<commit_after>/*
 * Diaspora
 * @author LoeiFy
 * @url http://lorem.in
 */

var Home = location.href;

var Diaspora = {

    L: function(url, f) {
		$.ajax({
			type: 'GET',
			url: url,
			timeout: 7000,
			success: function(data) {f(data)},
			error: function() {window.location.href = url}
		})
    },

    P: function() {
		return !!('ontouchstart' in window);
	},

    PS: function() {
        history.replaceState({u: Home, t: document.title}, document.title, Home);
		window.addEventListener('popstate', function(e) {
			var state = e.state;

			if (!state) return;

			document.title = state.t;

			if (state.u == Home) {

                $('#preview').css('position', 'fixed')
                setTimeout(function() {
                    $('#preview').removeClass('show')
                    $('#container').show()
                    window.scrollTo(0, parseInt($('#container').data('scroll')))
                    setTimeout(function() {
                        $('#preview').html('')
                    }, 300)
                }, 0)

			} else {

                Diaspora.loading()

                Diaspora.L(state.u, function(data) {

                    document.title = state.t;

                    $('#preview').html($(data).filter('#single'))

                    setTimeout(function() {

                        $('#preview').addClass('show')
                        $('#container').data('scroll', window.scrollY)
                        setTimeout(function() {
                            $('#container').hide()
                            setTimeout(function() {
                                $('#preview').css({
                                    'position': 'static',
                                    'overflow-y': 'auto'
                                })

                                Diaspora.loaded()
                            }, 500)
                        }, 300)

                        Diaspora.HS('.relate a', 'replace')

                    }, 0)

                })

			}
		})
    },

	HS: function(tag, flag) {
		$(tag).on('click', function(e) {
			e.preventDefault()

            Diaspora.loading()

			var url = $(this).attr('href'), title = $(this).text(),
                state = {t: title, u: url};

            Diaspora.L(url, function(data) {

                switch (flag) {

                    case 'push':
                        history.pushState(state, title, url)
                    break;

                    case 'replace':
				        history.replaceState(state, title, url)
                    break;

                }

                document.title = title;

                $('#preview').html($(data).filter('#single'))

                switch (flag) {

                    case 'push':
                        setTimeout(function() {

                            $('#preview').addClass('show')
                            $('#container').data('scroll', window.scrollY)
                            setTimeout(function() {
                                $('#container').hide()
                                setTimeout(function() {
                                    $('#preview').css({
                                        'position': 'static',
                                        'overflow-y': 'auto'
                                    })

                                    Diaspora.loaded()
                                }, 500)
                            }, 300)

                            Diaspora.HS('.relate a', 'replace')

                        }, 0)
                    break;

                    case 'replace':
                        Diaspora.HS('.relate a', 'replace')
                        window.scrollTo(0, 0)
                        Diaspora.loaded()
                    break;
                }

            })

		})
	},

    loader: function() {
        var w = window.innerWidth;
        var css = '<style id="loaderstyle">@-moz-keyframes loader{0%{background-position:0 0}100%{background-position:'+ w +'px 0}}@-webkit-keyframes loader{0%{background-position:0 0}100%{background-position:'+ w +'px 0}}></style>';
        $('#loaderstyle').remove()
        $('head').append(css)
    },

    loading: function() {
        $('.loader').addClass('loading').show()
    },

    loaded: function() {
        $('.loader').removeClass('loading').hide()
    }

}

$(function($) {

    Diaspora.PS()

    Diaspora.HS('.inner', 'push')

    Diaspora.loader()

    CBFimage({id: 'cover', cache: true})

})
<|endoftext|>


<commit_before>const path = require('path');
const autoprefixer = require('autoprefixer');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const generateConfig = function (isProd) {
  const config = {
    devtool: 'inline-source-map',
    entry: './src/index.ts',
    output: {
      path: path.resolve(__dirname, './dist/'),
      filename: 'bundle.[hash].js',
      publicPath: '/',
    },
    devServer: {
      contentBase: path.resolve(__dirname, './dist'),
      historyApiFallback: true,
      stats: {
        hash: false,
        version: false,
        modules: false,
      },
      port: 8080,
      disableHostCheck: true,
    },
    module: {
      rules: [
        {
          test: /\.ts?$/,
          use: [
            {
              loader: 'ts-loader',
              options: {
                transpileOnly: true,
                compilerOptions: {
                  module: isProd ? 'commonjs' : 'es6'
                }
              },
            },
            'tslint-loader',
          ],

        }, {
          test: /\.(tag)$/,
          use: [
            {
              loader: 'riot-tag-loader',
              options: {},
            },
          ],
        }, {
          test: /\.styl$/,
          use: ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: [
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [autoprefixer],
                  sourceMap: true,
                },
              },
              'stylus-loader',
            ],
          }),
        },
      ],
    },
    plugins: [
      new ExtractTextPlugin({
        filename: 'bundle.[hash].css',
        allChunks: true,
      }),
      new ForkTsCheckerWebpackPlugin(),
      new HtmlWebpackPlugin({
        template: './public/index.html',
        inject: false,
      })
    ],
    resolve: {
      extensions: ['.js', '.ts', 'styl'],
      modules: ['node_modules'],
    },
  };

  if (isProd) {
    config.plugins.push(
      new CleanWebpackPlugin(['dist/*'], {
        root: __dirname,
        verbose: true,
        dry: false,
      }),
    );

    delete config.devtool;
  }

  return config;
}

module.exports = generateConfig(process.argv.indexOf('-p') !== -1);
<commit_msg>Add proxies for dragons of mugloar api<commit_after>const path = require('path');
const autoprefixer = require('autoprefixer');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const generateConfig = function (isProd) {
  const config = {
    devtool: 'inline-source-map',
    entry: './src/index.ts',
    output: {
      path: path.resolve(__dirname, './dist/'),
      filename: 'bundle.[hash].js',
      publicPath: '/',
    },
    devServer: {
      contentBase: path.resolve(__dirname, './dist'),
      historyApiFallback: true,
      stats: {
        hash: false,
        version: false,
        modules: false,
      },
      port: 8080,
      disableHostCheck: true,
      proxy: {
        '/api/*': {
          target: 'http://www.dragonsofmugloar.com',
          changeOrigin: true
        },
        '/weather/*': {
          target: 'http://www.dragonsofmugloar.com',
          changeOrigin: true
        },
      },
    },
    module: {
      rules: [
        {
          test: /\.ts?$/,
          use: [
            {
              loader: 'ts-loader',
              options: {
                transpileOnly: true,
                compilerOptions: {
                  module: isProd ? 'commonjs' : 'es6'
                }
              },
            },
            'tslint-loader',
          ],

        }, {
          test: /\.(tag)$/,
          use: [
            {
              loader: 'riot-tag-loader',
              options: {},
            },
          ],
        }, {
          test: /\.styl$/,
          use: ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: [
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [autoprefixer],
                  sourceMap: true,
                },
              },
              'stylus-loader',
            ],
          }),
        },
      ],
    },
    plugins: [
      new ExtractTextPlugin({
        filename: 'bundle.[hash].css',
        allChunks: true,
      }),
      new ForkTsCheckerWebpackPlugin(),
      new HtmlWebpackPlugin({
        template: './public/index.html',
        inject: false,
      })
    ],
    resolve: {
      extensions: ['.js', '.ts', 'styl'],
      modules: ['node_modules'],
    },
  };

  if (isProd) {
    config.plugins.push(
      new CleanWebpackPlugin(['dist/*'], {
        root: __dirname,
        verbose: true,
        dry: false,
      }),
    );

    delete config.devtool;
  }

  return config;
}

module.exports = generateConfig(process.argv.indexOf('-p') !== -1);
<|endoftext|>


<commit_before>const dotenv = require('dotenv');
const glob = require('glob');
const path = require('path');
const {EnvironmentPlugin} = require('webpack');

dotenv.config();
dotenv.config({path: '.env.default'});

module.exports = {
  entry: './packages/node_modules/ciscospark',
  output: {
    filename: 'bundle.js',
    library: 'ciscospark',
    libraryTarget: 'var',
    path: __dirname,
    sourceMapFilename: '[file].map'
  },
  devtool: 'source-map',
  devServer: {
    https: true,
    disableHostCheck: true,
    port: 8000
  },
  resolve: {
    alias: glob
      .sync('**/package.json', {cwd: './packages/node_modules'})
      .map((p) => path.dirname(p))
      .reduce((alias, packageName) => {
        // Always use src as the entry point for local files so that we have the
        // best opportunity for treeshaking; also makes developing easier since
        // we don't need to manually rebuild after changing code.
        alias[`./packages/node_modules/${packageName}`] = path.resolve(__dirname, `./packages/node_modules/${packageName}/src/index.js`);
        alias[`${packageName}`] = path.resolve(__dirname, `./packages/node_modules/${packageName}/src/index.js`);
        return alias;
      }, {})
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: /packages\/node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },
  plugins: [
    new EnvironmentPlugin({
      CISCOSPARK_LOG_LEVEL: 'log',
      DEBUG: '',
      NODE_ENV: process.env.NODE_ENV || 'development',
      // The follow environment variables are specific to our continuous
      // integration process and should not be used in general
      // Also, yes, CONVERSATION_SERVICE does not end in URL
      CONVERSATION_SERVICE: process.env.CONVERSATION_SERVICE || process.env.CONVERSATION_SERVICE_URL || 'https://conv-a.wbx2.com/conversation/api/v1',
      WDM_SERVICE_URL: process.env.WDM_SERVICE_URL || 'https://wdm-a.wbx2.com/wdm/api/v1',
      HYDRA_SERVICE_URL: process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1',
      ATLAS_SERVICE_URL: process.env.ATLAS_SERVICE_URL || 'https://atlas-a.wbx2.com/admin/api/v1'
    })
  ]
};
<commit_msg>serve samples at root<commit_after>const path = require('path');

const dotenv = require('dotenv');
const glob = require('glob');
const {EnvironmentPlugin} = require('webpack');

dotenv.config();
dotenv.config({path: '.env.default'});

module.exports = {
  entry: './packages/node_modules/ciscospark',
  output: {
    filename: 'bundle.js',
    library: 'ciscospark',
    libraryTarget: 'var',
    path: __dirname,
    sourceMapFilename: '[file].map'
  },
  devtool: 'source-map',
  devServer: {
    https: true,
    disableHostCheck: true,
    port: 8000,
    contentBase: './packages/node_modules/samples'
  },
  resolve: {
    alias: glob
      .sync('**/package.json', {cwd: './packages/node_modules'})
      .map((p) => path.dirname(p))
      .reduce((alias, packageName) => {
        // Always use src as the entry point for local files so that we have the
        // best opportunity for treeshaking; also makes developing easier since
        // we don't need to manually rebuild after changing code.
        alias[`./packages/node_modules/${packageName}`] = path.resolve(
          __dirname,
          `./packages/node_modules/${packageName}/src/index.js`
        );
        alias[`${packageName}`] = path.resolve(__dirname, `./packages/node_modules/${packageName}/src/index.js`);
        return alias;
      }, {})
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: /packages\/node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },
  plugins: [
    new EnvironmentPlugin({
      CISCOSPARK_LOG_LEVEL: 'log',
      DEBUG: '',
      NODE_ENV: process.env.NODE_ENV || 'development',
      // The follow environment variables are specific to our continuous
      // integration process and should not be used in general
      // Also, yes, CONVERSATION_SERVICE does not end in URL
      CONVERSATION_SERVICE:
        process.env.CONVERSATION_SERVICE
        || process.env.CONVERSATION_SERVICE_URL
        || 'https://conv-a.wbx2.com/conversation/api/v1',
      WDM_SERVICE_URL: process.env.WDM_SERVICE_URL || 'https://wdm-a.wbx2.com/wdm/api/v1',
      HYDRA_SERVICE_URL: process.env.HYDRA_SERVICE_URL || 'https://api.ciscospark.com/v1',
      ATLAS_SERVICE_URL: process.env.ATLAS_SERVICE_URL || 'https://atlas-a.wbx2.com/admin/api/v1'
    })
  ]
};
<|endoftext|>


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

import PageHeader from './page_header';
import GuildsTable from './guilds_table';
import {globalState} from '../state';

class DashboardGuildsList extends Component {
  constructor() {
    super();
    this.state = {guilds: null};
  }

  componentWillMount() {
    globalState.getCurrentUser().then((user) => {
      user.getGuilds().then((guilds) => {
        this.setState({guilds});
      });
    });
  }

  render() {
    return (

          Guilds

          <GuildsTable guilds={this.state.guilds}/>

    );
  }
}

class ControlPanel extends Component {
  constructor() {
    super();

    this.messageTimer = null;

    this.state = {
      guilds: null,
      message: null,
    };
  }

  componentWillMount() {
    globalState.getCurrentUser().then((user) => {
      user.getGuilds().then((guilds) => {
        this.setState({guilds});
      });
    });
  }

  onDeploy() {
    globalState.deploy().then(() => {
      this.renderMessage('success', 'Deploy Started');
    }).catch((err) => {
      this.renderMessage('danger', `Deploy Failed: ${err}`);
    });
  }

  renderMessage(type, contents) {
    this.setState({
      message: {
        type: type,
        contents: contents,
      }
    })

    if (this.messageTimer) clearTimeout(this.messageTimer);

    this.messageTimer = setTimeout(() => {
      this.setState({
        message: null,
      });
      this.messageTimer = null;
    }, 5000);
  }

  render() {
    return (

        {this.state.message &&
{this.state.message.contents}
}

           Control Panel

         this.onDeploy()} className="btn btn-success btn-block">Deploy

    );
  }
}

class StatsPanel extends Component {
  render () {
    const panelClass = `panel panel-${this.props.color}`;
    const iconClass = `fa fa-${this.props.icon} fa-5x`;

    return (

{this.props.data || 'N/A'}

{this.props.text}

    );
  }
}

class Stats extends Component {
  getStats() {
    let statsPanels = [];
    if (globalState.user.admin) {
      globalState.getStats((stats) => {
        // statsPanels.push(
        //     <StatsPanel color='primary' icon='comments' data={stats.messages} text='Messages' key='messages' />
        // );
        // statsPanels.push(
        //     <StatsPanel color='green' icon='server' data={stats.guilds} text='Guilds' key='guilds' />
        // );
        // statsPanels.push(
        //     <StatsPanel color='yellow' icon='user' data={stats.users} text='Users' key='users' />
        // );
        // statsPanels.push(
        //     <StatsPanel color='red' icon='hashtag' data={stats.channels} text='Channels' key='channels' />
        // );
        statsPanels.push(stats);
      });
    }
    return statsPanels;
  }

  drawStats({ color, icon, data, text}) {
    const panelClass = `panel panel-${color}`;
    const iconClass = `fa fa-${icon} fa-5x`;

    return (

{data || 'N/A'}

{text}

    );
  }

  render() {
    let panel = this.getStats();
    console.log(panel);

    // let renderPanels = [];
    // for (let panel in panels[0]) {
    //   renderPanels.push(
    //     <StatsPanel color='primary' icon='comments' data={panels[0][panel]} text='Messages' key={panels} />
    //   );
    // }
    // console.log(renderPanels);

    return (

        {this.drawStats({
          color: "primary",
          icon: "comments",
          data: panel[0].messages,
          text: "Messages"
        })}

    );
  }
}

class Dashboard extends Component {
  render() {
    let parts = [];

    parts.push(
      <PageHeader name="Dashboard" />
    );

    parts.push(

        <Stats />

    );

    parts.push(

          <DashboardGuildsList />

        {
          globalState.user && globalState.user.admin &&

            <ControlPanel />

        }

    );

		return (

        {parts}

    );
  }
}

export default Dashboard;
<commit_msg>Stats 7<commit_after>import React, { Component } from 'react';

import PageHeader from './page_header';
import GuildsTable from './guilds_table';
import {globalState} from '../state';

class DashboardGuildsList extends Component {
  constructor() {
    super();
    this.state = {guilds: null};
  }

  componentWillMount() {
    globalState.getCurrentUser().then((user) => {
      user.getGuilds().then((guilds) => {
        this.setState({guilds});
      });
    });
  }

  render() {
    return (

          Guilds

          <GuildsTable guilds={this.state.guilds}/>

    );
  }
}

class ControlPanel extends Component {
  constructor() {
    super();

    this.messageTimer = null;

    this.state = {
      guilds: null,
      message: null,
    };
  }

  componentWillMount() {
    globalState.getCurrentUser().then((user) => {
      user.getGuilds().then((guilds) => {
        this.setState({guilds});
      });
    });
  }

  onDeploy() {
    globalState.deploy().then(() => {
      this.renderMessage('success', 'Deploy Started');
    }).catch((err) => {
      this.renderMessage('danger', `Deploy Failed: ${err}`);
    });
  }

  renderMessage(type, contents) {
    this.setState({
      message: {
        type: type,
        contents: contents,
      }
    })

    if (this.messageTimer) clearTimeout(this.messageTimer);

    this.messageTimer = setTimeout(() => {
      this.setState({
        message: null,
      });
      this.messageTimer = null;
    }, 5000);
  }

  render() {
    return (

        {this.state.message &&
{this.state.message.contents}
}

           Control Panel

         this.onDeploy()} className="btn btn-success btn-block">Deploy

    );
  }
}

class StatsPanel extends Component {
  render () {
    const panelClass = `panel panel-${this.props.color}`;
    const iconClass = `fa fa-${this.props.icon} fa-5x`;

    return (

{this.props.data || 'N/A'}

{this.props.text}

    );
  }
}

class Stats extends Component {
  getStats() {
    let statsPanels = [];
    if (globalState.user.admin) {
      globalState.getStats((stats) => {
        // statsPanels.push(
        //     <StatsPanel color='primary' icon='comments' data={stats.messages} text='Messages' key='messages' />
        // );
        // statsPanels.push(
        //     <StatsPanel color='green' icon='server' data={stats.guilds} text='Guilds' key='guilds' />
        // );
        // statsPanels.push(
        //     <StatsPanel color='yellow' icon='user' data={stats.users} text='Users' key='users' />
        // );
        // statsPanels.push(
        //     <StatsPanel color='red' icon='hashtag' data={stats.channels} text='Channels' key='channels' />
        // );
        statsPanels.push(stats);
      });
    }
    return statsPanels;
  }

  drawStats({ color, icon, data, text}) {
    const panelClass = `panel panel-${color}`;
    const iconClass = `fa fa-${icon} fa-5x`;

    return (

{data || 'N/A'}

{text}

    );
  }

  render() {
    let panel = this.getStats();
    console.log(panel);
    if (!anel[0]) return;

    // let renderPanels = [];
    // for (let panel in panels[0]) {
    //   renderPanels.push(
    //     <StatsPanel color='primary' icon='comments' data={panels[0][panel]} text='Messages' key={panels} />
    //   );
    // }
    // console.log(renderPanels);

    return (

        {this.drawStats({
          color: "primary",
          icon: "comments",
          data: panel[0].messages,
          text: "Messages"
        })}

    );
  }
}

class Dashboard extends Component {
  render() {
    let parts = [];

    parts.push(
      <PageHeader name="Dashboard" />
    );

    parts.push(

        <Stats />

    );

    parts.push(

          <DashboardGuildsList />

        {
          globalState.user && globalState.user.admin &&

            <ControlPanel />

        }

    );

		return (

        {parts}

    );
  }
}

export default Dashboard;
<|endoftext|>


<commit_before>var path = require('path');

// Webpack
var webpack = require('webpack');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var WebpackNotifierPlugin = require('webpack-notifier');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

// PostCSS
var autoprefixer = require('autoprefixer');

// Utils
var VERSION = JSON.stringify(require('./package.json').version);
var ENV = process.env.NODE_ENV;
var IS_PRODUCTION = ENV === 'production';

function root(args) {
  args = Array.prototype.slice.call(arguments, 0);
  return path.join.apply(path, [__dirname].concat(args));
}

function webpackConfig(options = {}) {

  var config = {
    context: root(),
    debug: true,
    // devtool: 'cheap-module-eval-source-map',
    devtool: 'source-map',

    resolve: {
      extensions: ['', '.js', '.ts', '.json', '.css', '.scss', '.html'],
      root: root('src'),
      modules: [
        'node_modules',
        root('src')
      ]
    },

    entry: {
      bootstrap: './src/demo/bootstrap.ts',
      vendor: './src/demo/vendor.ts',
      polyfills: './src/demo/polyfills.ts'
    },

    devServer: {
      outputPath: root('dist'),
      watchOptions: {
        poll: true
      },
      port: 9999,
      hot: options.HMR,
      inject: true,
      stats: {
        modules: false,
        cached: false,
        chunk: false
      }
    },

    output: {
      path: root('dist'),
      filename: '[name].js',
      sourceMapFilename: '[name].map',
      chunkFilename: '[id].chunk.js'
    },

    module: {
      preLoaders: [
        {
          test: /\.js$/,
          loader: 'source-map',
          exclude: /(node_modules)/
        }, {
          test: /\.ts$/,
          loader: 'tslint'
        }
      ],
      loaders: [
        {
          test: /\.ts$/,
          loaders: [
            'awesome-typescript-loader',
            '@angularclass/hmr-loader'
          ],
          exclude: /(node_modules\/)/
        },
        {
          test: /\.(png|woff|woff2|eot|ttf|svg|jpeg|jpg|gif)$/,
          loader: 'url',
          query: {
            limit: '100000'
          }
        },
        {
          test: /\.css/,
          loader:
            ExtractTextPlugin.extract({
              fallbackLoader: 'style',
              loader: !IS_PRODUCTION ?
                'css?sourceMap' :
                'css?sourceMap&minimize'
            })
        },
        {
          test: /\.scss$/,
          loader:
            ExtractTextPlugin.extract({
              fallbackLoader: 'style',
              loader: !IS_PRODUCTION ?
                'css?sourceMap!postcss?sourceMap!sass?sourceMap' :
                'css?sourceMap&minimize!postcss?sourceMap!sass?sourceMap'
            })
        },
        {
          test: /\.html$/,
          loader: 'raw'
        },
        {
          test: /\.json/,
          loader: 'json'
        }
      ]
    },

    plugins: [
      new webpack.HotModuleReplacementPlugin(),

      new webpack.NamedModulesPlugin(),

      // https://github.com/angular/angular/issues/11580#issuecomment-246880731
      new webpack.ContextReplacementPlugin(
        // The (\\|\/) piece accounts for path separators in *nix and Windows
        /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
        root('src') // location of your src
      ),

      new webpack.optimize.CommonsChunkPlugin({
        name: ['vendor', 'polyfills'],
        minChunks: Infinity
      }),

      new CopyWebpackPlugin([
        {
          from: 'src/assets',
          to: 'assets'
        },{
          from: 'src/styles',
          to: 'styles'
        }
      ]),

      new webpack.DefinePlugin({
        'APP_VERSION': VERSION,
        'HMR': options.HMR,
        'ENV': ENV
      }),

      new WebpackNotifierPlugin({
        alwaysNotify: true
      }),

      new ExtractTextPlugin({
        filename: '[name].[hash].css',
        allChunks: true
      }),

      new HtmlWebpackPlugin({
        template: 'src/index.html',
        chunksSortMode: 'dependency',
        title: 'swui'
  		})
    ],

    tslint: {
      emitErrors: false,
      failOnHint: false,
      resourcePath: 'src'
    },

    sassLoader: {
      includePaths: [
        root('src', 'styles'),
        root('src', 'assets')
      ]
    },

    postcss: function() {
      return [ autoprefixer ];
    }

  };

  if(!options.HMR) {
    config.plugins.push(new CleanWebpackPlugin(['dist'], {
      root: root(),
      verbose: false,
      dry: false
    }));
  }

  return config;
};

module.exports = webpackConfig;
<commit_msg>(chore): fix HMR not working after last update<commit_after>var path = require('path');

// Webpack
var webpack = require('webpack');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var WebpackNotifierPlugin = require('webpack-notifier');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

// PostCSS
var autoprefixer = require('autoprefixer');

// Utils
var VERSION = JSON.stringify(require('./package.json').version);
var ENV = process.env.NODE_ENV;
var IS_PRODUCTION = ENV === 'production';

function root(args) {
  args = Array.prototype.slice.call(arguments, 0);
  return path.join.apply(path, [__dirname].concat(args));
}

function webpackConfig(options = {}) {

  var IS_HMR = options.HMR;

  var config = {
    context: root(),
    debug: true,
    // devtool: 'cheap-module-eval-source-map',
    devtool: 'source-map',

    resolve: {
      extensions: ['', '.js', '.ts', '.json', '.css', '.scss', '.html'],
      root: root('src'),
      modules: [
        'node_modules',
        root('src')
      ]
    },

    entry: {
      bootstrap: './src/demo/bootstrap.ts',
      vendor: './src/demo/vendor.ts',
      polyfills: './src/demo/polyfills.ts'
    },

    devServer: {
      outputPath: root('dist'),
      watchOptions: {
        poll: true
      },
      port: 9999,
      hot: IS_HMR,
      inject: true,
      stats: {
        modules: false,
        cached: false,
        chunk: false
      }
    },

    output: {
      path: root('dist'),
      filename: '[name].js',
      sourceMapFilename: '[name].map',
      chunkFilename: '[id].chunk.js'
    },

    module: {
      preLoaders: [
        {
          test: /\.js$/,
          loader: 'source-map',
          exclude: /(node_modules)/
        }, {
          test: /\.ts$/,
          loader: 'tslint'
        }
      ],
      loaders: [
        {
          test: /\.ts$/,
          loaders: [
            'awesome-typescript-loader',
            '@angularclass/hmr-loader'
          ],
          exclude: /(node_modules\/)/
        },
        {
          test: /\.(png|woff|woff2|eot|ttf|svg|jpeg|jpg|gif)$/,
          loader: 'url',
          query: {
            limit: '100000'
          }
        },
        {
          test: /\.css/,
          loader:
            IS_HMR ?
              'style!css?sourceMap' :
              ExtractTextPlugin.extract({
                fallbackLoader: 'style',
                loader: !IS_PRODUCTION ?
                  'css?sourceMap' :
                  'css?sourceMap&minimize'
              })
        },
        {
          test: /\.scss$/,
          loader:
            IS_HMR ?
              'style!css!postcss?sourceMap!sass?sourceMap' :
              ExtractTextPlugin.extract({
                fallbackLoader: 'style',
                loader: !IS_PRODUCTION ?
                  'css?sourceMap!postcss?sourceMap!sass?sourceMap' :
                  'css?sourceMap&minimize!postcss?sourceMap!sass?sourceMap'
              })
        },
        {
          test: /\.html$/,
          loader: 'raw'
        },
        {
          test: /\.json/,
          loader: 'json'
        }
      ]
    },

    plugins: [
      new webpack.HotModuleReplacementPlugin(),

      new webpack.NamedModulesPlugin(),

      // https://github.com/angular/angular/issues/11580#issuecomment-246880731
      new webpack.ContextReplacementPlugin(
        // The (\\|\/) piece accounts for path separators in *nix and Windows
        /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
        root('src') // location of your src
      ),

      new webpack.optimize.CommonsChunkPlugin({
        name: ['vendor', 'polyfills'],
        minChunks: Infinity
      }),

      new CopyWebpackPlugin([
        {
          from: 'src/assets',
          to: 'assets'
        },{
          from: 'src/styles',
          to: 'styles'
        }
      ]),

      new webpack.DefinePlugin({
        'APP_VERSION': VERSION,
        'HMR': options.HMR,
        'ENV': ENV
      }),

      new WebpackNotifierPlugin({
        alwaysNotify: true
      }),

      new HtmlWebpackPlugin({
        template: 'src/index.html',
        chunksSortMode: 'dependency',
        title: 'swui'
  		})
    ],

    tslint: {
      emitErrors: false,
      failOnHint: false,
      resourcePath: 'src'
    },

    sassLoader: {
      includePaths: [
        root('src', 'styles'),
        root('src', 'assets')
      ]
    },

    postcss: function() {
      return [ autoprefixer ];
    }

  };

  console.log('IS HMR', IS_HMR)

  if(!IS_HMR) {
    config.plugins.push(new CleanWebpackPlugin(['dist'], {
      root: root(),
      verbose: false,
      dry: false
    }));

    config.plugins.push(new ExtractTextPlugin({
      filename: '[name].[hash].css',
      allChunks: true
    }));
  }

  return config;
};

module.exports = webpackConfig;
<|endoftext|>


<commit_before>window.audio = {

    // Instance to the AudioContext
    // Because of https://code.google.com/p/chromium/issues/detail?id=308784
    audioCtx : null,

    // Initialize global stuff
    init : function() {
        // Set the available AudioContext
        window.AudioContext = window.AudioContext || window.webkitAudioContext;

        // Create an instance of AudioContext
        audio.audioCtx = new AudioContext();
    },

    createSound : function(frequency, delay) {
        var oscillator = audio.audioCtx.createOscillator();
        oscillator.frequency.value = frequency;

        oscillator.connect(audio.audioCtx.destination);

        var currentTime = audio.audioCtx.currentTime;

        oscillator.start(currentTime);
        oscillator.stop(currentTime + delay);

        return audio;
    },

    // Player dies
    die : function() {
        audio.createSound(200, .25).createSound(300, .25);
    },

    // Collect a default power-up
    collectPowerUp : function() {
        audio.createSound(500, .25).createSound(600, .5).createSound(700, .75);
    },

    // Collect a bomb
    collectBomb : function() {
        audio.createSound(100, .1).createSound(150, .2).createSound(300, .3);
    }

}

// Initialize
window.audio.init();<commit_msg>Improved audio.<commit_after>window.audio = {

    // Instance to the AudioContext
    // Because of https://code.google.com/p/chromium/issues/detail?id=308784
    audioCtx : null,

    // Initialize global stuff
    init : function() {
        // Set the available AudioContext
        window.AudioContext = window.AudioContext || window.webkitAudioContext;

        // Create an instance of AudioContext
        audio.audioCtx = new AudioContext();
    },

    createSound : function(frequency, delay, overlap) {

        // Overlap multiple sounds
        overlap = overlap || true;

        var oscillator = audio.audioCtx.createOscillator();
        oscillator.frequency.value = frequency;

        oscillator.connect(audio.audioCtx.destination);

        var currentTime = audio.audioCtx.currentTime;

        console.log("overlap " + overlap);

        if (overlap) {
            oscillator.start(currentTime);
            oscillator.stop(currentTime + delay);

        } else {
            console.log('asdf');
            oscillator.start(currentTime + delay);
            oscillator.stop(currentTime + delay * 2);
        }

        return audio;
    },

    // Player dies
    die : function() {
        audio.createSound(200, .25).createSound(300, .25);
    },

    // Collect a default power-up
    collectPowerUp : function() {
        console.log('collect powerup');
        audio.createSound(500, .25, false).createSound(600, .5, false).createSound(700, .75, false);
    },

    // Collect a bomb
    collectBomb : function() {
        audio.createSound(100, .1).createSound(150, .2).createSound(300, .3);
    }

}

// Initialize
window.audio.init();<|endoftext|>


<commit_before>'use strict';

const webpack = require('webpack');
const path = require('path');

console.log('NODE_ENV', process.env.NODE_ENV);
let config =
{
  entry:['./src/root.js'],
  output:
  {
    filename:'fluid-pipe.js',
    path:path.resolve(__dirname, 'dist'),
    library:'fluid-pipe',
    libraryTarget:'umd',
    publicPath:'/dist/'
  },
  plugins:
  [
    new webpack.NoErrorsPlugin()
  ],
  module:
  {
    rules:
    [
      {
        test:/\.js?/,
        exclude:[/node_modules/, /styles/],
        include:path.resolve(__dirname, 'src'),
        use:['babel-loader']
      }
    ]
  },
  devtool:'source-map',
};

module.exports = function(env)
{
  console.log('env', env);
  process.env.BABEL_ENV = env;
  return config;
};<commit_msg>chore(build): Changed to more use friendly library name<commit_after>'use strict';

const webpack = require('webpack');
const path = require('path');

console.log('NODE_ENV', process.env.NODE_ENV);
let config =
{
  entry:['./src/root.js'],
  output:
  {
    filename:'fluid-pipe.js',
    path:path.resolve(__dirname, 'dist'),
    library:'FluidPipe',
    libraryTarget:'umd',
    publicPath:'/dist/'
  },
  plugins:
  [
    new webpack.NoErrorsPlugin()
  ],
  module:
  {
    rules:
    [
      {
        test:/\.js?/,
        exclude:[/node_modules/, /styles/],
        include:path.resolve(__dirname, 'src'),
        use:['babel-loader']
      }
    ]
  },
  devtool:'source-map',
};

module.exports = function(env)
{
  console.log('env', env);
  process.env.BABEL_ENV = env;
  return config;
};<|endoftext|>


<commit_before>var express = require('express'),
    validator = require('shared/schemas/validator'),
    supplierSchema = require('shared/schemas/supplier');

var router = module.exports = express.Router();

router.get('/suppliers', function(req, res, next) {
  var Supplier = req.app.get('bookshelf').models.Supplier;
  Supplier.query(function(qb) {
    qb.where({environment_id: req.user.get('environment_id')});
    qb.orderBy('name');
  }).fetchAll().then(function(suppliers) {
    res.send(suppliers.toJSON());
  }).catch(next);
});

router.post('/suppliers', function(req, res, next) {
  var Supplier = req.app.get('bookshelf').models.Supplier;
  var report = validator.validate(req.body, supplierSchema);
  if (report.errors.length) return res.status(400).send({error: 'Validation failed', details: report});
  Supplier.forge(req.body).save().then(function(supplier) {
    res.status(201).send(supplier);
  }).catch(next);
});
<commit_msg>Pass environment to supplier creation<commit_after>var express = require('express'),
    validator = require('shared/schemas/validator'),
    supplierSchema = require('shared/schemas/supplier'),
    _ = require('underscore');

var router = module.exports = express.Router();

router.get('/suppliers', function(req, res, next) {
  var Supplier = req.app.get('bookshelf').models.Supplier;
  Supplier.query(function(qb) {
    qb.where({environment_id: req.user.get('environment_id')});
    qb.orderBy('name');
  }).fetchAll().then(function(suppliers) {
    res.send(suppliers.toJSON());
  }).catch(next);
});

router.post('/suppliers', function(req, res, next) {
  var Supplier = req.app.get('bookshelf').models.Supplier;
  var data = _.omit(req.body, 'environment_id');
  var report = validator.validate(data, supplierSchema);
  if (report.errors.length) return res.status(400).send({error: 'Validation failed', details: report});
  Supplier.forge(_.extend({environment_id: req.user.get('environment_id')}, data)).save().then(function(supplier) {
    res.status(201).send(supplier);
  }).catch(next);
});
<|endoftext|>


<commit_before>const webpack = require('webpack');
const IS_PROD = process.argv.indexOf('-p') > -1;

module.exports = {
  devtool: IS_PROD ? 'source-map' : 'eval',
  entry: './demo/entry.ts',
  output: {
    filename: 'demo.js',
    path: IS_PROD ? './demo' : ''
  },
  module: {
    preLoaders: [{
      test: /\.ts$/, loader: 'tslint?emitErrors=false&failOnHint=false', exclude: /node_modules/
    }],
    loaders: [{
      test: /\.ts$/, loader: 'ts', exclude: /node_modules/
    }],
    noParse: [/zone\.js\/dist\/.+/]
  },
  resolve: {
    extensions: ['', '.ts', '.js']
  },
  devServer: {
    port: 8000,
    inline: true,
    hot: true,
    historyApiFallback: true,
    contentBase: 'demo'
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.optimize.DedupePlugin()
  ]
};<commit_msg>chore(webpack): remove module.noParse on zone.js as its no longer required<commit_after>const webpack = require('webpack');
const IS_PROD = process.argv.indexOf('-p') > -1;

module.exports = {
  devtool: IS_PROD ? 'source-map' : 'eval',
  entry: './demo/entry.ts',
  output: {
    filename: 'demo.js',
    path: IS_PROD ? './demo' : ''
  },
  module: {
    preLoaders: [{
      test: /\.ts$/, loader: 'tslint?emitErrors=false&failOnHint=false', exclude: /node_modules/
    }],
    loaders: [{
      test: /\.ts$/, loader: 'ts', exclude: /node_modules/
    }]
  },
  resolve: {
    extensions: ['', '.ts', '.js']
  },
  devServer: {
    port: 8000,
    inline: true,
    hot: true,
    historyApiFallback: true,
    contentBase: 'demo'
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.optimize.DedupePlugin()
  ]
};<|endoftext|>


<commit_before>var webpack = require("webpack")

module.exports = {

  output: {
    library: "ColorPicker",
    libraryTarget: "umd"
  },

  externals: [{
    "react": {
      root: "React",
      commonjs: "react",
      commonjs2: "react",
      amd: "react"
    },
    "react-dom": {
      root: "ReactDOM",
      commonjs: "react-dom",
      commonjs2: "react-dom",
      amd: "react-dom"
    }
  }],

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel"
      }
    ]
  },

  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
    })
  ]

};<commit_msg>uglify + banner for umd build<commit_after>var webpack = require("webpack");
var pkg = require("./package");

var BANNER = [
  pkg.name + " " + pkg.version + " - " + pkg.description,
  "Copyright (c) " + new Date().getFullYear() + " " + pkg.author.name + " - " + pkg.homepage,
  "Licensed under the " + pkg.license + " license"
].join("\n");

module.exports = {

  output: {
    library: "ColorPicker",
    libraryTarget: "umd"
  },

  externals: [{
    "react": {
      root: "React",
      commonjs: "react",
      commonjs2: "react",
      amd: "react"
    },
    "react-dom": {
      root: "ReactDOM",
      commonjs: "react-dom",
      commonjs2: "react-dom",
      amd: "react-dom"
    }
  }],

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel"
      }
    ]
  },

  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress : {
        unsafe : true,
        screw_ie8 : true
      },
      output : {
        comments : false
      }
    }),
    new webpack.BannerPlugin(BANNER)
  ]

};<|endoftext|>


<commit_before>var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var autoprefixer = require('autoprefixer');
var SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');

module.exports = {
    // configuration
    entry: {
        'app': './src/app.js',
        'vendor': ['jquery', 'crypto-js/aes', 'crypto-js/sha1', 'crypto-js/enc-utf8', './src/scripts/utils.js']
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        publicPath: "/",
        filename: "bundle.[name].js"
    },
    module: {
        loaders: [{
            test: /\.(css|scss)$/,
            loader: ExtractTextPlugin.extract('style', 'css!postcss-loader!sass'),
            include: [
                path.resolve(__dirname, 'src'),
                path.resolve(__dirname, 'node_modules/normalize.css')
            ]
        }, {
            test: /.jsx?$/,
            loader: 'babel-loader',
            include: [path.resolve(__dirname, 'src')],
            query: {
                presets: ['es2015', 'react']
            }
        }, {
            test: /.(png|jpg|gif|woff|woff2|eot|svg|ttf)$/,
            loader: 'url-loader',
            include: [path.resolve(__dirname, 'src')],
            query: {
                limit: 1000
            }
        }]
    },
    postcss: function() {
        return [autoprefixer];
    },
    plugins: [
        new ExtractTextPlugin("bundle.css"),
        new webpack.optimize.CommonsChunkPlugin( /* chunkName= */ "vendor", /* filename= */ "bundle.vendor.js"),
        new SWPrecacheWebpackPlugin({
            cacheId: 'sapientnitro-js-jargons-5'
        })
    ]
};<commit_msg>Updated service worker cache id<commit_after>var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var autoprefixer = require('autoprefixer');
var SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');

module.exports = {
    // configuration
    entry: {
        'app': './src/app.js',
        'vendor': ['jquery', 'crypto-js/aes', 'crypto-js/sha1', 'crypto-js/enc-utf8', './src/scripts/utils.js']
    },
    output: {
        path: path.resolve(__dirname, 'build'),
        publicPath: "/",
        filename: "bundle.[name].js"
    },
    module: {
        loaders: [{
            test: /\.(css|scss)$/,
            loader: ExtractTextPlugin.extract('style', 'css!postcss-loader!sass'),
            include: [
                path.resolve(__dirname, 'src'),
                path.resolve(__dirname, 'node_modules/normalize.css')
            ]
        }, {
            test: /.jsx?$/,
            loader: 'babel-loader',
            include: [path.resolve(__dirname, 'src')],
            query: {
                presets: ['es2015', 'react']
            }
        }, {
            test: /.(png|jpg|gif|woff|woff2|eot|svg|ttf)$/,
            loader: 'url-loader',
            include: [path.resolve(__dirname, 'src')],
            query: {
                limit: 1000
            }
        }]
    },
    postcss: function() {
        return [autoprefixer];
    },
    plugins: [
        new ExtractTextPlugin("bundle.css"),
        new webpack.optimize.CommonsChunkPlugin( /* chunkName= */ "vendor", /* filename= */ "bundle.vendor.js"),
        new SWPrecacheWebpackPlugin({
            cacheId: 'sapientnitro-js-jargons-6'
        })
    ]
};<|endoftext|>


<commit_before>(function (window) {
  var Ripples = function (initialState, setStateCallback) {
    this.state = initialState;
    this.events = {};
    this.eventTargets = {};
    this.setStateCallback = setStateCallback;
    for (var key in this.state) {
      var eventName = 'ripple' + key;
      this.events[eventName] = new Event(eventName);
      this.eventTargets[eventName] = [];
    }
  }
  Ripples.prototype.setState = function (newState) {
    for (var key in newState) {
      if (newState.hasOwnProperty(key)) {
        var eventName = 'ripple' + key;
        ripples.state[key] = newState[key];
        this.eventTargets[eventName].forEach(function (ele) {
          ele.dispatchEvent(this.events[eventName]);
        }.bind(this));
      }
    }
    if (typeof this.setStateCallback === 'function')
      this.setStateCallback();
  }
  Ripples.prototype.ripple = function (stateKeys, elements, reaction) {
    if (!Array.isArray(stateKeys))
      stateKeys = [stateKeys];
    if (!Array.isArray(elements))
      elements = [elements];
    stateKeys.forEach(function (key) {
      var eventName = 'ripple' + key;
      elements.forEach(function (element) {
        element.addEventListener(eventName, reaction);
        this.eventTargets[eventName].push(element);
      }.bind(this));
    }.bind(this));
  }
  Ripples.prototype.calm = function (stateKeys, elements, reaction) {
    if (!Array.isArray(stateKeys))
      stateKeys = [stateKeys];
    if (!Array.isArray(elements))
      elements = [elements];
    stateKeys.forEach(function (key) {
      var eventName = 'ripple' + key;
      elements.forEach(function (element) {
        element.removeEventListener(eventName, reaction);
        var i = this.eventTargets[eventName].indexOf(element);
        this.eventTargets[eventName].splice(i, 1);
      }.bind(this));
    }.bind(this));
  }
  Ripples.prototype.render = function (template) {
    if (typeof template[0] === 'string')
      template = [template];
    var docFrag = document.createDocumentFragment();
    template.forEach(function (subTemp) {
      var tag = subTemp[0], params = subTemp[1], children = subTemp[2];
      var element = document.createElement(tag);
      for (var key in params) {
        var param = params[key];
        if (typeof param === 'object' && param && !Array.isArray(param)) {
          for (var name in param)
            element[key][name] = param[name];
        } else { element[key] = param; }
      }
      if (Array.isArray(children)) {
        var childFrag = this.render(children);
        element.appendChild(childFrag);
      } else { element.innerHTML = children; }
      docFrag.appendChild(element);
    }.bind(this));
    return docFrag;
  }
  // Initialization
  var initialState = {
    open: false,
    busy: false
  }
  var refs = {
    excerpts: document.getElementsByClassName('post-excerpt'),
    ab: document.getElementById('action-button').childNodes[1],
    ink: document.getElementById('ink'),
    nav: document.getElementById('nav'),
    navItems: document.getElementsByClassName('nav-item')
  }
  var ripples = new Ripples(initialState);
  // Reactions
  var isHover = function (e) {
    return (e.parentElement.querySelector(':hover') === e);
  }
  var showNav = function () {
    refs.nav.classList.add('show');
  }
  var showNavItem = function (item) {
    item.classList.add('show');
  }
  var showInk = function () {
    var d = Math.max(window.innerWidth, window.innerHeight);
    var right = (-(d / 2) + refs.ab.offsetWidth / 2 + 25).toString() + 'px';
    var bottom = (-(d / 2) + refs.ab.offsetHeight / 2 + 15).toString() + 'px';
    refs.ink.classList.remove('animate-ripple');
    setTimeout(function() {
      d = d.toString() + 'px';
      refs.ink.style.width = d;
      refs.ink.style.height = d;
      refs.ink.style.right = right;
      refs.ink.style.bottom = bottom;
      refs.ink.classList.add('animate-ripple');
    });
  }
  var hideNav = function () {
    setTimeout(function () {
      if (!ripples.state.open)
        refs.nav.classList.remove('show');
    }, 500);
  }
  var hideNavItem = function (item) {
    item.classList.remove('show');
  }
  var hideInk = function () {
    refs.ink.classList.remove('animate-ripple');
  }
  var toggleNav = function () {
    switch (this.id) {
    case 'nav':
      ripples.state.open ? showNav() : hideNav();
      break;
    case 'ink':
      ripples.state.open ? showInk() : hideInk();
      break;
    default:
      ripples.state.open ? showNavItem(this) : hideNavItem(this);
    }
  }
  // Handlers
  function open() {
    if (ripples.state.open) return;
    ripples.setState({ open: true });
  }
  function close() {
    if (!ripples.state.open || isHover(refs.nav) || isHover(refs.ab)) return;
    ripples.setState({ open: false });
  }
  // Main
  // adding ellipse to the index excerpts
  if (refs.excerpts.length > 0) {
    Array.prototype.forEach.call(refs.excerpts, function(excerpt) {
      var paras = excerpt.getElementsByTagName('p');
      var p = paras[paras.length - 2];
      if (p.childNodes[0].nodeName === '#text')
        p.innerHTML += '...';
    });
  }
  var eles = [refs.nav, refs.ink];
  Array.prototype.push.apply(eles, refs.navItems);
  ripples.ripple('open', eles, toggleNav);
  refs.ab.addEventListener('click', open);
  refs.ab.addEventListener('mouseover', open);
  refs.ab.addEventListener('mouseout', close);
  refs.nav.addEventListener('mouseout', close);
  refs.ink.addEventListener('click', close);
})(window);

// dealing with image and embed widths on resize
document.addEventListener('DOMContentLoaded', function (e) {
  var post = document.querySelector('.post');
  if (post === null)
    return;
  var imgs = document.querySelectorAll('.post img');
  var embeds = document.querySelectorAll('.post iframe');
  var set = false;
  var init = true;
  var imageWidth = 662;
  var columnWidth = 550;
  var calcWidth = function(ele) {
    var windowWidth = document.body.offsetWidth;
    if (ele.tagName === 'IMG' && ele.naturalWidth < Math.min(columnWidth, windowWidth - 32)) {
      ele.style.width = 'auto';
      ele.style.marginLeft = 'auto';
      ele.classList.add('thin');
      return;
    }
    var margin = (windowWidth - post.offsetWidth) / 2;
    ele.style.width = windowWidth.toString() + 'px';
    ele.style.marginLeft = (-margin).toString() + 'px';
    if (ele.tagName === 'IFRAME')
      ele.style.height = (windowWidth / 1.776).toString() + 'px';
  }
  var resetWidth = function(ele) {
    var windowWidth = window.innerWidth
    if (ele.tagName === 'IMG' && ele.naturalWidth < Math.min(columnWidth, windowWidth - 32)) {
      ele.style.width = 'auto';
      ele.style.marginLeft = 'auto';
      ele.classList.add('thin');
      return;
    }
    ele.style.width = '126%';
    ele.style.marginLeft = '0px';
    if (ele.tagName === 'IFRAME')
      ele.style.height = (imageWidth / 1.776).toString() + 'px';
  }
  var resizeHandler = function(e) {
    var windowWidth = window.innerWidth
    if (windowWidth <= imageWidth) {
      if (imgs.length > 0) {
        Array.prototype.forEach.call(imgs, calcWidth);
      }
      if (embeds.length > 0) {
        Array.prototype.forEach.call(embeds, calcWidth)
      }
      if (set === false)
        set = true;
    } else if ((set || init) && windowWidth > imageWidth) {
      if (imgs.length > 0) {
        Array.prototype.forEach.call(imgs, resetWidth);
      }
      if (embeds.length > 0) {
        Array.prototype.forEach.call(embeds, resetWidth);
      }
      set = false;
      if (init)
        init = false;
    }
  }
  resizeHandler();
  window.addEventListener('resize', resizeHandler);
});
<commit_msg>fixed a bug in the open and closing on firefox<commit_after>(function (window) {
  var Ripples = function (initialState, setStateCallback) {
    this.state = initialState;
    this.events = {};
    this.eventTargets = {};
    this.setStateCallback = setStateCallback;
    for (var key in this.state) {
      var eventName = 'ripple' + key;
      this.events[eventName] = new Event(eventName);
      this.eventTargets[eventName] = [];
    }
  }
  Ripples.prototype.setState = function (newState) {
    for (var key in newState) {
      if (newState.hasOwnProperty(key)) {
        var eventName = 'ripple' + key;
        ripples.state[key] = newState[key];
        this.eventTargets[eventName].forEach(function (ele) {
          ele.dispatchEvent(this.events[eventName]);
        }.bind(this));
      }
    }
    if (typeof this.setStateCallback === 'function')
      this.setStateCallback();
  }
  Ripples.prototype.ripple = function (stateKeys, elements, reaction) {
    if (!Array.isArray(stateKeys))
      stateKeys = [stateKeys];
    if (!Array.isArray(elements))
      elements = [elements];
    stateKeys.forEach(function (key) {
      var eventName = 'ripple' + key;
      elements.forEach(function (element) {
        element.addEventListener(eventName, reaction);
        this.eventTargets[eventName].push(element);
      }.bind(this));
    }.bind(this));
  }
  Ripples.prototype.calm = function (stateKeys, elements, reaction) {
    if (!Array.isArray(stateKeys))
      stateKeys = [stateKeys];
    if (!Array.isArray(elements))
      elements = [elements];
    stateKeys.forEach(function (key) {
      var eventName = 'ripple' + key;
      elements.forEach(function (element) {
        element.removeEventListener(eventName, reaction);
        var i = this.eventTargets[eventName].indexOf(element);
        this.eventTargets[eventName].splice(i, 1);
      }.bind(this));
    }.bind(this));
  }
  Ripples.prototype.render = function (template) {
    if (typeof template[0] === 'string')
      template = [template];
    var docFrag = document.createDocumentFragment();
    template.forEach(function (subTemp) {
      var tag = subTemp[0], params = subTemp[1], children = subTemp[2];
      var element = document.createElement(tag);
      for (var key in params) {
        var param = params[key];
        if (typeof param === 'object' && param && !Array.isArray(param)) {
          for (var name in param)
            element[key][name] = param[name];
        } else { element[key] = param; }
      }
      if (Array.isArray(children)) {
        var childFrag = this.render(children);
        element.appendChild(childFrag);
      } else { element.innerHTML = children; }
      docFrag.appendChild(element);
    }.bind(this));
    return docFrag;
  }
  // Initialization
  var initialState = {
    open: false,
    busy: false
  }
  var refs = {
    excerpts: document.getElementsByClassName('post-excerpt'),
    ab: document.getElementById('action-button').childNodes[1],
    ink: document.getElementById('ink'),
    nav: document.getElementById('nav'),
    navItems: document.getElementsByClassName('nav-item'),
    post: document.querySelector('.post'),
    imgs: document.querySelectorAll('.post img'),
    embeds: document.querySelectorAll('.post iframe')
  }
  var ripples = new Ripples(initialState);
  // Reactions
  var isHover = function (e) {
    console.log(e.parentElement.querySelector(':hover'))
    return (e.parentElement.querySelector(':hover') === e);
  }
  var showNav = function () {
    refs.nav.classList.add('show');
  }
  var showNavItem = function (item) {
    item.classList.add('show');
  }
  var showInk = function () {
    var d = Math.max(window.innerWidth, window.innerHeight);
    var right = (-(d / 2) + refs.ab.offsetWidth / 2 + 25).toString() + 'px';
    var bottom = (-(d / 2) + refs.ab.offsetHeight / 2 + 15).toString() + 'px';
    refs.ink.classList.remove('animate-ripple');
    setTimeout(function() {
      d = d.toString() + 'px';
      refs.ink.style.width = d;
      refs.ink.style.height = d;
      refs.ink.style.right = right;
      refs.ink.style.bottom = bottom;
      refs.ink.classList.add('animate-ripple');
    });
  }
  var hideNav = function () {
    setTimeout(function () {
      if (!ripples.state.open)
        refs.nav.classList.remove('show');
    }, 500);
  }
  var hideNavItem = function (item) {
    item.classList.remove('show');
  }
  var hideInk = function () {
    refs.ink.classList.remove('animate-ripple');
  }
  var toggleNav = function () {
    switch (this.id) {
    case 'nav':
      ripples.state.open ? showNav() : hideNav();
      break;
    case 'ink':
      ripples.state.open ? showInk() : hideInk();
      break;
    default:
      ripples.state.open ? showNavItem(this) : hideNavItem(this);
    }
  }
  // Handlers
  function open() {
    if (ripples.state.open) return;
    ripples.setState({ open: true });
  }
  function close() {
    if (!ripples.state.open) return;
    ripples.setState({ open: false });
  }
  // Main
  // adding ellipse to the index excerpts
  if (refs.excerpts.length > 0) {
    Array.prototype.forEach.call(refs.excerpts, function(excerpt) {
      var paras = excerpt.getElementsByTagName('p');
      var p = paras[paras.length - 2];
      if (p.childNodes[0].nodeName === '#text')
        p.innerHTML += '...';
    });
  }
  var eles = [refs.nav, refs.ink];
  Array.prototype.push.apply(eles, refs.navItems);
  ripples.ripple('open', eles, toggleNav);
  refs.ab.addEventListener('click', open);
  refs.ab.addEventListener('mouseover', open);
  refs.nav.addEventListener('mouseover', open);
  refs.ink.addEventListener('mouseover', close);
  refs.ink.addEventListener('click', close);
  // dealing with image and embed widths on resize
  window.addEventListener('load', function (e) {
    var post = refs.post;
    var imgs = refs.imgs;
    var embeds = refs.embeds;
    if (post === null)
      return;
    var set = false;
    var init = true;
    var imageWidth = 662;
    var columnWidth = 550;
    var calcWidth = function(ele) {
      var windowWidth = document.body.offsetWidth;
      if (ele.tagName === 'IMG' && ele.naturalWidth < Math.min(columnWidth, windowWidth - 32)) {
        ele.style.width = 'auto';
        ele.style.marginLeft = 'auto';
        ele.classList.add('thin');
        return;
      }
      var margin = (windowWidth - post.offsetWidth) / 2;
      ele.style.width = windowWidth.toString() + 'px';
      ele.style.marginLeft = (-margin).toString() + 'px';
      if (ele.tagName === 'IFRAME')
        ele.style.height = (windowWidth / 1.776).toString() + 'px';
    }
    var resetWidth = function(ele) {
      var windowWidth = window.innerWidth
      if (ele.tagName === 'IMG' && ele.naturalWidth < Math.min(columnWidth, windowWidth - 32)) {
        ele.style.width = 'auto';
        ele.style.marginLeft = 'auto';
        ele.classList.add('thin');
        return;
      }
      ele.style.width = '126%';
      ele.style.marginLeft = '0px';
      if (ele.tagName === 'IFRAME')
        ele.style.height = (imageWidth / 1.776).toString() + 'px';
    }
    var resizeHandler = function(e) {
      var windowWidth = window.innerWidth
      if (windowWidth <= imageWidth) {
        if (imgs.length > 0) {
          Array.prototype.forEach.call(imgs, calcWidth);
        }
        if (embeds.length > 0) {
          Array.prototype.forEach.call(embeds, calcWidth)
        }
        if (set === false)
          set = true;
      } else if ((set || init) && windowWidth > imageWidth) {
        if (imgs.length > 0) {
          Array.prototype.forEach.call(imgs, resetWidth);
        }
        if (embeds.length > 0) {
          Array.prototype.forEach.call(embeds, resetWidth);
        }
        set = false;
        if (init)
          init = false;
      }
    }
    resizeHandler();
    window.addEventListener('resize', resizeHandler);
  });
})(window);
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var fs = require('fs');
var webpack = require('webpack');
//var Manifest    = require('manifest-revision-webpack-plugin');
var TextPlugin = require('extract-text-webpack-plugin');
var HtmlPlugin = require('html-webpack-plugin');
//var _ = require('lodash');

function getEnvironment() {
  return process.env.NODE_ENV;
}

function isProduction() {
  return getEnvironment() === 'production';
}

function projectRoot() {
  return path.dirname(fs.realpathSync(__filename));
}

function projectDependencies() {
  return Object.keys(require(projectRoot() + '/package').dependencies);
}

function WebpackConfigurer() {

  this.configure = function () {
    if (!getEnvironment()) {
      throw 'Can\'t find local environment variable via process.env.NODE_ENV';
    }

    var config = {};

    config.debug = isProduction() ? false : true;

    config.entry = {
      application: path.join(projectRoot(), 'src', 'app', 'app.js'),
      vendors: projectDependencies()
    };

    config.output = {
      path: path.join(projectRoot(), 'build'),
      filename: path.join('assets', 'js', '[name].bundle.[chunkhash].js'),
      chunkFilename: '[id].bundle.[chunkhash].js',
      publicPath: '/'
    };

    config.plugins = [
      //new webpack.IgnorePlugin(/\.(css|less)$/),
      new webpack.BannerPlugin('require("source-map-support").install();', {raw: true, entryOnly: false}),

      new webpack.optimize.CommonsChunkPlugin('vendors', 'assets/js/vendors.[hash].js'),
      new TextPlugin('assets/css/[name].[hash].css'),
      //new Manifest(path.join(projectRoot + '/src/config', 'manifest.json'), {
      //  rootAssetPath: rootAssetPath
      //}),

      new HtmlPlugin({
        title: 'Test App',
        chunks: ['application', 'vendors'],
        filename: 'index.html',
        template: path.join(projectRoot(), 'src', 'app', 'index.html')
      })
    ];

    config.devtool = '#eval-source-map';

    if (!isProduction()) {
      config.devServer = {
        contentBase: config.output.path,
        info: true,
        hot: false,
        inline: true
      }
    }

// Небольшие настройки связанные с тем, где искать сторонние библиотеки
//resolve: {
//  extensions: ['', '.js'],
//  modulesDirectories: ['node_modules'],
//  // Алиасы - очень важный инструмент для определения области видимости ex. require('_modules/test/index')
//  alias: {
//    _svg:         path.join(projectRoot, 'app', 'assets', 'svg'),
//    _data:        path.join(projectRoot, 'app', 'data'),
//    _fonts:       path.join(projectRoot, 'app', 'assets', 'fonts'),
//    _modules:     path.join(projectRoot, 'app', 'modules'),
//    _images:      path.join(projectRoot, 'app', 'assets', 'images'),
//    _stylesheets: path.join(projectRoot, 'app', 'assets', 'stylesheets'),
//    _templates:   path.join(projectRoot, 'app', 'assets', 'templates')
//  }
//},
//// Настройка загрузчиков, они выполняют роль обработчика исходного файла в конечный
//module: {
//  loaders: [
//    { test: /\.jade$/, loader: 'jade-loader' },
//    { test: /\.(css|ttf|eot|woff|woff2|png|ico|jpg|jpeg|gif|svg)$/i, loaders: ['file?context=' + rootAssetPath + '&name=assets/static/[ext]/[name].[hash].[ext]'] },
//    { test: /\.styl$/, loader: TextPlugin.extract('style-loader', 'css-loader!autoprefixer-loader?browsers=last 5 version!stylus-loader') }
//  ]
//},

    return config;
  };

  return this;
}

var configurer = new WebpackConfigurer();

module.exports = configurer.configure();

<commit_msg>adding webpack support<commit_after>'use strict';

var path = require('path');
var fs = require('fs');
var webpack = require('webpack');
//var Manifest    = require('manifest-revision-webpack-plugin');
var TextPlugin = require('extract-text-webpack-plugin');
var HtmlPlugin = require('html-webpack-plugin');
//var _ = require('lodash');

function getEnvironment() {
  return process.env.NODE_ENV;
}

function isProduction() {
  return getEnvironment() === 'production';
}

function isDevelopment() {
  return getEnvironment() === 'development';
}

function projectRoot() {
  return path.dirname(fs.realpathSync(__filename));
}

function projectDependencies() {
  return Object.keys(require(projectRoot() + '/package').dependencies);
}

if (!getEnvironment()) {
  throw 'Can\'t find local environment variable via process.env.NODE_ENV';
}

var mainJsFile = path.join(projectRoot(), 'public', 'app', 'app.js');
var mainHtmlTemplate = path.join(projectRoot(), 'public', 'app', 'acceptd', 'index.html');

var buildPath = path.join(projectRoot(), 'build');
var publicPath = '/';

var config = {};

config.debug = isProduction() ? false : true;

config.entry = {
  application: mainJsFile,
  vendors: projectDependencies()
};

config.output = {
  path: buildPath,
  filename: path.join('assets', 'js', '[name].bundle.[chunkhash].js'),
  chunkFilename: '[id].bundle.[chunkhash].js',
  publicPath: publicPath
};

config.plugins = [
  //new webpack.IgnorePlugin(/\.(css|less)$/),
  new webpack.BannerPlugin('require("source-map-support").install();', {raw: true, entryOnly: false}),

  new webpack.optimize.CommonsChunkPlugin('vendors', 'assets/js/vendors.[hash].js'),

  new TextPlugin('assets/css/[name].[hash].css'),

  //new Manifest(path.join(projectRoot + '/src/config', 'manifest.json'), {
  //  rootAssetPath: rootAssetPath
  //}),

  new HtmlPlugin({
    title: 'Test App',
    chunks: ['application', 'vendors'],
    filename: 'index.html',
    template: mainHtmlTemplate
  })
];

config.devtool = '#eval-source-map';

if (isDevelopment()) {
  config.devServer = {
    contentBase: config.output.path,
    info: true,
    hot: false,
    inline: true
  }
}

// Небольшие настройки связанные с тем, где искать сторонние библиотеки
config.resolve = {
  extensions: ['', '.js'],
  modulesDirectories: ['node_modules']
  // Алиасы - очень важный инструмент для определения области видимости ex. require('_modules/test/index')
  //alias: {
  //  _svg:         path.join(projectRoot(), 'app', 'assets', 'svg'),
  //  _data:        path.join(projectRoot(), 'app', 'data'),
  //  _fonts:       path.join(projectRoot(), 'app', 'assets', 'fonts'),
  //  _modules:     path.join(projectRoot(), 'app', 'modules'),
  //  _images:      path.join(projectRoot(), 'app', 'assets', 'images'),
  //  _stylesheets: path.join(projectRoot(), 'app', 'assets', 'stylesheets'),
  //  _templates:   path.join(projectRoot(), 'app', 'assets', 'templates')
  //}
};
//
//// Настройка загрузчиков, они выполняют роль обработчика исходного файла в конечный
//config.module = {
//  loaders: [
//    { test: /\.jade$/, loader: 'jade-loader' },
//    { test: /\.(css|ttf|eot|woff|woff2|png|ico|jpg|jpeg|gif|svg)$/i, loaders: ['file?context=' + projectRoot() +'/app' + '&name=assets/static/[ext]/[name].[hash].[ext]'] },
//    { test: /\.styl$/, loader: TextPlugin.extract('style-loader', 'css-loader!autoprefixer-loader?browsers=last 5 version!stylus-loader') }
//  ]
//};

module.exports = config;
<|endoftext|>


<commit_before>/*global
	$
*/
$(document).ready(function () {

	'use strict';

	var $grid = $('.grid'),
		$textItems = $grid.find('.grid-item');

	$grid = $('.grid').masonry({
        itemSelector: '.grid-item'
    });

    $grid.imagesLoaded().progress(function (imgLoad, image) {
        var $gridItem = $(image.img).parents('.grid-item');
        $gridItem.fadeIn().removeClass('loading');
        if (image.isLoaded) {
            $gridItem.addClass('loaded');
        } else {
            $gridItem.addClass('unloaded');
        }
        $grid.masonry('layout');
    });
});
<commit_msg>Change thumbnail load animation (Fade in fast)<commit_after>/*global
	$
*/
$(document).ready(function () {

	'use strict';

	var $grid = $('.grid'),
		$textItems = $grid.find('.grid-item');

	$grid = $('.grid').masonry({
        itemSelector: '.grid-item'
    });

    $grid.imagesLoaded().progress(function (imgLoad, image) {
        var $gridItem = $(image.img).parents('.grid-item');
        $gridItem.fadeIn('fast').removeClass('loading');
        if (image.isLoaded) {
            $gridItem.addClass('loaded');
        } else {
            $gridItem.addClass('unloaded');
        }
        $grid.masonry('layout');
    });
});
<|endoftext|>