<commit_before>import { app } from '../preinit/app_settings'
import { hideDescription } from './description'
import { DRAGGING_TYPE_NONE, draggingType } from '../segments/drag_and_drop'
import { cancelFadeoutControls } from '../segments/resizing'
import { getElAbsolutePos } from '../util/helpers'
import { registerKeypress } from '../app/keypress'
import store from '../store'
import {
  showInfoBubble,
  hideInfoBubble,
  setInfoBubbleSegmentDataNo,
  updateHoverPolygon
} from '../store/actions/infoBubble'

export const INFO_BUBBLE_TYPE_SEGMENT = 1
export const INFO_BUBBLE_TYPE_LEFT_BUILDING = 2
export const INFO_BUBBLE_TYPE_RIGHT_BUILDING = 3

const INFO_BUBBLE_MARGIN_BUBBLE = 20
const INFO_BUBBLE_MARGIN_MOUSE = 10

const MIN_TOP_MARGIN_FROM_VIEWPORT = 120

function isInfoBubbleVisible () {
  return store.getState().infoBubble.visible
}

export const infoBubble = {
  el: null,

  descriptionVisible: false,

  startMouseX: null,
  startMouseY: null,
  hoverPolygon: null,
  segmentEl: null,
  segment: null,
  type: null,

  lastMouseX: null,
  lastMouseY: null,

  suppressed: false,

  bubbleX: null,
  bubbleY: null,
  bubbleWidth: null,
  bubbleHeight: null,

  considerMouseX: null,
  considerMouseY: null,
  considerSegmentEl: null,
  considerType: null,

  hoverPolygonUpdateTimerId: -1,
  suppressTimerId: -1,

  registerKeypresses: function () {
    // Register keyboard shortcuts to hide info bubble
    // Only hide if it's currently visible, and if the
    // description is NOT visible. (If the description
    // is visible, the escape key should hide that first.)
    registerKeypress('esc', {
      condition: function () { return isInfoBubbleVisible() && !infoBubble.descriptionVisible }
    }, function () {
      infoBubble.hide()
      infoBubble.hideSegment(false)
    })
  },
  suppress: function () {
    if (!infoBubble.suppressed) {
      infoBubble.hide()
      infoBubble.hideSegment(true)
      infoBubble.suppressed = true
    }

    window.clearTimeout(infoBubble.suppressTimerId)
    infoBubble.suppressTimerId = window.setTimeout(infoBubble.unsuppress, 100)
  },

  unsuppress: function () {
    infoBubble.suppressed = false

    window.clearTimeout(infoBubble.suppressTimerId)
  },

  _withinHoverPolygon: function (x, y) {
    const hoverPolygon = store.getState().infoBubble.hoverPolygon
    return _isPointInPoly(hoverPolygon, [x, y])
  },

  // TODO: make this a pure(r) function
  createHoverPolygon: function (mouseX, mouseY) {
    let hoverPolygon = []

    if (!isInfoBubbleVisible()) {
      return hoverPolygon
    }

    const bubbleX = infoBubble.bubbleX
    const bubbleY = infoBubble.bubbleY
    const bubbleWidth = infoBubble.bubbleWidth
    const bubbleHeight = infoBubble.bubbleHeight

    let marginBubble

    if (infoBubble.descriptionVisible) {
      // TODO const
      marginBubble = 200
    } else {
      marginBubble = INFO_BUBBLE_MARGIN_BUBBLE
    }

    const mouseInside = store.getState().infoBubble.mouseInside
    if (mouseInside && !infoBubble.descriptionVisible) {
      var pos = getElAbsolutePos(infoBubble.segmentEl)

      var x = pos[0] - document.querySelector('#street-section-outer').scrollLeft

      var segmentX1 = x - INFO_BUBBLE_MARGIN_BUBBLE
      var segmentX2 = x + infoBubble.segmentEl.offsetWidth + INFO_BUBBLE_MARGIN_BUBBLE

      var segmentY = pos[1] + infoBubble.segmentEl.offsetHeight + INFO_BUBBLE_MARGIN_BUBBLE

      hoverPolygon = [
        [bubbleX - marginBubble, bubbleY - marginBubble],
        [bubbleX - marginBubble, bubbleY + bubbleHeight + marginBubble],
        [segmentX1, bubbleY + bubbleHeight + marginBubble + 120],
        [segmentX1, segmentY],
        [segmentX2, segmentY],
        [segmentX2, bubbleY + bubbleHeight + marginBubble + 120],
        [bubbleX + bubbleWidth + marginBubble, bubbleY + bubbleHeight + marginBubble],
        [bubbleX + bubbleWidth + marginBubble, bubbleY - marginBubble],
        [bubbleX - marginBubble, bubbleY - marginBubble]
      ]
    } else {
      var bottomY = mouseY - INFO_BUBBLE_MARGIN_MOUSE
      if (bottomY < bubbleY + bubbleHeight + INFO_BUBBLE_MARGIN_BUBBLE) {
        bottomY = bubbleY + bubbleHeight + INFO_BUBBLE_MARGIN_BUBBLE
      }
      var bottomY2 = mouseY + INFO_BUBBLE_MARGIN_MOUSE
      if (bottomY2 < bubbleY + bubbleHeight + INFO_BUBBLE_MARGIN_BUBBLE) {
        bottomY2 = bubbleY + bubbleHeight + INFO_BUBBLE_MARGIN_BUBBLE
      }

      if (infoBubble.descriptionVisible) {
        bottomY = bubbleY + bubbleHeight + marginBubble
        bottomY2 = bottomY
      }

      var diffX = 60 - ((mouseY - bubbleY) / 5)
      if (diffX < 0) {
        diffX = 0
      } else if (diffX > 50) {
        diffX = 50
      }

      hoverPolygon = [
        [bubbleX - marginBubble, bubbleY - marginBubble],
        [bubbleX - marginBubble, bubbleY + bubbleHeight + marginBubble],
        [(bubbleX - marginBubble + mouseX - INFO_BUBBLE_MARGIN_MOUSE - diffX) / 2, bottomY + ((bubbleY + bubbleHeight + marginBubble - bottomY) * 0.2)],
        [mouseX - INFO_BUBBLE_MARGIN_MOUSE - diffX, bottomY],
        [mouseX - INFO_BUBBLE_MARGIN_MOUSE, bottomY2],
        [mouseX + INFO_BUBBLE_MARGIN_MOUSE, bottomY2],
        [mouseX + INFO_BUBBLE_MARGIN_MOUSE + diffX, bottomY],
        [(bubbleX + bubbleWidth + marginBubble + mouseX + INFO_BUBBLE_MARGIN_MOUSE + diffX) / 2, bottomY + ((bubbleY + bubbleHeight + marginBubble - bottomY) * 0.2)],
        [bubbleX + bubbleWidth + marginBubble, bubbleY + bubbleHeight + marginBubble],
        [bubbleX + bubbleWidth + marginBubble, bubbleY - marginBubble],
        [bubbleX - marginBubble, bubbleY - marginBubble]
      ]
    }

    return hoverPolygon
  },

  updateHoverPolygon: function (mouseX, mouseY) {
    const hoverPolygon = infoBubble.createHoverPolygon(mouseX, mouseY)
    store.dispatch(updateHoverPolygon(hoverPolygon))
  },

  scheduleHoverPolygonUpdate: function () {
    window.clearTimeout(infoBubble.hoverPolygonUpdateTimerId)

    infoBubble.hoverPolygonUpdateTimerId = window.setTimeout(function () {
      infoBubble.updateHoverPolygon(infoBubble.lastMouseX, infoBubble.lastMouseY)
    }, 50)
  },

  onBodyMouseMove: function (event) {
    var mouseX = event.pageX
    var mouseY = event.pageY

    infoBubble.lastMouseX = mouseX
    infoBubble.lastMouseY = mouseY

    if (isInfoBubbleVisible()) {
      if (!infoBubble._withinHoverPolygon(mouseX, mouseY)) {
        infoBubble.show(false)
      }
    }

    infoBubble.scheduleHoverPolygonUpdate()
  },

  hideSegment: function (fast) {
    if (infoBubble.segmentEl) {
      infoBubble.segmentEl.classList.remove('hover')
      var el = infoBubble.segmentEl
      if (fast) {
        el.classList.add('immediate-show-drag-handles')
        window.setTimeout(function () {
          el.classList.remove('immediate-show-drag-handles')
        }, 0)
      } else {
        el.classList.remove('immediate-show-drag-handles')
      }
      infoBubble.segmentEl.classList.remove('hide-drag-handles-when-description-shown')
      infoBubble.segmentEl.classList.remove('hide-drag-handles-when-inside-info-bubble')
      infoBubble.segmentEl.classList.remove('show-drag-handles')
      infoBubble.segmentEl = null
      infoBubble.segment = null
    }
  },

  hide: function () {
    if (infoBubble.el) {
      hideDescription()
      document.body.classList.remove('controls-fade-out')

      store.dispatch(hideInfoBubble())

      document.body.removeEventListener('mousemove', infoBubble.onBodyMouseMove)
    }
  },

  considerShowing: function (event, segmentEl, type) {
    if (Boolean(store.getState().menus.activeMenu) === true || app.readOnly) {
      return
    }

    if (event) {
      infoBubble.considerMouseX = event.pageX
      infoBubble.considerMouseY = event.pageY
    } else {
      var pos = getElAbsolutePos(segmentEl)

      infoBubble.considerMouseX = pos[0] - document.querySelector('#street-section-outer').scrollLeft
      infoBubble.considerMouseY = pos[1]
    }
    infoBubble.considerSegmentEl = segmentEl
    infoBubble.considerType = type

    if ((segmentEl === infoBubble.segmentEl) && (type === infoBubble.type)) {
      return
    }

    if (!isInfoBubbleVisible() || !infoBubble._withinHoverPolygon(infoBubble.considerMouseX, infoBubble.considerMouseY)) {
      if (type === INFO_BUBBLE_TYPE_RIGHT_BUILDING) {
        console.log(infoBubble.considerMouseX, infoBubble.considerMouseY)
      }
      infoBubble.show(false)
    }
  },

  dontConsiderShowing: function () {
    infoBubble.considerSegmentEl = null
    infoBubble.considerType = null
  },

  updateContents: function () {
    const street = store.getState().street

    // If info bubble changes, wake this back up if it's fading out
    cancelFadeoutControls()

    window.dispatchEvent(new window.CustomEvent('stmx:force_infobubble_update'))

    switch (infoBubble.type) {
      case INFO_BUBBLE_TYPE_SEGMENT:
        var segment = street.segments[store.getState().infoBubble.dataNo]
        infoBubble.segment = segment
        break
    }
  },

  // TODO rename
  show: function (force) {
    if (infoBubble.suppressed) {
      window.setTimeout(infoBubble.show, 100)
      return
    }

    if (draggingType() !== DRAGGING_TYPE_NONE) {
      return
    }

    if (!infoBubble.considerType) {
      infoBubble.hide()
      infoBubble.hideSegment(false)
      return
    }

    var segmentEl = infoBubble.considerSegmentEl
    var type = infoBubble.considerType

    if ((segmentEl === infoBubble.segmentEl) &&
      (type === infoBubble.type) && !force) {
      return
    }
    infoBubble.hideSegment(true)

    var mouseX = infoBubble.considerMouseX
    var mouseY = infoBubble.considerMouseY

    infoBubble.segmentEl = segmentEl
    infoBubble.type = type

    if (segmentEl) {
      segmentEl.classList.add('hover')
      segmentEl.classList.add('show-drag-handles')
    }
    if (isInfoBubbleVisible()) {
      segmentEl.classList.add('immediate-show-drag-handles')

      if (infoBubble.descriptionVisible) {
        hideDescription()
      }
    }

    infoBubble.startMouseX = mouseX
    infoBubble.startMouseY = mouseY

    var pos = getElAbsolutePos(segmentEl)

    var bubbleX = pos[0] - document.querySelector('#street-section-outer').scrollLeft
    var bubbleY = pos[1]

    const dataNo = segmentEl.dataNo
    store.dispatch(setInfoBubbleSegmentDataNo(dataNo))

    infoBubble.el = document.querySelector('.info-bubble')
    infoBubble.updateContents()

    var bubbleWidth = infoBubble.el.offsetWidth
    var bubbleHeight = infoBubble.el.offsetHeight

    // TODO const
    bubbleY -= bubbleHeight - 20
    if (bubbleY < MIN_TOP_MARGIN_FROM_VIEWPORT) {
      bubbleY = MIN_TOP_MARGIN_FROM_VIEWPORT
    }

    console.log('offsetWidth: ', segmentEl.offsetWidth)
    bubbleX += segmentEl.offsetWidth / 2
    bubbleX -= bubbleWidth / 2

    const system = store.getState().system
    // TODO const
    if (bubbleX < 50) {
      bubbleX = 50
    } else if (bubbleX > system.viewportWidth - bubbleWidth - 50) {
      bubbleX = system.viewportWidth - bubbleWidth - 50
    }

    console.log('bubbleX: ', bubbleX)
    infoBubble.el.style.left = bubbleX + 'px'
    infoBubble.el.style.top = bubbleY + 'px'

    if (!isInfoBubbleVisible()) {
      store.dispatch(showInfoBubble())
    }

    infoBubble.bubbleX = bubbleX
    infoBubble.bubbleY = bubbleY
    infoBubble.bubbleWidth = bubbleWidth
    infoBubble.bubbleHeight = bubbleHeight

    infoBubble.updateHoverPolygon(mouseX, mouseY)
    document.body.addEventListener('mousemove', infoBubble.onBodyMouseMove)
  }
}

