<commit_before>###
#    Copyright 2015-2017 ppy Pty. Ltd.
#
#    This file is part of osu!web. osu!web is distributed with the hope of
#    attracting more community contributions to the core ecosystem of osu!.
#
#    osu!web is free software: you can redistribute it and/or modify
#    it under the terms of the Affero GNU General Public License version 3
#    as published by the Free Software Foundation.
#
#    osu!web is distributed WITHOUT ANY WARRANTY; without even the implied
#    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#    See the GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with osu!web.  If not, see <http://www.gnu.org/licenses/>.
###

{a, div, h2, li, ul} = ReactDOMFactories
el = React.createElement

pages = document.getElementsByClassName("js-switchable-mode-page--scrollspy")
pagesOffset = document.getElementsByClassName("js-switchable-mode-page--scrollspy-offset")

currentLocation = ->
  "#{document.location.pathname}#{document.location.search}"


class ProfilePage.Main extends React.PureComponent
  constructor: (props) ->
    super props

    @state = JSON.parse(props.container.dataset.profilePageState ? null)
    @restoredState = @state?

    if !@restoredState
      page = location.hash.slice(1)
      @initialPage = page if page?

      @state =
        currentMode: props.currentMode
        user: props.user
        userPage:
          html: props.userPage.html
          initialRaw: props.userPage.raw
          raw: props.userPage.raw
          editing: false
          selection: [0, 0]
        tabsSticky: false
        profileOrder: props.user.profile_order[..]
        recentActivity: @props.extras.recentActivity
        scoresBest: @props.extras.scoresBest
        scoresFirsts: @props.extras.scoresFirsts
        scoresRecent: @props.extras.scoresRecent
        beatmapPlaycounts: @props.extras.beatmapPlaycounts
        favouriteBeatmapsets: @props.extras.favouriteBeatmapsets
        rankedAndApprovedBeatmapsets: @props.extras.rankedAndApprovedBeatmapsets
        unrankedBeatmapsets: @props.extras.unrankedBeatmapsets
        graveyardBeatmapsets: @props.extras.graveyardBeatmapsets
        recentlyReceivedKudosu: @props.extras.recentlyReceivedKudosu
        showMorePagination: {}

      if @props.user.is_bot
        @state.profileOrder = ['me']

      for own elem, perPage of @props.perPage
        @state.showMorePagination[elem] ?= {}
        @state.showMorePagination[elem].hasMore = @state[elem].length > perPage

        if @state.showMorePagination[elem].hasMore
          @state[elem].pop()


  componentDidMount: =>
    $.subscribe 'user:update.profilePage', @userUpdate
    $.subscribe 'user:page:update.profilePage', @userPageUpdate
    $.subscribe 'profile:showMore.profilePage', @showMore
    $.subscribe 'profile:page:jump.profilePage', @pageJump
    $.subscribe 'stickyHeader.profilePage', @_tabsStick
    $(window).on 'throttled-scroll.profilePage', @pageScan
    $(document).on 'turbolinks:before-cache.profilePage', @saveStateToContainer

    $(@pages).sortable
      cursor: 'move'
      handle: '.js-profile-page-extra--sortable-handle'
      items: '.js-sortable--page'
      revert: 150
      scrollSpeed: 10
      update: @updateOrder

    $(@tabs).sortable
      containment: 'parent'
      cursor: 'move'
      disabled: !@props.withEdit
      items: '.js-sortable--tab'
      revert: 150
      scrollSpeed: 0
      update: @updateOrder
      start: =>
        # Somehow click event still goes through when dragging.
        # This prevents triggering @tabClick.
        Timeout.clear @draggingTabTimeout
        @draggingTab = true
      stop: =>
        @draggingTabTimeout = Timeout.set 500, => @draggingTab = false

    osu.pageChange()

    @modeScrollUrl = currentLocation()

    if !@restoredState
      Timeout.set 0, => @pageJump null, @initialPage


  componentWillUnmount: =>
    $.unsubscribe '.profilePage'
    $(window).off '.profilePage'

    for sortable in [@pages, @tabs]
      $(sortable).sortable 'destroy'

    $(window).stop()
    Timeout.clear @modeScrollTimeout


  render: =>
    withMePage = @state.userPage.initialRaw.trim() != '' || @props.withEdit

    profileOrder = @state.profileOrder.slice()
    profileOrder.push 'account_standing' if !_.isEmpty @state.user.account_history

    extraPageParams =
      me:
        extraClass: ('hidden' if !withMePage)
        props:
          userPage: @state.userPage
          user: @state.user
        component: ProfilePage.UserPage

      recent_activity:
        props:
          pagination: @state.showMorePagination
          recentActivity: @state.recentActivity
          user: @state.user
        component: ProfilePage.RecentActivity

      kudosu:
        props:
          user: @state.user
          recentlyReceivedKudosu: @state.recentlyReceivedKudosu
          pagination: @state.showMorePagination
        component: ProfilePage.Kudosu

      top_ranks:<commit_msg>Move the profileOrder setter for bot<commit_after>###
