"use strict";
/* Socket Lib - Built with esbuild */
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var logger_exports = {};
__export(logger_exports, {
  Logger: () => Logger,
  getDefaultLogger: () => getDefaultLogger
});
module.exports = __toCommonJS(logger_exports);
var import_node_process = __toESM(require("node:process"));
var import_array = require("../primordials/array");
var import_error = require("../primordials/error");
var import_math = require("../primordials/math");
var import_reflect = require("../primordials/reflect");
var import_format = require("../strings/format");
var import_predicates = require("../strings/predicates");
var import_context = require("../themes/context");
var import_themes = require("../themes/themes");
var import_internal = require("./_internal");
var import_symbols_builder = require("./symbols-builder");
var import_symbols = require("./symbols");
var import_console = require("./console");
class Logger {
  /**
   * Static reference to log symbols for convenience.
   */
  static LOG_SYMBOLS = import_symbols.LOG_SYMBOLS;
  #parent;
  #boundStream;
  #stderrLogger;
  #stdoutLogger;
  #stderrIndention = "";
  #stdoutIndention = "";
  #stderrLastWasBlank = false;
  #stdoutLastWasBlank = false;
  #logCallCount = 0;
  #options;
  #originalStdout;
  #theme;
  /**
   * Creates a new Logger instance.
   *
   * When called without arguments, creates a logger using the default
   * `process.stdout` and `process.stderr` streams. Can accept custom console
   * constructor arguments for advanced use cases.
   *
   * @param args - Optional console constructor arguments.
   */
  constructor(...args) {
    import_internal.privateConstructorArgs.set(this, args);
    const options = args["0"];
    if (typeof options === "object" && options !== null) {
      this.#options = { __proto__: null, ...options };
      this.#originalStdout = options.stdout;
      const themeOption = options.theme;
      if (themeOption) {
        if (typeof themeOption === "string") {
          const resolved = import_themes.THEMES[themeOption];
          if (resolved) {
            this.#theme = resolved;
          }
        } else {
          this.#theme = themeOption;
        }
      }
    } else {
      this.#options = { __proto__: null };
    }
  }
  /**
   * Apply a console method with indentation.
   *
   * @private
   */
  #apply(methodName, args, stream) {
    const con = this.#getConsole();
    const text = (0, import_array.ArrayPrototypeAt)(args, 0);
    const hasText = typeof text === "string";
    const targetStream = stream || (methodName === "log" ? "stdout" : "stderr");
    const indent = this.#getIndent(targetStream);
    const logArgs = hasText ? [
      (0, import_format.applyLinePrefix)(text, { prefix: indent }),
      ...(0, import_array.ArrayPrototypeSlice)(args, 1)
    ] : args;
    (0, import_reflect.ReflectApply)(
      con[methodName],
      con,
      logArgs
    );
    this[import_symbols.lastWasBlankSymbol](hasText && (0, import_predicates.isBlankString)(logArgs[0]), targetStream);
    this[import_symbols.incLogCallCountSymbol]();
    return this;
  }
  /**
   * Get the Console instance for this logger, creating it lazily on first
   * access.
   *
   * This lazy initialization allows the logger to be imported during early
   * Node.js bootstrap before stdout is ready, avoiding Console initialization
   * errors (ERR_CONSOLE_WRITABLE_STREAM).
   *
   * @private
   */
  #getConsole() {
    (0, import_console.ensurePrototypeInitialized)();
    let con = import_internal.privateConsole.get(this);
    if (!con) {
      const ctorArgs = import_internal.privateConstructorArgs.get(this) ?? [];
      if (ctorArgs.length) {
        con = (0, import_console.constructConsole)(...ctorArgs);
      } else {
        con = (0, import_console.constructConsole)({
          stdout: import_node_process.default.stdout,
          stderr: import_node_process.default.stderr
        });
        for (const { 0: key, 1: method } of import_internal.boundConsoleEntries) {
          con[key] = method;
        }
      }
      import_internal.privateConsole.set(this, con);
      import_internal.privateConstructorArgs.delete(this);
    }
    return con;
  }
  /**
   * Get indentation for a specific stream.
   *
   * @private
   */
  #getIndent(stream) {
    const root = this.#getRoot();
    return stream === "stderr" ? root.#stderrIndention : root.#stdoutIndention;
  }
  /**
   * Get lastWasBlank state for a specific stream.
   *
   * @private
   */
  #getLastWasBlank(stream) {
    const root = this.#getRoot();
    return stream === "stderr" ? root.#stderrLastWasBlank : root.#stdoutLastWasBlank;
  }
  /**
   * Get the root logger (for accessing shared indentation state).
   *
   * @private
   */
  #getRoot() {
    return this.#parent || this;
  }
  /**
   * Get logger-specific symbols using the resolved theme.
   *
   * @private
   */
  #getSymbols() {
    return (0, import_symbols_builder.buildLoggerSymbols)(this.#getTheme());
  }
  /**
   * Get the target stream for this logger instance.
   *
   * @private
   */
  #getTargetStream() {
    return this.#boundStream || "stderr";
  }
  /**
   * Get the resolved theme for this logger instance. Returns instance theme if
   * set, otherwise falls back to context theme.
   *
   * @private
   */
  #getTheme() {
    return this.#theme ?? (0, import_context.getTheme)();
  }
  /**
   * Set indentation for a specific stream.
   *
   * @private
   */
  #setIndent(stream, value) {
    const root = this.#getRoot();
    if (stream === "stderr") {
      root.#stderrIndention = value;
    } else {
      root.#stdoutIndention = value;
    }
  }
  /**
   * Set lastWasBlank state for a specific stream.
   *
   * @private
   */
  #setLastWasBlank(stream, value) {
    const root = this.#getRoot();
    if (stream === "stderr") {
      root.#stderrLastWasBlank = value;
    } else {
      root.#stdoutLastWasBlank = value;
    }
  }
  /**
   * Strip log symbols from the start of text.
   *
   * @private
   */
  #stripSymbols(text) {
    return (0, import_symbols_builder.stripLoggerSymbols)(text);
  }
  /**
   * Apply a method with a symbol prefix.
   *
   * @private
   */
  #symbolApply(symbolType, args) {
    const con = this.#getConsole();
    let text = (0, import_array.ArrayPrototypeAt)(args, 0);
    let extras;
    if (typeof text === "string") {
      text = this.#stripSymbols(text);
      extras = (0, import_array.ArrayPrototypeSlice)(args, 1);
    } else {
      extras = args;
      text = "";
    }
    const indent = this.#getIndent("stderr");
    const symbols = this.#getSymbols();
    con.error(
      (0, import_format.applyLinePrefix)(`${symbols[symbolType]} ${text}`, {
        prefix: indent
      }),
      ...extras
    );
    this[import_symbols.lastWasBlankSymbol](false, "stderr");
    this[import_symbols.incLogCallCountSymbol]();
    return this;
  }
  /**
   * Gets a logger instance bound exclusively to stderr.
   *
   * All logging operations on this instance will write to stderr only.
   * Indentation is tracked separately from stdout. The instance is cached and
   * reused on subsequent accesses.
   *
   * @returns A logger instance bound to stderr
   */
  get stderr() {
    if (!this.#stderrLogger) {
      const ctorArgs = import_internal.privateConstructorArgs.get(this) ?? [];
      const instance = new Logger(...ctorArgs);
      instance.#parent = this;
      instance.#boundStream = "stderr";
      instance.#options = { __proto__: null, ...this.#options };
      if (this.#theme) {
        instance.#theme = this.#theme;
      }
      this.#stderrLogger = instance;
    }
    return this.#stderrLogger;
  }
  /**
   * Gets a logger instance bound exclusively to stdout.
   *
   * All logging operations on this instance will write to stdout only.
   * Indentation is tracked separately from stderr. The instance is cached and
   * reused on subsequent accesses.
   *
   * @returns A logger instance bound to stdout
   */
  get stdout() {
    if (!this.#stdoutLogger) {
      const ctorArgs = import_internal.privateConstructorArgs.get(this) ?? [];
      const instance = new Logger(...ctorArgs);
      instance.#parent = this;
      instance.#boundStream = "stdout";
      instance.#options = { __proto__: null, ...this.#options };
      if (this.#theme) {
        instance.#theme = this.#theme;
      }
      this.#stdoutLogger = instance;
    }
    return this.#stdoutLogger;
  }
  /**
   * Gets the total number of log calls made on this logger instance.
   *
   * Tracks all logging method calls including `log()`, `error()`, `warn()`,
   * `success()`, `fail()`, etc. Useful for testing and monitoring logging
   * activity.
   *
   * @returns The number of times logging methods have been called
   */
  get logCallCount() {
    const root = this.#getRoot();
    return root.#logCallCount;
  }
  /**
   * Increments the internal log call counter.
   *
   * This is called automatically by logging methods and should not be called
   * directly in normal usage.
   */
  [import_symbols.incLogCallCountSymbol]() {
    const root = this.#getRoot();
    root.#logCallCount += 1;
    return this;
  }
  /**
   * Sets whether the last logged line was blank.
   *
   * Used internally to track blank lines and prevent duplicate spacing. This is
   * called automatically by logging methods.
   *
   * @param value - Whether the last line was blank.
   * @param stream - Optional stream to update (defaults to both streams if not
   *   bound, or target stream if bound)
   */
  [import_symbols.lastWasBlankSymbol](value, stream) {
    if (stream) {
      this.#setLastWasBlank(stream, !!value);
    } else if (this.#boundStream) {
      this.#setLastWasBlank(this.#boundStream, !!value);
    } else {
      this.#setLastWasBlank("stderr", !!value);
      this.#setLastWasBlank("stdout", !!value);
    }
    return this;
  }
  /**
   * Logs an assertion failure message if the value is falsy.
   *
   * Works like `console.assert()` but returns the logger for chaining. If the
   * value is truthy, nothing is logged. If falsy, logs an error message with an
   * assertion failure.
   *
   * @param value - The value to test.
   * @param message - Optional message and additional arguments to log.
   */
  assert(value, ...message) {
    const con = this.#getConsole();
    con.assert(value, message[0], ...message.slice(1));
    this[import_symbols.lastWasBlankSymbol](false);
    return value ? this : this[import_symbols.incLogCallCountSymbol]();
  }
  /**
   * Clears the current line in the terminal.
   *
   * Moves the cursor to the beginning of the line and clears all content. Works
   * in both TTY and non-TTY environments. Useful for clearing progress
   * indicators created with `progress()`.
   *
   * The stream to clear (stderr or stdout) depends on whether the logger is
   * stream-bound.
   */
  clearLine() {
    const con = this.#getConsole();
    const stream = this.#getTargetStream();
    const streamObj = stream === "stderr" ? con["_stderr"] : con["_stdout"];
    if (streamObj.isTTY) {
      streamObj.cursorTo(0);
      streamObj.clearLine(0);
    } else {
      streamObj.write("\r\x1B[K");
    }
    return this;
  }
  /**
   * Clears the visible terminal screen.
   *
   * Only available on the main logger instance, not on stream-bound instances
   * (`.stderr` or `.stdout`). Resets the log call count and blank line tracking
   * if the output is a TTY.
   *
   * @throws {Error} If called on a stream-bound logger instance
   */
  clearVisible() {
    if (this.#boundStream) {
      throw new import_error.ErrorCtor(
        "clearVisible() is only available on the main logger instance, not on stream-bound instances"
      );
    }
    const con = this.#getConsole();
    con.clear();
    if (con._stdout.isTTY) {
      ;
      this[import_symbols.lastWasBlankSymbol](true);
      this.#logCallCount = 0;
    }
    return this;
  }
  /**
   * Increments and logs a counter for the given label.
   *
   * Each unique label maintains its own counter. Works like `console.count()`.
   *
   * @default 'default'
   *
   * @param label - Optional label for the counter.
   */
  count(label) {
    const con = this.#getConsole();
    con.count(label);
    this[import_symbols.lastWasBlankSymbol](false);
    return this[import_symbols.incLogCallCountSymbol]();
  }
  /**
   * Creates a task that logs start and completion messages automatically.
   *
   * Returns a task object with a `run()` method that executes the provided
   * function and logs "Starting task: {name}" before execution and "Completed
   * task: {name}" after completion.
   *
   * @param name - The name of the task.
   *
   * @returns A task object with a `run()` method
   */
  createTask(name) {
    return {
      run: (f) => {
        this.log(`Starting task: ${name}`);
        const result = f();
        this.log(`Completed task: ${name}`);
        return result;
      }
    };
  }
  /**
   * Decreases the indentation level by removing spaces from the prefix.
   *
   * When called on the main logger, affects both stderr and stdout indentation.
   * When called on a stream-bound logger (`.stderr` or `.stdout`), affects only
   * that stream's indentation.
   *
   * @default 2
   */
  dedent(spaces = 2) {
    if (this.#boundStream) {
      const current = this.#getIndent(this.#boundStream);
      this.#setIndent(this.#boundStream, current.slice(0, -spaces));
    } else {
      const stderrCurrent = this.#getIndent("stderr");
      const stdoutCurrent = this.#getIndent("stdout");
      this.#setIndent("stderr", stderrCurrent.slice(0, -spaces));
      this.#setIndent("stdout", stdoutCurrent.slice(0, -spaces));
    }
    return this;
  }
  /**
   * Displays an object's properties in a formatted way.
   *
   * Works like `console.dir()` with customizable options for depth, colors,
   * etc. Useful for inspecting complex objects.
   *
   * @param obj - The object to display.
   * @param options - Optional formatting options (Node.js inspect options)
   */
  dir(obj, options) {
    const con = this.#getConsole();
    con.dir(obj, options);
    this[import_symbols.lastWasBlankSymbol](false);
    return this[import_symbols.incLogCallCountSymbol]();
  }
  /**
   * Displays data as XML/HTML in a formatted way.
   *
   * Works like `console.dirxml()`. In Node.js, behaves the same as `dir()`.
   *
   * @param data - The data to display.
   */
  dirxml(...data) {
    const con = this.#getConsole();
    con.dirxml(data);
    this[import_symbols.lastWasBlankSymbol](false);
    return this[import_symbols.incLogCallCountSymbol]();
  }
  /**
   * Logs a completion message with a success symbol (alias for `success()`).
   *
   * Provides semantic clarity when marking something as "done". Does NOT
   * automatically clear the current line - call `clearLine()` first if needed
   * after using `progress()`.
   */
  done(...args) {
    return this.#symbolApply("success", args);
  }
  /**
   * Logs an error message to stderr.
   *
   * Automatically applies current indentation. All arguments are formatted and
   * logged like `console.error()`.
   */
  error(...args) {
    return this.#apply("error", args);
  }
  /**
   * Logs a newline to stderr only if the last line wasn't already blank.
   *
   * Prevents multiple consecutive blank lines. Useful for adding spacing
   * between sections without creating excessive whitespace.
   */
  errorNewline() {
    return this.#getLastWasBlank("stderr") ? this : this.error("");
  }
  /**
   * Logs a failure message with a red colored fail symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.fail` (red ✖). Always
   * outputs to stderr. If the message starts with an existing symbol, it will
   * be stripped and replaced.
   */
  fail(...args) {
    return this.#symbolApply("fail", args);
  }
  /**
   * Starts a new indented log group.
   *
   * If a label is provided, it's logged before increasing indentation. Groups
   * can be nested. Each group increases indentation by the `kGroupIndentWidth`
   * (default 2 spaces). Call `groupEnd()` to close.
   *
   * @param label - Optional label to display before the group.
   */
  group(...label) {
    const { length } = label;
    if (length) {
      (0, import_reflect.ReflectApply)(this.log, this, label);
    }
    this.indent(this[(0, import_symbols.getKGroupIndentationWidthSymbol)()]);
    if (length) {
      ;
      this[import_symbols.lastWasBlankSymbol](false);
      this[import_symbols.incLogCallCountSymbol]();
    }
    return this;
  }
  /**
   * Starts a new collapsed log group (alias for `group()`).
   *
   * In browser consoles, this creates a collapsed group. In Node.js, it behaves
   * identically to `group()`.
   *
   * @param label - Optional label to display before the group.
   */
  // groupCollapsed is an alias of group.
  // https://nodejs.org/api/console.html#consolegroupcollapsed
  groupCollapsed(...label) {
    return (0, import_reflect.ReflectApply)(this.group, this, label);
  }
  /**
   * Ends the current log group and decreases indentation.
   *
   * Must be called once for each `group()` or `groupCollapsed()` call to
   * properly close the group and restore indentation.
   */
  groupEnd() {
    this.dedent(this[(0, import_symbols.getKGroupIndentationWidthSymbol)()]);
    return this;
  }
  /**
   * Increases the indentation level by adding spaces to the prefix.
   *
   * When called on the main logger, affects both stderr and stdout indentation.
   * When called on a stream-bound logger (`.stderr` or `.stdout`), affects only
   * that stream's indentation. Maximum indentation is 1000 spaces.
   *
   * @default 2
   */
  indent(spaces = 2) {
    const spacesToAdd = " ".repeat((0, import_math.MathMin)(spaces, import_internal.maxIndentation));
    if (this.#boundStream) {
      const current = this.#getIndent(this.#boundStream);
      this.#setIndent(this.#boundStream, current + spacesToAdd);
    } else {
      const stderrCurrent = this.#getIndent("stderr");
      const stdoutCurrent = this.#getIndent("stdout");
      this.#setIndent("stderr", stderrCurrent + spacesToAdd);
      this.#setIndent("stdout", stdoutCurrent + spacesToAdd);
    }
    return this;
  }
  /**
   * Logs an informational message with a blue colored info symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.info` (blue ℹ). Always
   * outputs to stderr. If the message starts with an existing symbol, it will
   * be stripped and replaced.
   */
  info(...args) {
    return this.#symbolApply("info", args);
  }
  /**
   * Logs a message to stdout.
   *
   * Automatically applies current indentation. All arguments are formatted and
   * logged like `console.log()`. This is the primary method for standard
   * output.
   */
  log(...args) {
    return this.#apply("log", args);
  }
  /**
   * Logs a newline to stdout only if the last line wasn't already blank.
   *
   * Prevents multiple consecutive blank lines. Useful for adding spacing
   * between sections without creating excessive whitespace.
   */
  logNewline() {
    return this.#getLastWasBlank("stdout") ? this : this.log("");
  }
  /**
   * Shows a progress indicator that can be cleared with `clearLine()`.
   *
   * Displays a simple status message with a '∴' prefix. Does not include
   * animation or spinner. Intended to be cleared once the operation completes.
   * The output stream (stderr or stdout) depends on whether the logger is
   * stream-bound.
   *
   * @param text - The progress message to display.
   */
  progress(text) {
    const con = this.#getConsole();
    const stream = this.#getTargetStream();
    const streamObj = stream === "stderr" ? con["_stderr"] : con["_stdout"];
    const symbols = this.#getSymbols();
    streamObj.write(`${symbols.progress} ${text}`);
    this[import_symbols.lastWasBlankSymbol](false);
    return this;
  }
  /**
   * Resets all indentation to zero.
   *
   * When called on the main logger, resets both stderr and stdout indentation.
   * When called on a stream-bound logger (`.stderr` or `.stdout`), resets only
   * that stream's indentation.
   */
  resetIndent() {
    if (this.#boundStream) {
      this.#setIndent(this.#boundStream, "");
    } else {
      this.#setIndent("stderr", "");
      this.#setIndent("stdout", "");
    }
    return this;
  }
  /**
   * Logs a skip message with a cyan colored skip symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.skip` (cyan ↻). Always
   * outputs to stderr. If the message starts with an existing symbol, it will
   * be stripped and replaced.
   */
  skip(...args) {
    return this.#symbolApply("skip", args);
  }
  /**
   * Logs a main step message with a cyan arrow symbol and blank line before it.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.step` (cyan →) and
   * adds a blank line before the message unless the last line was already
   * blank. Useful for marking major steps in a process with clear visual
   * separation. Always outputs to stdout. If the message starts with an
   * existing symbol, it will be stripped and replaced.
   *
   * @param msg - The step message to log.
   * @param extras - Additional arguments to log.
   */
  step(msg, ...extras) {
    if (!this.#getLastWasBlank("stdout")) {
      this.log("");
    }
    const text = this.#stripSymbols(msg);
    const indent = this.#getIndent("stdout");
    const symbols = this.#getSymbols();
    const con = this.#getConsole();
    con.log(
      (0, import_format.applyLinePrefix)(`${symbols.step} ${text}`, {
        prefix: indent
      }),
      ...extras
    );
    this[import_symbols.lastWasBlankSymbol](false, "stdout");
    this[import_symbols.incLogCallCountSymbol]();
    return this;
  }
  /**
   * Logs an indented substep message (stateless).
   *
   * Adds a 2-space indent to the message without affecting the logger's
   * indentation state. Useful for showing sub-items under a main step.
   *
   * @param msg - The substep message to log.
   * @param extras - Additional arguments to log.
   */
  substep(msg, ...extras) {
    const indentedMsg = `  ${msg}`;
    return this.log(indentedMsg, ...extras);
  }
  /**
   * Logs a success message with a green colored success symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.success` (green ✔).
   * Always outputs to stderr. If the message starts with an existing symbol, it
   * will be stripped and replaced.
   */
  success(...args) {
    return this.#symbolApply("success", args);
  }
  /**
   * Displays data in a table format.
   *
   * Works like `console.table()`. Accepts arrays of objects or objects with
   * nested objects. Optionally specify which properties to include in the
   * table.
   *
   * @param tabularData - The data to display as a table.
   * @param properties - Optional array of property names to include.
   */
  table(tabularData, properties) {
    const con = this.#getConsole();
    con.table(tabularData, properties);
    this[import_symbols.lastWasBlankSymbol](false);
    return this[import_symbols.incLogCallCountSymbol]();
  }
  /**
   * Starts a timer for measuring elapsed time.
   *
   * Creates a timer with the given label. Use `timeEnd()` with the same label
   * to stop the timer and log the elapsed time, or use `timeLog()` to check the
   * time without stopping the timer.
   *
   * @default 'default'
   *
   * @param label - Optional label for the timer.
   */
  time(label) {
    const con = this.#getConsole();
    con.time(label);
    return this;
  }
  /**
   * Ends a timer and logs the elapsed time.
   *
   * Logs the duration since `console.time()` or `logger.time()` was called with
   * the same label. The timer is stopped and removed.
   *
   * @default 'default'
   *
   * @param label - Optional label for the timer.
   */
  timeEnd(label) {
    const con = this.#getConsole();
    con.timeEnd(label);
    this[import_symbols.lastWasBlankSymbol](false);
    return this[import_symbols.incLogCallCountSymbol]();
  }
  /**
   * Logs the current value of a timer without stopping it.
   *
   * Logs the duration since `console.time()` was called with the same label,
   * but keeps the timer running. Can include additional data to log alongside
   * the time.
   *
   * @default 'default'
   *
   * @param label - Optional label for the timer.
   * @param data - Additional data to log with the time.
   */
  timeLog(label, ...data) {
    const con = this.#getConsole();
    con.timeLog(label, ...data);
    this[import_symbols.lastWasBlankSymbol](false);
    return this[import_symbols.incLogCallCountSymbol]();
  }
  /**
   * Logs a stack trace to the console.
   *
   * Works like `console.trace()`. Shows the call stack leading to where this
   * method was called. Useful for debugging.
   *
   * @param message - Optional message to display with the trace.
   * @param args - Additional arguments to log.
   */
  trace(message, ...args) {
    const con = this.#getConsole();
    con.trace(message, ...args);
    this[import_symbols.lastWasBlankSymbol](false);
    return this[import_symbols.incLogCallCountSymbol]();
  }
  /**
   * Logs a warning message with a yellow colored warning symbol.
   *
   * Automatically prefixes the message with `LOG_SYMBOLS.warn` (yellow ⚠).
   * Always outputs to stderr. If the message starts with an existing symbol, it
   * will be stripped and replaced.
   */
  warn(...args) {
    return this.#symbolApply("warn", args);
  }
  /**
   * Writes text directly to stdout without a newline or indentation.
   *
   * Useful for progress indicators or custom formatting where you need
   * low-level control. Does not apply any indentation or formatting.
   *
   * @param text - The text to write.
   */
  write(text) {
    const con = this.#getConsole();
    const ctorArgs = import_internal.privateConstructorArgs.get(this) ?? [];
    const stdout = this.#originalStdout || ctorArgs[0]?.stdout || con._stdout;
    stdout.write(text);
    this[import_symbols.lastWasBlankSymbol](false);
    return this;
  }
}
let _logger;
function getDefaultLogger() {
  if (_logger === void 0) {
    _logger = new Logger();
  }
  return _logger;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Logger,
  getDefaultLogger
});
