<commit_before>class TabPaper {
  constructor(title = "Untitled", event = null, w = 900, h = 900 * 1.41, bps = 4, bl = 4, lw = 840, lh = 140) {
    this.width = w;
    this.height = h;
    this.lineHeight = lh;
    this.lineWidth = lw;
    this.beatLength = bl;
    this.beatPerSection = bps;
    this.vHTML = "";
    this.scale = 1;
    this.content = document.createElement("div");
    this.content.style.outline = "none";
    this.inputing = 0;
	this.displayer=null;
	this.manager=null;
    this.content.onselectstart = function() {
      return false;
    };
    this.defaultNoteLength = 4;
    this.st = 0; //scroll top ,just record, will not cause any effect if be changed
    this.sl = 0; //scroll left
    this.dragStart = null;
    this.content.setAttribute("tabindex", "1");
    this.content.addEventListener("mousedown", this.mdEvent.bind(this));
    this.content.addEventListener("mousemove", this.mvEvent.bind(this));
    this.content.addEventListener("mouseup", this.muEvent.bind(this));
    this.content.addEventListener("click", this.ckEvent.bind(this));
    this.content.addEventListener("keydown", this.kdEvent.bind(this));
    this.content.addEventListener("keypress", this.kpEvent.bind(this));
    this.event = event != null
      ? event
      : {
          cursormove: null
        };
    this.data = null;
    this.title = title;
    this.selectedNotes = [];
    this.selectedDoms = [];
    this.cursor = [0, 0, 1];
    this.playingCursor = [0, 0];
    this.check();
    Math.clamp = function(number, min, max) {
      return Math.max(min, Math.min(number, max));
    };
  }
  check() {
    if (this.width < 500) this.width = 500;
    if (this.height < 500) this.height = 500;
    if (this.lineHeight > 300) this.lineHeight = 120;
    if (this.lineWidth > this.width) this.lineWidth = this.width - 60;
  }

  partialRender(line) {
    let vobj = {
      vHTML: "",
      cursor: this.cursor,
      lineHeight: this.lineHeight,
      lineWidth: this.lineWidth,
      beatLength: this.beatLength,
      beatPerSection: this.beatPerSection
    };
    let targetElement = document.getElementById("line_" + line);
    if (!targetElement) {
      this.render();
      return;
    }
    let ix = Number(targetElement.getAttribute("ix")),
      iy = Number(targetElement.getAttribute("iy"));

    let notes_four_sections = 0;
    var tie_begin_ix = -1
    var calc_beats = function(beatLength, arr) {
      var ret = 0;
      for (let i = 0; i < arr.length; i++) ret += beatLength / arr[i][0];
      return ret;
    };
    for (let i = line * 4; i < line * 4 + 4 && i < this.data.length; i++) {
      if (i % 4 == 0) {
        notes_four_sections = 0;
        for (let j = i; j < i + 4; j++) {
          if (j < this.data.length) notes_four_sections += Math.clamp(this.data[j].length, 4, 6);
          else notes_four_sections += 4;
        }
      }
      var section_width = (this.lineWidth - 80) * (Math.clamp(this.data[i].length, 4, 6) / notes_four_sections);
      var beats = calc_beats(this.beatLength, this.data[i]);
      var beat_width = Math.min(section_width / beats, (this.lineWidth - 80) / (this.beatPerSection * 4));
      var oix = ix;
      var actual_section_width = beat_width * beats;

      ix += (section_width - actual_section_width) / 2;

      // draw note background first
      let tix = ix;
      for (let j = 0; j < this.data[i].length; j++) {
        tix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
        this.drawNoteBackground.call(vobj, tix, iy, this.data[i][j].slice(1));
        tix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
      }

      var pos = vobj.vHTML.length - 1;
      if(this.data[i] == [[4, -1]])
        this.drawFakeElement.call(vobj, ix, iy, i);
      for (let j = 0; j < this.data[i].length; j++) {
        ix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
        if (i == this.cursor[0] && j == this.cursor[1] && !this.hideCursor) this.drawCursor.call(vobj, ix, iy);
        if (i == this.playingCursor[0] && j == this.playingCursor[1] && this.hideCursor) this.drawPlayingCursor.call(vobj, ix, iy);
        this.drawNote.call(vobj, ix, iy, i, j, this.data[i][j][0], this.data[i][j].slice(1));
        if(this.data[i][j][this.data[i][j].length-1]=='c' && tie_begin_ix==-1) {
          tie_begin_ix = ix;
        }
        if(this.data[i][j][this.data[i][j].length-1]=='e') {
          if(tie_begin_ix == -1)
            tie_begin_ix = ix;
          this.drawTiePath.call(vobj, tie_begin_ix, ix, iy);
          tie_begin_ix = -1;
        }
        ix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
      }
      ix = oix + section_width;
      if (beats != this.beatPerSection && this.cursor[0] != i ) this.drawAlert.call(vobj, ix - section_width, iy, section_width, pos);
      if (i % 4 != 3) this.drawBar.call(vobj, ix, iy);
    }
    targetElement.innerHTML = vobj.vHTML;
  }

  isInserting() {
    return this.data[this.cursor[0]][this.cursor[1]][1] == -1;
  } 
  
  isInsertingTab() {
    return this.data[this.cursor[0]].length == 1 && this.isInserting();
  }
  drawSectionMark(ix,iy,s){
	  this.vHTML+=`<text x="${ix}" y="${iy}" fill="black" font-size="12">section ${s}</text>`;
  }
  render() {
    var checkY = function() {
      if (iy + 130 > this.height) {
		this.height+=this.lineHeight;
      }
    }.bind(this);
    let nx = (this.width - this.lineWidth) / 2,
      ix = nx,
      iy = 80;
    if (!this.data) {
	  this.drawSectionMark(ix,iy-10,1);
      this.drawLine(ix, iy);
      this.vHTML =
        `<div style="overflow:hidden;padding:3px;padding-top:20px;" id='pg0'>
			<svg width="${this.width}" height="${this.height}" 
			style="background:#FFFFFF">${note_svg.notes}` +
        this.vHTML +
        "</svg></div>";
      this.content.innerHTML = this.vHTML;
      this.zoom();
      return;
    }
	
    this.drawTitle(ix, iy);
    iy += 40;
	this.drawSectionMark(ix,iy-10,1);
    this.drawLine(ix, iy, true);
    ix += 80;

    var note_distance = 80;
    var distance_ratio = 1.0;
    var notes_four_sections = 0;
    var tie_begin_ix = -1;
    var calc_beats = function(beatLength, arr) {
      var ret = 0;
      for (let i = 0; i < arr.length; i++) ret += beatLength / arr[i][0];
      return ret;
    };
    for (let i = 0; i < this.data.length; i++) {
      // estimate note  section

      if (i % 4 == 0) {
        this.vHTML += `<svg class="tab_line" id='line_${i / 4}' ix=${ix} iy=${iy}>`;
        notes_four_sections = 0;
        for (let j = i; j < i + 4; j++) {
          if (j < this.data.length) notes_four_sections += Math.clamp(this.data[j].length, 4, 6);
          else notes_four_sections += 4;
        }
      }

      var section_width = (this.lineWidth - 80) * (Math.clamp(this.data[i].length, 4, 6) / notes_four_sections);
      var beats = calc_beats(this.beatLength, this.data[i]);
      var beat_width = Math.min(section_width / beats, (this.lineWidth - 80) / (this.beatPerSection * 4));
      var oix = ix;
      var actual_section_width = beat_width * beats;

      ix += (section_width - actual_section_width) / 2;

      // draw note background first
      let tix = ix;
      for (let j = 0; j < this.data[i].length; j++) {
        tix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
        this.drawNoteBackground(tix, iy, this.data[i][j].slice(1));
        tix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
      }
<commit_msg>Change render algorithm<commit_after>class TabPaper {
  constructor(title = "Untitled", event = null, w = 900, h = 900 * 1.41, bps = 4, bl = 4, lw = 840, lh = 140) {
    this.width = w;
    this.height = h;
    this.lineHeight = lh;
    this.lineWidth = lw;
    this.beatLength = bl;
    this.beatPerSection = bps;
    this.vHTML = "";
    this.scale = 1;
    this.content = document.createElement("div");
    this.content.style.outline = "none";
    this.inputing = 0;
	this.displayer=null;
	this.manager=null;
    this.content.onselectstart = function() {
      return false;
    };
    this.defaultNoteLength = 4;
    this.st = 0; //scroll top ,just record, will not cause any effect if be changed
    this.sl = 0; //scroll left
    this.dragStart = null;
    this.content.setAttribute("tabindex", "1");
    this.content.addEventListener("mousedown", this.mdEvent.bind(this));
    this.content.addEventListener("mousemove", this.mvEvent.bind(this));
    this.content.addEventListener("mouseup", this.muEvent.bind(this));
    this.content.addEventListener("click", this.ckEvent.bind(this));
    this.content.addEventListener("keydown", this.kdEvent.bind(this));
    this.content.addEventListener("keypress", this.kpEvent.bind(this));
    this.event = event != null
      ? event
      : {
          cursormove: null
        };
    this.data = null;
    this.title = title;
    this.selectedNotes = [];
    this.selectedDoms = [];
    this.cursor = [0, 0, 1];
    this.playingCursor = [0, 0];
    this.check();
    Math.clamp = function(number, min, max) {
      return Math.max(min, Math.min(number, max));
    };
  }
  check() {
    if (this.width < 500) this.width = 500;
    if (this.height < 500) this.height = 500;
    if (this.lineHeight > 300) this.lineHeight = 120;
    if (this.lineWidth > this.width) this.lineWidth = this.width - 60;
  }

  partialRender(line) {
    let vobj = {
      vHTML: "",
      cursor: this.cursor,
      lineHeight: this.lineHeight,
      lineWidth: this.lineWidth,
      beatLength: this.beatLength,
      beatPerSection: this.beatPerSection
    };
    let targetElement = document.getElementById("line_" + line);
    if (!targetElement) {
      this.render();
      return;
    }
    let ix = Number(targetElement.getAttribute("ix")),
      iy = Number(targetElement.getAttribute("iy"));

    let notes_four_sections = 0;
    var tie_begin_ix = -1
    var calc_beats = function(beatLength, arr) {
      var ret = 0;
      for (let i = 0; i < arr.length; i++) ret += beatLength / arr[i][0];
      return ret;
    };
    for (let i = line * 4; i < line * 4 + 4 && i < this.data.length; i++) {
      if (i % 4 == 0) {
        notes_four_sections = 0;
        for (let j = i; j < i + 4; j++) {
          if (j < this.data.length) notes_four_sections += Math.clamp(this.data[j].length, 4, 6);
          else notes_four_sections += 4;
        }
      }
      var section_width = (this.lineWidth - 80) * (Math.clamp(this.data[i].length, 4, 6) / notes_four_sections);
      var beats = calc_beats(this.beatLength, this.data[i]);
      var beat_width = section_width / beats;

      let tix=ix;
      for (let j = 0; j < this.data[i].length; j++) {
        tix += beat_width * (this.beatLength / this.data[i][j][0]);
      }
      beat_width = section_width/(tix-ix)*beat_width;

      var oix = ix;
      var actual_section_width = beat_width * beats;

      ix += (section_width - actual_section_width) / 2;

      // draw note background first
      tix = ix;
      for (let j = 0; j < this.data[i].length; j++) {
        tix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
        this.drawNoteBackground.call(vobj, tix, iy, this.data[i][j].slice(1));
        tix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
      }

      var pos = vobj.vHTML.length - 1;
      if(this.data[i] == [[4, -1]])
        this.drawFakeElement.call(vobj, ix, iy, i);
      for (let j = 0; j < this.data[i].length; j++) {
        ix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
        if (i == this.cursor[0] && j == this.cursor[1] && !this.hideCursor) this.drawCursor.call(vobj, ix, iy);
        if (i == this.playingCursor[0] && j == this.playingCursor[1] && this.hideCursor) this.drawPlayingCursor.call(vobj, ix, iy);
        this.drawNote.call(vobj, ix, iy, i, j, this.data[i][j][0], this.data[i][j].slice(1));
        if(this.data[i][j][this.data[i][j].length-1]=='c' && tie_begin_ix==-1) {
          tie_begin_ix = ix;
        }
        if(this.data[i][j][this.data[i][j].length-1]=='e') {
          if(tie_begin_ix == -1)
            tie_begin_ix = ix;
          this.drawTiePath.call(vobj, tie_begin_ix, ix, iy);
          tie_begin_ix = -1;
        }
        ix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
      }
      ix = oix + section_width;
      if (beats != this.beatPerSection && this.cursor[0] != i ) this.drawAlert.call(vobj, ix - section_width, iy, section_width, pos);
      if (i % 4 != 3) this.drawBar.call(vobj, ix, iy);
    }
    targetElement.innerHTML = vobj.vHTML;
  }

  isInserting() {
    return this.data[this.cursor[0]][this.cursor[1]][1] == -1;
  } 
  
  isInsertingTab() {
    return this.data[this.cursor[0]].length == 1 && this.isInserting();
  }
  drawSectionMark(ix,iy,s){
	  this.vHTML+=`<text x="${ix}" y="${iy}" fill="black" font-size="12">section ${s}</text>`;
  }
  render() {
    var checkY = function() {
      if (iy + 130 > this.height) {
		this.height+=this.lineHeight;
      }
    }.bind(this);
    let nx = (this.width - this.lineWidth) / 2,
      ix = nx,
      iy = 80;
    if (!this.data) {
	  this.drawSectionMark(ix,iy-10,1);
      this.drawLine(ix, iy);
      this.vHTML =
        `<div style="overflow:hidden;padding:3px;padding-top:20px;" id='pg0'>
			<svg width="${this.width}" height="${this.height}" 
			style="background:#FFFFFF">${note_svg.notes}` +
        this.vHTML +
        "</svg></div>";
      this.content.innerHTML = this.vHTML;
      this.zoom();
      return;
    }
	
    this.drawTitle(ix, iy);
    iy += 40;
	this.drawSectionMark(ix,iy-10,1);
    this.drawLine(ix, iy, true);
    ix += 80;

    var note_distance = 80;
    var distance_ratio = 1.0;
    var notes_four_sections = 0;
    var tie_begin_ix = -1;
    var calc_beats = function(beatLength, arr) {
      var ret = 0;
      for (let i = 0; i < arr.length; i++) ret += beatLength / arr[i][0];
      return ret;
    };
    for (let i = 0; i < this.data.length; i++) {
      // estimate note  section

      if (i % 4 == 0) {
        this.vHTML += `<svg class="tab_line" id='line_${i / 4}' ix=${ix} iy=${iy}>`;
        notes_four_sections = 0;
        for (let j = i; j < i + 4; j++) {
          if (j < this.data.length) notes_four_sections += Math.clamp(this.data[j].length, 4, 6);
          else notes_four_sections += 4;
        }
      }

      var section_width = (this.lineWidth - 80) * (Math.clamp(this.data[i].length, 4, 6) / notes_four_sections);
      var beats = calc_beats(this.beatLength, this.data[i]);
      var beat_width = Math.min(section_width / beats);

      let tix=ix;
      for (let j = 0; j < this.data[i].length; j++) {
        tix += beat_width * (this.beatLength / this.data[i][j][0]);
      }
      beat_width = section_width/(tix-ix)*beat_width;

      var oix = ix;
      var actual_section_width = beat_width * beats;

      ix += (section_width - actual_section_width) / 2;

      // draw note background first
      tix = ix;
      for (let j = 0; j < this.data[i].length; j++) {
        tix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
        this.drawNoteBackground(tix, iy, this.data[i][j].slice(1));
        tix += beat_width * (this.beatLength / this.data[i][j][0]) / 2;
      }

{'fraction_non_alphanumeric': 0.17092609669345277, 'fraction_numerical': 0.020814121986563034, 'mean_word_length': 2.511332099907493, 'pattern_counts': {'":': 0, '<': 47, '<?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': '5268317', 'n_tokens_mistral': 5749, 'n_tokens_neox': 5394, 'n_words': 1150}