function _isPointInPoly (vs, point) {
  var x = point[0]
  var y = point[1]

  var inside = false
  for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
    var xi = vs[i][0]
    var yi = vs[i][1]
    var xj = vs[j][0]
    var yj = vs[j][1]

    var intersect = ((yi > y) !== (yj > y)) &&
      (x < ((xj - xi) * (y - yi) / (yj - yi)) + xi)
    if (intersect) inside = !inside
  }

  return inside
}
<commit_msg>removed console.logs; if segment hovered is a building, dataNo = left or right<commit_after>import { app } from '../preinit/app_settings'
import { hideDescription } from './description'
import { DRAGGING_TYPE_NONE, draggingType } from '../segments/drag_and_drop'
import { cancelFadeoutControls } from '../segments/resizing'
import { getElAbsolutePos } from '../util/helpers'
import { registerKeypress } from '../app/keypress'
import store from '../store'
import {
  showInfoBubble,
  hideInfoBubble,
  setInfoBubbleSegmentDataNo,
  updateHoverPolygon
} from '../store/actions/infoBubble'

export const INFO_BUBBLE_TYPE_SEGMENT = 1
export const INFO_BUBBLE_TYPE_LEFT_BUILDING = 2
export const INFO_BUBBLE_TYPE_RIGHT_BUILDING = 3

const INFO_BUBBLE_MARGIN_BUBBLE = 20
const INFO_BUBBLE_MARGIN_MOUSE = 10

const MIN_TOP_MARGIN_FROM_VIEWPORT = 120

function isInfoBubbleVisible () {
  return store.getState().infoBubble.visible
}

export const infoBubble = {
  el: null,

  descriptionVisible: false,

  startMouseX: null,
  startMouseY: null,
  hoverPolygon: null,
  segmentEl: null,
  segment: null,
  type: null,

  lastMouseX: null,
  lastMouseY: null,

  suppressed: false,

  bubbleX: null,
  bubbleY: null,
  bubbleWidth: null,
  bubbleHeight: null,

  considerMouseX: null,
  considerMouseY: null,
  considerSegmentEl: null,
  considerType: null,

  hoverPolygonUpdateTimerId: -1,
  suppressTimerId: -1,

  registerKeypresses: function () {
    // Register keyboard shortcuts to hide info bubble
    // Only hide if it's currently visible, and if the
    // description is NOT visible. (If the description
    // is visible, the escape key should hide that first.)
    registerKeypress('esc', {
      condition: function () { return isInfoBubbleVisible() && !infoBubble.descriptionVisible }
    }, function () {
      infoBubble.hide()
      infoBubble.hideSegment(false)
    })
  },
  suppress: function () {
    if (!infoBubble.suppressed) {
      infoBubble.hide()
      infoBubble.hideSegment(true)
      infoBubble.suppressed = true
    }

    window.clearTimeout(infoBubble.suppressTimerId)
    infoBubble.suppressTimerId = window.setTimeout(infoBubble.unsuppress, 100)
  },

  unsuppress: function () {
    infoBubble.suppressed = false

    window.clearTimeout(infoBubble.suppressTimerId)
  },

  _withinHoverPolygon: function (x, y) {
    const hoverPolygon = store.getState().infoBubble.hoverPolygon
    return _isPointInPoly(hoverPolygon, [x, y])
  },

  // TODO: make this a pure(r) function
  createHoverPolygon: function (mouseX, mouseY) {
    let hoverPolygon = []

    if (!isInfoBubbleVisible()) {
      return hoverPolygon
    }

    const bubbleX = infoBubble.bubbleX
    const bubbleY = infoBubble.bubbleY
    const bubbleWidth = infoBubble.bubbleWidth
    const bubbleHeight = infoBubble.bubbleHeight

    let marginBubble

    if (infoBubble.descriptionVisible) {
      // TODO const
      marginBubble = 200
    } else {
      marginBubble = INFO_BUBBLE_MARGIN_BUBBLE
    }

    const mouseInside = store.getState().infoBubble.mouseInside
    if (mouseInside && !infoBubble.descriptionVisible) {
      var pos = getElAbsolutePos(infoBubble.segmentEl)

      var x = pos[0] - document.querySelector('#street-section-outer').scrollLeft

      var segmentX1 = x - INFO_BUBBLE_MARGIN_BUBBLE
      var segmentX2 = x + infoBubble.segmentEl.offsetWidth + INFO_BUBBLE_MARGIN_BUBBLE

      var segmentY = pos[1] + infoBubble.segmentEl.offsetHeight + INFO_BUBBLE_MARGIN_BUBBLE

      hoverPolygon = [
        [bubbleX - marginBubble, bubbleY - marginBubble],
        [bubbleX - marginBubble, bubbleY + bubbleHeight + marginBubble],
        [segmentX1, bubbleY + bubbleHeight + marginBubble + 120],
        [segmentX1, segmentY],
        [segmentX2, segmentY],
        [segmentX2, bubbleY + bubbleHeight + marginBubble + 120],
        [bubbleX + bubbleWidth + marginBubble, bubbleY + bubbleHeight + marginBubble],
        [bubbleX + bubbleWidth + marginBubble, bubbleY - marginBubble],
        [bubbleX - marginBubble, bubbleY - marginBubble]
      ]
    } else {
      var bottomY = mouseY - INFO_BUBBLE_MARGIN_MOUSE
      if (bottomY < bubbleY + bubbleHeight + INFO_BUBBLE_MARGIN_BUBBLE) {
        bottomY = bubbleY + bubbleHeight + INFO_BUBBLE_MARGIN_BUBBLE
      }
      var bottomY2 = mouseY + INFO_BUBBLE_MARGIN_MOUSE
      if (bottomY2 < bubbleY + bubbleHeight + INFO_BUBBLE_MARGIN_BUBBLE) {
        bottomY2 = bubbleY + bubbleHeight + INFO_BUBBLE_MARGIN_BUBBLE
      }

      if (infoBubble.descriptionVisible) {
        bottomY = bubbleY + bubbleHeight + marginBubble
        bottomY2 = bottomY
      }

      var diffX = 60 - ((mouseY - bubbleY) / 5)
      if (diffX < 0) {
        diffX = 0
      } else if (diffX > 50) {
        diffX = 50
      }

      hoverPolygon = [
        [bubbleX - marginBubble, bubbleY - marginBubble],
        [bubbleX - marginBubble, bubbleY + bubbleHeight + marginBubble],
        [(bubbleX - marginBubble + mouseX - INFO_BUBBLE_MARGIN_MOUSE - diffX) / 2, bottomY + ((bubbleY + bubbleHeight + marginBubble - bottomY) * 0.2)],
        [mouseX - INFO_BUBBLE_MARGIN_MOUSE - diffX, bottomY],
        [mouseX - INFO_BUBBLE_MARGIN_MOUSE, bottomY2],
        [mouseX + INFO_BUBBLE_MARGIN_MOUSE, bottomY2],
        [mouseX + INFO_BUBBLE_MARGIN_MOUSE + diffX, bottomY],
        [(bubbleX + bubbleWidth + marginBubble + mouseX + INFO_BUBBLE_MARGIN_MOUSE + diffX) / 2, bottomY + ((bubbleY + bubbleHeight + marginBubble - bottomY) * 0.2)],
        [bubbleX + bubbleWidth + marginBubble, bubbleY + bubbleHeight + marginBubble],
        [bubbleX + bubbleWidth + marginBubble, bubbleY - marginBubble],
        [bubbleX - marginBubble, bubbleY - marginBubble]
      ]
    }

    return hoverPolygon
  },

  updateHoverPolygon: function (mouseX, mouseY) {
    const hoverPolygon = infoBubble.createHoverPolygon(mouseX, mouseY)
    store.dispatch(updateHoverPolygon(hoverPolygon))
  },

  scheduleHoverPolygonUpdate: function () {
    window.clearTimeout(infoBubble.hoverPolygonUpdateTimerId)

    infoBubble.hoverPolygonUpdateTimerId = window.setTimeout(function () {
      infoBubble.updateHoverPolygon(infoBubble.lastMouseX, infoBubble.lastMouseY)
    }, 50)
  },

  onBodyMouseMove: function (event) {
    var mouseX = event.pageX
    var mouseY = event.pageY

    infoBubble.lastMouseX = mouseX
    infoBubble.lastMouseY = mouseY

    if (isInfoBubbleVisible()) {
      if (!infoBubble._withinHoverPolygon(mouseX, mouseY)) {
        infoBubble.show(false)
      }
    }

    infoBubble.scheduleHoverPolygonUpdate()
  },

  hideSegment: function (fast) {
    if (infoBubble.segmentEl) {
      infoBubble.segmentEl.classList.remove('hover')
      var el = infoBubble.segmentEl
      if (fast) {
        el.classList.add('immediate-show-drag-handles')
        window.setTimeout(function () {
          el.classList.remove('immediate-show-drag-handles')
        }, 0)
      } else {
        el.classList.remove('immediate-show-drag-handles')
      }
      infoBubble.segmentEl.classList.remove('hide-drag-handles-when-description-shown')
      infoBubble.segmentEl.classList.remove('hide-drag-handles-when-inside-info-bubble')
      infoBubble.segmentEl.classList.remove('show-drag-handles')
      infoBubble.segmentEl = null
      infoBubble.segment = null
    }
  },

  hide: function () {
    if (infoBubble.el) {
      hideDescription()
      document.body.classList.remove('controls-fade-out')

      store.dispatch(hideInfoBubble())

      document.body.removeEventListener('mousemove', infoBubble.onBodyMouseMove)
    }
  },

  considerShowing: function (event, segmentEl, type) {
    if (Boolean(store.getState().menus.activeMenu) === true || app.readOnly) {
      return
    }

    if (event) {
      infoBubble.considerMouseX = event.pageX
      infoBubble.considerMouseY = event.pageY
    } else {
      var pos = getElAbsolutePos(segmentEl)

      infoBubble.considerMouseX = pos[0] - document.querySelector('#street-section-outer').scrollLeft
      infoBubble.considerMouseY = pos[1]
    }
    infoBubble.considerSegmentEl = segmentEl
    infoBubble.considerType = type

    if ((segmentEl === infoBubble.segmentEl) && (type === infoBubble.type)) {
      return
    }

    if (!isInfoBubbleVisible() || !infoBubble._withinHoverPolygon(infoBubble.considerMouseX, infoBubble.considerMouseY)) {
      infoBubble.show(false)
    }
  },

  dontConsiderShowing: function () {
    infoBubble.considerSegmentEl = null
    infoBubble.considerType = null
  },

  updateContents: function () {
    const street = store.getState().street

    // If info bubble changes, wake this back up if it's fading out
    cancelFadeoutControls()

    // window.dispatchEvent(new window.CustomEvent('stmx:force_infobubble_update'))

    switch (infoBubble.type) {
      case INFO_BUBBLE_TYPE_SEGMENT:
        window.dispatchEvent(new window.CustomEvent('stmx:force_infobubble_update'))
        var segment = street.segments[store.getState().infoBubble.dataNo]
        infoBubble.segment = segment
        break
    }
  },

  // TODO rename
  show: function (force) {
    if (infoBubble.suppressed) {
      window.setTimeout(infoBubble.show, 100)
      return
    }

    if (draggingType() !== DRAGGING_TYPE_NONE) {
      return
    }

    if (!infoBubble.considerType) {
      infoBubble.hide()
      infoBubble.hideSegment(false)
      return
    }

    var segmentEl = infoBubble.considerSegmentEl
    var type = infoBubble.considerType

    if ((segmentEl === infoBubble.segmentEl) &&
      (type === infoBubble.type) && !force) {
      return
    }
    infoBubble.hideSegment(true)

    var mouseX = infoBubble.considerMouseX
    var mouseY = infoBubble.considerMouseY

    infoBubble.segmentEl = segmentEl
    infoBubble.type = type

    if (segmentEl) {
      segmentEl.classList.add('hover')
      segmentEl.classList.add('show-drag-handles')
    }
    if (isInfoBubbleVisible()) {
      segmentEl.classList.add('immediate-show-drag-handles')

      if (infoBubble.descriptionVisible) {
        hideDescription()
      }
    }

    infoBubble.startMouseX = mouseX
    infoBubble.startMouseY = mouseY

    var pos = getElAbsolutePos(segmentEl)

    var bubbleX = pos[0] - document.querySelector('#street-section-outer').scrollLeft
    var bubbleY = pos[1]

    let dataNo = segmentEl.dataNo
    if (!dataNo) {
      dataNo = (type === INFO_BUBBLE_TYPE_LEFT_BUILDING) ? 'left' : 'right'
    }
    store.dispatch(setInfoBubbleSegmentDataNo(dataNo))

    infoBubble.el = document.querySelector('.info-bubble')
    infoBubble.updateContents()

    var bubbleWidth = infoBubble.el.offsetWidth
    var bubbleHeight = infoBubble.el.offsetHeight

    // TODO const
    bubbleY -= bubbleHeight - 20
    if (bubbleY < MIN_TOP_MARGIN_FROM_VIEWPORT) {
      bubbleY = MIN_TOP_MARGIN_FROM_VIEWPORT
    }

    bubbleX += segmentEl.offsetWidth / 2
    bubbleX -= bubbleWidth / 2

    const system = store.getState().system
    // TODO const
    if (bubbleX < 50) {
      bubbleX = 50
    } else if (bubbleX > system.viewportWidth - bubbleWidth - 50) {
      bubbleX = system.viewportWidth - bubbleWidth - 50
    }

    infoBubble.el.style.left = bubbleX + 'px'
    infoBubble.el.style.top = bubbleY + 'px'

    if (!isInfoBubbleVisible()) {
      store.dispatch(showInfoBubble())
    }

    infoBubble.bubbleX = bubbleX
    infoBubble.bubbleY = bubbleY
    infoBubble.bubbleWidth = bubbleWidth
    infoBubble.bubbleHeight = bubbleHeight

    infoBubble.updateHoverPolygon(mouseX, mouseY)
    document.body.addEventListener('mousemove', infoBubble.onBodyMouseMove)
  }
}

