"use strict";
/* Socket Lib - Built with rolldown */
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../_virtual/_rolldown/runtime.js');
const require_primordials_error = require('../primordials/error.js');
const require_primordials_math = require('../primordials/math.js');
const require_primordials_array = require('../primordials/array.js');
const require_primordials_object = require('../primordials/object.js');
const require_strings_predicates = require('../strings/predicates.js');
const require_themes_themes = require('../themes/themes.js');
const require_themes_context = require('../themes/context.js');
const require_logger_symbols = require('../logger/symbols.js');
const require_logger_default = require('../logger/default.js');
const require_process_abort = require('../process/abort.js');
const require_colors_convert = require('../colors/convert.js');
const require_debug_namespace = require('../debug/namespace.js');
const require_effects_shimmer = require('../effects/shimmer.js');
const require_effects_shimmer_terminal = require('../effects/shimmer-terminal.js');
const require_env_ci = require('../env/ci.js');
const require_strings_width = require('../strings/width.js');
const require_themes_resolve = require('../themes/resolve.js');
const require_spinner_format = require('./format.js');
const require_spinner_default = require('./default.js');
let src_external__socketregistry_yocto_spinner = require("../external/@socketregistry/yocto-spinner");
src_external__socketregistry_yocto_spinner = require_runtime.__toESM(src_external__socketregistry_yocto_spinner);

