"use strict";
/* Socket Lib - Built with esbuild */
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, desc2) => {
  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: !(desc2 = __getOwnPropDesc(from, key)) || desc2.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 spinner_exports = {};
__export(spinner_exports, {
  Spinner: () => Spinner,
  ciSpinner: () => ciSpinner,
  getCliSpinners: () => getCliSpinners,
  getDefaultSpinner: () => getDefaultSpinner,
  withSpinner: () => withSpinner,
  withSpinnerRestore: () => withSpinnerRestore,
  withSpinnerSync: () => withSpinnerSync
});
module.exports = __toCommonJS(spinner_exports);
var import_yoctocolors_cjs = __toESM(require("./external/yoctocolors-cjs"));
var import_colors = require("./colors");
var import_process = require("./constants/process");
var import_ci = require("./env/ci");
var import_debug = require("./debug");
var import_pulse_frames = require("./effects/pulse-frames");
var import_text_shimmer = require("./effects/text-shimmer");
var import_yocto_spinner = __toESM(require("./external/@socketregistry/yocto-spinner"));
var import_logger = require("./logger");
var import_objects = require("./objects");
var import_strings = require("./strings");
var import_context = require("./themes/context");
var import_themes = require("./themes/themes");
var import_utils = require("./themes/utils");
const ciSpinner = {
  frames: [""],
  interval: 2147483647
};
function desc(value) {
  return {
    __proto__: null,
    configurable: true,
    value,
    writable: true
  };
}
function formatProgress(progress) {
  const { current, total, unit } = progress;
  const percentage = Math.round(current / total * 100);
  const bar = renderProgressBar(percentage);
  const count = unit ? `${current}/${total} ${unit}` : `${current}/${total}`;
  return `${bar} ${percentage}% (${count})`;
}
function normalizeText(value) {
  return typeof value === "string" ? value.trimStart() : "";
}
function renderProgressBar(percentage, width = 20) {
  const filled = Math.round(percentage / 100 * width);
  const empty = width - filled;
  const bar = "\u2588".repeat(filled) + "\u2591".repeat(empty);
  return import_yoctocolors_cjs.default.cyan(bar);
}
let _cliSpinners;
// @__NO_SIDE_EFFECTS__
function getCliSpinners(styleName) {
  if (_cliSpinners === void 0) {
    const YoctoCtor = import_yocto_spinner.default;
    const tempInstance = YoctoCtor({});
    const YoctoSpinnerClass = tempInstance.constructor;
    _cliSpinners = {
      __proto__: null,
      ...YoctoSpinnerClass.spinners,
      socket: (0, import_pulse_frames.generateSocketSpinnerFrames)()
    };
  }
  if (typeof styleName === "string" && _cliSpinners) {
    return (0, import_objects.hasOwn)(_cliSpinners, styleName) ? _cliSpinners[styleName] : void 0;
  }
  return _cliSpinners;
}
let _Spinner;
let _defaultSpinner;
// @__NO_SIDE_EFFECTS__
function Spinner(options) {
  if (_Spinner === void 0) {
    const YoctoCtor = import_yocto_spinner.default;
    const tempInstance = YoctoCtor({});
    const YoctoSpinnerClass = tempInstance.constructor;
    const logger = (0, import_logger.getDefaultLogger)();
    _Spinner = class SpinnerClass extends YoctoSpinnerClass {
      #baseText = "";
      #indentation = "";
      #progress;
      #shimmer;
      #shimmerSavedConfig;
      constructor(options2) {
        const opts = { __proto__: null, ...options2 };
        let theme = (0, import_context.getTheme)();
        if (opts.theme) {
          if (typeof opts.theme === "string") {
            theme = import_themes.THEMES[opts.theme];
          } else {
            theme = opts.theme;
          }
        }
        let defaultColor = theme.colors.primary;
        if (theme.effects?.spinner?.color) {
          const resolved = (0, import_utils.resolveColor)(
            theme.effects.spinner.color,
            theme.colors
          );
          if (resolved === "inherit" || Array.isArray(resolved[0])) {
            defaultColor = theme.colors.primary;
          } else {
            defaultColor = resolved;
          }
        }
        const spinnerColor = opts.color ?? defaultColor;
        if ((0, import_colors.isRgbTuple)(spinnerColor) && (spinnerColor.length !== 3 || !spinnerColor.every(
          (n) => typeof n === "number" && n >= 0 && n <= 255
        ))) {
          throw new TypeError(
            "RGB color must be an array of 3 numbers between 0 and 255"
          );
        }
        const spinnerColorRgb = (0, import_colors.toRgb)(spinnerColor);
        let shimmerInfo;
        if (opts.shimmer) {
          let shimmerDir;
          let shimmerColor;
          let shimmerSpeed = 1 / 3;
          if (typeof opts.shimmer === "string") {
            shimmerDir = opts.shimmer;
          } else {
            const shimmerConfig = {
              __proto__: null,
              ...opts.shimmer
            };
            shimmerDir = shimmerConfig.dir ?? import_text_shimmer.DIR_LTR;
            shimmerColor = shimmerConfig.color ?? import_text_shimmer.COLOR_INHERIT;
            shimmerSpeed = shimmerConfig.speed ?? 1 / 3;
          }
          shimmerInfo = {
            __proto__: null,
            color: shimmerColor === void 0 ? import_text_shimmer.COLOR_INHERIT : shimmerColor,
            currentDir: import_text_shimmer.DIR_LTR,
            mode: shimmerDir,
            speed: shimmerSpeed,
            step: 0
          };
        }
        super({
          signal: (0, import_process.getAbortSignal)(),
          ...opts,
          // Pass RGB color directly to yocto-spinner (it now supports RGB).
          color: spinnerColorRgb,
          // onRenderFrame callback provides full control over frame + text layout.
          // Calculates spacing based on frame width to prevent text jumping.
          onRenderFrame: (frame, text, applyColor) => {
            const width = (0, import_strings.stringWidth)(frame);
            const spacing = width === 1 ? "  " : " ";
            return frame ? `${applyColor(frame)}${spacing}${text}` : text;
          },
          // onFrameUpdate callback is called by yocto-spinner whenever a frame advances.
          // This ensures shimmer updates are perfectly synchronized with animation beats.
          onFrameUpdate: shimmerInfo ? () => {
            if (this.#baseText) {
              super.text = this.#buildDisplayText();
            }
          } : void 0
        });
        this.#shimmer = shimmerInfo;
        this.#shimmerSavedConfig = shimmerInfo;
      }
      // Override color getter to ensure it's always RGB.
      get color() {
        const value = super.color;
        return (0, import_colors.isRgbTuple)(value) ? value : (0, import_colors.toRgb)(value);
      }
      // Override color setter to always convert to RGB before passing to yocto-spinner.
      set color(value) {
        super.color = (0, import_colors.isRgbTuple)(value) ? value : (0, import_colors.toRgb)(value);
      }
      // Getter to expose current shimmer state.
      get shimmerState() {
        if (!this.#shimmer) {
          return void 0;
        }
        return {
          color: this.#shimmer.color,
          currentDir: this.#shimmer.currentDir,
          mode: this.#shimmer.mode,
          speed: this.#shimmer.speed,
          step: this.#shimmer.step
        };
      }
      /**
       * Apply a yocto-spinner method and update logger state.
       * Handles text normalization, extra arguments, and logger tracking.
       * @private
       */
      #apply(methodName, args) {
        let extras;
        let text = args.at(0);
        if (typeof text === "string") {
          extras = args.slice(1);
        } else {
          extras = args;
          text = "";
        }
        const wasSpinning = this.isSpinning;
        const normalized = normalizeText(text);
        if (methodName === "stop" && !normalized) {
          super[methodName]();
        } else {
          super[methodName](normalized);
        }
        if (methodName === "stop") {
          if (wasSpinning && normalized) {
            logger[import_logger.lastWasBlankSymbol]((0, import_strings.isBlankString)(normalized));
            logger[import_logger.incLogCallCountSymbol]();
          }
        } else {
          logger[import_logger.lastWasBlankSymbol](false);
          logger[import_logger.incLogCallCountSymbol]();
        }
        if (extras.length) {
          logger.log(...extras);
          logger[import_logger.lastWasBlankSymbol](false);
        }
        return this;
      }
      /**
       * Build the complete display text with progress, shimmer, and indentation.
       * Combines base text, progress bar, shimmer effects, and indentation.
       * @private
       */
      #buildDisplayText() {
        let displayText = this.#baseText;
        if (this.#progress) {
          const progressText = formatProgress(this.#progress);
          displayText = displayText ? `${displayText} ${progressText}` : progressText;
        }
        if (displayText && this.#shimmer) {
          let shimmerColor;
          if (this.#shimmer.color === import_text_shimmer.COLOR_INHERIT) {
            shimmerColor = this.color;
          } else if (Array.isArray(this.#shimmer.color[0])) {
            shimmerColor = this.#shimmer.color;
          } else {
            shimmerColor = (0, import_colors.toRgb)(this.#shimmer.color);
          }
          displayText = (0, import_text_shimmer.applyShimmer)(displayText, this.#shimmer, {
            color: shimmerColor,
            direction: this.#shimmer.mode
          });
        }
        if (this.#indentation && displayText) {
          displayText = this.#indentation + displayText;
        }
        return displayText;
      }
      /**
       * Show a status message without stopping the spinner.
       * Outputs the symbol and message to stderr, then continues spinning.
       * @private
       */
      #showStatusAndKeepSpinning(symbolType, args) {
        let text = args.at(0);
        let extras;
        if (typeof text === "string") {
          extras = args.slice(1);
        } else {
          extras = args;
          text = "";
        }
        logger.error(`${import_logger.LOG_SYMBOLS[symbolType]} ${text}`, ...extras);
        return this;
      }
      /**
       * Update the spinner's displayed text.
       * Rebuilds display text and triggers render.
       * @private
       */
      #updateSpinnerText() {
        super.text = this.#buildDisplayText();
      }
      /**
       * Show a debug message (ℹ) without stopping the spinner.
       * Only displays if debug mode is enabled via environment variable.
       * Outputs to stderr and continues spinning.
       *
       * @param text - Debug message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      debug(text, ...extras) {
        if ((0, import_debug.isDebug)()) {
          return this.#showStatusAndKeepSpinning("info", [text, ...extras]);
        }
        return this;
      }
      /**
       * Show a debug message (ℹ) and stop the spinner.
       * Only displays if debug mode is enabled via environment variable.
       * Auto-clears the spinner line before displaying the message.
       *
       * @param text - Debug message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      debugAndStop(text, ...extras) {
        if ((0, import_debug.isDebug)()) {
          return this.#apply("info", [text, ...extras]);
        }
        return this;
      }
      /**
       * Decrease indentation level by removing spaces from the left.
       * Pass 0 to reset indentation to zero completely.
       *
       * @param spaces - Number of spaces to remove
       * @returns This spinner for chaining
       * @default spaces=2
       *
       * @example
       * ```ts
       * spinner.dedent()    // Remove 2 spaces
       * spinner.dedent(4)   // Remove 4 spaces
       * spinner.dedent(0)   // Reset to zero indentation
       * ```
       */
      dedent(spaces) {
        if (spaces === 0) {
          this.#indentation = "";
        } else {
          const amount = spaces ?? 2;
          const newLength = Math.max(0, this.#indentation.length - amount);
          this.#indentation = this.#indentation.slice(0, newLength);
        }
        this.#updateSpinnerText();
        return this;
      }
      /**
       * Disable shimmer effect.
       * Preserves config for later re-enable via enableShimmer().
       *
       * @returns This spinner for chaining
       *
       * @example
       * spinner.disableShimmer()
       */
      disableShimmer() {
        this.#shimmer = void 0;
        this.#updateSpinnerText();
        return this;
      }
      /**
       * Show a done/success message (✓) without stopping the spinner.
       * Alias for `success()` with a shorter name.
       *
       * DESIGN DECISION: Unlike yocto-spinner, our `done()` does NOT stop the spinner.
       * Use `doneAndStop()` if you want to stop the spinner.
       *
       * @param text - Message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      done(text, ...extras) {
        return this.#showStatusAndKeepSpinning("success", [text, ...extras]);
      }
      /**
       * Show a done/success message (✓) and stop the spinner.
       * Auto-clears the spinner line before displaying the success message.
       *
       * @param text - Message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      doneAndStop(text, ...extras) {
        return this.#apply("success", [text, ...extras]);
      }
      /**
       * Enable shimmer effect.
       * Restores saved config or uses defaults if no saved config exists.
       *
       * @returns This spinner for chaining
       *
       * @example
       * spinner.enableShimmer()
       */
      enableShimmer() {
        if (this.#shimmerSavedConfig) {
          this.#shimmer = { ...this.#shimmerSavedConfig };
        } else {
          this.#shimmer = {
            color: import_text_shimmer.COLOR_INHERIT,
            currentDir: import_text_shimmer.DIR_LTR,
            mode: import_text_shimmer.DIR_LTR,
            speed: 1 / 3,
            step: 0
          };
          this.#shimmerSavedConfig = this.#shimmer;
        }
        this.#updateSpinnerText();
        return this;
      }
      /**
       * Show a failure message (✗) without stopping the spinner.
       * DESIGN DECISION: Unlike yocto-spinner, our `fail()` does NOT stop the spinner.
       * This allows displaying errors while continuing to spin.
       * Use `failAndStop()` if you want to stop the spinner.
       *
       * @param text - Error message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      fail(text, ...extras) {
        return this.#showStatusAndKeepSpinning("fail", [text, ...extras]);
      }
      /**
       * Show a failure message (✗) and stop the spinner.
       * Auto-clears the spinner line before displaying the error message.
       *
       * @param text - Error message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      failAndStop(text, ...extras) {
        return this.#apply("error", [text, ...extras]);
      }
      /**
       * Increase indentation level by adding spaces to the left.
       * Pass 0 to reset indentation to zero completely.
       *
       * @param spaces - Number of spaces to add
       * @returns This spinner for chaining
       * @default spaces=2
       *
       * @example
       * ```ts
       * spinner.indent()    // Add 2 spaces
       * spinner.indent(4)   // Add 4 spaces
       * spinner.indent(0)   // Reset to zero indentation
       * ```
       */
      indent(spaces) {
        if (spaces === 0) {
          this.#indentation = "";
        } else {
          const amount = spaces ?? 2;
          this.#indentation += " ".repeat(amount);
        }
        this.#updateSpinnerText();
        return this;
      }
      /**
       * Show an info message (ℹ) without stopping the spinner.
       * Outputs to stderr and continues spinning.
       *
       * @param text - Info message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      info(text, ...extras) {
        return this.#showStatusAndKeepSpinning("info", [text, ...extras]);
      }
      /**
       * Show an info message (ℹ) and stop the spinner.
       * Auto-clears the spinner line before displaying the message.
       *
       * @param text - Info message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      infoAndStop(text, ...extras) {
        return this.#apply("info", [text, ...extras]);
      }
      /**
       * Log a message to stdout without stopping the spinner.
       * Unlike other status methods, this outputs to stdout for data logging.
       *
       * @param args - Values to log to stdout
       * @returns This spinner for chaining
       */
      log(...args) {
        logger.log(...args);
        return this;
      }
      /**
       * Log a message to stdout and stop the spinner.
       * Auto-clears the spinner line before displaying the message.
       *
       * @param text - Message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      logAndStop(text, ...extras) {
        return this.#apply("stop", [text, ...extras]);
      }
      /**
       * Update progress information displayed with the spinner.
       * Shows a progress bar with percentage and optional unit label.
       *
       * @param current - Current progress value
       * @param total - Total/maximum progress value
       * @param unit - Optional unit label (e.g., 'files', 'items')
       * @returns This spinner for chaining
       *
       * @example
       * ```ts
       * spinner.progress(5, 10)            // "███████░░░░░░░░░░░░░ 50% (5/10)"
       * spinner.progress(7, 20, 'files')   // "███████░░░░░░░░░░░░░ 35% (7/20 files)"
       * ```
       */
      progress = (current, total, unit) => {
        this.#progress = {
          __proto__: null,
          current,
          total,
          ...unit ? { unit } : {}
        };
        this.#updateSpinnerText();
        return this;
      };
      /**
       * Increment progress by a specified amount.
       * Updates the progress bar displayed with the spinner.
       * Clamps the result between 0 and the total value.
       *
       * @param amount - Amount to increment by
       * @returns This spinner for chaining
       * @default amount=1
       *
       * @example
       * ```ts
       * spinner.progress(0, 10, 'files')
       * spinner.progressStep()    // Progress: 1/10
       * spinner.progressStep(3)   // Progress: 4/10
       * ```
       */
      progressStep(amount = 1) {
        if (this.#progress) {
          const newCurrent = this.#progress.current + amount;
          this.#progress = {
            __proto__: null,
            current: Math.max(0, Math.min(newCurrent, this.#progress.total)),
            total: this.#progress.total,
            ...this.#progress.unit ? { unit: this.#progress.unit } : {}
          };
          this.#updateSpinnerText();
        }
        return this;
      }
      /**
       * Show a skip message (↻) without stopping the spinner.
       * Outputs to stderr and continues spinning.
       *
       * @param text - Skip message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      skip(text, ...extras) {
        return this.#showStatusAndKeepSpinning("skip", [text, ...extras]);
      }
      /**
       * Show a skip message (↻) and stop the spinner.
       * Auto-clears the spinner line before displaying the message.
       *
       * Implementation note: Unlike other *AndStop methods (successAndStop, failAndStop, etc.),
       * this method cannot use #apply() with a 'skip' method name because yocto-spinner doesn't
       * have a built-in 'skip' method. Instead, we manually stop the spinner then log the message
       * with the skip symbol.
       *
       * @param text - Skip message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      skipAndStop(text, ...extras) {
        this.#apply("stop", []);
        const normalized = normalizeText(text);
        if (normalized) {
          logger.error(`${import_logger.LOG_SYMBOLS.skip} ${normalized}`, ...extras);
        }
        return this;
      }
      /**
       * Set complete shimmer configuration.
       * Replaces any existing shimmer config with the provided values.
       * Undefined properties will use default values.
       *
       * @param config - Complete shimmer configuration
       * @returns This spinner for chaining
       *
       * @example
       * spinner.setShimmer({
       *   color: [255, 0, 0],
       *   dir: 'rtl',
       *   speed: 0.5
       * })
       */
      setShimmer(config) {
        this.#shimmer = {
          color: config.color ?? import_text_shimmer.COLOR_INHERIT,
          currentDir: import_text_shimmer.DIR_LTR,
          mode: config.dir ?? import_text_shimmer.DIR_LTR,
          speed: config.speed ?? 1 / 3,
          step: 0
        };
        this.#shimmerSavedConfig = this.#shimmer;
        this.#updateSpinnerText();
        return this;
      }
      /**
       * Start the spinner animation with optional text.
       * Begins displaying the animated spinner on stderr.
       *
       * @param text - Optional text to display with the spinner
       * @returns This spinner for chaining
       *
       * @example
       * ```ts
       * spinner.start('Loading…')
       * // Later:
       * spinner.successAndStop('Done!')
       * ```
       */
      start(...args) {
        if (args.length) {
          const text = args.at(0);
          const normalized = normalizeText(text);
          if (!normalized) {
            this.#baseText = "";
            super.text = "";
          } else {
            this.#baseText = normalized;
          }
        }
        this.#updateSpinnerText();
        return this.#apply("start", []);
      }
      /**
       * Log a main step message to stderr without stopping the spinner.
       * Adds a blank line before the message for visual separation.
       * Aligns with `logger.step()` to use stderr for status messages.
       *
       * @param text - Step message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       *
       * @example
       * ```ts
       * spinner.step('Building application')
       * spinner.substep('Compiling TypeScript')
       * spinner.substep('Bundling assets')
       * ```
       */
      step(text, ...extras) {
        if (typeof text === "string") {
          logger.error("");
          logger.error(text, ...extras);
        }
        return this;
      }
      /**
       * Stop the spinner animation and clear internal state.
       * Auto-clears the spinner line via yocto-spinner.stop().
       * Resets progress, shimmer, and text state.
       *
       * @param text - Optional final text to display after stopping
       * @returns This spinner for chaining
       *
       * @example
       * ```ts
       * spinner.start('Processing…')
       * // Do work
       * spinner.stop() // Just stop, no message
       * // or
       * spinner.stop('Finished processing')
       * ```
       */
      stop(...args) {
        this.#baseText = "";
        this.#progress = void 0;
        this.#shimmer = void 0;
        const result = this.#apply("stop", args);
        return result;
      }
      /**
       * Log an indented substep message to stderr without stopping the spinner.
       * Adds 2-space indentation to the message.
       * Aligns with `logger.substep()` to use stderr for status messages.
       *
       * @param text - Substep message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       *
       * @example
       * ```ts
       * spinner.step('Building application')
       * spinner.substep('Compiling TypeScript')
       * spinner.substep('Bundling assets')
       * ```
       */
      substep(text, ...extras) {
        if (typeof text === "string") {
          logger.error(`  ${text}`, ...extras);
        }
        return this;
      }
      /**
       * Show a success message (✓) without stopping the spinner.
       * DESIGN DECISION: Unlike yocto-spinner, our `success()` does NOT stop the spinner.
       * This allows displaying success messages while continuing to spin for multi-step operations.
       * Use `successAndStop()` if you want to stop the spinner.
       *
       * @param text - Success message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      success(text, ...extras) {
        return this.#showStatusAndKeepSpinning("success", [text, ...extras]);
      }
      /**
       * Show a success message (✓) and stop the spinner.
       * Auto-clears the spinner line before displaying the success message.
       *
       * @param text - Success message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      successAndStop(text, ...extras) {
        return this.#apply("success", [text, ...extras]);
      }
      text(value) {
        if (arguments.length === 0) {
          return this.#baseText;
        }
        this.#baseText = value ?? "";
        this.#updateSpinnerText();
        return this;
      }
      /**
       * Update partial shimmer configuration.
       * Merges with existing config, enabling shimmer if currently disabled.
       *
       * @param config - Partial shimmer configuration to merge
       * @returns This spinner for chaining
       *
       * @example
       * // Update just the speed
       * spinner.updateShimmer({ speed: 0.5 })
       *
       * // Update direction
       * spinner.updateShimmer({ dir: 'rtl' })
       *
       * // Update multiple properties
       * spinner.updateShimmer({ color: [255, 0, 0], speed: 0.8 })
       */
      updateShimmer(config) {
        const partialConfig = {
          __proto__: null,
          ...config
        };
        if (this.#shimmer) {
          this.#shimmer = {
            ...this.#shimmer,
            ...partialConfig.color !== void 0 ? { color: partialConfig.color } : {},
            ...partialConfig.dir !== void 0 ? { mode: partialConfig.dir } : {},
            ...partialConfig.speed !== void 0 ? { speed: partialConfig.speed } : {}
          };
          this.#shimmerSavedConfig = this.#shimmer;
        } else if (this.#shimmerSavedConfig) {
          this.#shimmer = {
            ...this.#shimmerSavedConfig,
            ...partialConfig.color !== void 0 ? { color: partialConfig.color } : {},
            ...partialConfig.dir !== void 0 ? { mode: partialConfig.dir } : {},
            ...partialConfig.speed !== void 0 ? { speed: partialConfig.speed } : {}
          };
          this.#shimmerSavedConfig = this.#shimmer;
        } else {
          this.#shimmer = {
            color: partialConfig.color ?? import_text_shimmer.COLOR_INHERIT,
            currentDir: import_text_shimmer.DIR_LTR,
            mode: partialConfig.dir ?? import_text_shimmer.DIR_LTR,
            speed: partialConfig.speed ?? 1 / 3,
            step: 0
          };
          this.#shimmerSavedConfig = this.#shimmer;
        }
        this.#updateSpinnerText();
        return this;
      }
      /**
       * Show a warning message (⚠) without stopping the spinner.
       * Outputs to stderr and continues spinning.
       *
       * @param text - Warning message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      warn(text, ...extras) {
        return this.#showStatusAndKeepSpinning("warn", [text, ...extras]);
      }
      /**
       * Show a warning message (⚠) and stop the spinner.
       * Auto-clears the spinner line before displaying the warning message.
       *
       * @param text - Warning message to display
       * @param extras - Additional values to log
       * @returns This spinner for chaining
       */
      warnAndStop(text, ...extras) {
        return this.#apply("warning", [text, ...extras]);
      }
    };
    Object.defineProperties(_Spinner.prototype, {
      error: desc(_Spinner.prototype.fail),
      errorAndStop: desc(_Spinner.prototype.failAndStop),
      warning: desc(_Spinner.prototype.warn),
      warningAndStop: desc(_Spinner.prototype.warnAndStop)
    });
    _defaultSpinner = (0, import_ci.getCI)() ? ciSpinner : /* @__PURE__ */ getCliSpinners("socket");
  }
  return new _Spinner({
    spinner: _defaultSpinner,
    ...options
  });
}
let _spinner;
function getDefaultSpinner() {
  if (_spinner === void 0) {
    _spinner = /* @__PURE__ */ Spinner();
  }
  return _spinner;
}
async function withSpinner(options) {
  const { message, operation, spinner, withOptions } = {
    __proto__: null,
    ...options
  };
  if (!spinner) {
    return await operation();
  }
  const savedColor = withOptions?.color !== void 0 ? spinner.color : void 0;
  const savedShimmerState = withOptions?.shimmer !== void 0 ? spinner.shimmerState : void 0;
  if (withOptions?.color !== void 0) {
    spinner.color = (0, import_colors.toRgb)(withOptions.color);
  }
  if (withOptions?.shimmer !== void 0) {
    if (typeof withOptions.shimmer === "string") {
      spinner.updateShimmer({ dir: withOptions.shimmer });
    } else {
      spinner.setShimmer(withOptions.shimmer);
    }
  }
  spinner.start(message);
  try {
    return await operation();
  } finally {
    const wasSpinning = spinner.isSpinning;
    spinner.stop();
    if (wasSpinning) {
      process.stderr.write("\r\x1B[2K");
    }
    if (savedColor !== void 0) {
      spinner.color = savedColor;
    }
    if (withOptions?.shimmer !== void 0) {
      if (savedShimmerState) {
        spinner.setShimmer({
          color: savedShimmerState.color,
          dir: savedShimmerState.mode,
          speed: savedShimmerState.speed
        });
      } else {
        spinner.disableShimmer();
      }
    }
  }
}
async function withSpinnerRestore(options) {
  const { operation, spinner, wasSpinning } = {
    __proto__: null,
    ...options
  };
  try {
    return await operation();
  } finally {
    if (spinner && wasSpinning) {
      spinner.start();
    }
  }
}
function withSpinnerSync(options) {
  const { message, operation, spinner, withOptions } = {
    __proto__: null,
    ...options
  };
  if (!spinner) {
    return operation();
  }
  const savedColor = withOptions?.color !== void 0 ? spinner.color : void 0;
  const savedShimmerState = withOptions?.shimmer !== void 0 ? spinner.shimmerState : void 0;
  if (withOptions?.color !== void 0) {
    spinner.color = (0, import_colors.toRgb)(withOptions.color);
  }
  if (withOptions?.shimmer !== void 0) {
    if (typeof withOptions.shimmer === "string") {
      spinner.updateShimmer({ dir: withOptions.shimmer });
    } else {
      spinner.setShimmer(withOptions.shimmer);
    }
  }
  spinner.start(message);
  try {
    return operation();
  } finally {
    spinner.stop();
    if (savedColor !== void 0) {
      spinner.color = savedColor;
    }
    if (withOptions?.shimmer !== void 0) {
      if (savedShimmerState) {
        spinner.setShimmer({
          color: savedShimmerState.color,
          dir: savedShimmerState.mode,
          speed: savedShimmerState.speed
        });
      } else {
        spinner.disableShimmer();
      }
    }
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Spinner,
  ciSpinner,
  getCliSpinners,
  getDefaultSpinner,
  withSpinner,
  withSpinnerRestore,
  withSpinnerSync
});