function _isPointInPoly (vs, point) {
  var x = point[0]
  var y = point[1]

  var inside = false
  for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
    var xi = vs[i][0]
    var yi = vs[i][1]
    var xj = vs[j][0]
    var yj = vs[j][1]

    var intersect = ((yi > y) !== (yj > y)) &&
      (x < ((xj - xi) * (y - yi) / (yj - yi)) + xi)
    if (intersect) inside = !inside
  }

  return inside
}
<|endoftext|>


<commit_before><commit_msg>not needed<commit_after><|endoftext|>


<commit_before>// You are given an n x n 2D matrix representing an image.

// Rotate the image by 90 degrees (clockwise).

// Follow up:
// Could you do this in-place?
<commit_msg>add solution<commit_after>// You are given an n x n 2D matrix representing an image.

// Rotate the image by 90 degrees (clockwise).

// Follow up:
// Could you do this in-place?

var rotate = function(matrix) {
    var rows = matrix.length,
        col = matrix.length;

    for (var i = 0; i < rows; i++){
        for (var j = i + 1; j < col; j++){
            var temp = matrix[i][j];
            matrix[i][j] = matrix[j][i];
            matrix[j][i] = temp;
        }
    }

    for (i = 0; i < rows; i++){
        for (j = 0; j < col / 2; j++){
            temp = matrix[i][j];
            matrix[i][j] = matrix[i][col - 1 - j];
            matrix[i][col - 1 - j] = temp;
        }
    }
};
<|endoftext|>


<commit_before>//
// Thin hook to include the accessibility extension.
//
(function(HUB,EXTENSIONS) {
  var SETTINGS = HUB.config.menuSettings;
  var ITEM, MENU; // filled in when MathMenu extension loads

  var BIND = (Function.prototype.bind ? function (f,t) {return f.bind(t)} :
              function (f,t) {return function () {f.apply(t,arguments)}});
  var KEYS = Object.keys || function (obj) {
    var keys = [];
    for (var id in obj) {if (obj.hasOwnProperty(id)) keys.push(id)}
    return keys;
  };

  var Accessibility = EXTENSIONS.Accessibility = {
    version: '1.0',
    prefix: '', //'Accessibility-',
    default: {},
    modules: [],
    MakeOption: function(name) {
      return Accessibility.prefix + name;
    },
    GetOption: function(option) {
      return SETTINGS[Accessibility.MakeOption(option)];
    },
    AddDefaults: function() {
      var keys = KEYS(Accessibility.default);
      for (var i = 0, key; key = keys[i]; i++) {
        var option = Accessibility.MakeOption(key);
        if (typeof(SETTINGS[option]) === 'undefined') {
          SETTINGS[option] = Accessibility.default[key];
        }
      }
    },
    // Attaches the menu items;
    AddMenu: function() {
      var items = Array(this.modules.length);
      for (var i = 0, module; module = this.modules[i]; i++) items[i] = module.placeHolder;
      var about = MENU.IndexOfId('About');
      if (about === null) {
        items.unshift(ITEM.RULE());
        MENU.items.push.apply(MENU.items, items);
      } else {
        items.push(ITEM.RULE());
        items.unshift(about, 0);
        MENU.items.splice.apply(MENU.items, items);
      }
    },
    Register: function(module) {
      Accessibility.default[module.option] = false;
      Accessibility.modules.push(module);
    },
    Startup: function() {
      ITEM = MathJax.Menu.ITEM;
      MENU = MathJax.Menu.menu;
      for (var i = 0, module; module = this.modules[i]; i++) {
        module.CreateMenu();
        module.AddMethods();
      }
      this.AddMenu();
    },
    LoadExtensions: function () {
      var extensions = [];
      for (var i = 0, mpdule; module = this.modules[i]; i++) {
        if (SETTINGS[module.option]) extensions.push(module.module);
      }
      return (extensions.length ? HUB.Startup.loadArray(extensions) : null);
    }
  };

  var ModuleLoader = MathJax.Extension.ModuleLoader = MathJax.Object.Subclass({
    option: '',
    name: '',
    module: '',
    placeHolder: null,
    submenu: false,
    extension: null,
    Enable: null,
    Disable: null,
    Init: function(option, name, module, extension, submenu) {
      this.option = option;
      this.name = [name.replace(/ /g,''),name];
      this.module = module;
      this.extension = extension;
      this.submenu = (submenu || false);
    },
    CreateMenu: function() {
      var load = BIND(this.Load,this);
      if (this.submenu) {
        this.placeHolder =
          ITEM.SUBMENU(this.name,
            ITEM.CHECKBOX(["Activate","Activate"],
                          Accessibility.MakeOption(this.option), {action: load}),
            ITEM.RULE(),
            ITEM.COMMAND(["OptionsWhenActive","(Options when Active)"],null,{disabled:true})
          );
      } else {
        this.placeHolder = ITEM.CHECKBOX(
          this.name, Accessibility.MakeOption(this.option), {action: load}
        );
      }
    },
    Load: function() {
      HUB.Queue(["Require",MathJax.Ajax,this.module,["AddMethods",this,true]]);
    },
    AddMethods: function(menu) {
      var ext = MathJax.Extension[this.extension];
      if (ext) {
        this.Enable = BIND(ext.Enable,ext);
        this.Disable = BIND(ext.Disable,ext);
        if (menu) {
          this.Enable(true,true);
          MathJax.Menu.saveCookie();
        }
      }
    }
  });

  HUB.Register.StartupHook('End Extensions', function () {
    HUB.Register.StartupHook('MathMenu Ready', function () {
      Accessibility.Startup();
      HUB.Startup.signal.Post('Accessibility Loader Ready');
    },5);   // run before other extensions' menu hooks even if they are loaded first
  },5);

  Accessibility.Register(
    ModuleLoader(
      'collapsible', 'Collapsible Math', '[RespEq]/Semantic-Complexity.js',
      'SemanticComplexity'
    )
  );
  Accessibility.Register(
    ModuleLoader(
      'autocollapse', 'Auto Collapse', '[RespEq]/Semantic-Collapse.js',
      'SemanticCollapse'
    )
  );
  Accessibility.Register(
    ModuleLoader(
      'explorer', 'Accessibility', '[RespEq]/Assistive-Explore.js',
      'Assistive', true
    )
  );

  Accessibility.AddDefaults();

  MathJax.Callback.Queue(
    ["LoadExtensions",Accessibility],
    ["loadComplete",MathJax.Ajax,"[RespEq]/Accessibility-Extension.js"]
  );

})(MathJax.Hub,MathJax.Extension);

