<commit_before>const ExecutableCodeTemplate = require('./executable-fragment.monk');

const CodeMirror = require('codemirror');
require('codemirror/lib/codemirror.css');

require('./executable-fragment.scss');

const Monkberry = require('monkberry');
const directives = require('monkberry-directives').default;
require('monkberry-events');

const $ = require('jquery');

function getExceptionCauses(exception) {
  if (exception.cause !== undefined && exception.cause != null) {
    return [exception.cause].concat(getExceptionCauses(exception.cause))
  } else {
    return []
  }
}

function foldCode(codeMirror, range) {
  return codeMirror.markText(range.from, range.to, {
    collapsed: true
  })
}

function findComment(cm, commentText) {
  for (let line = 0; line < cm.lineCount(); line++) {
    let tokens = cm.getLineTokens(line);
    if (tokens.length > 1) continue;

    let token = tokens[0];
    if (token.type != "comment") continue;

    if (token.string == '//' + commentText) {
      return line
    }
  }
}

function getTopFoldRange(cm) {
  return {
    from: {
      line: 0,
      ch: 0
    },
    to: {
      line: findComment(cm, "sampleStart") + 1,
      ch: 0
    }
  }
}

function getBottomFoldRange(cm) {
  return {
    from: {
      line: findComment(cm, "sampleEnd") - 1,
      ch: null
    },
    to: {
      line: cm.lineCount(),
      ch: 0
    }
  }
}

function unEscapeString(s) {
  const tagsToReplace = {
    "&": "&amp;",
    "<": "&amp;lt;",
    ">": "&amp;gt;",
    " ": "%20"
  };
  let unEscapedString = s;
  Object.keys(tagsToReplace).forEach(function (key) {
    unEscapedString = unEscapedString.replace(tagsToReplace[key], key)
  });
  return unEscapedString
}

class ExecutableFragment extends ExecutableCodeTemplate {
  constructor() {
    super();
    this.arrayClasses = [];
    this.initialized = false;
    this.foldMarkers = [];
    this.state = {
      code: '',
      foldButtonHover: false,
      folded: true,
      output: null,
    };
  }

  static render(element) {
    const instance = Monkberry.render(ExecutableFragment, element, {
      'directives': directives
    });

    instance.on('click', '.fold-button', (event) => {
      instance.update({folded: !instance.state.folded});
    });

    return instance;
  }

  update(state) {
    Object.assign(this.state, state);
    super.update(this.state);

    if (!this.initialized) {
      this.initializeCodeMirror();
      this.initialized = true;

      const commentStartLineNo = findComment(this.codemirror, "sampleStart");
      const commentEndLineNo = findComment(this.codemirror, "sampleEnd");
      this.codemirror.markText({
          line: commentStartLineNo,
          ch: 0
        },
        {
          line: commentStartLineNo,
          ch: null
        },
        {
          readOnly: true
        }
      );
      this.codemirror.markText({
          line: commentEndLineNo,
          ch: 0
        },
        {
          line: commentEndLineNo,
          ch: null
        },
        {
          readOnly: true
        }
      );
    }

    if (this.state.folded) {
      this.foldCode()
    } else {
      this.unfoldCode()
    }
  }

  onFoldButtonMouseEnter(){
    if(!this.state.foldButtonHover){
      this.update({foldButtonHover: true})
    }
  }

  onFoldButtonMouseLeave(){
    if(this.state.foldButtonHover){
      this.update({foldButtonHover: false})
    }
  }

  unfoldCode() {
    this.foldMarkers.forEach((marker) => {
      marker.clear()
    });
    this.foldMarkers = [];
  }

  foldCode() {
    this.foldMarkers.push(foldCode(this.codemirror, getTopFoldRange(this.codemirror)));
    this.foldMarkers.push(foldCode(this.codemirror, getBottomFoldRange(this.codemirror)));
  }