//#region src/spinner/spinner.ts
let _Spinner;
let _defaultSpinner;
/**
* Create a spinner instance for displaying loading indicators. Provides an
* animated CLI spinner with status messages, progress tracking, and shimmer
* effects.
*
* AUTO-CLEAR BEHAVIOR:
*
* - All *AndStop() methods AUTO-CLEAR the spinner line via yocto-spinner.stop()
*   Examples: `doneAndStop()`, `successAndStop()`, `failAndStop()`, etc.
* - Methods WITHOUT "AndStop" do NOT clear (spinner keeps spinning) Examples:
*   `done()`, `success()`, `fail()`, etc.
*
* STREAM USAGE:
*
* - Spinner animation: stderr (yocto-spinner default)
* - Status methods (done, success, fail, info, warn, step, substep): stderr
* - Data methods (`log()`): stdout
*
* COMPARISON WITH LOGGER:
*
* - `logger.done()` does NOT auto-clear (requires manual `logger.clearLine()`)
* - `spinner.doneAndStop()` DOES auto-clear (built into yocto-spinner.stop())
* - Pattern: `logger.clearLine().done()` vs `spinner.doneAndStop()`
*
* @param options - Configuration options for the spinner.
*
* @returns New spinner instance
*/
/*@__NO_SIDE_EFFECTS__*/
function Spinner(options) {
	if (_Spinner === void 0) {
		const YoctoSpinnerClass = (0, src_external__socketregistry_yocto_spinner.default)({}).constructor;
		/* c8 ignore stop */
		const logger = require_logger_default.getDefaultLogger();
		_Spinner = class SpinnerClass extends YoctoSpinnerClass {
			#baseText = "";
			#indentation = "";
			#progress;
			#shimmer;
			#shimmerSavedConfig;
			constructor(options) {
				const opts = {
					__proto__: null,
					...options
				};
				let theme = require_themes_context.getTheme();
				if (opts.theme) if (typeof opts.theme === "string") theme = require_themes_themes.THEMES[opts.theme] ?? theme;
				else theme = opts.theme;
				let defaultColor = theme.colors.primary;
				if (theme.effects?.spinner?.color) {
					const resolved = require_themes_resolve.resolveColor(theme.effects.spinner.color, theme.colors);
					if (resolved === "inherit" || require_primordials_array.ArrayIsArray(resolved[0])) defaultColor = theme.colors.primary;
					else defaultColor = resolved;
				}
				const spinnerColor = opts.color ?? defaultColor;
				if (require_colors_convert.isRgbTuple(spinnerColor) && (spinnerColor.length !== 3 || !spinnerColor.every((n) => typeof n === "number" && n >= 0 && n <= 255))) throw new require_primordials_error.TypeErrorCtor("RGB color must be an array of 3 numbers between 0 and 255");
				const spinnerColorRgb = require_colors_convert.toRgb(spinnerColor);
				let shimmerInfo;
				if (opts.shimmer) {
					let shimmerDir;
					let shimmerColor;
					let shimmerSpeed = 1 / 3;
					if (typeof opts.shimmer === "string") {
						shimmerDir = opts.shimmer;
						shimmerColor = require_spinner_format.COLOR_INHERIT;
					} else {
						const shimmerConfig = {
							__proto__: null,
							...opts.shimmer
						};
						shimmerDir = shimmerConfig.dir ?? "ltr";
						shimmerColor = shimmerConfig.color ?? "inherit";
						shimmerSpeed = shimmerConfig.speed ?? 1 / 3;
					}
					shimmerInfo = {
						__proto__: null,
						color: shimmerColor,
						direction: shimmerDir,
						speed: shimmerSpeed,
						frame: 0
					};
				}
				super({
					signal: require_process_abort.getAbortSignal(),
					...opts,
					color: spinnerColorRgb,
					onRenderFrame: (frame, text, applyColor) => {
						const spacing = /* @__PURE__ */ require_strings_width.stringWidth(frame) === 1 ? "  " : " ";
						return frame ? `${applyColor(frame)}${spacing}${text}` : text;
					},
					onFrameUpdate: shimmerInfo ? () => {
						if (this.#baseText) super.text = this.#buildDisplayText();
					} : void 0
				});
				this.#shimmer = shimmerInfo;
				this.#shimmerSavedConfig = shimmerInfo;
			}
			get color() {
				const value = super.color;
				return require_colors_convert.isRgbTuple(value) ? value : require_colors_convert.toRgb(value);
			}
			set color(value) {
				super.color = require_colors_convert.isRgbTuple(value) ? value : require_colors_convert.toRgb(value);
			}
			get shimmerState() {
				if (!this.#shimmer) return;
				return {
					__proto__: null,
					color: this.#shimmer.color,
					direction: this.#shimmer.direction,
					speed: this.#shimmer.speed,
					frame: this.#shimmer.frame
				};
			}
			/**
			* 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 = require_primordials_array.ArrayPrototypeAt(args, 0);
				if (typeof text === "string") extras = require_primordials_array.ArrayPrototypeSlice(args, 1);
				else {
					extras = args;
					text = "";
				}
				const wasSpinning = this.isSpinning;
				const normalized = require_spinner_format.normalizeText(text);
				if (methodName === "stop" && !normalized) super[methodName]();
				else super[methodName](normalized);
				if (methodName === "stop") {
					if (wasSpinning && normalized) {
						logger[require_logger_symbols.lastWasBlankSymbol](/* @__PURE__ */ require_strings_predicates.isBlankString(normalized));
						logger[require_logger_symbols.incLogCallCountSymbol]();
					}
				} else {
					logger[require_logger_symbols.lastWasBlankSymbol](false);
					logger[require_logger_symbols.incLogCallCountSymbol]();
				}
				/* c8 ignore start */
				if (extras.length) {
					logger.log(...extras);
					logger[require_logger_symbols.lastWasBlankSymbol](false);
				}
				/* c8 ignore stop */
				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;
				/* c8 ignore start */
				if (this.#progress) {
					const progressText = require_spinner_format.formatProgress(this.#progress);
					displayText = displayText ? `${displayText} ${progressText}` : progressText;
				}
				if (displayText && this.#shimmer) {
					let shimmerColor;
					if (this.#shimmer.color === "inherit") shimmerColor = this.color;
					else if (require_primordials_array.ArrayIsArray(this.#shimmer.color[0])) shimmerColor = this.#shimmer.color;
					else shimmerColor = require_colors_convert.toRgb(this.#shimmer.color);
					if (!/* @__PURE__ */ require_env_ci.getCI() && this.#shimmer.direction !== "none") {
						const chars = [...displayText];
						const colors = require_effects_shimmer.frameColors(require_effects_shimmer.configToSpec({
							color: shimmerColor,
							dir: this.#shimmer.direction,
							speed: this.#shimmer.speed
						}, chars.length), chars.length, this.#shimmer.frame);
						displayText = require_effects_shimmer_terminal.colorsToAnsi(displayText, colors);
						this.#shimmer.frame++;
					}
				}
				if (this.#indentation && displayText) displayText = this.#indentation + displayText;
				/* c8 ignore stop */
				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 = require_primordials_array.ArrayPrototypeAt(args, 0);
				let extras;
				if (typeof text === "string") extras = require_primordials_array.ArrayPrototypeSlice(args, 1);
				else {
					extras = args;
					text = "";
				}
				logger.error(`${require_logger_symbols.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 (/* @__PURE__ */ require_debug_namespace.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 (/* @__PURE__ */ require_debug_namespace.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.
			*
			* @default spaces=2
			*
			* @param spaces - Number of spaces to remove.
			*
			* @returns This spinner for chaining
			*/
			dedent(spaces) {
				if (spaces === 0) this.#indentation = "";
				else {
					const amount = spaces ?? 2;
					const newLength = require_primordials_math.MathMax(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().
			*
			* @example
			*   spinner.disableShimmer()
			*
			* @returns This spinner for chaining
			*/
			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.
			*
			* @example
			*   spinner.enableShimmer()
			*
			* @returns This spinner for chaining
			*/
			enableShimmer() {
				if (this.#shimmerSavedConfig) this.#shimmer = {
					...this.#shimmerSavedConfig,
					frame: 0
				};
				else {
					this.#shimmer = {
						__proto__: null,
						color: require_spinner_format.COLOR_INHERIT,
						direction: "ltr",
						speed: 1 / 3,
						frame: 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.
			*
			* @default spaces=2
			*
			* @param spaces - Number of spaces to add.
			*
			* @returns This spinner for chaining
			*/
			indent(spaces) {
				/* c8 ignore start */
				if (spaces === 0) this.#indentation = "";
				else {
					const amount = spaces ?? 2;
					this.#indentation += " ".repeat(amount);
				}
				/* c8 ignore stop */
				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
			*/
			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.
			*
			* @default amount=1
			*
			* @param amount - Amount to increment by.
			*
			* @returns This spinner for chaining
			*/
			progressStep(amount = 1) {
				/* c8 ignore start */
				if (this.#progress) {
					const newCurrent = this.#progress.current + amount;
					this.#progress = {
						__proto__: null,
						current: require_primordials_math.MathMax(0, Math.min(newCurrent, this.#progress.total)),
						total: this.#progress.total,
						...this.#progress.unit ? { unit: this.#progress.unit } : {}
					};
					this.#updateSpinnerText();
				}
				return this;
				/* c8 ignore stop */
			}
			/**
			* 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 = require_spinner_format.normalizeText(text);
				/* c8 ignore start */
				if (normalized) logger.error(`${require_logger_symbols.LOG_SYMBOLS["skip"]} ${normalized}`, ...extras);
				return this;
				/* c8 ignore stop */
			}
			/**
			* Set complete shimmer configuration. Replaces any existing shimmer
			* config with the provided values. Undefined properties will use default
			* values.
			*
			* @example
			*   spinner.setShimmer({
			*     color: [255, 0, 0],
			*     dir: 'rtl',
			*     speed: 0.5,
			*   })
			*
			* @param config - Complete shimmer configuration.
			*
			* @returns This spinner for chaining
			*/
			setShimmer(config) {
				this.#shimmer = {
					__proto__: null,
					color: config.color ?? "inherit",
					direction: config.dir ?? "ltr",
					speed: config.speed ?? 1 / 3,
					frame: 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
			*/
			start(...args) {
				/* c8 ignore start */
				if (args.length) {
					const normalized = require_spinner_format.normalizeText(require_primordials_array.ArrayPrototypeAt(args, 0));
					if (!normalized) {
						this.#baseText = "";
						super.text = "";
					} else this.#baseText = normalized;
				}
				/* c8 ignore stop */
				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
			*/
			step(text, ...extras) {
				/* c8 ignore start */
				if (typeof text === "string") {
					logger.error("");
					logger.error(text, ...extras);
				}
				return this;
				/* c8 ignore stop */
			}
			/**
			* 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
			*/
			stop(...args) {
				this.#baseText = "";
				this.#progress = void 0;
				this.#shimmer = void 0;
				return this.#apply("stop", args);
			}
			/**
			* 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
			*/
			substep(text, ...extras) {
				/* c8 ignore start */
				if (typeof text === "string") logger.error(`  ${text}`, ...extras);
				return this;
				/* c8 ignore stop */
			}
			/**
			* 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.
			*
			* @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 })
			*
			* @param config - Partial shimmer configuration to merge.
			*
			* @returns This spinner for chaining
			*/
			updateShimmer(config) {
				/* c8 ignore start */
				const partialConfig = {
					__proto__: null,
					...config
				};
				const update = { __proto__: null };
				if (partialConfig.color !== void 0) update.color = partialConfig.color;
				if (partialConfig.dir !== void 0) update.direction = partialConfig.dir;
				if (partialConfig.speed !== void 0) update.speed = partialConfig.speed;
				if (this.#shimmer) this.#shimmer = {
					...this.#shimmer,
					...update
				};
				else if (this.#shimmerSavedConfig) this.#shimmer = {
					...this.#shimmerSavedConfig,
					...update,
					frame: 0
				};
				else this.#shimmer = {
					__proto__: null,
					color: require_spinner_format.COLOR_INHERIT,
					direction: "ltr",
					speed: 1 / 3,
					frame: 0,
					...update
				};
				this.#shimmerSavedConfig = this.#shimmer;
				this.#updateSpinnerText();
				return this;
				/* c8 ignore stop */
			}
			/**
			* 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]);
			}
		};
		require_primordials_object.ObjectDefineProperties(_Spinner.prototype, {
			error: require_spinner_format.desc(_Spinner.prototype.fail),
			errorAndStop: require_spinner_format.desc(_Spinner.prototype.failAndStop),
			warning: require_spinner_format.desc(_Spinner.prototype.warn),
			warningAndStop: require_spinner_format.desc(_Spinner.prototype.warnAndStop)
		});
		/* c8 ignore start */
		_defaultSpinner = /* @__PURE__ */ require_env_ci.getCI() ? require_spinner_format.ciSpinner : /* @__PURE__ */ require_spinner_default.getCliSpinners("socket");
	}
	return new _Spinner({
		spinner: _defaultSpinner,
		...options
	});
}

//#endregion
exports.Spinner = Spinner;