<commit_msg>Remove AddMethods module, since all we do is load and enable.<commit_after>//
// Thin hook to include the accessibility extension.
//
(function(HUB,EXTENSIONS) {
  var SETTINGS = HUB.config.menuSettings;
  var ITEM, MENU; // filled in when MathMenu extension loads

  var BIND = (Function.prototype.bind ? function (f,t) {return f.bind(t)} :
              function (f,t) {return function () {f.apply(t,arguments)}});
  var KEYS = Object.keys || function (obj) {
    var keys = [];
    for (var id in obj) {if (obj.hasOwnProperty(id)) keys.push(id)}
    return keys;
  };

  var Accessibility = EXTENSIONS.Accessibility = {
    version: '1.0',
    prefix: '', //'Accessibility-',
    default: {},
    modules: [],
    MakeOption: function(name) {
      return Accessibility.prefix + name;
    },
    GetOption: function(option) {
      return SETTINGS[Accessibility.MakeOption(option)];
    },
    AddDefaults: function() {
      var keys = KEYS(Accessibility.default);
      for (var i = 0, key; key = keys[i]; i++) {
        var option = Accessibility.MakeOption(key);
        if (typeof(SETTINGS[option]) === 'undefined') {
          SETTINGS[option] = Accessibility.default[key];
        }
      }
    },
    // Attaches the menu items;
    AddMenu: function() {
      var items = Array(this.modules.length);
      for (var i = 0, module; module = this.modules[i]; i++) items[i] = module.placeHolder;
      var about = MENU.IndexOfId('About');
      if (about === null) {
        items.unshift(ITEM.RULE());
        MENU.items.push.apply(MENU.items, items);
      } else {
        items.push(ITEM.RULE());
        items.unshift(about, 0);
        MENU.items.splice.apply(MENU.items, items);
      }
    },
    Register: function(module) {
      Accessibility.default[module.option] = false;
      Accessibility.modules.push(module);
    },
    Startup: function() {
      ITEM = MathJax.Menu.ITEM;
      MENU = MathJax.Menu.menu;
      for (var i = 0, module; module = this.modules[i]; i++) module.CreateMenu();
      this.AddMenu();
    },
    LoadExtensions: function () {
      var extensions = [];
      for (var i = 0, mpdule; module = this.modules[i]; i++) {
        if (SETTINGS[module.option]) extensions.push(module.module);
      }
      return (extensions.length ? HUB.Startup.loadArray(extensions) : null);
    }
  };

  var ModuleLoader = MathJax.Extension.ModuleLoader = MathJax.Object.Subclass({
    option: '',
    name: ['',''],
    module: '',
    placeHolder: null,
    submenu: false,
    extension: null,
    Init: function(option, name, module, extension, submenu) {
      this.option = option;
      this.name = [name.replace(/ /g,''),name];
      this.module = module;
      this.extension = extension;
      this.submenu = (submenu || false);
    },
    CreateMenu: function() {
      var load = BIND(this.Load,this);
      if (this.submenu) {
        this.placeHolder =
          ITEM.SUBMENU(this.name,
            ITEM.CHECKBOX(["Activate","Activate"],
                          Accessibility.MakeOption(this.option), {action: load}),
            ITEM.RULE(),
            ITEM.COMMAND(["OptionsWhenActive","(Options when Active)"],null,{disabled:true})
          );
      } else {
        this.placeHolder = ITEM.CHECKBOX(
          this.name, Accessibility.MakeOption(this.option), {action: load}
        );
      }
    },
    Load: function() {
      HUB.Queue(["Require",MathJax.Ajax,this.module,["Enable",this]]);
    },
    Enable: function(menu) {
      var extension = MathJax.Extension[this.extension];
      if (extension) {
        extension.Enable(true,true);
        MathJax.Menu.saveCookie();
      }
    }
  });

  HUB.Register.StartupHook('End Extensions', function () {
    HUB.Register.StartupHook('MathMenu Ready', function () {
      Accessibility.Startup();
      HUB.Startup.signal.Post('Accessibility Loader Ready');
    },5);   // run before other extensions' menu hooks even if they are loaded first
  },5);

  Accessibility.Register(
    ModuleLoader(
      'collapsible', 'Collapsible Math', '[RespEq]/Semantic-Complexity.js',
      'SemanticComplexity'
    )
  );
  Accessibility.Register(
    ModuleLoader(
      'autocollapse', 'Auto Collapse', '[RespEq]/Semantic-Collapse.js',
      'SemanticCollapse'
    )
  );
  Accessibility.Register(
    ModuleLoader(
      'explorer', 'Accessibility', '[RespEq]/Assistive-Explore.js',
      'Assistive', true
    )
  );

  Accessibility.AddDefaults();

  MathJax.Callback.Queue(
    ["LoadExtensions",Accessibility],
    ["loadComplete",MathJax.Ajax,"[RespEq]/Accessibility-Extension.js"]
  );

})(MathJax.Hub,MathJax.Extension);

<|endoftext|>


<commit_before>(function($){

	$.fn.responav = function(options) {

		var settings = $.extend({
			breakpoint : 720,
			trigger : true
		}, options);

		var menu = $(this);
		var hasTrigger = false;

		$(window).on('resize.responav', function () {
			var browserWidth = $(window).width();
			if (browserWidth < settings.breakpoint) {
				$('body').addClass('responav-active');
				menu.addClass('responav-menu');
				if (!hasTrigger && settings.trigger) {
					$('.responav-inner').prepend('<button class="responav-trigger" id="responav-trigger"></button>');
					hasTrigger = true;
				}
			} else {
				$('body').removeClass('responav-active');
				menu.removeClass('responav-menu');
				if (hasTrigger) {
					$('#responav-trigger').remove();
					hasTrigger = false;
				}
			}
		}).trigger('resize');

		$(document).on('click.responav touchstart.responav', '#responav-trigger', function(event) {
			$('body').toggleClass('responav-open');
			$(document).one(event.type, function() {
				$('body').removeClass('responav-open');
			});
			return false;
		});

		menu.on("click touchstart", function(e) {
			e.stopPropagation();
		});

		return this;
	};
})($);<commit_msg>Remove the outer function<commit_after>$.fn.responav = function(options) {

	var settings = $.extend({
		breakpoint : 720,
		trigger : true
	}, options);

	var menu = $(this);
	var hasTrigger = false;

	$(window).on('resize.responav', function () {
		var browserWidth = $(window).width();
		if (browserWidth < settings.breakpoint) {
			$('body').addClass('responav-active');
			menu.addClass('responav-menu');
			if (!hasTrigger && settings.trigger) {
				$('.responav-inner').prepend('<button class="responav-trigger" id="responav-trigger"></button>');
				hasTrigger = true;
			}
		} else {
			$('body').removeClass('responav-active');
			menu.removeClass('responav-menu');
			if (hasTrigger) {
				$('#responav-trigger').remove();
				hasTrigger = false;
			}
		}
	}).trigger('resize');

	$(document).on('click.responav touchstart.responav', '#responav-trigger', function(event) {
		$('body').toggleClass('responav-open');
		$(document).one(event.type, function() {
			$('body').removeClass('responav-open');
		});
		return false;
	});

	menu.on("click.responav touchstart.responav", function(e) {
		e.stopPropagation();
	});

	return this;
};<|endoftext|>


<commit_before>describe("PlayerController", function () {
    var scope;
    var samplePeople;
    var PeopleRestService;

    beforeEach(module('songbuzz'));
    beforeEach(inject(function (_$rootScope_, _$controller_, _PeopleRestService_) {
        scope = _$rootScope_.$new();
        $controller = _$controller_;
        PeopleRestService = _PeopleRestService_;

        peopleCtrl = $controller('PeopleController', {
            $rootScope: _$rootScope_,
            $scope: scope,
            PeopleRestService: _PeopleRestService_
        });

        samplePeople = [
            { provider: 'google',
                uid: 100000000000000000001,
                name: 'Test User 1',
                picture: 'http://test.com/1/photo.jpg',
                createdAt: "2013-08-22T19:57:38.029Z",
                updatedAt: "2013-08-22T19:57:38.029Z",
                id: '500000000000000000001' },
            { provider: 'google',
                uid: 100000000000000000002,
                name: 'Test User 2',
                picture: 'http://test.com/2/photo.jpg',
                createdAt: "2013-08-22T19:57:38.029Z",
                updatedAt: "2013-08-22T19:57:38.029Z",
                id: '500000000000000000002' }
        ];
    }));

    describe("fetchPeople", function () {
        it("should get all people and assign them to the scope", function () {
            spyOn(PeopleRestService, 'getAll').andReturn(getThenObject(samplePeople));

            scope.fetchPeople();
            expect(PeopleRestService.getAll).toHaveBeenCalled();
        })
    })

});<commit_msg>Fixed a typo in the PeopleController specs.<commit_after>describe("PeopleController", function () {
    var scope;
    var samplePeople;
    var PeopleRestService;

    beforeEach(module('songbuzz'));
    beforeEach(inject(function (_$rootScope_, _$controller_, _PeopleRestService_) {
        scope = _$rootScope_.$new();
        $controller = _$controller_;
        PeopleRestService = _PeopleRestService_;

        peopleCtrl = $controller('PeopleController', {
            $rootScope: _$rootScope_,
            $scope: scope,
            PeopleRestService: _PeopleRestService_
        });

        samplePeople = [
            { provider: 'google',
                uid: 100000000000000000001,
                name: 'Test User 1',
                picture: 'http://test.com/1/photo.jpg',
                createdAt: "2013-08-22T19:57:38.029Z",
                updatedAt: "2013-08-22T19:57:38.029Z",
                id: '500000000000000000001' },
            { provider: 'google',
                uid: 100000000000000000002,
                name: 'Test User 2',
                picture: 'http://test.com/2/photo.jpg',
                createdAt: "2013-08-22T19:57:38.029Z",
                updatedAt: "2013-08-22T19:57:38.029Z",
                id: '500000000000000000002' }
        ];
    }));

    describe("fetchPeople", function () {
        it("should get all people and assign them to the scope", function () {
            spyOn(PeopleRestService, 'getAll').andReturn(getThenObject(samplePeople));

            scope.fetchPeople();
            expect(PeopleRestService.getAll).toHaveBeenCalled();
        })
    })

});<|endoftext|>


