ansimax 1.3.6 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -402,6 +402,16 @@ var safeInt = (value, fallback = 0, min = -Infinity, max = Infinity) => {
402
402
  var clamp = (n, min, max) => Math.min(Math.max(n, min), max);
403
403
  var lerp = (a, b, t) => a + (b - a) * t;
404
404
  var clampByte2 = (v) => clamp(Math.round(v), 0, 255);
405
+ var clampPercent = (p) => {
406
+ if (!isFiniteNumber2(p)) return 0;
407
+ return Math.max(0, Math.min(100, p));
408
+ };
409
+ var clampInt = (value, min, max, fallback = 0) => {
410
+ if (!isFiniteNumber2(value)) {
411
+ return Math.max(min, Math.min(max, Math.floor(fallback)));
412
+ }
413
+ return Math.max(min, Math.min(max, Math.floor(value)));
414
+ };
405
415
  var HEX_RE = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
406
416
  var isHexColor = (hex) => typeof hex === "string" && HEX_RE.test(hex.trim());
407
417
  var hexToRgb = (hex) => {
@@ -3036,16 +3046,11 @@ var ascii = {
3036
3046
 
3037
3047
  // src/loaders/index.ts
3038
3048
  var canAnimate2 = () => Boolean(process.stdout?.isTTY) && supportsColor() !== "none";
3039
- var isFiniteNumber3 = (n) => typeof n === "number" && Number.isFinite(n);
3040
3049
  var ensureString3 = (v) => typeof v === "string" ? v : String(v ?? "");
3041
3050
  var clampPositiveInt = (n, fallback) => {
3042
- if (!isFiniteNumber3(n)) return fallback;
3051
+ if (!isFiniteNumber2(n)) return fallback;
3043
3052
  return Math.max(1, Math.floor(n));
3044
3053
  };
3045
- var clampPercent = (p) => {
3046
- if (!isFiniteNumber3(p)) return 0;
3047
- return Math.max(0, Math.min(100, p));
3048
- };
3049
3054
  var isUnicodeCapable = () => {
3050
3055
  const env = process.env;
3051
3056
  if (env["CI"]) return true;
@@ -3187,7 +3192,7 @@ var spin = (text = "Loading", opts = {}) => {
3187
3192
  const animInterval = Math.max(FRAME_MS, safeInterval);
3188
3193
  acquireCursor();
3189
3194
  const startTime = Date.now();
3190
- const render = () => {
3195
+ const render2 = () => {
3191
3196
  if (stopped) return;
3192
3197
  const elapsed = Date.now() - startTime;
3193
3198
  frame2 = Math.floor(elapsed / animInterval) % frames2.length;
@@ -3197,8 +3202,8 @@ var spin = (text = "Loading", opts = {}) => {
3197
3202
  const buf = createOutputBuffer().push("\r").push(screen.clearLine()).push(line).toString();
3198
3203
  write(buf);
3199
3204
  };
3200
- render();
3201
- timer = setInterval(render, animInterval);
3205
+ render2();
3206
+ timer = setInterval(render2, animInterval);
3202
3207
  let abortedBySignal = false;
3203
3208
  const onAbort = () => {
3204
3209
  abortedBySignal = true;
@@ -3369,15 +3374,15 @@ var dots = (text = "Processing", opts = {}) => {
3369
3374
  let count = 0;
3370
3375
  let stopped = false;
3371
3376
  let timer = null;
3372
- const render = () => {
3377
+ const render2 = () => {
3373
3378
  if (stopped) return;
3374
3379
  const dotStr = ".".repeat(count);
3375
3380
  const colored = applyColor(dotStr, hex);
3376
3381
  write("\r" + screen.clearLine() + text + colored);
3377
3382
  count = (count + 1) % (max + 1);
3378
3383
  };
3379
- render();
3380
- timer = setInterval(render, Math.max(FRAME_MS, interval));
3384
+ render2();
3385
+ timer = setInterval(render2, Math.max(FRAME_MS, interval));
3381
3386
  const onAbort = () => stopFn();
3382
3387
  if (signal) signal.addEventListener("abort", onAbort, { once: true });
3383
3388
  const stopFn = () => {
@@ -3409,15 +3414,15 @@ var custom = (frames2, text = "", opts = {}) => {
3409
3414
  let timer = null;
3410
3415
  const safeInterval = Math.max(FRAME_MS, interval);
3411
3416
  const startTime = Date.now();
3412
- const render = () => {
3417
+ const render2 = () => {
3413
3418
  if (stopped) return;
3414
3419
  const elapsed = Date.now() - startTime;
3415
3420
  frame2 = Math.floor(elapsed / safeInterval) % frames2.length;
3416
3421
  const f = frames2[frame2] ?? "";
3417
3422
  write("\r" + screen.clearLine() + applyColor(f, hex) + " " + text);
3418
3423
  };
3419
- render();
3420
- timer = setInterval(render, safeInterval);
3424
+ render2();
3425
+ timer = setInterval(render2, safeInterval);
3421
3426
  const onAbort = () => stopFn();
3422
3427
  if (signal) signal.addEventListener("abort", onAbort, { once: true });
3423
3428
  const stopFn = () => {
@@ -3435,7 +3440,7 @@ var custom = (frames2, text = "", opts = {}) => {
3435
3440
  };
3436
3441
  var countdown = async (seconds, opts = {}) => {
3437
3442
  const { label = "Starting in", color: hex, signal } = opts;
3438
- const safeSeconds = isFiniteNumber3(seconds) ? Math.max(0, Math.floor(seconds)) : 0;
3443
+ const safeSeconds = isFiniteNumber2(seconds) ? Math.max(0, Math.floor(seconds)) : 0;
3439
3444
  const safeLabel = ensureString3(label);
3440
3445
  const colorToUse = safeColor(hex) ? hex : "#ffd700";
3441
3446
  if (!canAnimate2() || signal?.aborted) {
@@ -3524,7 +3529,7 @@ var multi = (opts = {}) => {
3524
3529
  let frame2 = 0;
3525
3530
  let timer = null;
3526
3531
  let lastLineCount = 0;
3527
- const render = () => {
3532
+ const render2 = () => {
3528
3533
  if (lastLineCount > 0) {
3529
3534
  write("\r" + cursor.up(lastLineCount) + screen.clearDown());
3530
3535
  }
@@ -3546,8 +3551,8 @@ var multi = (opts = {}) => {
3546
3551
  const start = () => {
3547
3552
  if (timer) return;
3548
3553
  acquireCursor();
3549
- render();
3550
- timer = setInterval(render, interval);
3554
+ render2();
3555
+ timer = setInterval(render2, interval);
3551
3556
  };
3552
3557
  const tick = () => {
3553
3558
  if (!timer) start();
@@ -3571,35 +3576,35 @@ var multi = (opts = {}) => {
3571
3576
  },
3572
3577
  set text(v) {
3573
3578
  item.text = v;
3574
- render();
3579
+ render2();
3575
3580
  },
3576
3581
  update(newText) {
3577
3582
  item.text = newText;
3578
- render();
3583
+ render2();
3579
3584
  },
3580
3585
  succeed(t) {
3581
3586
  item.state = "success";
3582
3587
  if (t !== void 0) item.finalText = t;
3583
- render();
3588
+ render2();
3584
3589
  setTimeout(() => {
3585
3590
  items.delete(id);
3586
- render();
3591
+ render2();
3587
3592
  checkEmpty();
3588
3593
  }, interval);
3589
3594
  },
3590
3595
  fail(t) {
3591
3596
  item.state = "fail";
3592
3597
  if (t !== void 0) item.finalText = t;
3593
- render();
3598
+ render2();
3594
3599
  setTimeout(() => {
3595
3600
  items.delete(id);
3596
- render();
3601
+ render2();
3597
3602
  checkEmpty();
3598
3603
  }, interval);
3599
3604
  },
3600
3605
  stop() {
3601
3606
  items.delete(id);
3602
- render();
3607
+ render2();
3603
3608
  checkEmpty();
3604
3609
  }
3605
3610
  };
@@ -3643,11 +3648,10 @@ var loader = {
3643
3648
  };
3644
3649
 
3645
3650
  // src/frames/index.ts
3646
- var isFiniteNumber4 = (n) => typeof n === "number" && Number.isFinite(n);
3647
3651
  var ensureString4 = (v) => typeof v === "string" ? v : String(v ?? "");
3648
3652
  var MAX_FPS = 60;
3649
3653
  var clampFps = (fps, fallback) => {
3650
- if (!isFiniteNumber4(fps)) return fallback;
3654
+ if (!isFiniteNumber2(fps)) return fallback;
3651
3655
  return Math.max(1, Math.min(MAX_FPS, Math.floor(fps)));
3652
3656
  };
3653
3657
  var _cursorHiddenCount2 = 0;
@@ -3746,14 +3750,14 @@ var play = (frames2, opts = {}) => {
3746
3750
  if (fps !== void 0) {
3747
3751
  const safeFps = clampFps(fps, 60);
3748
3752
  tickMs = Math.max(FRAME_MS, Math.floor(1e3 / safeFps));
3749
- } else if (isFiniteNumber4(interval)) {
3753
+ } else if (isFiniteNumber2(interval)) {
3750
3754
  tickMs = Math.max(FRAME_MS, Math.floor(interval));
3751
3755
  } else {
3752
3756
  tickMs = 100;
3753
3757
  }
3754
3758
  let safeRepeat;
3755
3759
  let infinite;
3756
- if (!isFiniteNumber4(repeat)) {
3760
+ if (!isFiniteNumber2(repeat)) {
3757
3761
  safeRepeat = 1;
3758
3762
  infinite = false;
3759
3763
  } else if (repeat === 0) {
@@ -3878,7 +3882,7 @@ var play = (frames2, opts = {}) => {
3878
3882
  paused = false;
3879
3883
  },
3880
3884
  seek: (idx) => {
3881
- if (!isFiniteNumber4(idx)) return;
3885
+ if (!isFiniteNumber2(idx)) return;
3882
3886
  const safe = Math.max(0, Math.floor(idx));
3883
3887
  frameIdx = frames2.length > 0 ? safe % frames2.length : 0;
3884
3888
  },
@@ -3891,7 +3895,7 @@ var play = (frames2, opts = {}) => {
3891
3895
  };
3892
3896
  };
3893
3897
  var generate = (count, fn) => {
3894
- const safeCount = isFiniteNumber4(count) ? Math.max(0, Math.floor(count)) : 0;
3898
+ const safeCount = isFiniteNumber2(count) ? Math.max(0, Math.floor(count)) : 0;
3895
3899
  if (typeof fn !== "function") return Array(safeCount).fill("");
3896
3900
  return Array.from({ length: safeCount }, (_, i) => {
3897
3901
  try {
@@ -3910,7 +3914,7 @@ var live = (opts = {}) => {
3910
3914
  let running = false;
3911
3915
  let timer = null;
3912
3916
  let abortHandler = null;
3913
- const render = () => {
3917
+ const render2 = () => {
3914
3918
  if (lastLines > 0) clearLines(lastLines);
3915
3919
  const frame2 = isColorless2() ? stripAnsi(currentFrame) : currentFrame;
3916
3920
  try {
@@ -3925,7 +3929,7 @@ var live = (opts = {}) => {
3925
3929
  running = true;
3926
3930
  registerCrashHandlers3();
3927
3931
  hideCursorSafe2();
3928
- timer = setInterval(render, interval);
3932
+ timer = setInterval(render2, interval);
3929
3933
  if (signal && !abortHandler) {
3930
3934
  abortHandler = () => stop({ clear: false });
3931
3935
  if (signal.aborted) abortHandler();
@@ -3954,7 +3958,7 @@ var live = (opts = {}) => {
3954
3958
  };
3955
3959
  const update = (newFrame) => {
3956
3960
  currentFrame = ensureString4(newFrame);
3957
- if (running) render();
3961
+ if (running) render2();
3958
3962
  };
3959
3963
  if (autoStart) start();
3960
3964
  return { start, stop, update, isRunning: () => running };
@@ -3963,7 +3967,7 @@ var morph = (frameA, frameB, steps = 8, charset = "\u2591\u2592\u2593\u2588\u259
3963
3967
  const a0 = ensureString4(frameA);
3964
3968
  const b0 = ensureString4(frameB);
3965
3969
  if (!a0 && !b0) return [""];
3966
- const n = Math.max(2, isFiniteNumber4(steps) ? Math.floor(steps) : 8);
3970
+ const n = Math.max(2, isFiniteNumber2(steps) ? Math.floor(steps) : 8);
3967
3971
  const len = Math.max(a0.length, b0.length);
3968
3972
  const a = a0.padEnd(len);
3969
3973
  const b = b0.padEnd(len);
@@ -3985,7 +3989,7 @@ var morph = (frameA, frameB, steps = 8, charset = "\u2591\u2592\u2593\u2588\u259
3985
3989
  var presets2 = {
3986
3990
  loadingBar: (opts = {}) => {
3987
3991
  const { width = 20, char = "\u2588", empty = "\u2591", label = "Loading" } = opts;
3988
- const safeWidth = Math.max(0, isFiniteNumber4(width) ? Math.floor(width) : 20);
3992
+ const safeWidth = Math.max(0, isFiniteNumber2(width) ? Math.floor(width) : 20);
3989
3993
  const safeChar = typeof char === "string" && char.length > 0 ? char : "\u2588";
3990
3994
  const safeEmpty = typeof empty === "string" && empty.length > 0 ? empty : "\u2591";
3991
3995
  const safeLabel = ensureString4(label);
@@ -3999,7 +4003,7 @@ var presets2 = {
3999
4003
  /* istanbul ignore next — default opts {} */
4000
4004
  ball: (opts = {}) => {
4001
4005
  const { width = 20, char = "\u25CF" } = opts;
4002
- const safeWidth = Math.max(1, isFiniteNumber4(width) ? Math.floor(width) : 20);
4006
+ const safeWidth = Math.max(1, isFiniteNumber2(width) ? Math.floor(width) : 20);
4003
4007
  const safeChar = typeof char === "string" && char.length > 0 ? char : "\u25CF";
4004
4008
  const forward = generate(safeWidth, (i) => " ".repeat(i) + safeChar);
4005
4009
  const backward = generate(safeWidth, (i) => " ".repeat(safeWidth - i - 1) + safeChar);
@@ -4009,7 +4013,7 @@ var presets2 = {
4009
4013
  breathe: (text, opts = {}) => {
4010
4014
  const { steps = 8 } = opts;
4011
4015
  const safeText = ensureString4(text);
4012
- const safeSteps2 = Math.max(1, isFiniteNumber4(steps) ? Math.floor(steps) : 8);
4016
+ const safeSteps2 = Math.max(1, isFiniteNumber2(steps) ? Math.floor(steps) : 8);
4013
4017
  const shades = ["\u2591", "\u2592", "\u2593", "\u2588"];
4014
4018
  return generate(safeSteps2 * 2, (i) => {
4015
4019
  const t = i < safeSteps2 ? i / safeSteps2 : 1 - (i - safeSteps2) / safeSteps2;
@@ -4030,22 +4034,17 @@ var presets2 = {
4030
4034
  var frames = { play, generate, live, morph, presets: presets2 };
4031
4035
 
4032
4036
  // src/components/index.ts
4033
- var isFiniteNumber5 = (n) => typeof n === "number" && Number.isFinite(n);
4034
4037
  var ensureString5 = (v) => typeof v === "string" ? v : String(v ?? "");
4035
- var clampPercent2 = (p) => {
4036
- if (!isFiniteNumber5(p)) return 0;
4037
- return Math.max(0, Math.min(100, p));
4038
- };
4039
4038
  var clampNonNeg = (n, fallback) => {
4040
- if (!isFiniteNumber5(n)) return fallback;
4039
+ if (!isFiniteNumber2(n)) return fallback;
4041
4040
  return Math.max(0, Math.floor(n));
4042
4041
  };
4043
4042
  var clampPositive2 = (n, fallback) => {
4044
- if (!isFiniteNumber5(n)) return fallback;
4043
+ if (!isFiniteNumber2(n)) return fallback;
4045
4044
  return Math.max(1, Math.floor(n));
4046
4045
  };
4047
4046
  var safeSgrCode = (code, fallback) => {
4048
- if (!isFiniteNumber5(code)) return fallback;
4047
+ if (!isFiniteNumber2(code)) return fallback;
4049
4048
  return Math.max(0, Math.min(255, Math.floor(code)));
4050
4049
  };
4051
4050
  var truncateVisible = (str, maxWidth, ellipsis = "\u2026") => {
@@ -4083,7 +4082,7 @@ var table = (rows, opts = {}) => {
4083
4082
  const b = TABLE_BORDERS[borderStyle] ?? TABLE_BORDERS.rounded;
4084
4083
  const safePadding = clampNonNeg(padding, 1);
4085
4084
  const pad = " ".repeat(safePadding);
4086
- const safeMaxCol = maxColWidth !== null && isFiniteNumber5(maxColWidth) ? Math.max(1, Math.floor(maxColWidth)) : null;
4085
+ const safeMaxCol = maxColWidth !== null && isFiniteNumber2(maxColWidth) ? Math.max(1, Math.floor(maxColWidth)) : null;
4087
4086
  const validRows = rows.filter((r) => Array.isArray(r));
4088
4087
  if (validRows.length === 0) return "";
4089
4088
  const cols = Math.max(...validRows.map((r) => r.length), 0);
@@ -4170,13 +4169,13 @@ var progressBar = (percent, opts = {}) => {
4170
4169
  const safeChar = typeof char === "string" && char.length > 0 ? char : "\u2588";
4171
4170
  const safeEmpty = typeof emptyChar === "string" && emptyChar.length > 0 ? emptyChar : "\u2591";
4172
4171
  const safeLabel = ensureString5(label);
4173
- const clamped = clampPercent2(percent);
4172
+ const clamped = clampPercent(percent);
4174
4173
  const filled = Math.floor(clamped / 100 * safeWidth);
4175
4174
  const empty = Math.max(0, safeWidth - filled);
4176
4175
  let filledStr = safeChar.repeat(filled);
4177
4176
  if (Array.isArray(gradientStops2) && gradientStops2.length >= 1 && filled > 0) {
4178
4177
  filledStr = gradient(filledStr, gradientStops2);
4179
- } else if (color2 !== null && isFiniteNumber5(color2)) {
4178
+ } else if (color2 !== null && isFiniteNumber2(color2)) {
4180
4179
  filledStr = sgr(safeSgrCode(color2, FG.white)) + filledStr + reset();
4181
4180
  }
4182
4181
  const emptyStr = safeEmpty.repeat(empty);
@@ -4212,7 +4211,7 @@ var section = (title, opts = {}) => {
4212
4211
  const safeChar = typeof char === "string" && char.length > 0 ? char : "\u2500";
4213
4212
  const safeColor2 = safeSgrCode(colorCode, FG.cyan);
4214
4213
  const titleLen = visibleLen(safeTitle);
4215
- const requestedWidth = width !== null && isFiniteNumber5(width) ? Math.max(1, Math.floor(width)) : cols;
4214
+ const requestedWidth = width !== null && isFiniteNumber2(width) ? Math.max(1, Math.floor(width)) : cols;
4216
4215
  const w = Math.max(requestedWidth, titleLen + 2);
4217
4216
  const side = Math.floor((w - titleLen - 2) / 2);
4218
4217
  const dividerL = sgr(safeColor2) + safeChar.repeat(Math.max(0, side)) + reset();
@@ -4226,7 +4225,7 @@ var columns = (items, opts = {}) => {
4226
4225
  const safeCols = clampPositive2(numCols, 2);
4227
4226
  const safeGap = clampNonNeg(gap, 2);
4228
4227
  const { cols: termCols } = termSize();
4229
- const totalW = width !== null && isFiniteNumber5(width) ? Math.max(safeCols, Math.floor(width)) : termCols;
4228
+ const totalW = width !== null && isFiniteNumber2(width) ? Math.max(safeCols, Math.floor(width)) : termCols;
4230
4229
  const colW = Math.max(1, Math.floor((totalW - safeGap * (safeCols - 1)) / safeCols));
4231
4230
  const gapStr = " ".repeat(safeGap);
4232
4231
  const rows = [];
@@ -4266,7 +4265,7 @@ var timeline = (events, opts = {}) => {
4266
4265
  const safeColor2 = safeSgrCode(colorCode, FG.cyan);
4267
4266
  const safeDoneColor = safeSgrCode(doneColor, FG.green);
4268
4267
  const safePendingColor = safeSgrCode(pendingColor, FG.brightBlack);
4269
- const computedTimeWidth = timeColumnWidth !== null && isFiniteNumber5(timeColumnWidth) ? Math.max(0, Math.floor(timeColumnWidth)) : Math.max(0, ...events.map((e) => e.time ? visibleLen(ensureString5(e.time)) : 0));
4268
+ const computedTimeWidth = timeColumnWidth !== null && isFiniteNumber2(timeColumnWidth) ? Math.max(0, Math.floor(timeColumnWidth)) : Math.max(0, ...events.map((e) => e.time ? visibleLen(ensureString5(e.time)) : 0));
4270
4269
  const lines = [];
4271
4270
  events.forEach((ev, i) => {
4272
4271
  const isLast = i === events.length - 1;
@@ -4308,7 +4307,7 @@ var menu = (items, opts = {}) => {
4308
4307
  } catch {
4309
4308
  }
4310
4309
  };
4311
- const render = () => {
4310
+ const render2 = () => {
4312
4311
  let totalLines = 0;
4313
4312
  const { cols: termCols } = termSize();
4314
4313
  const safeTermCols = Math.max(1, termCols);
@@ -4382,7 +4381,7 @@ var menu = (items, opts = {}) => {
4382
4381
  try {
4383
4382
  emit(cursor.hide());
4384
4383
  cursorHidden = true;
4385
- lastRenderedLines = render();
4384
+ lastRenderedLines = render2();
4386
4385
  } catch {
4387
4386
  cleanup(null);
4388
4387
  return Promise.resolve(MENU_CANCELLED);
@@ -4423,7 +4422,7 @@ var menu = (items, opts = {}) => {
4423
4422
  return;
4424
4423
  }
4425
4424
  clearLinesLocal();
4426
- lastRenderedLines = render();
4425
+ lastRenderedLines = render2();
4427
4426
  } catch {
4428
4427
  cleanup(onKey);
4429
4428
  safeResolve(MENU_CANCELLED);
@@ -4458,10 +4457,9 @@ var STYLES = {
4458
4457
  heavy: { branch: "\u2523\u2501\u2501 ", last: "\u2517\u2501\u2501 ", vert: "\u2503 ", space: " " },
4459
4458
  ascii: { branch: "+-- ", last: "`-- ", vert: "| ", space: " " }
4460
4459
  };
4461
- var isFiniteNumber6 = (n) => typeof n === "number" && Number.isFinite(n);
4462
4460
  var ensureString6 = (v) => typeof v === "string" ? v : String(v ?? "");
4463
4461
  var clampNonNeg2 = (n, fallback) => {
4464
- if (!isFiniteNumber6(n)) return fallback;
4462
+ if (!isFiniteNumber2(n)) return fallback;
4465
4463
  return Math.max(0, Math.floor(n));
4466
4464
  };
4467
4465
  var normalizeNewlines = (s) => s.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
@@ -4533,7 +4531,7 @@ var renderChildren = (children, parentContinuation, lines, indentStr, defaultSty
4533
4531
  if (!Array.isArray(children)) return;
4534
4532
  let visible = children;
4535
4533
  let collapsedCount = 0;
4536
- const safeCollapse = isFiniteNumber6(collapse) ? Math.floor(collapse) : 0;
4534
+ const safeCollapse = isFiniteNumber2(collapse) ? Math.floor(collapse) : 0;
4537
4535
  if (safeCollapse > 0 && safeCollapse < children.length) {
4538
4536
  visible = children.slice(safeCollapse);
4539
4537
  collapsedCount = safeCollapse;
@@ -4603,7 +4601,7 @@ var renderTree = (root, opts = {}) => {
4603
4601
  } = opts;
4604
4602
  const safeStyle = style && STYLES[style] ? style : "normal";
4605
4603
  const safeIndent = clampNonNeg2(indent, 0);
4606
- const safeMaxDepth = isFiniteNumber6(maxDepth) ? Math.max(0, Math.floor(maxDepth)) : Infinity;
4604
+ const safeMaxDepth = isFiniteNumber2(maxDepth) ? Math.max(0, Math.floor(maxDepth)) : Infinity;
4607
4605
  const indentStr = " ".repeat(safeIndent);
4608
4606
  const lines = [];
4609
4607
  const rootLabel = formatNode(root, 0, palette);
@@ -5222,13 +5220,8 @@ var themes = {
5222
5220
  var FULL_BLOCK = "\u2588";
5223
5221
  var UPPER_HALF = "\u2580";
5224
5222
  var LOWER_HALF = "\u2584";
5225
- var isFiniteNumber7 = (n) => typeof n === "number" && Number.isFinite(n);
5226
- var clampInt = (n, min, max, fallback) => {
5227
- if (!isFiniteNumber7(n)) return fallback;
5228
- return Math.max(min, Math.min(max, Math.floor(n)));
5229
- };
5230
5223
  var clampByte3 = (n) => {
5231
- if (!isFiniteNumber7(n)) return 0;
5224
+ if (!isFiniteNumber2(n)) return 0;
5232
5225
  return Math.max(0, Math.min(255, Math.round(n)));
5233
5226
  };
5234
5227
  var MAX_DIMENSION = 1e4;
@@ -5533,7 +5526,7 @@ var gradientRect = (opts = {}) => {
5533
5526
  const safeW = clampInt(width, 2, MAX_DIMENSION, 40);
5534
5527
  const safeH = clampInt(height, 2, MAX_DIMENSION, 10);
5535
5528
  let cosA = 1, sinA = 0;
5536
- if (isFiniteNumber7(angle)) {
5529
+ if (isFiniteNumber2(angle)) {
5537
5530
  const rad = angle * Math.PI / 180;
5538
5531
  cosA = Math.cos(rad);
5539
5532
  sinA = Math.sin(rad);
@@ -5543,7 +5536,7 @@ var gradientRect = (opts = {}) => {
5543
5536
  const line = [];
5544
5537
  for (let col = 0; col < safeW; col++) {
5545
5538
  let t;
5546
- if (isFiniteNumber7(angle)) {
5539
+ if (isFiniteNumber2(angle)) {
5547
5540
  const projection = col / (safeW - 1) * cosA + row / (safeH - 1) * sinA;
5548
5541
  t = clamp((projection + 1) / 2, 0, 1);
5549
5542
  } else if (style === "horizontal") t = col / (safeW - 1);
@@ -5600,7 +5593,7 @@ var createCanvas = (width, height, fillColor = null) => {
5600
5593
  if (y > dirtyMaxY) dirtyMaxY = y;
5601
5594
  };
5602
5595
  const setInternal = (x, y, color2) => {
5603
- if (!isFiniteNumber7(x) || !isFiniteNumber7(y)) return;
5596
+ if (!isFiniteNumber2(x) || !isFiniteNumber2(y)) return;
5604
5597
  const ix = Math.floor(x);
5605
5598
  const iy = Math.floor(y);
5606
5599
  if (iy < 0 || iy >= h || ix < 0 || ix >= w) return;
@@ -5615,7 +5608,7 @@ var createCanvas = (width, height, fillColor = null) => {
5615
5608
  },
5616
5609
  set: setInternal,
5617
5610
  get(x, y) {
5618
- if (!isFiniteNumber7(x) || !isFiniteNumber7(y)) return null;
5611
+ if (!isFiniteNumber2(x) || !isFiniteNumber2(y)) return null;
5619
5612
  const ix = Math.floor(x), iy = Math.floor(y);
5620
5613
  return cloneColor(pixels[iy]?.[ix] ?? null);
5621
5614
  },
@@ -5631,7 +5624,7 @@ var createCanvas = (width, height, fillColor = null) => {
5631
5624
  dirtyMaxY = h - 1;
5632
5625
  },
5633
5626
  drawRect(x, y, rw, rh, color2, fill = false) {
5634
- if (!isFiniteNumber7(x) || !isFiniteNumber7(y) || !isFiniteNumber7(rw) || !isFiniteNumber7(rh)) return;
5627
+ if (!isFiniteNumber2(x) || !isFiniteNumber2(y) || !isFiniteNumber2(rw) || !isFiniteNumber2(rh)) return;
5635
5628
  if (rw <= 0 || rh <= 0) return;
5636
5629
  const ix = Math.floor(x);
5637
5630
  const iy = Math.floor(y);
@@ -5653,7 +5646,7 @@ var createCanvas = (width, height, fillColor = null) => {
5653
5646
  }
5654
5647
  },
5655
5648
  drawCircle(cx, cy, radius, color2, fill = false) {
5656
- if (!isFiniteNumber7(cx) || !isFiniteNumber7(cy) || !isFiniteNumber7(radius)) return;
5649
+ if (!isFiniteNumber2(cx) || !isFiniteNumber2(cy) || !isFiniteNumber2(radius)) return;
5657
5650
  if (radius <= 0) return;
5658
5651
  const x0 = Math.max(0, Math.floor(cx - radius - 1));
5659
5652
  const y0 = Math.max(0, Math.floor(cy - radius - 1));
@@ -5676,7 +5669,7 @@ var createCanvas = (width, height, fillColor = null) => {
5676
5669
  }
5677
5670
  },
5678
5671
  drawSprite(x, y, sprite) {
5679
- if (!isFiniteNumber7(x) || !isFiniteNumber7(y)) return;
5672
+ if (!isFiniteNumber2(x) || !isFiniteNumber2(y)) return;
5680
5673
  if (!Array.isArray(sprite)) return;
5681
5674
  const sx = Math.floor(x);
5682
5675
  const sy = Math.floor(y);
@@ -6141,8 +6134,8 @@ var _renderValue = (value, depth, config) => {
6141
6134
  inlineItems.push(_c(`... (${remaining} more)`, COLORS.comment, useColor));
6142
6135
  }
6143
6136
  const candidate = _c("[", COLORS.bracket, useColor) + inlineItems.join(", ") + _c("]", COLORS.bracket, useColor);
6144
- const visibleLen2 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
6145
- if (visibleLen2 <= inlineArrayMaxLength) {
6137
+ const visibleLen3 = candidate.replace(/\x1b\[[0-9;]*m/g, "").length;
6138
+ if (visibleLen3 <= inlineArrayMaxLength) {
6146
6139
  return candidate;
6147
6140
  }
6148
6141
  }
@@ -6221,6 +6214,269 @@ var json = {
6221
6214
  pretty
6222
6215
  };
6223
6216
 
6217
+ // src/markdown/index.ts
6218
+ var THEMES = {
6219
+ dark: {
6220
+ h1: ["#ff79c6", "#bd93f9", "#8be9fd"],
6221
+ h2: "#bd93f9",
6222
+ h3: "#8be9fd",
6223
+ h4: "#50fa7b",
6224
+ h5: "#f1fa8c",
6225
+ h6: "#ffb86c",
6226
+ code: "#ff79c6",
6227
+ codeBlockBorder: "#6272a4",
6228
+ link: "#8be9fd",
6229
+ blockquote: "#6272a4",
6230
+ hr: "#6272a4",
6231
+ tableHeader: "#bd93f9"
6232
+ },
6233
+ light: {
6234
+ h1: ["#d63384", "#6f42c1", "#0d6efd"],
6235
+ h2: "#6f42c1",
6236
+ h3: "#0d6efd",
6237
+ h4: "#198754",
6238
+ h5: "#664d03",
6239
+ h6: "#fd7e14",
6240
+ code: "#d63384",
6241
+ codeBlockBorder: "#adb5bd",
6242
+ link: "#0d6efd",
6243
+ blockquote: "#6c757d",
6244
+ hr: "#adb5bd",
6245
+ tableHeader: "#6f42c1"
6246
+ }
6247
+ };
6248
+ var _normalize = (text) => typeof text === "string" ? text.replace(/\r\n/g, "\n").replace(/\r/g, "\n") : "";
6249
+ var HEADING_RE = /^(#{1,6})\s+(.+?)\s*#*\s*$/;
6250
+ var ORDERED_LIST_RE = /^(\s*)(\d+)[.)]\s+(.+)$/;
6251
+ var UNORDERED_LIST_RE = /^(\s*)[-*+]\s+(.+)$/;
6252
+ var HR_RE = /^[ \t]*(?:-{3,}|\*{3,}|_{3,})[ \t]*$/;
6253
+ var CODEBLOCK_OPEN_RE = /^```[ \t]*(\S*)[ \t]*$/;
6254
+ var CODEBLOCK_CLOSE_RE = /^```\s*$/;
6255
+ var BLOCKQUOTE_RE = /^>\s?(.*)$/;
6256
+ var TABLE_SEPARATOR_RE = /^\|?[ \t]*:?-{2,}:?[ \t]*(\|[ \t]*:?-{2,}:?[ \t]*)+\|?[ \t]*$/;
6257
+ var TABLE_ROW_RE = /^\|.*\|[ \t]*$/;
6258
+ var parseBlocks = (source) => {
6259
+ if (typeof source !== "string" || source.length === 0) return [];
6260
+ const lines = _normalize(source).split("\n");
6261
+ const out = [];
6262
+ let i = 0;
6263
+ while (i < lines.length) {
6264
+ const line = lines[i];
6265
+ if (line.trim() === "") {
6266
+ out.push({ type: "blank" });
6267
+ i++;
6268
+ continue;
6269
+ }
6270
+ if (HR_RE.test(line)) {
6271
+ out.push({ type: "hr" });
6272
+ i++;
6273
+ continue;
6274
+ }
6275
+ const headingMatch = HEADING_RE.exec(line);
6276
+ if (headingMatch) {
6277
+ const level = headingMatch[1].length;
6278
+ const text = headingMatch[2].trim();
6279
+ out.push({ type: "heading", level, text });
6280
+ i++;
6281
+ continue;
6282
+ }
6283
+ const codeOpen = CODEBLOCK_OPEN_RE.exec(line);
6284
+ if (codeOpen) {
6285
+ const lang = codeOpen[1].trim();
6286
+ const codeLines = [];
6287
+ i++;
6288
+ while (i < lines.length && !CODEBLOCK_CLOSE_RE.test(lines[i])) {
6289
+ codeLines.push(lines[i]);
6290
+ i++;
6291
+ }
6292
+ if (i < lines.length) i++;
6293
+ out.push({ type: "codeblock", lang, code: codeLines.join("\n") });
6294
+ continue;
6295
+ }
6296
+ if (BLOCKQUOTE_RE.test(line)) {
6297
+ const qLines = [];
6298
+ while (i < lines.length && BLOCKQUOTE_RE.test(lines[i])) {
6299
+ const m = BLOCKQUOTE_RE.exec(lines[i]);
6300
+ qLines.push((m?.[1] ?? "").trim());
6301
+ i++;
6302
+ }
6303
+ out.push({ type: "blockquote", text: qLines.join("\n") });
6304
+ continue;
6305
+ }
6306
+ if (TABLE_ROW_RE.test(line) && i + 1 < lines.length && TABLE_SEPARATOR_RE.test(lines[i + 1])) {
6307
+ const headers = _splitTableRow(line);
6308
+ i += 2;
6309
+ const rows = [];
6310
+ while (i < lines.length && TABLE_ROW_RE.test(lines[i])) {
6311
+ rows.push(_splitTableRow(lines[i]));
6312
+ i++;
6313
+ }
6314
+ out.push({ type: "table", headers, rows });
6315
+ continue;
6316
+ }
6317
+ const ulMatch = UNORDERED_LIST_RE.exec(line);
6318
+ const olMatch = ORDERED_LIST_RE.exec(line);
6319
+ if (ulMatch || olMatch) {
6320
+ const ordered = olMatch != null;
6321
+ const items = [];
6322
+ while (i < lines.length) {
6323
+ const ln = lines[i];
6324
+ const u = UNORDERED_LIST_RE.exec(ln);
6325
+ const o = ORDERED_LIST_RE.exec(ln);
6326
+ if (ordered && o) {
6327
+ items.push(o[3].trim());
6328
+ i++;
6329
+ } else if (!ordered && u) {
6330
+ items.push(u[2].trim());
6331
+ i++;
6332
+ } else {
6333
+ break;
6334
+ }
6335
+ }
6336
+ out.push({ type: "list", ordered, items });
6337
+ continue;
6338
+ }
6339
+ const paraLines = [line];
6340
+ i++;
6341
+ while (i < lines.length) {
6342
+ const next = lines[i];
6343
+ if (next.trim() === "" || HEADING_RE.test(next) || HR_RE.test(next) || CODEBLOCK_OPEN_RE.test(next) || BLOCKQUOTE_RE.test(next) || UNORDERED_LIST_RE.test(next) || ORDERED_LIST_RE.test(next) || TABLE_ROW_RE.test(next)) {
6344
+ break;
6345
+ }
6346
+ paraLines.push(next);
6347
+ i++;
6348
+ }
6349
+ out.push({ type: "paragraph", text: paraLines.join(" ").trim() });
6350
+ }
6351
+ return out;
6352
+ };
6353
+ var _splitTableRow = (row) => {
6354
+ const stripped = row.trim().replace(/^\|/, "").replace(/\|[ \t]*$/, "");
6355
+ return stripped.split("|").map((c) => c.trim());
6356
+ };
6357
+ var parseInline = (text, opts = {
6358
+ theme: "dark",
6359
+ inlineCodeBackground: true
6360
+ }) => {
6361
+ if (typeof text !== "string" || text.length === 0) return "";
6362
+ const t = THEMES[opts.theme];
6363
+ const codeSlots = [];
6364
+ let s = text.replace(/`([^`\n]+)`/g, (_m, code) => {
6365
+ const styled = opts.inlineCodeBackground ? color.dim(color.hex(t.code)("\xA0" + code + "\xA0")) : color.dim(color.hex(t.code)(code));
6366
+ codeSlots.push(styled);
6367
+ return `\0CODE${codeSlots.length - 1}\0`;
6368
+ });
6369
+ s = s.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_m, label, url) => {
6370
+ return hyperlink(url, color.hex(t.link)(color.underline(label)));
6371
+ });
6372
+ s = s.replace(/~~([^~\n]+)~~/g, (_m, inner) => color.strikethrough(inner));
6373
+ s = s.replace(/\*\*([^*\n]+)\*\*/g, (_m, inner) => color.bold(inner));
6374
+ s = s.replace(/__([^_\n]+)__/g, (_m, inner) => color.bold(inner));
6375
+ s = s.replace(/(^|[^*])\*([^*\n]+)\*(?!\*)/g, (_m, pre, inner) => pre + color.italic(inner));
6376
+ s = s.replace(/(^|[^_])_([^_\n]+)_(?!_)/g, (_m, pre, inner) => pre + color.italic(inner));
6377
+ s = s.replace(/\x00CODE(\d+)\x00/g, (_m, idx) => codeSlots[Number(idx)] ?? "");
6378
+ return s;
6379
+ };
6380
+ var _detectWidth = () => {
6381
+ const w = process.stdout?.columns;
6382
+ return isFiniteNumber2(w) && w > 10 ? w : 80;
6383
+ };
6384
+ var render = (source, opts = {}) => {
6385
+ if (typeof source !== "string" || source.length === 0) return "";
6386
+ const {
6387
+ width = _detectWidth(),
6388
+ theme = "dark",
6389
+ headingGradient,
6390
+ boxCodeBlocks = true,
6391
+ inlineCodeBackground = true
6392
+ } = opts;
6393
+ const safeWidth = isFiniteNumber2(width) && width > 4 ? Math.floor(width) : 80;
6394
+ const t = THEMES[theme] ?? THEMES.dark;
6395
+ const h1Colors = headingGradient && headingGradient.length >= 2 ? headingGradient : t.h1;
6396
+ const blocks = parseBlocks(source);
6397
+ const inlineOpts = { theme, inlineCodeBackground };
6398
+ const out = [];
6399
+ for (const block of blocks) {
6400
+ switch (block.type) {
6401
+ case "blank":
6402
+ out.push("");
6403
+ break;
6404
+ case "hr":
6405
+ out.push(color.hex(t.hr)(ascii.divider({ width: safeWidth, char: "\u2500" })));
6406
+ break;
6407
+ case "heading": {
6408
+ const inline = parseInline(block.text, inlineOpts);
6409
+ if (block.level === 1) {
6410
+ out.push(color.bold(gradient(inline, h1Colors)));
6411
+ } else if (block.level === 2) {
6412
+ out.push(color.bold(color.underline(color.hex(t.h2)(inline))));
6413
+ } else {
6414
+ const colorKey = `h${block.level}`;
6415
+ const hex = t[colorKey];
6416
+ out.push(color.bold(color.hex(hex)(inline)));
6417
+ }
6418
+ break;
6419
+ }
6420
+ case "paragraph": {
6421
+ out.push(parseInline(block.text, inlineOpts));
6422
+ break;
6423
+ }
6424
+ case "codeblock": {
6425
+ const codeText = block.code.length > 0 ? block.code : " ";
6426
+ if (boxCodeBlocks) {
6427
+ const labeled = block.lang ? ` ${block.lang} ` : null;
6428
+ const box3 = ascii.box(codeText, {
6429
+ borderStyle: "rounded",
6430
+ padding: 1,
6431
+ title: labeled
6432
+ });
6433
+ out.push(color.hex(t.codeBlockBorder)(box3));
6434
+ } else {
6435
+ const indented = codeText.split("\n").map((l) => " " + l).join("\n");
6436
+ out.push(color.dim(indented));
6437
+ }
6438
+ break;
6439
+ }
6440
+ case "list": {
6441
+ const lines = [];
6442
+ for (let idx = 0; idx < block.items.length; idx++) {
6443
+ const marker = block.ordered ? `${idx + 1}.` : "\u2022";
6444
+ const rendered = parseInline(block.items[idx], inlineOpts);
6445
+ lines.push(` ${color.hex(t.h3)(marker)} ${rendered}`);
6446
+ }
6447
+ out.push(lines.join("\n"));
6448
+ break;
6449
+ }
6450
+ case "blockquote": {
6451
+ const rendered = parseInline(block.text, inlineOpts);
6452
+ const quoted = rendered.split("\n").map((l) => color.hex(t.blockquote)("\u2502 ") + color.dim(l)).join("\n");
6453
+ out.push(quoted);
6454
+ break;
6455
+ }
6456
+ case "table": {
6457
+ const styledHeaders = block.headers.map(
6458
+ (h) => color.bold(color.hex(t.tableHeader)(parseInline(h, inlineOpts)))
6459
+ );
6460
+ const styledRows = block.rows.map(
6461
+ (row) => row.map((cell) => parseInline(cell, inlineOpts))
6462
+ );
6463
+ out.push(components.table([styledHeaders, ...styledRows], {
6464
+ borderStyle: "rounded",
6465
+ padding: 1
6466
+ }));
6467
+ break;
6468
+ }
6469
+ }
6470
+ }
6471
+ while (out.length > 0 && out[out.length - 1] === "") out.pop();
6472
+ return out.join("\n");
6473
+ };
6474
+ var markdown = {
6475
+ render,
6476
+ parseBlocks,
6477
+ parseInline
6478
+ };
6479
+
6224
6480
  // src/configure.ts
6225
6481
  var DEFAULTS = Object.freeze({
6226
6482
  colorMode: "auto",
@@ -6528,7 +6784,23 @@ var resolveEasingByName = (e) => {
6528
6784
  };
6529
6785
 
6530
6786
  // src/index.ts
6531
- var ansimax = { color, animate, ascii, loader, frames, components, trees, themes, images, configure };
6787
+ var ansimax = {
6788
+ color,
6789
+ animate,
6790
+ ascii,
6791
+ loader,
6792
+ frames,
6793
+ components,
6794
+ trees,
6795
+ themes,
6796
+ images,
6797
+ configure,
6798
+ // v1.3.0+
6799
+ panels,
6800
+ json,
6801
+ // v1.4.0
6802
+ markdown
6803
+ };
6532
6804
  var index_default = ansimax;
6533
6805
  export {
6534
6806
  ASCII_RAMPS,
@@ -6562,6 +6834,8 @@ export {
6562
6834
  charWidth,
6563
6835
  clamp,
6564
6836
  clampByte2 as clampByte,
6837
+ clampInt,
6838
+ clampPercent,
6565
6839
  clearAnsiCache,
6566
6840
  clearColorCache,
6567
6841
  clearLine,
@@ -6626,6 +6900,7 @@ export {
6626
6900
  listPresets,
6627
6901
  loader,
6628
6902
  mapTree,
6903
+ markdown,
6629
6904
  measureBlock,
6630
6905
  measureTree,
6631
6906
  memoize,
@@ -6641,6 +6916,8 @@ export {
6641
6916
  padStart,
6642
6917
  panels,
6643
6918
  parseFiglet,
6919
+ parseBlocks as parseMarkdownBlocks,
6920
+ parseInline as parseMarkdownInline,
6644
6921
  pauseListeners,
6645
6922
  presetNames,
6646
6923
  presets,
@@ -6648,6 +6925,7 @@ export {
6648
6925
  rainbow,
6649
6926
  registerFont,
6650
6927
  registerPreset,
6928
+ render as renderMarkdown,
6651
6929
  renderPixelArt,
6652
6930
  renderTree,
6653
6931
  renderTreeStream,