code: function () {
      if (beatmap.timingPoints.length === 0) { return; }
  
      var maxCombo         = 0;
      var sliderMultiplier = parseFloat(beatmap.SliderMultiplier);
      var sliderTickRate   = parseInt(beatmap.SliderTickRate, 10);
  
      var timingPoints  = beatmap.timingPoints;
      var currentTiming = timingPoints[0];
      var nextOffset    = timingPoints[1] ? timingPoints[1].offset : Infinity;
      var i = 1;
  
      beatmap.hitObjects.forEach(function (hitObject) {
        if (hitObject.startTime >= nextOffset) {
          currentTiming = timingPoints[i++];
          nextOffset = timingPoints[i] ? timingPoints[i].offset : Infinity;
        }
  
        var osupxPerBeat = sliderMultiplier * 100 * currentTiming.velocity;
        var tickLength   = osupxPerBeat / sliderTickRate;
  
        switch (hitObject.objectName) {
          case 'spinner':
          case 'circle':
            maxCombo++;
            break;
          case 'slider':
            var tickPerSide = Math.ceil((Math.floor(hitObject.pixelLength / tickLength * 100) / 100) - 1);
            maxCombo += (hitObject.edges.length - 1) * (tickPerSide + 1) + 1;  // 1 combo for each tick and endpoint
        }
      });
  
      beatmap.maxCombo = maxCombo;
    }
docs: Browse objects and compute max combo