<commit_before>/**
 * extend.js
 * Copyright (c) 2013 Marshall Farrier
 * http://www.opensource.org/licenses/mit-license.php
 *
 * For background to this script
 * cf. John Resig, Secrets of the JavaScript Ninja, pp. 145ff.
 * http://ejohn.org/blog/simple-javascript-inheritance
 *
 * My version differs from Resig's in 3 ways:
 * 1) It doesn't check for whether the corresponding
 *    _super method is called by the overriding subclass method.
 *    (seems to me like too much overhead since the if-condition
 *    is only met if the superclass already has the given method)
 * 2) No functionality is added directly to the built-in
 *    JavaScript Object.
 * 3) The reference to arguments.callee (likely to be
 *    deprecated) is eliminated.
 */

(function () {
    var initializing = false;

    // generic base class
    this.Base = function() {};

    Base.extend = function extend(properties) {
        var _super = this.prototype,
            proto,
            name;

        initializing = true;
        proto = new this();
        initializing = false;

        // leaving out check for presence of "_super" string
        for (name in properties) {
            proto[name] = typeof properties[name] === "function" &&
                typeof _super[name] === "function" ? (function (name, fn) {
                    return function () {
                        var tmp = this._super,
                            ret;

                        this._super = _super[name];
                        ret = fn.apply(this, arguments);
                        this._super = tmp;
                        return ret;
                    };
                })(name, properties[name]) : properties[name];
        }

        function Class() {
            if (!initializing && this.init) {
                this.init.apply(this, arguments);
            }
        }

        Class.prototype = proto;
        Class.constructor = Class;
        Class.extend = extend;
        return Class;
    };
})();
<commit_msg>Assign rather than declare function in block. Cf. https://github.com/airbnb/javascript#functions<commit_after>/**
 * extend.js
 * Copyright (c) 2013 Marshall Farrier
 * http://www.opensource.org/licenses/mit-license.php
 *
 * For background to this script
 * cf. John Resig, Secrets of the JavaScript Ninja, pp. 145ff.
 * http://ejohn.org/blog/simple-javascript-inheritance
 *
 * My version differs from Resig's in 3 ways:
 * 1) It doesn't check for whether the corresponding
 *    _super method is called by the overriding subclass method.
 *    (seems to me like too much overhead since the if-condition
 *    is only met if the superclass already has the given method)
 * 2) No functionality is added directly to the built-in
 *    JavaScript Object.
 * 3) The reference to arguments.callee (likely to be
 *    deprecated) is eliminated.
 */

(function () {
    var initializing = false;

    // generic base class
    this.Base = function() {};

    Base.extend = function extend(properties) {
        var _super = this.prototype,
            proto,
            name;

        initializing = true;
        proto = new this();
        initializing = false;

        // leaving out check for presence of "_super" string
        for (name in properties) {
            proto[name] = typeof properties[name] === "function" &&
                typeof _super[name] === "function" ? (function (name, fn) {
                    var retFn = function () {
                        var tmp = this._super,
                            ret;

                        this._super = _super[name];
                        ret = fn.apply(this, arguments);
                        this._super = tmp;
                        return ret;
                    };
                    return retFn;
                })(name, properties[name]) : properties[name];
        }

        function Class() {
            if (!initializing && this.init) {
                this.init.apply(this, arguments);
            }
        }

        Class.prototype = proto;
        Class.constructor = Class;
        Class.extend = extend;
        return Class;
    };
})();
<|endoftext|>


<commit_before>var answers = require('./answers');
var stopwords = require('./stopwords');
// var storage = require('./storage');

var makeDictionary = function(d) {
	var final = {}
	for (item in d) {
		var key = item.toLowerCase();
		var val = d[item];
		final[key] = val;
	}
	return final
}

var answerDict = makeDictionary(answers);

