<commit_before>const SVG   = require('./utils/svg')();
const sh    = require('kool-shell');

function Job(jobName, config) {

  let buffer = ['\n', '\0'];
  let penIsUp = true;

  const api = {
    // DEPRECATED
    // callback: function(){},
    getName() { return jobName; },
    getBuffer() { return [...buffer]; },
    setBuffer(_buffer) {
      buffer = _buffer;
      return api;
    },

    addToBuffer(message) {
      // insert the message into the buffer before the last two commands \n and \0
      // \n is required by the firmware to launch the previous commands
      // \0 tells the firmware when the buffer ends
      buffer.splice(-2, 0, message);
      return api;
    },

    // -------------------------------------------------------------------------
    // SETUP COMMANDS

    setSpeed(speedPercent) {
      if (speedPercent) {
        let maxDelay = 1000; // ms
        let securityMinDelay = 100; // ms
        if (speedPercent > 1) {
          sh.warning(`Speed value must be between 0 and 1.`);
          speedPercent = Math.min(1, speedPercent);
        }
        let speed = securityMinDelay + maxDelay - (maxDelay * speedPercent);
        api.addToBuffer(`S1 ${speed}`);
      } else api.resetSpeed();
      return api;
    },

    resetSpeed() {
      api.addToBuffer(`S0`);
      return api;
    },

    drawBoundaries() {
      api
        .home()
        .pen_down()
        .setSpeed(.8)
        // FIXME : the plotter can't go from 0 to HEIGHT in one move (???)
        .move(0, config.height / 2)
        .move(0, config.height)
        .move(config.width, config.height)
        .move(config.width, config.height / 2)
        .move(config.width, 0)
        .move(0, 0)
        .resetSpeed();
      return api;
    },

    // -------------------------------------------------------------------------
    // UTILS COMMANDS

    home() {
      api
        .pen_up()
        .resetSpeed();
      api.addToBuffer('G28');
      return api;
    },

    // TODO : find a way to get the value
    getPosition() {
      api.addToBuffer('P');
      return api;
    },

    wait(promise) {
      function waitForIt() {
        return sh.question('Waiting... press enter to continue.', () => { return true; });
      }
      api.addToBuffer(promise || waitForIt);
      return api;
    },

    // DEPRECATED : a callback can now be called at the end of a job
    // with the promises, see serial.js
    // end(_callback) {
    //   // send a last command before disconnect
    //   // to ensure that the prev command is executed
    //   // by the plotter's firmware
    //   api.addToBuffer('\n');
    //   api.addToBuffer(-1);
    //   api.callback = _callback;
    //   return api;
    // },

    // -------------------------------------------------------------------------
    // PEN COMMANDS

    move(x, y) {
      x = round(x, config.decimals || 3);
      y = round(y, config.decimals || 3);

      // if the plotter is in portrait, swap x and y
      if (config.width / config.height > 1) {
        let t = x;
        x = y;
        y = t;
      }

      if (x < 0 || x > config.width || y < 0 || y > config.height) {
        sh.warning(`G1 X${x} Y${y} : position will be outside plotter's boundaries.`);<commit_msg>job: only one warning when outside boundaries<commit_after>const SVG   = require('./utils/svg')();
const sh    = require('kool-shell');

function Job(jobName, config) {

  let buffer = ['\n', '\0'];
  let penIsUp = true;
  let alreadyWarned = false;

  const api = {
    // DEPRECATED
    // callback: function(){},
    getName() { return jobName; },
    getBuffer() { return [...buffer]; },
    setBuffer(_buffer) {
      buffer = _buffer;
      return api;
    },

    addToBuffer(message) {
      // insert the message into the buffer before the last two commands \n and \0
      // \n is required by the firmware to launch the previous commands
      // \0 tells the firmware when the buffer ends
      buffer.splice(-2, 0, message);
      return api;
    },

    // -------------------------------------------------------------------------
    // SETUP COMMANDS

    setSpeed(speedPercent) {
      if (speedPercent) {
        let maxDelay = 1000; // ms
        let securityMinDelay = 100; // ms
        if (speedPercent > 1) {
          sh.warning(`Speed value must be between 0 and 1.`);
          speedPercent = Math.min(1, speedPercent);
        }
        let speed = securityMinDelay + maxDelay - (maxDelay * speedPercent);
        api.addToBuffer(`S1 ${speed}`);
      } else api.resetSpeed();
      return api;
    },

    resetSpeed() {
      api.addToBuffer(`S0`);
      return api;
    },

    drawBoundaries() {
      api
        .home()
        .pen_down()
        .setSpeed(.8)
        // FIXME : the plotter can't go from 0 to HEIGHT in one move (???)
        .move(0, config.height / 2)
        .move(0, config.height)
        .move(config.width, config.height)
        .move(config.width, config.height / 2)
        .move(config.width, 0)
        .move(0, 0)
        .resetSpeed();
      return api;
    },

    // -------------------------------------------------------------------------
    // UTILS COMMANDS

    home() {
      api
        .pen_up()
        .resetSpeed();
      api.addToBuffer('G28');
      return api;
    },

    // TODO : find a way to get the value
    getPosition() {
      api.addToBuffer('P');
      return api;
    },

    wait(promise) {
      function waitForIt() {
        return sh.question('Waiting... press enter to continue.', () => { return true; });
      }
      api.addToBuffer(promise || waitForIt);
      return api;
    },

    // DEPRECATED : a callback can now be called at the end of a job
    // with the promises, see serial.js
    // end(_callback) {
    //   // send a last command before disconnect
    //   // to ensure that the prev command is executed
    //   // by the plotter's firmware
    //   api.addToBuffer('\n');
    //   api.addToBuffer(-1);
    //   api.callback = _callback;
    //   return api;
    // },

    // -------------------------------------------------------------------------
    // PEN COMMANDS

    move(x, y) {
      x = round(x, config.decimals || 3);
      y = round(y, config.decimals || 3);

      // if the plotter is in portrait, swap x and y
      if (config.width / config.height > 1) {
        let t = x;
        x = y;
        y = t;
      }

      if (x < 0 || x > config.width || y < 0 || y > config.height) {
        if (!alreadyWarned) {
          alreadyWarned = true;
          sh.warning(`Some positions will be outside plotter's boundaries.`);
        }
{'fraction_non_alphanumeric': 0.1959214501510574, 'fraction_numerical': 0.010725075528700907, 'mean_word_length': 1.471444568868981, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, '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': '1623671', 'n_tokens_mistral': 2012, 'n_tokens_neox': 1915, 'n_words': 566}