  execute() {
    const projectJson = JSON.stringify({
      "id": "",
      "name": "",
      "args": "",
      "compilerVersion": null,
      "confType": "java",
      "originUrl": null,
      "files": [
        {
          "name": "File.kt",
          "text": this.codemirror.getValue(),
          "publicId": ""<commit_msg>JS-5288: show line numbers if unfolded.<commit_after>const ExecutableCodeTemplate = require('./executable-fragment.monk');

const CodeMirror = require('codemirror');
require('codemirror/lib/codemirror.css');

require('./executable-fragment.scss');

const Monkberry = require('monkberry');
const directives = require('monkberry-directives').default;
require('monkberry-events');

const $ = require('jquery');

function getExceptionCauses(exception) {
  if (exception.cause !== undefined && exception.cause != null) {
    return [exception.cause].concat(getExceptionCauses(exception.cause))
  } else {
    return []
  }
}

function foldCode(codeMirror, range) {
  return codeMirror.markText(range.from, range.to, {
    collapsed: true
  })
}

function findComment(cm, commentText) {
  for (let line = 0; line < cm.lineCount(); line++) {
    let tokens = cm.getLineTokens(line);
    if (tokens.length > 1) continue;

    let token = tokens[0];
    if (token.type != "comment") continue;

    if (token.string == '//' + commentText) {
      return line
    }
  }
}

function getTopFoldRange(cm) {
  return {
    from: {
      line: 0,
      ch: 0
    },
    to: {
      line: findComment(cm, "sampleStart") + 1,
      ch: 0
    }
  }
}

function getBottomFoldRange(cm) {
  return {
    from: {
      line: findComment(cm, "sampleEnd") - 1,
      ch: null
    },
    to: {
      line: cm.lineCount(),
      ch: 0
    }
  }
}

function unEscapeString(s) {
  const tagsToReplace = {
    "&": "&amp;",
    "<": "&amp;lt;",
    ">": "&amp;gt;",
    " ": "%20"
  };
  let unEscapedString = s;
  Object.keys(tagsToReplace).forEach(function (key) {
    unEscapedString = unEscapedString.replace(tagsToReplace[key], key)
  });
  return unEscapedString
}

class ExecutableFragment extends ExecutableCodeTemplate {
  constructor() {
    super();
    this.arrayClasses = [];
    this.initialized = false;
    this.foldMarkers = [];
    this.state = {
      code: '',
      foldButtonHover: false,
      folded: true,
      output: null,
    };
  }

  static render(element) {
    const instance = Monkberry.render(ExecutableFragment, element, {
      'directives': directives
    });

    instance.on('click', '.fold-button', (event) => {
      instance.update({folded: !instance.state.folded});
    });

    return instance;
  }

  update(state) {
    Object.assign(this.state, state);
    super.update(this.state);

    if (!this.initialized) {
      this.initializeCodeMirror();
      this.initialized = true;

      const commentStartLineNo = findComment(this.codemirror, "sampleStart");
      const commentEndLineNo = findComment(this.codemirror, "sampleEnd");
      this.codemirror.markText({
          line: commentStartLineNo,
          ch: 0
        },
        {
          line: commentStartLineNo,
          ch: null
        },
        {
          readOnly: true
        }
      );
      this.codemirror.markText({
          line: commentEndLineNo,
          ch: 0
        },
        {
          line: commentEndLineNo,
          ch: null
        },
        {
          readOnly: true
        }
      );
    }

    if (this.state.folded) {
      this.foldCode()
    } else {
      this.unfoldCode()
    }
  }

  onFoldButtonMouseEnter(){
    if(!this.state.foldButtonHover){
      this.update({foldButtonHover: true})
    }
  }

  onFoldButtonMouseLeave() {
    if (this.state.foldButtonHover) {
      this.update({foldButtonHover: false})
    }
  }

  unfoldCode() {
    this.codemirror.setOption("lineNumbers", true);
    this.foldMarkers.forEach((marker) => {
      marker.clear()
    });
    this.foldMarkers = [];
  }

  foldCode() {
    this.codemirror.setOption("lineNumbers", false);
    this.foldMarkers.push(foldCode(this.codemirror, getTopFoldRange(this.codemirror)));
    this.foldMarkers.push(foldCode(this.codemirror, getBottomFoldRange(this.codemirror)));
  }

  execute() {
    const projectJson = JSON.stringify({
      "id": "",
      "name": "",
      "args": "",
      "compilerVersion": null,
      "confType": "java",
      "originUrl": null,
      "files": [
        {
          "name": "File.kt",
          "text": this.codemirror.getValue(),
          "publicId": ""
{'fraction_non_alphanumeric': 0.14873725109276348, 'fraction_numerical': 0.003642544924720738, 'mean_word_length': 2.518581802648441, 'pattern_counts': {'":': 28, '<': 7, '<?xml version=': 0, '>': 11, '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': '6884020', 'n_tokens_mistral': 2758, 'n_tokens_neox': 2685, 'n_words': 462}