#    Copyright 2015-2017 ppy Pty. Ltd.
#
#    This file is part of osu!web. osu!web is distributed with the hope of
#    attracting more community contributions to the core ecosystem of osu!.
#
#    osu!web is free software: you can redistribute it and/or modify
#    it under the terms of the Affero GNU General Public License version 3
#    as published by the Free Software Foundation.
#
#    osu!web is distributed WITHOUT ANY WARRANTY; without even the implied
#    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#    See the GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with osu!web.  If not, see <http://www.gnu.org/licenses/>.
###

{a, div, h2, li, ul} = ReactDOMFactories
el = React.createElement

pages = document.getElementsByClassName("js-switchable-mode-page--scrollspy")
pagesOffset = document.getElementsByClassName("js-switchable-mode-page--scrollspy-offset")

currentLocation = ->
  "#{document.location.pathname}#{document.location.search}"


class ProfilePage.Main extends React.PureComponent
  constructor: (props) ->
    super props

    @state = JSON.parse(props.container.dataset.profilePageState ? null)
    @restoredState = @state?

    if !@restoredState
      page = location.hash.slice(1)
      @initialPage = page if page?

      @state =
        currentMode: props.currentMode
        user: props.user
        userPage:
          html: props.userPage.html
          initialRaw: props.userPage.raw
          raw: props.userPage.raw
          editing: false
          selection: [0, 0]
        tabsSticky: false
        profileOrder: props.user.profile_order[..]
        recentActivity: @props.extras.recentActivity
        scoresBest: @props.extras.scoresBest
        scoresFirsts: @props.extras.scoresFirsts
        scoresRecent: @props.extras.scoresRecent
        beatmapPlaycounts: @props.extras.beatmapPlaycounts
        favouriteBeatmapsets: @props.extras.favouriteBeatmapsets
        rankedAndApprovedBeatmapsets: @props.extras.rankedAndApprovedBeatmapsets
        unrankedBeatmapsets: @props.extras.unrankedBeatmapsets
        graveyardBeatmapsets: @props.extras.graveyardBeatmapsets
        recentlyReceivedKudosu: @props.extras.recentlyReceivedKudosu
        showMorePagination: {}

      for own elem, perPage of @props.perPage
        @state.showMorePagination[elem] ?= {}
        @state.showMorePagination[elem].hasMore = @state[elem].length > perPage

        if @state.showMorePagination[elem].hasMore
          @state[elem].pop()


  componentDidMount: =>
    $.subscribe 'user:update.profilePage', @userUpdate
    $.subscribe 'user:page:update.profilePage', @userPageUpdate
    $.subscribe 'profile:showMore.profilePage', @showMore
    $.subscribe 'profile:page:jump.profilePage', @pageJump
    $.subscribe 'stickyHeader.profilePage', @_tabsStick
    $(window).on 'throttled-scroll.profilePage', @pageScan
    $(document).on 'turbolinks:before-cache.profilePage', @saveStateToContainer

    $(@pages).sortable
      cursor: 'move'
      handle: '.js-profile-page-extra--sortable-handle'
      items: '.js-sortable--page'
      revert: 150
      scrollSpeed: 10
      update: @updateOrder

    $(@tabs).sortable
      containment: 'parent'
      cursor: 'move'
      disabled: !@props.withEdit
      items: '.js-sortable--tab'
      revert: 150
      scrollSpeed: 0
      update: @updateOrder
      start: =>
        # Somehow click event still goes through when dragging.
        # This prevents triggering @tabClick.
        Timeout.clear @draggingTabTimeout
        @draggingTab = true
      stop: =>
        @draggingTabTimeout = Timeout.set 500, => @draggingTab = false

    osu.pageChange()

    @modeScrollUrl = currentLocation()

    if !@restoredState
      Timeout.set 0, => @pageJump null, @initialPage


  componentWillUnmount: =>
    $.unsubscribe '.profilePage'
    $(window).off '.profilePage'

    for sortable in [@pages, @tabs]
      $(sortable).sortable 'destroy'

    $(window).stop()
    Timeout.clear @modeScrollTimeout


  render: =>
    withMePage = @state.userPage.initialRaw.trim() != '' || @props.withEdit

    if @props.user.is_bot
      profileOrder = ['me']
    else
      profileOrder = @state.profileOrder.slice()

    profileOrder.push 'account_standing' if !_.isEmpty @state.user.account_history

    extraPageParams =
      me:
        extraClass: ('hidden' if !withMePage)
        props:
          userPage: @state.userPage
          user: @state.user
        component: ProfilePage.UserPage

      recent_activity:
        props:
          pagination: @state.showMorePagination
          recentActivity: @state.recentActivity
          user: @state.user
        component: ProfilePage.RecentActivity

      kudosu:
        props:
          user: @state.user
          recentlyReceivedKudosu: @state.recentlyReceivedKudosu
          pagination: @state.showMorePagination
        component: ProfilePage.Kudosu

      top_ranks:
{'fraction_non_alphanumeric': 0.1012933162207523, 'fraction_numerical': 0.005133774311383157, 'mean_word_length': 2.9477786438035856, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6341652', 'n_tokens_mistral': 3064, 'n_tokens_neox': 2945, 'n_words': 695}