11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst {
41cb0ef41Sopenharmony_ci  NumberIsNaN,
51cb0ef41Sopenharmony_ci} = primordials;
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst {
81cb0ef41Sopenharmony_ci  codes: {
91cb0ef41Sopenharmony_ci    ERR_INVALID_ARG_VALUE,
101cb0ef41Sopenharmony_ci    ERR_INVALID_CURSOR_POS,
111cb0ef41Sopenharmony_ci  },
121cb0ef41Sopenharmony_ci} = require('internal/errors');
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst {
151cb0ef41Sopenharmony_ci  validateFunction,
161cb0ef41Sopenharmony_ci} = require('internal/validators');
171cb0ef41Sopenharmony_ciconst {
181cb0ef41Sopenharmony_ci  CSI,
191cb0ef41Sopenharmony_ci} = require('internal/readline/utils');
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciconst {
221cb0ef41Sopenharmony_ci  kClearLine,
231cb0ef41Sopenharmony_ci  kClearScreenDown,
241cb0ef41Sopenharmony_ci  kClearToLineBeginning,
251cb0ef41Sopenharmony_ci  kClearToLineEnd,
261cb0ef41Sopenharmony_ci} = CSI;
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci/**
301cb0ef41Sopenharmony_ci * moves the cursor to the x and y coordinate on the given stream
311cb0ef41Sopenharmony_ci */
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cifunction cursorTo(stream, x, y, callback) {
341cb0ef41Sopenharmony_ci  if (callback !== undefined) {
351cb0ef41Sopenharmony_ci    validateFunction(callback, 'callback');
361cb0ef41Sopenharmony_ci  }
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  if (typeof y === 'function') {
391cb0ef41Sopenharmony_ci    callback = y;
401cb0ef41Sopenharmony_ci    y = undefined;
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  if (NumberIsNaN(x)) throw new ERR_INVALID_ARG_VALUE('x', x);
441cb0ef41Sopenharmony_ci  if (NumberIsNaN(y)) throw new ERR_INVALID_ARG_VALUE('y', y);
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  if (stream == null || (typeof x !== 'number' && typeof y !== 'number')) {
471cb0ef41Sopenharmony_ci    if (typeof callback === 'function') process.nextTick(callback, null);
481cb0ef41Sopenharmony_ci    return true;
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  if (typeof x !== 'number') throw new ERR_INVALID_CURSOR_POS();
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  const data = typeof y !== 'number' ? CSI`${x + 1}G` : CSI`${y + 1};${x + 1}H`;
541cb0ef41Sopenharmony_ci  return stream.write(data, callback);
551cb0ef41Sopenharmony_ci}
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci/**
581cb0ef41Sopenharmony_ci * moves the cursor relative to its current location
591cb0ef41Sopenharmony_ci */
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_cifunction moveCursor(stream, dx, dy, callback) {
621cb0ef41Sopenharmony_ci  if (callback !== undefined) {
631cb0ef41Sopenharmony_ci    validateFunction(callback, 'callback');
641cb0ef41Sopenharmony_ci  }
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  if (stream == null || !(dx || dy)) {
671cb0ef41Sopenharmony_ci    if (typeof callback === 'function') process.nextTick(callback, null);
681cb0ef41Sopenharmony_ci    return true;
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  let data = '';
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  if (dx < 0) {
741cb0ef41Sopenharmony_ci    data += CSI`${-dx}D`;
751cb0ef41Sopenharmony_ci  } else if (dx > 0) {
761cb0ef41Sopenharmony_ci    data += CSI`${dx}C`;
771cb0ef41Sopenharmony_ci  }
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  if (dy < 0) {
801cb0ef41Sopenharmony_ci    data += CSI`${-dy}A`;
811cb0ef41Sopenharmony_ci  } else if (dy > 0) {
821cb0ef41Sopenharmony_ci    data += CSI`${dy}B`;
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  return stream.write(data, callback);
861cb0ef41Sopenharmony_ci}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci/**
891cb0ef41Sopenharmony_ci * clears the current line the cursor is on:
901cb0ef41Sopenharmony_ci *   -1 for left of the cursor
911cb0ef41Sopenharmony_ci *   +1 for right of the cursor
921cb0ef41Sopenharmony_ci *    0 for the entire line
931cb0ef41Sopenharmony_ci */
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_cifunction clearLine(stream, dir, callback) {
961cb0ef41Sopenharmony_ci  if (callback !== undefined) {
971cb0ef41Sopenharmony_ci    validateFunction(callback, 'callback');
981cb0ef41Sopenharmony_ci  }
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  if (stream === null || stream === undefined) {
1011cb0ef41Sopenharmony_ci    if (typeof callback === 'function') process.nextTick(callback, null);
1021cb0ef41Sopenharmony_ci    return true;
1031cb0ef41Sopenharmony_ci  }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  const type =
1061cb0ef41Sopenharmony_ci    dir < 0 ? kClearToLineBeginning : dir > 0 ? kClearToLineEnd : kClearLine;
1071cb0ef41Sopenharmony_ci  return stream.write(type, callback);
1081cb0ef41Sopenharmony_ci}
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci/**
1111cb0ef41Sopenharmony_ci * clears the screen from the current position of the cursor down
1121cb0ef41Sopenharmony_ci */
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_cifunction clearScreenDown(stream, callback) {
1151cb0ef41Sopenharmony_ci  if (callback !== undefined) {
1161cb0ef41Sopenharmony_ci    validateFunction(callback, 'callback');
1171cb0ef41Sopenharmony_ci  }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  if (stream === null || stream === undefined) {
1201cb0ef41Sopenharmony_ci    if (typeof callback === 'function') process.nextTick(callback, null);
1211cb0ef41Sopenharmony_ci    return true;
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  return stream.write(kClearScreenDown, callback);
1251cb0ef41Sopenharmony_ci}
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_cimodule.exports = {
1281cb0ef41Sopenharmony_ci  clearLine,
1291cb0ef41Sopenharmony_ci  clearScreenDown,
1301cb0ef41Sopenharmony_ci  cursorTo,
1311cb0ef41Sopenharmony_ci  moveCursor,
1321cb0ef41Sopenharmony_ci};
133