<commit_before>import * as utils from 'base/utils';
import Component from 'base/component';
import globals from 'base/globals';

import Trail from './bubblechart-trail';
import PanZoom from './bubblechart-panzoom';
import Exporter from 'helpers/svgexport';
import axisSmart from 'helpers/d3.axisWithLabelPicker';
import DynamicBackground from 'helpers/d3.dynamicBackground';

import {
  warn as iconWarn,
  question as iconQuestion
}
from 'base/iconset';

//BUBBLE CHART COMPONENT
var BubbleChartComp = Component.extend({

  /**
   * Initializes the component (Bubble Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The options passed to the component
   * @param {Object} context The component's parent
   */
  init: function(config, context) {
    var _this = this;
    this.name = 'bubblechart';
    this.template = 'bubblechart.html';

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "language",
      type: "language"
    }];

    //starts as splash if this is the option
    this._splash = config.ui.splash;

    this.model_binds = {
      'change:time': function(evt, original) {
        if(_this._splash !== _this.model.time.splash) {
          if(!_this._readyOnce) return;
          _this._splash = _this.model.time.splash;
          //TODO: adjust X & Y axis here
        }
      },
      "change:time:record": function() {
        //console.log("change time record");
        if(_this.model.time.record) {
          _this._export.open(this.element, this.name);
        } else {
          _this._export.reset();
        }
      },
      "change:time:trails": function(evt) {
        //console.log("EVENT change:time:trails");
        _this._trails.toggle(_this.model.time.trails);
        _this.redrawDataPoints();
      },
      "change:time:lockNonSelected": function(evt) {
        //console.log("EVENT change:time:lockNonSelected");
        _this.redrawDataPoints(500);
      },
      "change:marker": function(evt) {
        // bubble size change is processed separately
        if(!_this._readyOnce) return;
        if(evt.indexOf("change:marker:size") !== -1) return;
        if(evt.indexOf("change:marker:color:palette") > -1) return;
        if(evt.indexOf("min") > -1 || evt.indexOf("max") > -1) {
          _this.updateSize();
          _this.updateMarkerSizeLimits();
          _this._trails.run("findVisible");
          _this.redrawDataPoints();
          _this._trails.run("resize");
          return;
        }
        if(evt.indexOf("fakeMin") > -1 || evt.indexOf("fakeMax") > -1) {
          if(_this.draggingNow)return;
            _this._panZoom.zoomToMaxMin(
              _this.model.marker.axis_x.fakeMin,
              _this.model.marker.axis_x.fakeMax,
              _this.model.marker.axis_y.fakeMin,
              _this.model.marker.axis_y.fakeMax,
              500
          )
          return;
        }

        if(evt.indexOf("axis_x") > -1 || evt.indexOf("axis_y") > -1) return;

        _this.ready();
        //console.log("EVENT change:marker", evt);
      },
      "change:entities:select": function() {
        if(!_this._readyOnce) return;
        //console.log("EVENT change:entities:select");
        _this.selectDataPoints();
        _this.redrawDataPoints();
        _this._trails.run(["resize", "recolor", "findVisible", "reveal"]);
        _this.updateBubbleOpacity();
        _this._updateDoubtOpacity();
      },
      "change:entities:highlight": function() {
        if(!_this._readyOnce) return;
        //console.log("EVENT change:entities:highlight");
        _this.highlightDataPoints();
      },
      'change:time:value': function() {
        //console.log("EVENT change:time:value");
        _this.updateTime();
        _this._updateDoubtOpacity();

        _this._trails.run("findVisible");
        if(_this.model.time.adaptMinMaxZoom) {
          _this._panZoom.expandCanvas();
        } else {
          _this.redrawDataPoints();
        }
        _this._trails.run("reveal");
        _this.tooltipMobile.classed('vzb-hidden', true);
        //_this._bubblesInteract().mouseout();
      },
      'change:time:adaptMinMaxZoom': function() {
        //console.log("EVENT change:time:adaptMinMaxZoom");
        if(_this.model.time.adaptMinMaxZoom) {
          _this._panZoom.expandCanvas();
        } else {
          _this._panZoom.reset();
        }
      },
      'change:marker:size': function() {
        //console.log("EVENT change:marker:size:max");
        _this.updateMarkerSizeLimits();
        _this._trails.run("findVisible");
        _this.redrawDataPointsOnlySize();
        _this._trails.run("resize");
      },
      'change:marker:color:palette': function() {
        //console.log("EVENT change:marker:color:palette");
        _this.redrawDataPointsOnlyColors();
        _this._trails.run("recolor");
      },
      'change:entities:opacitySelectDim': function() {
        _this.updateBubbleOpacity();
      },
      'change:entities:opacityRegular': function() {
        _this.updateBubbleOpacity();
      }
    };

    this._super(config, context);

    this.xScale = null;
    this.yScale = null;
    this.sScale = null;
    this.cScale = null;

    this.xAxis = axisSmart();
    this.yAxis = axisSmart();


    this.cached = {};
    this.xyMaxMinMean = {};
    this.currentZoomFrameXY = null;
    this.draggingNow = null;

    // default UI settings
    this.ui = utils.extend({
      whenHovering: {},
      labels: {}
    }, this.ui["vzb-tool-" + this.name]);

    this.ui.whenHovering = utils.extend({
      showProjectionLineX: true,
      showProjectionLineY: true,
      higlightValueX: true,
      higlightValueY: true
    }, this.ui.whenHovering);

    this.ui.labels = utils.extend({
      autoResolveCollisions: false,
      dragging: true
    }, this.ui.labels);

    this._trails = new Trail(this);
    this._panZoom = new PanZoom(this);
    this._export = new Exporter(this);
    this._export
      .prefix("vzb-bc-")
      .deleteClasses(["vzb-bc-bubbles-crop", "vzb-hidden", "vzb-bc-year", "vzb-bc-zoom-rect",
        "vzb-bc-projection-x", "vzb-bc-projection-y", "vzb-bc-axis-c-title"
      ]);



    //            this.collisionResolver = d3.svg.collisionResolver()
    //                .value("labelY2")
    //                .fixed("labelFixed")
    //                .selector("text")
    //                .scale(this.yScale)
    //                .handleResult(this._repositionLabels);


    this.labelDragger = d3.behavior.drag()
      .on("dragstart", function(d, i) {
        d3.event.sourceEvent.stopPropagation();
        var KEY = _this.KEY;
        _this.druging = d[KEY];
      })
      .on("drag", function(d, i) {
        var KEY = _this.KEY;
        if(!_this.ui.labels.dragging) return;
        var cache = _this.cached[d[KEY]];
        cache.labelFixed = true;


        cache.labelX_ += d3.event.dx / _this.width;
        cache.labelY_ += d3.event.dy / _this.height;

        var resolvedX = _this.xScale(cache.labelX0) + cache.labelX_ * _this.width;
        var resolvedY = _this.yScale(cache.labelY0) + cache.labelY_ * _this.height;

        var resolvedX0 = _this.xScale(cache.labelX0);
        var resolvedY0 = _this.yScale(cache.labelY0);

        var lineGroup = _this.entityLines.filter(function(f) {
          return f[KEY] == d[KEY];
        });

        _this._repositionLabels(d, i, this, resolvedX, resolvedY, resolvedX0, resolvedY0, 0, lineGroup);
      })
      .on("dragend", function(d, i) {
        var KEY = _this.KEY;
        _this.druging = null;
        _this.model.entities.setLabelOffset(d, [
          _this.cached[d[KEY]].labelX_,
          _this.cached[d[KEY]].labelY_
        ]);
      });



  },




  _rangeBump: function(arg, undo) {
    var bump = this.profiles[this.getLayoutProfile()].maxRadius;
    undo = undo?-1:1;
    if(utils.isArray(arg) && arg.length > 1) {
      var z1 = arg[0];
      var z2 = arg[arg.length - 1];

      //the sign of bump depends on the direction of the scale
      if(z1 < z2) {
        z1 += bump * undo;
        z2 -= bump * undo;
        // if the scale gets inverted because of bump, set it to avg between z1 and z2
        if(z1 > z2) z1 = z2 = (z1 + z2) / 2;
      } else if(z1 > z2) {
        z1 -= bump * undo;
        z2 += bump * undo;
        // if the scale gets inverted because of bump, set it to avg between z1 and z2
        if(z1 < z2) z1 = z2 = (z1 + z2) / 2;
      } else {
        utils.warn("rangeBump error: the input scale range has 0 length. that sucks");
      }
      return [z1, z2];
    } else {
      utils.warn("rangeBump error: input is not an array or empty");
    }
  },