var removePunc = function(text) {
	return text.replace(/[.,\/#!?$%\^&\*;:{}=\-_`~()]/g,"");
}

var hasWords = function(text, wordList) {
	var arr = text.split(" ");
	for (i in wordList) {
		var word = wordList[i];
		if (arr.indexOf(word) !== -1) {
			return true;
		}
	}
	return false;
}

var cleanText = function(text) {
	text = text.toLowerCase();
	text = removePunc(text);
	return text;
}

var countDict = function(arr) {
	var dict = {};
	for (i in arr) {
		var val = arr[i];
		if (!(val in dict)) {
			dict[val] = 0;
		}
		dict[val] += 1;
	}
	return dict;
}

var checkFave = function(text) {
	return hasWords(text, ["you"]) && hasWords(text, ["best", "fav", "fave", "favorite", "awesome", "smart"]);
};

var checkGreetings = function(text) {
	return hasWords(text, ["hi", "hello", "hey"]);
};

var checkAgreement = function(text) {
	return hasWords(text, ["yes", "yep", "okay"]);
};

var stringDistance = function(str1, str2) {

	str1 = removePunc(str1);
	str2 = removePunc(str2);
	var arr1 = str1.split(" ");
	var arr2 = str2.split(" ");
	var matches = 0;
	var dict1 = countDict(arr1);
	var dict2 = countDict(arr2);

	for (key in dict1) {
		if (key in dict2) {
			matches += Math.min(dict1[key], dict2[key]);
		}
	}
	matches = matches/(arr1.length+arr2.length);
	return matches;
}

var getCloserString = function(closestStr, newStr, text) {
	closestStr = closestStr.toLowerCase();
	newStr = newStr.toLowerCase();

	var closestScore = stringDistance(closestStr, text);
	var newScore = stringDistance(newStr, text);
	if (newScore > closestScore) {
		return newStr;
	}
	return closestStr;
}

var getClosestString = function(questions, text) {
	var closestQuestion = '';
	for (i in questions) {
		var question = questions[i];
		closestQuestion = getCloserString(closestQuestion, question, text);
	}
	return closestQuestion;
}

var getQuestionPreComment = function() {
	var commentArray = [
		"",
		"",
		"Good question!",
		"Great question!",
		"Very good question!",
		"Smart question!",
		"Hmm... Let me see.",
		"Okay, let's see.."
	];
	var comment = commentArray[Math.floor(Math.random() * commentArray.length)];
	return comment;
}

var getQuestionPostComment = function() {
	var commentArray = [
		"",
		"",
		"",
		"Make sense?",
		"\nAnything else you want to know?",
		"\nAny questions?",
		"That's pretty much it!",
		"I hope that makes sense!",
		"I hope that helps!"
	];
	var comment = commentArray[Math.floor(Math.random() * commentArray.length)];
	return comment;
}

var searchAnswers = function (userId, text) {
	var questions = Object.keys(answerDict);
	var closestQuestion = getClosestString(questions, stopwords.removeStopWords(text).join(' '));
	if (closestQuestion === '') {
		closestQuestion = getClosestString(questions, text);
		if (closestQuestion === '') {
			return '🙊\nI\'m sorry, I didn\'t understand that.\nCould you ask in another way?';
		}
		return '🙊\nI\'m sorry, I didn\'t quite understand that.\nDid you mean:\n"' + closestQuestion +'"';
	}
	console.log("RESPONSE:");
	console.log(closestQuestion);
	console.log(answerDict[closestQuestion]);

	var responseArr = [
		'"'+closestQuestion+'"\n\n🐵',
		getQuestionPreComment(),
		answerDict[closestQuestion],
		getQuestionPostComment()
	];

	return responseArr.join(" ");
}

var respond = function (userId, text) {
	text = cleanText(text);
	if (checkFave(text)) {
		return "🙉 Aww golly gee! Thanks!"
	}
	if (checkGreetings(text)) {
		return "🐵 I'm Madeliene!\nGreat to meet you!\n\nWhat are you interested in?\n1. I want to learn about sex\n2. I want to get hygiene products\n3. I want to talk to a real person"
	}
	if (checkAgreement(text)) {
		return "🙉 That's great to hear!"
	}
	return searchAnswers(userId, text);
}

module.exports = {
	'respond': respond
}
<commit_msg>changed intro text<commit_after>var answers = require('./answers');
var stopwords = require('./stopwords');
// var storage = require('./storage');

var makeDictionary = function(d) {
	var final = {}
	for (item in d) {
		var key = item.toLowerCase();
		var val = d[item];
		final[key] = val;
	}
	return final
}

var answerDict = makeDictionary(answers);

var removePunc = function(text) {
	return text.replace(/[.,\/#!?$%\^&\*;:{}=\-_`~()]/g,"");
}

var hasWords = function(text, wordList) {
	var arr = text.split(" ");
	for (i in wordList) {
		var word = wordList[i];
		if (arr.indexOf(word) !== -1) {
			return true;
		}
	}
	return false;
}

var cleanText = function(text) {
	text = text.toLowerCase();
	text = removePunc(text);
	return text;
}

var countDict = function(arr) {
	var dict = {};
	for (i in arr) {
		var val = arr[i];
		if (!(val in dict)) {
			dict[val] = 0;
		}
		dict[val] += 1;
	}
	return dict;
}

var checkFave = function(text) {
	return hasWords(text, ["you"]) && hasWords(text, ["best", "fav", "fave", "favorite", "awesome", "smart"]);
};

var checkGreetings = function(text) {
	return hasWords(text, ["hi", "hello", "hey"]);
};

var checkAgreement = function(text) {
	return hasWords(text, ["yes", "yep", "okay"]);
};

var stringDistance = function(str1, str2) {

	str1 = removePunc(str1);
	str2 = removePunc(str2);
	var arr1 = str1.split(" ");
	var arr2 = str2.split(" ");
	var matches = 0;
	var dict1 = countDict(arr1);
	var dict2 = countDict(arr2);

	for (key in dict1) {
		if (key in dict2) {
			matches += Math.min(dict1[key], dict2[key]);
		}
	}
	matches = matches/(arr1.length+arr2.length);
	return matches;
}

var getCloserString = function(closestStr, newStr, text) {
	closestStr = closestStr.toLowerCase();
	newStr = newStr.toLowerCase();

	var closestScore = stringDistance(closestStr, text);
	var newScore = stringDistance(newStr, text);
	if (newScore > closestScore) {
		return newStr;
	}
	return closestStr;
}

var getClosestString = function(questions, text) {
	var closestQuestion = '';
	for (i in questions) {
		var question = questions[i];
		closestQuestion = getCloserString(closestQuestion, question, text);
	}
	return closestQuestion;
}

var getQuestionPreComment = function() {
	var commentArray = [
		"",
		"",
		"Good question!",
		"Great question!",
		"Very good question!",
		"Smart question!",
		"Hmm... Let me see.",
		"Okay, let's see.."
	];
	var comment = commentArray[Math.floor(Math.random() * commentArray.length)];
	return comment;
}

var getQuestionPostComment = function() {
	var commentArray = [
		"",
		"",
		"",
		"Make sense?",
		"\nAnything else you want to know?",
		"\nAny questions?",
		"That's pretty much it!",
		"I hope that makes sense!",
		"I hope that helps!"
	];
	var comment = commentArray[Math.floor(Math.random() * commentArray.length)];
	return comment;
}

var searchAnswers = function (userId, text) {
	var questions = Object.keys(answerDict);
	var closestQuestion = getClosestString(questions, stopwords.removeStopWords(text).join(' '));
	if (closestQuestion === '') {
		closestQuestion = getClosestString(questions, text);
		if (closestQuestion === '') {
			return '🙊\nI\'m sorry, I didn\'t understand that.\nCould you ask in another way?';
		}
		return '🙊\nI\'m sorry, I didn\'t quite understand that.\nDid you mean:\n"' + closestQuestion +'"';
	}
	console.log("RESPONSE:");
	console.log(closestQuestion);
	console.log(answerDict[closestQuestion]);

	var responseArr = [
		'"'+closestQuestion+'"\n\n🐵',
		getQuestionPreComment(),
		answerDict[closestQuestion],
		getQuestionPostComment()
	];

	return responseArr.join(" ");
}

var respond = function (userId, text) {
	text = cleanText(text);
	if (checkFave(text)) {
		return "🙉 Aww golly gee! Thanks!"
	}
	if (checkGreetings(text)) {
		return "🐵 I'm Madeliene!\nGreat to meet you!\n\nWhat are you interested in?\n1. I want to learn about sex\n2. I want to get hygiene products\n3. I want to find resources near me"
	}
	if (checkAgreement(text)) {
		return "🙉 That's great to hear!"
	}
	return searchAnswers(userId, text);
}

module.exports = {
	'respond': respond
}
<|endoftext|>


<commit_before>/**
 * Location
 *
 * @class Backbone model representing a location on the map.
 * @author Joakim Lundin
 * @type {Backbone.Model}
 */
var Location = Backbone.Model.extend(
    /** @lends Location */
    {
      defaults: {
        id: 0,
        campus: 'unknown',
        type: 'unknown',
        subType: null,
        shape: "point",
        text: "",
        coords: [],
        directionAware: true,
        hasIcon: false,
        pin: new google.maps.MarkerImage(
            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkw' +
                'AAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wKExQWIJ3tCJcAAAC/SURBVAjXNc4/jgFRAMDh3/tj8oaJKchENBRsQTZ2VCpncAFO4A' +
                'QkDqB0AYnCCfRuQGYzhUypUWzEyEp072n4TvABUNS6Hxmzqfl+Ehmz9pX6BhAlrQejZnM/7XZNKwzJ8pxVmj525/NQlwqF+SyOTadScVgrqv' +
                'W6Czwv2F8uCynh5ysMwVoBgLWiXS4joSctHE55DlI6AKR02f2OhaNykP09n+NGEHieUvxer2KZJP/p7TbhvY0jY7bv7eazfQE67zjGgilfew' +
                'AAAABJRU5ErkJggg==')
      },

      /**
       * Get google points for this location.
       *
       * @return {Array} an array of google.maps.LatLng representing the points for this location.
       */
      getGPoints: function () {
        var points = [];

        $.each(this.get("coords"), function (index, point) {
          var coord = new google.maps.LatLng(point[0], point[1]);
          points.push(coord);
        });

        return points;
      },

      /**
       * Get a generated poi-type.
       * @return {string} the poi-type
       */
      getPoiType: function () {
        return this.get('campus') + "." + this.get('type');
      }
    });

/**
 * Collection of locations.
 *
 * @class Backbone collection of Locations
 * @author Joakim Lundin
 * @type {Backbone.Collection}
 */
var Locations = Backbone.Collection.extend(
    /** @lends Locations */
    {
      /** The model used for this Location. */
      model: Location,
      bounds: null,
      campuses: null,

      /**
       * Intercept method performed after fetch().
       * In this method the bounds and campuses variable are set.
       */
      parse: function (response) {
        this.bounds = response.bounds;
        this.campuses = response.campuses;
        return response.locations;
      },

      /**
       * Constructs the URL used for getting locations.
       *
       * @return {string} the URL.
       */
      url: function () {
        return config.map.location.url;
      },

      /**
       * Filter Locations by campus.
       *
       * @param {string} campus the Campus to filter by.
       * @return {Array} an array of filtered Locations.
       */
      byCampus: function (campus) {
        return _(this.filter(function (data) {
          return data.get("campus") == campus;
        }));
      },

      /**
       * Filter Locations by type.
       *
       * @param {string} type the type to filter by.
       * @return {Array} an array of filtered Locations.
       */
      byType: function (type) {
        return _(this.filter(function (data) {
          return data.get("type") == type;
        }));
      },

      /**
       * Filter Locations by campus and types.
       *
       * @param {string} campus the Campus to filter by.
       * @param {Array} types an array of types to filter by.
       * @return {Array} an array of filtered Locations.
       */
      byCampusAndType: function (campus, types) {
        var ret = this.byCampus(campus);
        return _(ret.filter(function (data) {
          return _.contains(types, data.get("type"));
        }));
      }
    });

/**
 * A collection of searchresults for Locations.
 *
 * @class Backbone collection of Locations
 * @type {Backbone.Collection}
 */
var LocationSearchResult = Backbone.Collection.extend(
    /** @lends LocationSearchResult */
    {
      /** The model used for this collection. */
      model: Location,
      bounds: null,
      campuses: null,

      /**
       * Intercept method performed after fetch().
       * In this method the bounds and campuses variable are set.
       */
      parse: function (response) {
        this.bounds = response.bounds;
        this.campuses = response.campuses;
        return response.locations;
      },

      /**
       * Constructs the URL used for getting search results.
       *
       * @return {string} the URL.
       */
      url: function () {
        return config.map.search.url;
      }
    });
<commit_msg>Added default for name.<commit_after>/**
 * Location
 *
 * @class Backbone model representing a location on the map.
 * @author Joakim Lundin
 * @type {Backbone.Model}
 */
var Location = Backbone.Model.extend(
    /** @lends Location */
    {
      defaults: {
        id: 0,
        name: 'unknown',
        campus: 'unknown',
        type: 'unknown',
        subType: null,
        shape: "point",
        text: "",
        coords: [],
        directionAware: true,
        hasIcon: false,
        pin: new google.maps.MarkerImage(
            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkw' +
                'AAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wKExQWIJ3tCJcAAAC/SURBVAjXNc4/jgFRAMDh3/tj8oaJKchENBRsQTZ2VCpncAFO4A' +
                'QkDqB0AYnCCfRuQGYzhUypUWzEyEp072n4TvABUNS6Hxmzqfl+Ehmz9pX6BhAlrQejZnM/7XZNKwzJ8pxVmj525/NQlwqF+SyOTadScVgrqv' +
                'W6Czwv2F8uCynh5ysMwVoBgLWiXS4joSctHE55DlI6AKR02f2OhaNykP09n+NGEHieUvxer2KZJP/p7TbhvY0jY7bv7eazfQE67zjGgilfew' +
                'AAAABJRU5ErkJggg==')
      },

      /**
       * Get google points for this location.
       *
       * @return {Array} an array of google.maps.LatLng representing the points for this location.
       */
      getGPoints: function () {
        var points = [];

        $.each(this.get("coords"), function (index, point) {
          var coord = new google.maps.LatLng(point[0], point[1]);
          points.push(coord);
        });

        return points;
      },

      /**
       * Get a generated poi-type.
       * @return {string} the poi-type
       */
      getPoiType: function () {
        return this.get('campus') + "." + this.get('type');
      }
    });

/**
 * Collection of locations.
 *
 * @class Backbone collection of Locations
 * @author Joakim Lundin
 * @type {Backbone.Collection}
 */
var Locations = Backbone.Collection.extend(
    /** @lends Locations */
    {
      /** The model used for this Location. */
      model: Location,
      bounds: null,
      campuses: null,

      /**
       * Intercept method performed after fetch().
       * In this method the bounds and campuses variable are set.
       */
      parse: function (response) {
        this.bounds = response.bounds;
        this.campuses = response.campuses;
        return response.locations;
      },

      /**
       * Constructs the URL used for getting locations.
       *
       * @return {string} the URL.
       */
      url: function () {
        return config.map.location.url;
      },

      /**
       * Filter Locations by campus.
       *
       * @param {string} campus the Campus to filter by.
       * @return {Array} an array of filtered Locations.
       */
      byCampus: function (campus) {
        return _(this.filter(function (data) {
          return data.get("campus") == campus;
        }));
      },

      /**
       * Filter Locations by type.
       *
       * @param {string} type the type to filter by.
       * @return {Array} an array of filtered Locations.
       */
      byType: function (type) {
        return _(this.filter(function (data) {
          return data.get("type") == type;
        }));
      },

      /**
       * Filter Locations by campus and types.
       *
       * @param {string} campus the Campus to filter by.
       * @param {Array} types an array of types to filter by.
       * @return {Array} an array of filtered Locations.
       */
      byCampusAndType: function (campus, types) {
        var ret = this.byCampus(campus);
        return _(ret.filter(function (data) {
          return _.contains(types, data.get("type"));
        }));
      }
    });

/**
 * A collection of searchresults for Locations.
 *
 * @class Backbone collection of Locations
 * @type {Backbone.Collection}
 */
var LocationSearchResult = Backbone.Collection.extend(
    /** @lends LocationSearchResult */
    {
      /** The model used for this collection. */
      model: Location,
      bounds: null,
      campuses: null,

      /**
       * Intercept method performed after fetch().
       * In this method the bounds and campuses variable are set.
       */
      parse: function (response) {
        this.bounds = response.bounds;
        this.campuses = response.campuses;
        return response.locations;
      },

      /**
       * Constructs the URL used for getting search results.
       *
       * @return {string} the URL.
       */
      url: function () {
        return config.map.search.url;
      }
    });
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var Initial = require('postcss-initial');
var merge = require('webpack-merge');
var prettyjson = require('prettyjson');
var getInstalledPath = require('get-installed-path');
var config = require('../src/utils/config');

module.exports = function(env) {
	var isProd = env === 'production';
	var cssLoader = 'css?modules&importLoaders=1&localIdentName=ReactStyleguidist-[name]__[local]!postcss';

	var codeMirrorPath = getInstalledPath('codemirror', true);
	var reactTransformPath = getInstalledPath('babel-plugin-react-transform', true);

	var includes = [
		__dirname,
		config.rootDir
	];
	var webpackConfig = {
		output: {
			path: config.styleguideDir,
			filename: 'build/bundle.js'
		},
		resolve: {
			root: path.join(__dirname),
			extensions: ['', '.js', '.jsx'],
			modulesDirectories: [
				path.resolve(__dirname, '../node_modules'),
				'node_modules'
			],
			alias: {
				'codemirror': codeMirrorPath
			}
		},
		resolveLoader: {
			modulesDirectories: [
				path.resolve(__dirname, '../loaders'),
				path.resolve(__dirname, '../node_modules'),
				'node_modules'
			]
		},
		plugins: [
			new HtmlWebpackPlugin({
				title: config.title,
				template: config.template,
				inject: true
			}),
			new webpack.DefinePlugin({
				'process.env': {
					NODE_ENV: JSON.stringify(env)
				}
			})
		],
		module: {
			loaders: [
			],
			noParse: [
				/babel-core\/browser.js/
			]
		},
		postcss: function() {
			return [
				Initial({
					reset: 'inherited'
				})
			];
		}
	};

	var entryScript = path.join(__dirname, 'index');

	if (isProd) {
		webpackConfig = merge(webpackConfig, {
			entry: [
				entryScript
			],
			devtool: false,
			debug: false,
			cache: false,
			plugins: [
				new webpack.optimize.UglifyJsPlugin({
					compress: {
						warnings: false
					},
					output: {
						comments: false
					},
					mangle: false
				}),
				new webpack.optimize.DedupePlugin(),
				new ExtractTextPlugin('build/styles.css', {
					allChunks: true
				})
			],
			module: {
				loaders: [
					{
						test: /\.jsx?$/,
						include: includes,
						loader: 'babel',
						query: {
							stage: 0
						}
					},
					{
						test: /\.json$/,
						loader: 'json'
					},
					{
						test: /\.css$/,
						include: codeMirrorPath,
						loader: ExtractTextPlugin.extract('style', 'css')
					},
					{
						test: /\.css$/,
						include: includes,
						loader: ExtractTextPlugin.extract('style', cssLoader)
					}
				]
			}
		});
	}
	else {
		webpackConfig = merge(webpackConfig, {
			entry: [
				'webpack-hot-middleware/client',
				entryScript
			],
			debug: true,
			cache: true,
			devtool: 'eval-source-map',
			stats: {
				colors: true,
				reasons: true
			},
			plugins: [
				new webpack.optimize.OccurenceOrderPlugin(),
				new webpack.HotModuleReplacementPlugin(),
				new webpack.NoErrorsPlugin()
			],
			module: {
				loaders: [
					{
						test: /\.jsx?$/,
						include: includes,
						loader: 'babel',
						query: {
							stage: 0,
							plugins: [
								reactTransformPath
							],
							extra: {
								'react-transform': {
									transforms: [
										{
											transform: 'react-transform-hmr',
											imports: ['react'],
											locals: ['module']
										},
										{
											transform: 'react-transform-catch-errors',
											imports: ['react', 'redbox-react']
										}
									]
								}
							}
						}
					},
					{
						test: /\.json$/,
						loader: 'json'
					},
					{
						test: /\.css$/,
						include: codeMirrorPath,
						loader: 'style!css'
					},
					{
						test: /\.css$/,
						include: includes,
						loader: 'style!' + cssLoader
					}
				]
			}
		});
	}

	if (config.updateWebpackConfig) {
		webpackConfig = config.updateWebpackConfig(webpackConfig, env);
	}

	if (config.verbose) {
		console.log();
		console.log('Using Webpack config:');
		console.log(prettyjson.render(webpackConfig));
		console.log();
	}

	return webpackConfig;
};
<commit_msg>Remove unused fs.<commit_after>var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var Initial = require('postcss-initial');
var merge = require('webpack-merge');
var prettyjson = require('prettyjson');
var getInstalledPath = require('get-installed-path');
var config = require('../src/utils/config');

module.exports = function(env) {
	var isProd = env === 'production';
	var cssLoader = 'css?modules&importLoaders=1&localIdentName=ReactStyleguidist-[name]__[local]!postcss';

	var codeMirrorPath = getInstalledPath('codemirror', true);
	var reactTransformPath = getInstalledPath('babel-plugin-react-transform', true);

	var includes = [
		__dirname,
		config.rootDir
	];
	var webpackConfig = {
		output: {
			path: config.styleguideDir,
			filename: 'build/bundle.js'
		},
		resolve: {
			root: path.join(__dirname),
			extensions: ['', '.js', '.jsx'],
			modulesDirectories: [
				path.resolve(__dirname, '../node_modules'),
				'node_modules'
			],
			alias: {
				'codemirror': codeMirrorPath
			}
		},
		resolveLoader: {
			modulesDirectories: [
				path.resolve(__dirname, '../loaders'),
				path.resolve(__dirname, '../node_modules'),
				'node_modules'
			]
		},
		plugins: [
			new HtmlWebpackPlugin({
				title: config.title,
				template: config.template,
				inject: true
			}),
			new webpack.DefinePlugin({
				'process.env': {
					NODE_ENV: JSON.stringify(env)
				}
			})
		],
		module: {
			loaders: [
			],
			noParse: [
				/babel-core\/browser.js/
			]
		},
		postcss: function() {
			return [
				Initial({
					reset: 'inherited'
				})
			];
		}
	};

	var entryScript = path.join(__dirname, 'index');

	if (isProd) {
		webpackConfig = merge(webpackConfig, {
			entry: [
				entryScript
			],
			devtool: false,
			debug: false,
			cache: false,
			plugins: [
				new webpack.optimize.UglifyJsPlugin({
					compress: {
						warnings: false
					},
					output: {
						comments: false
					},
					mangle: false
				}),
				new webpack.optimize.DedupePlugin(),
				new ExtractTextPlugin('build/styles.css', {
					allChunks: true
				})
			],
			module: {
				loaders: [
					{
						test: /\.jsx?$/,
						include: includes,
						loader: 'babel',
						query: {
							stage: 0
						}
					},
					{
						test: /\.json$/,
						loader: 'json'
					},
					{
						test: /\.css$/,
						include: codeMirrorPath,
						loader: ExtractTextPlugin.extract('style', 'css')
					},
					{
						test: /\.css$/,
						include: includes,
						loader: ExtractTextPlugin.extract('style', cssLoader)
					}
				]
			}
		});
	}
	else {
		webpackConfig = merge(webpackConfig, {
			entry: [
				'webpack-hot-middleware/client',
				entryScript
			],
			debug: true,
			cache: true,
			devtool: 'eval-source-map',
			stats: {
				colors: true,
				reasons: true
			},
			plugins: [
				new webpack.optimize.OccurenceOrderPlugin(),
				new webpack.HotModuleReplacementPlugin(),
				new webpack.NoErrorsPlugin()
			],
			module: {
				loaders: [
					{
						test: /\.jsx?$/,
						include: includes,
						loader: 'babel',
						query: {
							stage: 0,
							plugins: [
								reactTransformPath
							],
							extra: {
								'react-transform': {
									transforms: [
										{
											transform: 'react-transform-hmr',
											imports: ['react'],
											locals: ['module']
										},
										{
											transform: 'react-transform-catch-errors',
											imports: ['react', 'redbox-react']
										}
									]
								}
							}
						}
					},
					{
						test: /\.json$/,
						loader: 'json'
					},
					{
						test: /\.css$/,
						include: codeMirrorPath,
						loader: 'style!css'
					},
					{
						test: /\.css$/,
						include: includes,
						loader: 'style!' + cssLoader
					}
				]
			}
		});
	}

	if (config.updateWebpackConfig) {
		webpackConfig = config.updateWebpackConfig(webpackConfig, env);
	}

	if (config.verbose) {
		console.log();
		console.log('Using Webpack config:');
		console.log(prettyjson.render(webpackConfig));
		console.log();
	}

	return webpackConfig;
};
<|endoftext|>


<commit_before>/*
 * Created by matthias on 26/10/15.
 * VERSION: Scenario 1
 */
 'use strict';

// Required modules
var cheerio = require('cheerio'),
    clone = require('clone'),
    kuler = require('kuler'),
    async = require('async');

module.exports = function (options, config) {

  options = options || {};
  config = config.get() || {};

  var maxProcess =  config.concurrency || 1,
      delay =  config.delay || 100;

  return function (input, submit) {

    //Load Cheerio on xml DOC input
    var $ = cheerio.load(input.content.xml, {
      normalizeWhitespace: true,
      xmlMode: true
    });
    // Get only span in right spanGrp that have righ attrbs (OBJ)
    var words = $('spanGrp[type="candidatsTermes"] span').filter('[ana~="#DM4"],[ana~="#DAOn"]').toArray();

    if(words.length == "0"){
      return submit(null , input);
    }

    var filtr = $("body div ,text front div[lang='fr'], text front div:not([lang]),  teiHeader fileDesc titleStmt title[lang='fr'], teiHeader fileDesc titleStmt title:not([lang])");

    var attribut;
    $('hi').each(function (i,el) {
      if ($(this).attr('rend')) {
        attribut = $(this).attr('rend');
        $(this).children().each(function () {
          $(this).attr('rend' , attribut);
        });
      }
      $(this).replaceWith($(this).children());
    });
    // Remove big & useless XML in input
    delete input.content.xml;
    var qe;

    //For each span in file ~ Seems does not work
    async.eachSeries(words, function (word, next) {

      // Build clone of input file
      var obj = clone(input,false);

      var firstWord,
          endWord,
          para,
          sentence,
          target,
          corresp,
          lemma,
          prevAllW,
          nextAllW,
          prevW,
          nextW,
          wBefore = "",
          wAfter = "",
          askedWord = "";

      target = ($(word).attr("target") || '').replace(/#/g , "").split(" ");
      firstWord = $('[xml\\:id="' + target[0] + '"]');

      var isInFiltr = filtr.find(firstWord).length

      // If word not in body balise continue with other span
      if (isInFiltr < 1) {
        return next();
      }
      // filtr.find('[nb]').removeAttr('nb');

      endWord = (target.length > 1) ? $('[xml\\:id="' + target[target.length - 1] + '"]') : firstWord;
      corresp = $(word).attr("corresp");
      lemma   = ($(word).attr("lemma") || '').toString();

      if(corresp.indexOf("#TS2.0") && corresp.indexOf("#TS1.4")){
        corresp = corresp.replace(/#TS1.4-entry-.*$|#TS2.0-entry-/g, "").toString();
      }
      else if(corresp.indexOf("#TS2.0")){
        corresp = corresp.replace(/#TS2.0-entry-/g, "").toString();
      }
      else if(corresp.indexOf("#TS1.4")){
        corresp = corresp.replace(/#TS1.4-entry-/g, "").toString();
      }

      var nbSiblings = firstWord.siblings();
      var nbParaChildren = firstWord.closest("p").children(),
          content,
          reg = /\B[^\w\s\n\t]\B/,
          pc = $('<pc>ex</pc>'),
          element;

      para = (nbSiblings.length < 11 && nbParaChildren.length > 12) ? nbParaChildren.clone() : firstWord.parent().clone();
      para.find("w").each(function(index, el){
        element = para.find(el);
        if(element.contents()[0].type == "text"){
          content = element.contents().text();
          if (reg.test(content)) {
            pc.attr("xml:id" , element.attr("xml:id"));
            pc.text(content);
            // console.info("pc : " , pc.toString());
            element.replaceWith(pc.toString());
            // console.info(element);
          }
        }
      });

      var word2Add;
      //Create asked words and add attribut nb
      for (var i = 0 ; i < target.length ; i++) {
        word2Add = para.find('[xml\\:id="' + target[i] + '"]');
        if(word2Add[0] && word2Add[0].next){
          if(word2Add[0].next.type == "text"){
           word2Add.attr("wsAfter", "true");
          }
        }
        askedWord = askedWord + word2Add.attr("nb" , "0");
      }

      sentence = para.clone();
      sentence.find('note').remove();

      prevAllW = sentence.find('[xml\\:id="' + target[0] + '"]').prevAll();
      nextAllW = sentence.find('[xml\\:id="' + target[target.length - 1] + '"]').nextAll();

      for (var nbWBefore = 0, nbWAfter = 0, index = 0; (nbWBefore < 5 || nbWAfter < 5) ; index++) {
        prevW = (prevAllW[index]) ? prevAllW.filter(prevAllW[index]) : null;
        nextW = (nextAllW[index]) ? nextAllW.filter(nextAllW[index]) : null;
        if(prevW){
          if(prevW.is('w')){
            prevW = prevW.attr("nb", ++nbWBefore);
            if(prevW[0] && prevW[0].next){
              if(prevW[0].next.type == "text"){
               prevW.attr("wsAfter", "true");
              }
            }
          }
          if (!(prevW.is('note'))) {
            wBefore = prevW + wBefore ;
          }
        }
        else{
          nbWBefore = 5;
        }
        if(nextW){
          if(nextW.is('w')){
            nextW = nextW.attr("nb", ++nbWAfter);
            if(nextW[0] && nextW[0].next){
              if(nextW[0].next.type == "text"){
                nextW.attr("wsAfter", "true");
              }
            }
          }
          if (!(nextW.is('note'))) {
            wAfter = wAfter + nextW ;
          }
        }
        else{
          nbWAfter = 5;
        }
      }

      /* Create sentence */
      sentence = '' + wBefore + '' + '' + askedWord + '' +  '' + wAfter + '' ;

      para = para.toString();
      para = para.replace(/<head/g, "<div");
      para = para.replace(/<\/head>/g, "
");
      para = para.replace(/<title/g, "<h4");
      para = para.replace(/<\/title>/g, "
");
      para = para.replace(/<hi/g, "<i");
      para = para.replace(/<\/hi>/g, "");
      para = para.replace(/<note/g, "<div");
      para = para.replace(/<\/note>/g, "
");

      // Add elements to OBJ
      obj.content.corresp = corresp;
      obj.content.target = target;
      obj.content.sentence = sentence;
      obj.content.para = para;
      obj.content.lemma = lemma;
      obj.content.words = askedWord.toString();

      qe = submit(obj);

      if (qe.length() >= maxProcess) {
        setTimeout(function () {
          return next();
        }, delay * qe.length());
      } else {
        return next();
      }
    },
    function (err) {
      if (err) {
        console.info(kuler("\n " + err + " \n" , "red"));
      }
      // the last callback means that all documents have been submitted
      submit();
    })
  }
};
<commit_msg>Correction wsafter ponctuations<commit_after>/*
 * Created by matthias on 26/10/15.
 * VERSION: Scenario 1
 */
 'use strict';

// Required modules
var cheerio = require('cheerio'),
    clone = require('clone'),
    kuler = require('kuler'),
    async = require('async');

module.exports = function (options, config) {

  options = options || {};
  config = config.get() || {};

  var maxProcess =  config.concurrency || 1,
      delay =  config.delay || 100;

  return function (input, submit) {

    //Load Cheerio on xml DOC input
    var $ = cheerio.load(input.content.xml, {
      normalizeWhitespace: true,
      xmlMode: true
    });
    // Get only span in right spanGrp that have righ attrbs (OBJ)
    var words = $('spanGrp[type="candidatsTermes"] span').filter('[ana~="#DM4"],[ana~="#DAOn"]').toArray();

    if(words.length == "0"){
      return submit(null , input);
    }

    var filtr = $("body div ,text front div[lang='fr'], text front div:not([lang]),  teiHeader fileDesc titleStmt title[lang='fr'], teiHeader fileDesc titleStmt title:not([lang])");

    var attribut;
    $('hi').each(function (i,el) {
      if ($(this).attr('rend')) {
        attribut = $(this).attr('rend');
        $(this).children().each(function () {
          $(this).attr('rend' , attribut);
        });
      }
      $(this).replaceWith($(this).children());
    });
    // Remove big & useless XML in input
    delete input.content.xml;
    var qe;

    //For each span in file ~ Seems does not work
    async.eachSeries(words, function (word, next) {

      // Build clone of input file
      var obj = clone(input,false);

      var firstWord,
          endWord,
          para,
          sentence,
          target,
          corresp,
          lemma,
          prevAllW,
          nextAllW,
          prevW,
          nextW,
          wBefore = "",
          wAfter = "",
          askedWord = "";

      target = ($(word).attr("target") || '').replace(/#/g , "").split(" ");
      firstWord = $('[xml\\:id="' + target[0] + '"]');

      var isInFiltr = filtr.find(firstWord).length

      // If word not in body balise continue with other span
      if (isInFiltr < 1) {
        return next();
      }
      // filtr.find('[nb]').removeAttr('nb');

      endWord = (target.length > 1) ? $('[xml\\:id="' + target[target.length - 1] + '"]') : firstWord;
      corresp = $(word).attr("corresp");
      lemma   = ($(word).attr("lemma") || '').toString();

      if((corresp.indexOf("#TS2.0") > (-1)) && (corresp.indexOf("#TS1.4") > (-1))){
         corresp = corresp.replace(/-#TS1.4-entry-.*$|#TS2.0-entry-/g, "").toString();
      }
      else if(corresp.indexOf("#TS2.0") > (-1)){
        corresp = corresp.replace(/#TS2.0-entry-/g, "").toString();
      }
      else if(corresp.indexOf("#TS1.4") > (-1)){
        corresp = corresp.replace(/#TS1.4-entry-/g, "").toString();
      }

      var nbSiblings = firstWord.siblings();
      var nbParaChildren = firstWord.closest("p").children(),
          content,
          reg = /\B[^\w\s\n\t]\B/,
          pc = $('<pc>ex</pc>'),
          element;

      para = (nbSiblings.length < 11 && nbParaChildren.length > 12) ? nbParaChildren.clone() : firstWord.parent().clone();
      para.find("w").each(function(index, el){
        element = para.find(el);
        if(element.contents()[0].type == "text"){
          content = element.contents().text();
          if (reg.test(content)) {
            pc.attr("xml:id" , element.attr("xml:id"));
            pc.text(content);
            // console.info("pc : " , pc.toString());
            element.replaceWith(pc.toString());
            // console.info(element);
          }
        }
      });

      var word2Add;
      //Create asked words and add attribut nb
      for (var i = 0 ; i < target.length ; i++) {
        word2Add = para.find('[xml\\:id="' + target[i] + '"]');
        if(word2Add[0] && word2Add[0].next){
          if(word2Add[0].next.type == "text"){
           word2Add.attr("wsAfter", "true");
          }
        }
        askedWord = askedWord + word2Add.attr("nb" , "0");
      }

      sentence = para.clone();
      sentence.find('note').remove();

      prevAllW = sentence.find('[xml\\:id="' + target[0] + '"]').prevAll();
      nextAllW = sentence.find('[xml\\:id="' + target[target.length - 1] + '"]').nextAll();

      for (var nbWBefore = 0, nbWAfter = 0, index = 0; (nbWBefore < 5 || nbWAfter < 5) ; index++) {
        prevW = (prevAllW[index]) ? prevAllW.filter(prevAllW[index]) : null;
        nextW = (nextAllW[index]) ? nextAllW.filter(nextAllW[index]) : null;
        if(prevW){
          if(prevW.is('w')){
            prevW = prevW.attr("nb", ++nbWBefore);
          }
          if (!(prevW.is('note'))) {
            if(prevW[0] && prevW[0].next){
              if(prevW[0].next.type == "text"){
               prevW.attr("wsAfter", "true");
              }
            }
            wBefore = prevW + wBefore;
          }
        }
        else{
          nbWBefore = 5;
        }
        if(nextW){
          if(nextW.is('w')){
            nextW = nextW.attr("nb", ++nbWAfter);
          }
          if (!(nextW.is('note'))) {
            if(nextW[0] && nextW[0].next){
              if(nextW[0].next.type == "text"){
                nextW.attr("wsAfter", "true");
              }
            }
            wAfter = wAfter + nextW ;
          }
        }
        else{
          nbWAfter = 5;
        }
      }

      /* Create sentence */
      sentence = '' + wBefore + '' + '' + askedWord + '' +  '' + wAfter + '' ;

      para = para.toString();
      para = para.replace(/<head/g, "<div");
      para = para.replace(/<\/head>/g, "
");
      para = para.replace(/<title/g, "<h4");
      para = para.replace(/<\/title>/g, "
");
      para = para.replace(/<hi/g, "<i");
      para = para.replace(/<\/hi>/g, "");
      para = para.replace(/<note/g, "<div");
      para = para.replace(/<\/note>/g, "
");

      // Add elements to OBJ
      obj.content.corresp = corresp;
      obj.content.target = target;
      obj.content.sentence = sentence;
      obj.content.para = para;
      obj.content.lemma = lemma;
      obj.content.words = askedWord.toString();

      qe = submit(obj);

      if (qe.length() >= maxProcess) {
        setTimeout(function () {
          return next();
        }, delay * qe.length());
      } else {
        return next();
      }
    },
    function (err) {
      if (err) {
        console.info(kuler("\n " + err + " \n" , "red"));
      }
      // the last callback means that all documents have been submitted
      submit();
    })
  }
};
<|endoftext|>


<commit_before>ace.define("ace/mode/lucene_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"], function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var lang = require("../lib/lang");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var LuceneHighlightRules = function() {
    this.$rules = {
        "start" : [
            {
                token : "constant.character.negation",
                regex : "[\\-]"
            }, {
                token : "constant.character.interro",
                regex : "[\\?]"
            }, {
                token : "constant.character.asterisk",
                regex : "[\\*]"
            }, {
                token: 'constant.character.proximity',
                regex: '~[0-9]+\\b'
            }, {
                token : 'keyword.operator',
                regex: '(?:AND|OR|NOT)\\b'
            }, {
                token : "paren.lparen",
                regex : "[\\(]"
            }, {
                token : "paren.rparen",
                regex : "[\\)]"
            }, {
                token : "keyword",
                regex : "[\\S]+:"
            }, {
                token : "string",           // " string
                regex : '".*?"'
            }, {
                token : "text",
                regex : "\\s+"
            }
        ]
    };
};

oop.inherits(LuceneHighlightRules, TextHighlightRules);

exports.LuceneHighlightRules = LuceneHighlightRules;
});

ace.define("ace/mode/lucene",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lucene_highlight_rules"], function(require, exports, module) {
'use strict';

var oop = require("../lib/oop");
var TextMode = require("./text").Mode;
var LuceneHighlightRules = require("./lucene_highlight_rules").LuceneHighlightRules;

var Mode = function() {
    this.HighlightRules = LuceneHighlightRules;
};

oop.inherits(Mode, TextMode);

(function() {
    this.$id = "ace/mode/lucene";
}).call(Mode.prototype);

exports.Mode = Mode;
});
<commit_msg>Update tmp/bower_components/ace-builds/src-noconflict/mode-lucene.js<commit_after><|endoftext|>