<commit_before>import React from 'react'
import classnames from 'classnames'
//
export default {
  get,
  set,
  takeRight,
  last,
  orderBy,
  range,
  remove,
  clone,
  getFirstDefined,
  sum,
  makeTemplateComponent,
  groupBy,
  isArray,
  splitProps,
  compactObject,
  isSortingDesc,
  normalizeComponent
}

function get (obj, path, def) {
  if (!path) {
    return obj
  }
  const pathObj = makePathArray(path)
  let val
  try {
    val = pathObj.reduce((current, pathPart) => current[pathPart], obj)
  } catch (e) {}
  return typeof val !== 'undefined' ? val : def
}

function set (obj = {}, path, value) {
  const keys = makePathArray(path)
  let keyPart
  let cursor = obj
  while ((keyPart = keys.shift()) && keys.length) {
    if (!cursor[keyPart]) {
      cursor[keyPart] = {}
    }
    cursor = cursor[keyPart]
  }
  cursor[keyPart] = value
  return obj
}

function takeRight (arr, n) {
  const start = n > arr.length ? 0 : arr.length - n
  return arr.slice(start)
}

function last (arr) {
  return arr[arr.length - 1]
}

function range (n) {
  const arr = []
  for (let i = 0; i < n; i++) {
    arr.push(n)
  }
  return arr
}

function orderBy (arr, funcs, dirs) {
  return arr.sort((a, b) => {
    for (let i = 0; i < funcs.length; i++) {
      const comp = funcs[i]
      const ca = comp(a)
      const cb = comp(b)
      const desc = dirs[i] === false || dirs[i] === 'desc'
      if (ca > cb) {
        return desc ? -1 : 1
      }
      if (ca < cb) {
        return desc ? 1 : -1
      }
    }
    return dirs[0]
      ? a.__index - b.__index
      : b.__index - b.__index
  })
}

function remove (a, b) {
  return a.filter(function (o, i) {
    var r = b(o)
    if (r) {
      a.splice(i, 1)
      return true
    }
    return false
  })
}

function clone (a) {
  try {
    return JSON.parse(JSON.stringify(a, (key, value) => {
      if (typeof value === 'function') {
        return value.toString()<commit_msg>Fix descending sort being non-deterministic<commit_after>import React from 'react'
import classnames from 'classnames'
//
export default {
  get,
  set,
  takeRight,
  last,
  orderBy,
  range,
  remove,
  clone,
  getFirstDefined,
  sum,
  makeTemplateComponent,
  groupBy,
  isArray,
  splitProps,
  compactObject,
  isSortingDesc,
  normalizeComponent
}

function get (obj, path, def) {
  if (!path) {
    return obj
  }
  const pathObj = makePathArray(path)
  let val
  try {
    val = pathObj.reduce((current, pathPart) => current[pathPart], obj)
  } catch (e) {}
  return typeof val !== 'undefined' ? val : def
}

function set (obj = {}, path, value) {
  const keys = makePathArray(path)
  let keyPart
  let cursor = obj
  while ((keyPart = keys.shift()) && keys.length) {
    if (!cursor[keyPart]) {
      cursor[keyPart] = {}
    }
    cursor = cursor[keyPart]
  }
  cursor[keyPart] = value
  return obj
}

function takeRight (arr, n) {
  const start = n > arr.length ? 0 : arr.length - n
  return arr.slice(start)
}

function last (arr) {
  return arr[arr.length - 1]
}

function range (n) {
  const arr = []
  for (let i = 0; i < n; i++) {
    arr.push(n)
  }
  return arr
}

function orderBy (arr, funcs, dirs) {
  return arr.sort((a, b) => {
    for (let i = 0; i < funcs.length; i++) {
      const comp = funcs[i]
      const ca = comp(a)
      const cb = comp(b)
      const desc = dirs[i] === false || dirs[i] === 'desc'
      if (ca > cb) {
        return desc ? -1 : 1
      }
      if (ca < cb) {
        return desc ? 1 : -1
      }
    }
    return dirs[0]
      ? a.__index - b.__index
      : b.__index - a.__index
  })
}

function remove (a, b) {
  return a.filter(function (o, i) {
    var r = b(o)
    if (r) {
      a.splice(i, 1)
      return true
    }
    return false
  })
}

function clone (a) {
  try {
    return JSON.parse(JSON.stringify(a, (key, value) => {
      if (typeof value === 'function') {
        return value.toString()
{'fraction_non_alphanumeric': 0.14384615384615385, 'fraction_numerical': 0.005128205128205128, 'mean_word_length': 2.374567474048443, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '7167759', 'n_tokens_mistral': 1437, 'n_tokens_neox': 1420, 'n_words': 399}