//  _marginUnBump: function(arg) {
//    var bump = this.profiles[this.getLayoutProfile()].maxRadius;
//    if(utils.isObject(arg)) {
//      return {
//        left: arg.left - bump,
//        right: arg.right - bump,
//        top: arg.top - bump,
//        bottom: arg.bottom - bump
//      };
//    } else {
//      utils.warn("marginUnBump error: input is not an object {left top bottom right}");
//    }
//  },


  /**
   * Executes right after the template is in place, but the model is not yet ready
   */
  readyOnce: function() {
    var _this = this;

    this.scrollableAncestor = utils.findScrollableAncestor(this.element);
    this.element = d3.select(this.element);

    // reference elements
    this.graph = this.element.select('.vzb-bc-graph');
    this.yAxisElContainer = this.graph.select('.vzb-bc-axis-y');
    this.yAxisEl = this.yAxisElContainer.select('g');

    this.xAxisElContainer = this.graph.select('.vzb-bc-axis-x');
    this.xAxisEl = this.xAxisElContainer.select('g');

    this.yTitleEl = this.graph.select('.vzb-bc-axis-y-title');
    this.xTitleEl = this.graph.select('.vzb-bc-axis-x-title');
    this.sTitleEl = this.graph.select('.vzb-bc-axis-s-title');
    this.cTitleEl = this.graph.select('.vzb-bc-axis-c-title');
    this.yearEl = this.graph.select('.vzb-bc-year');

    this.year = new DynamicBackground(this.yearEl);

    this.yInfoEl = this.graph.select('.vzb-bc-axis-y-info');
    this.xInfoEl = this.graph.select('.vzb-bc-axis-x-info');
    this.dataWarningEl = this.graph.select('.vzb-data-warning');

    this.projectionX = this.graph.select(".vzb-bc-projection-x");
    this.projectionY = this.graph.select(".vzb-bc-projection-y");

    this.trailsContainer = this.graph.select('.vzb-bc-trails');
    this.bubbleContainerCrop = this.graph.select('.vzb-bc-bubbles-crop');
    this.bubbleContainer = this.graph.select('.vzb-bc-bubbles');
    this.labelsContainer = this.graph.select('.vzb-bc-labels');
    this.linesContainer = this.graph.select('.vzb-bc-lines');
    this.zoomRect = this.element.select('.vzb-bc-zoom-rect');
    this.eventArea = this.element.select('.vzb-bc-eventarea');

    this.entityBubbles = null;
    this.entityLabels = null;
    this.tooltip = this.element.select('.vzb-bc-tooltip');
    this.tooltipMobile = this.element.select('.vzb-tooltip-mobile');
    this.entityLines = null;
    //component events
    this.on("resize", function() {
      //console.log("EVENT: resize");
      _this.updateSize();
      _this.updateMarkerSizeLimits();
      _this._trails.run("findVisible");
      _this._panZoom.reset(); // includes redraw data points and trail resize
    });

    //keyboard listeners
    d3.select("body")
      .on("keydown", function() {
        if(d3.event.metaKey || d3.event.ctrlKey) _this.element.select("svg").classed("vzb-zoomin", true);
      })
      .on("keyup", function() {
        if(!d3.event.metaKey && !d3.event.ctrlKey) _this.element.select("svg").classed("vzb-zoomin", false);
      });

    this.bubbleContainerCrop
      .call(this._panZoom.zoomer)
      .call(this._panZoom.dragRectangle)
      .on("mouseup", function() {
        _this.draggingNow = false;
      })
      .onTap(function() {
        return;
        _this._bubblesInteract().mouseout();
        _this.tooltipMobile.classed('vzb-hidden', true);
      });

    this.KEY = this.model.entities.getDimension();
    this.TIMEDIM = this.model.time.getDimension();

    this._calculateAllValues();
    this._valuesCalculated = true; //hack to avoid recalculation<commit_msg>Disable double click zoom. Fixes #690<commit_after>import * as utils from 'base/utils';
import Component from 'base/component';
import globals from 'base/globals';

import Trail from './bubblechart-trail';
import PanZoom from './bubblechart-panzoom';
import Exporter from 'helpers/svgexport';
import axisSmart from 'helpers/d3.axisWithLabelPicker';
import DynamicBackground from 'helpers/d3.dynamicBackground';

import {
  warn as iconWarn,
  question as iconQuestion
}
from 'base/iconset';

//BUBBLE CHART COMPONENT
var BubbleChartComp = Component.extend({

  /**
   * Initializes the component (Bubble Chart).
   * Executed once before any template is rendered.
   * @param {Object} config The options passed to the component
   * @param {Object} context The component's parent
   */
  init: function(config, context) {
    var _this = this;
    this.name = 'bubblechart';
    this.template = 'bubblechart.html';

    //define expected models for this component
    this.model_expects = [{
      name: "time",
      type: "time"
    }, {
      name: "entities",
      type: "entities"
    }, {
      name: "marker",
      type: "model"
    }, {
      name: "language",
      type: "language"
    }];

    //starts as splash if this is the option
    this._splash = config.ui.splash;

    this.model_binds = {
      'change:time': function(evt, original) {
        if(_this._splash !== _this.model.time.splash) {
          if(!_this._readyOnce) return;
          _this._splash = _this.model.time.splash;
          //TODO: adjust X & Y axis here
        }
      },
      "change:time:record": function() {
        //console.log("change time record");
        if(_this.model.time.record) {
          _this._export.open(this.element, this.name);
        } else {
          _this._export.reset();
        }
      },
      "change:time:trails": function(evt) {
        //console.log("EVENT change:time:trails");
        _this._trails.toggle(_this.model.time.trails);
        _this.redrawDataPoints();
      },
      "change:time:lockNonSelected": function(evt) {
        //console.log("EVENT change:time:lockNonSelected");
        _this.redrawDataPoints(500);
      },
      "change:marker": function(evt) {
        // bubble size change is processed separately
        if(!_this._readyOnce) return;
        if(evt.indexOf("change:marker:size") !== -1) return;
        if(evt.indexOf("change:marker:color:palette") > -1) return;
        if(evt.indexOf("min") > -1 || evt.indexOf("max") > -1) {
          _this.updateSize();
          _this.updateMarkerSizeLimits();
          _this._trails.run("findVisible");
          _this.redrawDataPoints();
          _this._trails.run("resize");
          return;
        }
        if(evt.indexOf("fakeMin") > -1 || evt.indexOf("fakeMax") > -1) {
          if(_this.draggingNow)return;
            _this._panZoom.zoomToMaxMin(
              _this.model.marker.axis_x.fakeMin,
              _this.model.marker.axis_x.fakeMax,
              _this.model.marker.axis_y.fakeMin,
              _this.model.marker.axis_y.fakeMax,
              500
          )
          return;
        }

        if(evt.indexOf("axis_x") > -1 || evt.indexOf("axis_y") > -1) return;

        _this.ready();
        //console.log("EVENT change:marker", evt);
      },
      "change:entities:select": function() {
        if(!_this._readyOnce) return;
        //console.log("EVENT change:entities:select");
        _this.selectDataPoints();
        _this.redrawDataPoints();
        _this._trails.run(["resize", "recolor", "findVisible", "reveal"]);
        _this.updateBubbleOpacity();
        _this._updateDoubtOpacity();
      },
      "change:entities:highlight": function() {
        if(!_this._readyOnce) return;
        //console.log("EVENT change:entities:highlight");
        _this.highlightDataPoints();
      },
      'change:time:value': function() {
        //console.log("EVENT change:time:value");
        _this.updateTime();
        _this._updateDoubtOpacity();

        _this._trails.run("findVisible");
        if(_this.model.time.adaptMinMaxZoom) {
          _this._panZoom.expandCanvas();
        } else {
          _this.redrawDataPoints();
        }
        _this._trails.run("reveal");
        _this.tooltipMobile.classed('vzb-hidden', true);
        //_this._bubblesInteract().mouseout();
      },
      'change:time:adaptMinMaxZoom': function() {
        //console.log("EVENT change:time:adaptMinMaxZoom");
        if(_this.model.time.adaptMinMaxZoom) {
          _this._panZoom.expandCanvas();
        } else {
          _this._panZoom.reset();
        }
      },
      'change:marker:size': function() {
        //console.log("EVENT change:marker:size:max");
        _this.updateMarkerSizeLimits();
        _this._trails.run("findVisible");
        _this.redrawDataPointsOnlySize();
        _this._trails.run("resize");
      },
      'change:marker:color:palette': function() {
        //console.log("EVENT change:marker:color:palette");
        _this.redrawDataPointsOnlyColors();
        _this._trails.run("recolor");
      },
      'change:entities:opacitySelectDim': function() {
        _this.updateBubbleOpacity();
      },
      'change:entities:opacityRegular': function() {
        _this.updateBubbleOpacity();
      }
    };

    this._super(config, context);

    this.xScale = null;
    this.yScale = null;
    this.sScale = null;
    this.cScale = null;

    this.xAxis = axisSmart();
    this.yAxis = axisSmart();


    this.cached = {};
    this.xyMaxMinMean = {};
    this.currentZoomFrameXY = null;
    this.draggingNow = null;

    // default UI settings
    this.ui = utils.extend({
      whenHovering: {},
      labels: {}
    }, this.ui["vzb-tool-" + this.name]);

    this.ui.whenHovering = utils.extend({
      showProjectionLineX: true,
      showProjectionLineY: true,
      higlightValueX: true,
      higlightValueY: true
    }, this.ui.whenHovering);

    this.ui.labels = utils.extend({
      autoResolveCollisions: false,
      dragging: true
    }, this.ui.labels);

    this._trails = new Trail(this);
    this._panZoom = new PanZoom(this);
    this._export = new Exporter(this);
    this._export
      .prefix("vzb-bc-")
      .deleteClasses(["vzb-bc-bubbles-crop", "vzb-hidden", "vzb-bc-year", "vzb-bc-zoom-rect",
        "vzb-bc-projection-x", "vzb-bc-projection-y", "vzb-bc-axis-c-title"
      ]);



    //            this.collisionResolver = d3.svg.collisionResolver()
    //                .value("labelY2")
    //                .fixed("labelFixed")
    //                .selector("text")
    //                .scale(this.yScale)
    //                .handleResult(this._repositionLabels);


    this.labelDragger = d3.behavior.drag()
      .on("dragstart", function(d, i) {
        d3.event.sourceEvent.stopPropagation();
        var KEY = _this.KEY;
        _this.druging = d[KEY];
      })
      .on("drag", function(d, i) {
        var KEY = _this.KEY;
        if(!_this.ui.labels.dragging) return;
        var cache = _this.cached[d[KEY]];
        cache.labelFixed = true;


        cache.labelX_ += d3.event.dx / _this.width;
        cache.labelY_ += d3.event.dy / _this.height;

        var resolvedX = _this.xScale(cache.labelX0) + cache.labelX_ * _this.width;
        var resolvedY = _this.yScale(cache.labelY0) + cache.labelY_ * _this.height;

        var resolvedX0 = _this.xScale(cache.labelX0);
        var resolvedY0 = _this.yScale(cache.labelY0);

        var lineGroup = _this.entityLines.filter(function(f) {
          return f[KEY] == d[KEY];
        });

        _this._repositionLabels(d, i, this, resolvedX, resolvedY, resolvedX0, resolvedY0, 0, lineGroup);
      })
      .on("dragend", function(d, i) {
        var KEY = _this.KEY;
        _this.druging = null;
        _this.model.entities.setLabelOffset(d, [
          _this.cached[d[KEY]].labelX_,
          _this.cached[d[KEY]].labelY_
        ]);
      });



  },




  _rangeBump: function(arg, undo) {
    var bump = this.profiles[this.getLayoutProfile()].maxRadius;
    undo = undo?-1:1;
    if(utils.isArray(arg) && arg.length > 1) {
      var z1 = arg[0];
      var z2 = arg[arg.length - 1];

      //the sign of bump depends on the direction of the scale
      if(z1 < z2) {
        z1 += bump * undo;
        z2 -= bump * undo;
        // if the scale gets inverted because of bump, set it to avg between z1 and z2
        if(z1 > z2) z1 = z2 = (z1 + z2) / 2;
      } else if(z1 > z2) {
        z1 -= bump * undo;
        z2 += bump * undo;
        // if the scale gets inverted because of bump, set it to avg between z1 and z2
        if(z1 < z2) z1 = z2 = (z1 + z2) / 2;
      } else {
        utils.warn("rangeBump error: the input scale range has 0 length. that sucks");
      }
      return [z1, z2];
    } else {
      utils.warn("rangeBump error: input is not an array or empty");
    }
  },

//  _marginUnBump: function(arg) {
//    var bump = this.profiles[this.getLayoutProfile()].maxRadius;
//    if(utils.isObject(arg)) {
//      return {
//        left: arg.left - bump,
//        right: arg.right - bump,
//        top: arg.top - bump,
//        bottom: arg.bottom - bump
//      };
//    } else {
//      utils.warn("marginUnBump error: input is not an object {left top bottom right}");
//    }
//  },


  /**
   * Executes right after the template is in place, but the model is not yet ready
   */
  readyOnce: function() {
    var _this = this;

    this.scrollableAncestor = utils.findScrollableAncestor(this.element);
    this.element = d3.select(this.element);

    // reference elements
    this.graph = this.element.select('.vzb-bc-graph');
    this.yAxisElContainer = this.graph.select('.vzb-bc-axis-y');
    this.yAxisEl = this.yAxisElContainer.select('g');

    this.xAxisElContainer = this.graph.select('.vzb-bc-axis-x');
    this.xAxisEl = this.xAxisElContainer.select('g');

    this.yTitleEl = this.graph.select('.vzb-bc-axis-y-title');
    this.xTitleEl = this.graph.select('.vzb-bc-axis-x-title');
    this.sTitleEl = this.graph.select('.vzb-bc-axis-s-title');
    this.cTitleEl = this.graph.select('.vzb-bc-axis-c-title');
    this.yearEl = this.graph.select('.vzb-bc-year');

    this.year = new DynamicBackground(this.yearEl);

    this.yInfoEl = this.graph.select('.vzb-bc-axis-y-info');
    this.xInfoEl = this.graph.select('.vzb-bc-axis-x-info');
    this.dataWarningEl = this.graph.select('.vzb-data-warning');

    this.projectionX = this.graph.select(".vzb-bc-projection-x");
    this.projectionY = this.graph.select(".vzb-bc-projection-y");

    this.trailsContainer = this.graph.select('.vzb-bc-trails');
    this.bubbleContainerCrop = this.graph.select('.vzb-bc-bubbles-crop');
    this.bubbleContainer = this.graph.select('.vzb-bc-bubbles');
    this.labelsContainer = this.graph.select('.vzb-bc-labels');
    this.linesContainer = this.graph.select('.vzb-bc-lines');
    this.zoomRect = this.element.select('.vzb-bc-zoom-rect');
    this.eventArea = this.element.select('.vzb-bc-eventarea');

    this.entityBubbles = null;
    this.entityLabels = null;
    this.tooltip = this.element.select('.vzb-bc-tooltip');
    this.tooltipMobile = this.element.select('.vzb-tooltip-mobile');
    this.entityLines = null;
    //component events
    this.on("resize", function() {
      //console.log("EVENT: resize");
      _this.updateSize();
      _this.updateMarkerSizeLimits();
      _this._trails.run("findVisible");
      _this._panZoom.reset(); // includes redraw data points and trail resize
    });

    //keyboard listeners
    d3.select("body")
      .on("keydown", function() {
        if(d3.event.metaKey || d3.event.ctrlKey) _this.element.select("svg").classed("vzb-zoomin", true);
      })
      .on("keyup", function() {
        if(!d3.event.metaKey && !d3.event.ctrlKey) _this.element.select("svg").classed("vzb-zoomin", false);
      });

    this.bubbleContainerCrop
      .call(this._panZoom.zoomer)
      .call(this._panZoom.dragRectangle)
      .on('dblclick.zoom', null) 
      .on("mouseup", function() {
        _this.draggingNow = false;
      })
      .onTap(function() {
        return;
        _this._bubblesInteract().mouseout();
        _this.tooltipMobile.classed('vzb-hidden', true);
      });

    this.KEY = this.model.entities.getDimension();
    this.TIMEDIM = this.model.time.getDimension();

    this._calculateAllValues();
    this._valuesCalculated = true; //hack to avoid recalculation
{'fraction_non_alphanumeric': 0.15280690433940958, 'fraction_numerical': 0.0060090337151153415, 'mean_word_length': 2.394989047097481, 'pattern_counts': {'":': 12, '<': 7, '<?xml version=': 0, '>': 23, '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': '6807542', 'n_tokens_mistral': 8189, 'n_tokens_neox': 8061, 'n_words': 1398}