 
     document.body.dataset.profilePageState = JSON.stringify(@state)
 
-
-  render: ->
+    $(window).stop()
+    Timeout.clear @modeScrollTimeout
+
+
+  render: =>
     rankHistories = @props.allRankHistories[@state.currentMode]
     stats = @props.allStats[@state.currentMode]
     scores = @props.allScores[@state.currentMode]

      .always LoadingOverlay.hide


  userUpdate: (_e, user) ->
    return if !user?
    @setState user: user


  userPageUpdate: (_e, newUserPage) ->
    currentUserPage = _.cloneDeep @state.userPage
    @setState userPage: _.extend(currentUserPage, newUserPage)


  validMode: (mode) ->
    modes = BeatmapHelper.modes

    if _.includes(modes, mode)

      el component, props


  pageJump: (_e, page) =>
    if page == 'main'
      @setCurrentPage null, page
      return

    target = $(".js-switchable-mode-page--page[data-page-id='#{page}']")

    # if invalid page is specified, scan current position
    if target.length == 0
      @pageScan()
      return

    # Don't bother scanning the current position.
    # The result will be wrong when target page is too short anyway.
    @scrolling = true
    Timeout.clear @modeScrollTimeout

    $(window).stop().scrollTo target, 500,
      onAfter: =>
        # Manually set the mode to avoid confusion (wrong highlight).
        # Scrolling will obviously break it but that's unfortunate result
        # from having the scrollspy marker at middle of page.
        @setCurrentPage null, page, =>
          # Doesn't work:
          # - part of state (callback, part of mode setting)
          # - simple variable in callback
          # Both still change the switch too soon.
          @modeScrollTimeout = Timeout.set 100, => @scrolling = false
      # count for the tabs height
      offset: pagesOffset[0].getBoundingClientRect().height * -1


  pageScan: =>
    return if @modeScrollUrl != currentLocation()

    return if @scrolling
    return if pages.length == 0

    anchorHeight = pagesOffset[0].getBoundingClientRect().height

    if osu.bottomPage()
      @setCurrentPage null, _.last(pages).dataset.pageId
      return

    for page in pages
      pageDims = page.getBoundingClientRect()
      pageBottom = pageDims.bottom - Math.min(pageDims.height * 0.75, 200)
      continue unless pageBottom > anchorHeight

      @setCurrentPage null, page.dataset.pageId
      return

    @setCurrentPage null, page.dataset.pageId


  setCurrentMode: (_e, {mode}) =>
    return if @state.currentMode == mode
    @setState currentMode: @validMode(mode)


  setCurrentPage: (_e, page, extraCallback) =>
    callback = =>
      extraCallback?()
      @setHash?()

    if @state.currentPage == page
      return callback()

    @setState currentPage: page, callback


  updateOrder: (event) =>
    $elems = $(event.target)

    newOrder = $elems.sortable('toArray', attribute: 'data-page-id')
