<commit_before>'use strict';

import R from 'ramda';
void R;

const applyToThis = fn => function() {
  return fn.call(this, this, ...arguments);
};

class _Cube {
  constructor(q, r, s) {
    this.q = q;
    this.r = r;
    this.s = s;
  }

  equals({q, r, s}) {
    return this.q === q && this.r === r && this.s === s;
  }
}

const Cube = R.curry(function(q, r, s) { return new _Cube(q, r, s); });

const gridDistance = R.curry(({q: aq, r: ar, s: as}, {q: bq, r: br, s: bs})
                             => Math.max(Math.abs(aq - bq),
                                         Math.abs(ar - br),
                                         Math.abs(as - bs)));

const h = {
  gridDistance,
  add: (a, b) => Cube(a.q + b.q, a.r + b.r, a.s + b.s),
  sub: (a, b) => Cube(a.q - b.q, a.r - b.r, a.s - b.s),
  scale: (a, k) => Cube(a.q * k, a.r * k, a.s * k),
  length: gridDistance(Cube(0, 0, 0)),
};

R.extend(Cube, h);
R.extend(_Cube.prototype, R.mapObj(applyToThis, h));

export default Cube;
export {Cube};<commit_msg>more function adapted from Hexagonal Grids<commit_after>'use strict';

import R from 'ramda';

const extend = function(destination, ...sources) {
  sources.forEach(source => {
    for (let property in source) {
      if (destination === window && window.hasOwnProperty(property)) {
        console.warn('window already has a property "' + property + '". If needed, it should be '
                     + 'set directly and explicitly, not through the use of extend()');
      }

      const getter = source.__lookupGetter__(property);
      if (getter) { destination.__defineGetter__(property, getter); }

      const setter = source.__lookupSetter__(property);
      if (setter) { destination.__defineSetter__(property, setter); }

      if (getter || setter) { continue; }

      destination[property] = source[property];
    }
  });

  return destination;
};

const applyToThis = fn => R.curryN(fn.length - 1, function() {
  return fn.call(this, this, ...arguments);
});

class _Cube {
  constructor(q, r, s) {
    this.q = q;
    this.r = r;
    this.s = R.defaultTo(-q - r, s);
  }

  equals({q, r, s}) {
    return this.q === q && this.r === r && this.s === s;
  }
}

const Cube = R.curryN(2, function(q, r, s) { return new _Cube(q, r, s); });

const gridDistance = R.curry(({q: aq, r: ar, s: az}, {q: bq, r: br, s: bs})
                             => Math.max(Math.abs(aq - bq),
                                         Math.abs(ar - br),
                                         Math.abs(az - bs)));

const add = R.curry((a, b) => Cube(a.q + b.q, a.r + b.r));
const sub = R.curry((a, b) => Cube(a.q - b.q, a.r - b.r));
const scale = R.curry((a, k) => Cube(a.q * k, a.r * k));

const round = R.curry(function(h) {
  // rX means rounded X, short for glanceability (otherwise the rounded dominates the word)
  const rQ = Math.round(h.q);
  const rR = Math.round(h.r);
  const rS = Math.round(h.s);

  const dQ = Math.abs(rQ - h.q);
  const dR = Math.abs(rR - h.r);
  const dS = Math.abs(rS - h.s);

  if (dQ > dR && dQ > dS) {
    return Cube(-rR - rS, rR, rS);
  } else if (dR > dS) {
    return Cube(rQ, -rQ - rS, rS);
  }

  return Cube(rQ, rR, -rQ - rR);
});

const directions = [
  Cube(+1, -1, 0), Cube(+1, 0, -1), Cube(0, +1, -1),
  Cube(-1, +1, 0), Cube(-1, 0, +1), Cube(0, -1, +1)
];

const line = (a, b) => {
  const {q: dq, r: dr} = sub(b, a);
  const N = gridDistance(a, b);
  const dN = 1.0 / N;
  return R.map(i => Cube(a.q + dq * dN * i,
                         a.r + dr * dN * i),
               R.range(0, N + 1));
};

// pointy top variant
const fromPoint = R.curry(function(size, x, y) {
  const q = (x * Math.sqrt(3) / 3 - y / 3) / size;
  const r = y * 2 / 3 / size;
  return Cube(q, r);
});

const toPoint = R.curry(function(size, cube) {
  const x = size * Math.sqrt(3) * (cube.q + cube.r / 2);
  const y = size * 3 / 2 * cube.r;
  return {x, y};
});

const h = {
  add,
  sub,
  scale,
  round,
  gridDistance,
  length: gridDistance(Cube(0, 0, 0)),

  line,
  gridLine: R.curryN(2, R.compose(R.map(round), line)),
  directions,
};

extend(Cube, h, {fromPoint, toPoint});
extend(_Cube.prototype, R.mapObj(applyToThis, h));

export default Cube;
export {Cube};
{'fraction_non_alphanumeric': 0.1920514040932889, 'fraction_numerical': 0.00951927653498334, 'mean_word_length': 2.220689655172414, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '285999', 'n_tokens_mistral': 1698, 'n_tokens_neox': 1655, 'n_words': 453}