+ */
+class HelpCommand extends Command
+{
+ /**
+ * @var \Symfony\Component\Console\Command\Command
+ */
+ private $command;
+ /**
+ * @return void
+ */
+ protected function configure()
+ {
+ $this->ignoreValidationErrors();
+ $this->setName('help')->setDefinition([new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help', function () {
+ return \array_keys((new ApplicationDescription($this->getApplication()))->getCommands());
+ }), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt', function () {
+ return (new DescriptorHelper())->getFormats();
+ }), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help')])->setDescription('Display help for a command')->setHelp(<<<'EOF'
+The %command.name% command displays help for a given command:
+
+ %command.full_name% list
+
+You can also output the help in other formats by using the --format option:
+
+ %command.full_name% --format=xml list
+
+To display the list of available commands, please use the list command.
+EOF
+);
+ }
+ /**
+ * @return void
+ */
+ public function setCommand(Command $command)
+ {
+ $this->command = $command;
+ }
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $this->command = $this->command ?? $this->getApplication()->find($input->getArgument('command_name'));
+ $helper = new DescriptorHelper();
+ $helper->describe($output, $this->command, ['format' => $input->getOption('format'), 'raw_text' => $input->getOption('raw')]);
+ unset($this->command);
+ return 0;
+ }
+}
diff --git a/vendor/symfony/console/Command/LazyCommand.php b/vendor/symfony/console/Command/LazyCommand.php
new file mode 100644
index 00000000..08db492d
--- /dev/null
+++ b/vendor/symfony/console/Command/LazyCommand.php
@@ -0,0 +1,188 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Command;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionInput;
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionSuggestions;
+use VendorPatches202401\Symfony\Component\Console\Completion\Suggestion;
+use VendorPatches202401\Symfony\Component\Console\Helper\HelperInterface;
+use VendorPatches202401\Symfony\Component\Console\Helper\HelperSet;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * @author Nicolas Grekas
+ */
+final class LazyCommand extends Command
+{
+ /**
+ * @var \Closure|\Symfony\Component\Console\Command\Command
+ */
+ private $command;
+ /**
+ * @var bool|null
+ */
+ private $isEnabled;
+ public function __construct(string $name, array $aliases, string $description, bool $isHidden, \Closure $commandFactory, ?bool $isEnabled = \true)
+ {
+ $this->setName($name)->setAliases($aliases)->setHidden($isHidden)->setDescription($description);
+ $this->command = $commandFactory;
+ $this->isEnabled = $isEnabled;
+ }
+ public function ignoreValidationErrors() : void
+ {
+ $this->getCommand()->ignoreValidationErrors();
+ }
+ public function setApplication(Application $application = null) : void
+ {
+ if (1 > \func_num_args()) {
+ trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
+ }
+ if ($this->command instanceof parent) {
+ $this->command->setApplication($application);
+ }
+ parent::setApplication($application);
+ }
+ public function setHelperSet(HelperSet $helperSet) : void
+ {
+ if ($this->command instanceof parent) {
+ $this->command->setHelperSet($helperSet);
+ }
+ parent::setHelperSet($helperSet);
+ }
+ public function isEnabled() : bool
+ {
+ return $this->isEnabled ?? $this->getCommand()->isEnabled();
+ }
+ public function run(InputInterface $input, OutputInterface $output) : int
+ {
+ return $this->getCommand()->run($input, $output);
+ }
+ public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
+ {
+ $this->getCommand()->complete($input, $suggestions);
+ }
+ /**
+ * @return static
+ */
+ public function setCode(callable $code)
+ {
+ $this->getCommand()->setCode($code);
+ return $this;
+ }
+ /**
+ * @internal
+ */
+ public function mergeApplicationDefinition(bool $mergeArgs = \true) : void
+ {
+ $this->getCommand()->mergeApplicationDefinition($mergeArgs);
+ }
+ /**
+ * @param mixed[]|\Symfony\Component\Console\Input\InputDefinition $definition
+ * @return static
+ */
+ public function setDefinition($definition)
+ {
+ $this->getCommand()->setDefinition($definition);
+ return $this;
+ }
+ public function getDefinition() : InputDefinition
+ {
+ return $this->getCommand()->getDefinition();
+ }
+ public function getNativeDefinition() : InputDefinition
+ {
+ return $this->getCommand()->getNativeDefinition();
+ }
+ /**
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ * @param mixed $default
+ * @return static
+ */
+ public function addArgument(string $name, int $mode = null, string $description = '', $default = null)
+ {
+ $suggestedValues = 5 <= \func_num_args() ? \func_get_arg(4) : [];
+ $this->getCommand()->addArgument($name, $mode, $description, $default, $suggestedValues);
+ return $this;
+ }
+ /**
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ * @param string|mixed[] $shortcut
+ * @param mixed $default
+ * @return static
+ */
+ public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
+ {
+ $suggestedValues = 6 <= \func_num_args() ? \func_get_arg(5) : [];
+ $this->getCommand()->addOption($name, $shortcut, $mode, $description, $default, $suggestedValues);
+ return $this;
+ }
+ /**
+ * @return static
+ */
+ public function setProcessTitle(string $title)
+ {
+ $this->getCommand()->setProcessTitle($title);
+ return $this;
+ }
+ /**
+ * @return static
+ */
+ public function setHelp(string $help)
+ {
+ $this->getCommand()->setHelp($help);
+ return $this;
+ }
+ public function getHelp() : string
+ {
+ return $this->getCommand()->getHelp();
+ }
+ public function getProcessedHelp() : string
+ {
+ return $this->getCommand()->getProcessedHelp();
+ }
+ public function getSynopsis(bool $short = \false) : string
+ {
+ return $this->getCommand()->getSynopsis($short);
+ }
+ /**
+ * @return static
+ */
+ public function addUsage(string $usage)
+ {
+ $this->getCommand()->addUsage($usage);
+ return $this;
+ }
+ public function getUsages() : array
+ {
+ return $this->getCommand()->getUsages();
+ }
+ public function getHelper(string $name) : HelperInterface
+ {
+ return $this->getCommand()->getHelper($name);
+ }
+ public function getCommand() : parent
+ {
+ if (!$this->command instanceof \Closure) {
+ return $this->command;
+ }
+ $command = $this->command = ($this->command)();
+ $command->setApplication($this->getApplication());
+ if (null !== $this->getHelperSet()) {
+ $command->setHelperSet($this->getHelperSet());
+ }
+ $command->setName($this->getName())->setAliases($this->getAliases())->setHidden($this->isHidden())->setDescription($this->getDescription());
+ // Will throw if the command is not correctly initialized.
+ $command->getDefinition();
+ return $command;
+ }
+}
diff --git a/vendor/symfony/console/Command/ListCommand.php b/vendor/symfony/console/Command/ListCommand.php
new file mode 100644
index 00000000..d575fdc7
--- /dev/null
+++ b/vendor/symfony/console/Command/ListCommand.php
@@ -0,0 +1,60 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Command;
+
+use VendorPatches202401\Symfony\Component\Console\Descriptor\ApplicationDescription;
+use VendorPatches202401\Symfony\Component\Console\Helper\DescriptorHelper;
+use VendorPatches202401\Symfony\Component\Console\Input\InputArgument;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * ListCommand displays the list of all available commands for the application.
+ *
+ * @author Fabien Potencier
+ */
+class ListCommand extends Command
+{
+ /**
+ * @return void
+ */
+ protected function configure()
+ {
+ $this->setName('list')->setDefinition([new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name', null, function () {
+ return \array_keys((new ApplicationDescription($this->getApplication()))->getNamespaces());
+ }), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt', function () {
+ return (new DescriptorHelper())->getFormats();
+ }), new InputOption('short', null, InputOption::VALUE_NONE, 'To skip describing commands\' arguments')])->setDescription('List commands')->setHelp(<<<'EOF'
+The %command.name% command lists all commands:
+
+ %command.full_name%
+
+You can also display the commands for a specific namespace:
+
+ %command.full_name% test
+
+You can also output the information in other formats by using the --format option:
+
+ %command.full_name% --format=xml
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ %command.full_name% --raw
+EOF
+);
+ }
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $helper = new DescriptorHelper();
+ $helper->describe($output, $this->getApplication(), ['format' => $input->getOption('format'), 'raw_text' => $input->getOption('raw'), 'namespace' => $input->getArgument('namespace'), 'short' => $input->getOption('short')]);
+ return 0;
+ }
+}
diff --git a/vendor/symfony/console/Command/LockableTrait.php b/vendor/symfony/console/Command/LockableTrait.php
new file mode 100644
index 00000000..b0bde012
--- /dev/null
+++ b/vendor/symfony/console/Command/LockableTrait.php
@@ -0,0 +1,62 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Command;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\LogicException;
+use VendorPatches202401\Symfony\Component\Lock\LockFactory;
+use VendorPatches202401\Symfony\Component\Lock\LockInterface;
+use VendorPatches202401\Symfony\Component\Lock\Store\FlockStore;
+use VendorPatches202401\Symfony\Component\Lock\Store\SemaphoreStore;
+/**
+ * Basic lock feature for commands.
+ *
+ * @author Geoffrey Brier
+ */
+trait LockableTrait
+{
+ /**
+ * @var \Symfony\Component\Lock\LockInterface|null
+ */
+ private $lock;
+ /**
+ * Locks a command.
+ */
+ private function lock(string $name = null, bool $blocking = \false) : bool
+ {
+ if (!\class_exists(SemaphoreStore::class)) {
+ throw new LogicException('To enable the locking feature you must install the symfony/lock component. Try running "composer require symfony/lock".');
+ }
+ if (null !== $this->lock) {
+ throw new LogicException('A lock is already in place.');
+ }
+ if (SemaphoreStore::isSupported()) {
+ $store = new SemaphoreStore();
+ } else {
+ $store = new FlockStore();
+ }
+ $this->lock = (new LockFactory($store))->createLock($name ?: $this->getName());
+ if (!$this->lock->acquire($blocking)) {
+ $this->lock = null;
+ return \false;
+ }
+ return \true;
+ }
+ /**
+ * Releases the command lock if there is one.
+ */
+ private function release() : void
+ {
+ if ($this->lock) {
+ $this->lock->release();
+ $this->lock = null;
+ }
+ }
+}
diff --git a/vendor/symfony/console/Command/SignalableCommandInterface.php b/vendor/symfony/console/Command/SignalableCommandInterface.php
new file mode 100644
index 00000000..5dc32369
--- /dev/null
+++ b/vendor/symfony/console/Command/SignalableCommandInterface.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Command;
+
+/**
+ * Interface for command reacting to signal.
+ *
+ * @author Grégoire Pineau
+ */
+interface SignalableCommandInterface
+{
+ /**
+ * Returns the list of signals to subscribe.
+ */
+ public function getSubscribedSignals() : array;
+ /**
+ * The method will be called when the application is signaled.
+ *
+ * @param int|false $previousExitCode
+ *
+ * @return int|false The exit code to return or false to continue the normal execution
+ */
+ public function handleSignal(int $signal);
+}
diff --git a/vendor/symfony/console/Command/TraceableCommand.php b/vendor/symfony/console/Command/TraceableCommand.php
new file mode 100644
index 00000000..6b3866d7
--- /dev/null
+++ b/vendor/symfony/console/Command/TraceableCommand.php
@@ -0,0 +1,340 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Command;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionInput;
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionSuggestions;
+use VendorPatches202401\Symfony\Component\Console\Helper\HelperInterface;
+use VendorPatches202401\Symfony\Component\Console\Helper\HelperSet;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\ConsoleOutputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Component\Stopwatch\Stopwatch;
+/**
+ * @internal
+ *
+ * @author Jules Pietri
+ */
+final class TraceableCommand extends Command implements SignalableCommandInterface
+{
+ /**
+ * @readonly
+ * @var \Symfony\Component\Stopwatch\Stopwatch
+ */
+ private $stopwatch;
+ /**
+ * @readonly
+ * @var \Symfony\Component\Console\Command\Command
+ */
+ public $command;
+ /**
+ * @var int
+ */
+ public $exitCode;
+ /**
+ * @var int|null
+ */
+ public $interruptedBySignal;
+ /**
+ * @var bool
+ */
+ public $ignoreValidation;
+ /**
+ * @var bool
+ */
+ public $isInteractive = \false;
+ /**
+ * @var string
+ */
+ public $duration = 'n/a';
+ /**
+ * @var string
+ */
+ public $maxMemoryUsage = 'n/a';
+ /**
+ * @var \Symfony\Component\Console\Input\InputInterface
+ */
+ public $input;
+ /**
+ * @var \Symfony\Component\Console\Output\OutputInterface
+ */
+ public $output;
+ /** @var array */
+ public $arguments;
+ /** @var array */
+ public $options;
+ /** @var array */
+ public $interactiveInputs = [];
+ /**
+ * @var mixed[]
+ */
+ public $handledSignals = [];
+ public function __construct(Command $command, Stopwatch $stopwatch)
+ {
+ $this->stopwatch = $stopwatch;
+ if ($command instanceof LazyCommand) {
+ $command = $command->getCommand();
+ }
+ $this->command = $command;
+ // prevent call to self::getDefaultDescription()
+ $this->setDescription($command->getDescription());
+ parent::__construct($command->getName());
+ // init below enables calling {@see parent::run()}
+ [$code, $processTitle, $ignoreValidationErrors] = \Closure::bind(function () {
+ return [$this->code, $this->processTitle, $this->ignoreValidationErrors];
+ }, $command, Command::class)();
+ if (\is_callable($code)) {
+ $this->setCode($code);
+ }
+ if ($processTitle) {
+ parent::setProcessTitle($processTitle);
+ }
+ if ($ignoreValidationErrors) {
+ parent::ignoreValidationErrors();
+ }
+ $this->ignoreValidation = $ignoreValidationErrors;
+ }
+ /**
+ * @return mixed
+ */
+ public function __call(string $name, array $arguments)
+ {
+ return $this->command->{$name}(...$arguments);
+ }
+ public function getSubscribedSignals() : array
+ {
+ return $this->command instanceof SignalableCommandInterface ? $this->command->getSubscribedSignals() : [];
+ }
+ /**
+ * @param int|false $previousExitCode
+ * @return int|false
+ */
+ public function handleSignal(int $signal, $previousExitCode = 0)
+ {
+ if (!$this->command instanceof SignalableCommandInterface) {
+ return \false;
+ }
+ $event = $this->stopwatch->start($this->getName() . '.handle_signal');
+ $exit = $this->command->handleSignal($signal, $previousExitCode);
+ $event->stop();
+ if (!isset($this->handledSignals[$signal])) {
+ $this->handledSignals[$signal] = ['handled' => 0, 'duration' => 0, 'memory' => 0];
+ }
+ ++$this->handledSignals[$signal]['handled'];
+ $this->handledSignals[$signal]['duration'] += $event->getDuration();
+ $this->handledSignals[$signal]['memory'] = \max($this->handledSignals[$signal]['memory'], $event->getMemory() >> 20);
+ return $exit;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * Calling parent method is required to be used in {@see parent::run()}.
+ */
+ public function ignoreValidationErrors() : void
+ {
+ $this->ignoreValidation = \true;
+ $this->command->ignoreValidationErrors();
+ parent::ignoreValidationErrors();
+ }
+ public function setApplication(Application $application = null) : void
+ {
+ $this->command->setApplication($application);
+ }
+ public function getApplication() : ?Application
+ {
+ return $this->command->getApplication();
+ }
+ public function setHelperSet(HelperSet $helperSet) : void
+ {
+ $this->command->setHelperSet($helperSet);
+ }
+ public function getHelperSet() : ?HelperSet
+ {
+ return $this->command->getHelperSet();
+ }
+ public function isEnabled() : bool
+ {
+ return $this->command->isEnabled();
+ }
+ public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
+ {
+ $this->command->complete($input, $suggestions);
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * Calling parent method is required to be used in {@see parent::run()}.
+ * @return static
+ */
+ public function setCode(callable $code)
+ {
+ $this->command->setCode($code);
+ return parent::setCode(function (InputInterface $input, OutputInterface $output) use($code) : int {
+ $event = $this->stopwatch->start($this->getName() . '.code');
+ $this->exitCode = $code($input, $output);
+ $event->stop();
+ return $this->exitCode;
+ });
+ }
+ /**
+ * @internal
+ */
+ public function mergeApplicationDefinition(bool $mergeArgs = \true) : void
+ {
+ $this->command->mergeApplicationDefinition($mergeArgs);
+ }
+ /**
+ * @param mixed[]|\Symfony\Component\Console\Input\InputDefinition $definition
+ * @return static
+ */
+ public function setDefinition($definition)
+ {
+ $this->command->setDefinition($definition);
+ return $this;
+ }
+ public function getDefinition() : InputDefinition
+ {
+ return $this->command->getDefinition();
+ }
+ public function getNativeDefinition() : InputDefinition
+ {
+ return $this->command->getNativeDefinition();
+ }
+ /**
+ * @param mixed[]|\Closure $suggestedValues
+ * @param mixed $default
+ * @return static
+ */
+ public function addArgument(string $name, int $mode = null, string $description = '', $default = null, $suggestedValues = [])
+ {
+ $this->command->addArgument($name, $mode, $description, $default, $suggestedValues);
+ return $this;
+ }
+ /**
+ * @param string|mixed[] $shortcut
+ * @param mixed[]|\Closure $suggestedValues
+ * @param mixed $default
+ * @return static
+ */
+ public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null, $suggestedValues = [])
+ {
+ $this->command->addOption($name, $shortcut, $mode, $description, $default, $suggestedValues);
+ return $this;
+ }
+ /**
+ * {@inheritdoc}
+ *
+ * Calling parent method is required to be used in {@see parent::run()}.
+ * @return static
+ */
+ public function setProcessTitle(string $title)
+ {
+ $this->command->setProcessTitle($title);
+ return parent::setProcessTitle($title);
+ }
+ /**
+ * @return static
+ */
+ public function setHelp(string $help)
+ {
+ $this->command->setHelp($help);
+ return $this;
+ }
+ public function getHelp() : string
+ {
+ return $this->command->getHelp();
+ }
+ public function getProcessedHelp() : string
+ {
+ return $this->command->getProcessedHelp();
+ }
+ public function getSynopsis(bool $short = \false) : string
+ {
+ return $this->command->getSynopsis($short);
+ }
+ /**
+ * @return static
+ */
+ public function addUsage(string $usage)
+ {
+ $this->command->addUsage($usage);
+ return $this;
+ }
+ public function getUsages() : array
+ {
+ return $this->command->getUsages();
+ }
+ public function getHelper(string $name) : HelperInterface
+ {
+ return $this->command->getHelper($name);
+ }
+ public function run(InputInterface $input, OutputInterface $output) : int
+ {
+ $this->input = $input;
+ $this->output = $output;
+ $this->arguments = $input->getArguments();
+ $this->options = $input->getOptions();
+ $event = $this->stopwatch->start($this->getName(), 'command');
+ try {
+ $this->exitCode = parent::run($input, $output);
+ } finally {
+ $event->stop();
+ if ($output instanceof ConsoleOutputInterface && $output->isDebug()) {
+ $output->getErrorOutput()->writeln((string) $event);
+ }
+ $this->duration = $event->getDuration() . ' ms';
+ $this->maxMemoryUsage = ($event->getMemory() >> 20) . ' MiB';
+ if ($this->isInteractive) {
+ $this->extractInteractiveInputs($input->getArguments(), $input->getOptions());
+ }
+ }
+ return $this->exitCode;
+ }
+ protected function initialize(InputInterface $input, OutputInterface $output) : void
+ {
+ $event = $this->stopwatch->start($this->getName() . '.init', 'command');
+ $this->command->initialize($input, $output);
+ $event->stop();
+ }
+ protected function interact(InputInterface $input, OutputInterface $output) : void
+ {
+ if (!($this->isInteractive = Command::class !== (new \ReflectionMethod($this->command, 'interact'))->getDeclaringClass()->getName())) {
+ return;
+ }
+ $event = $this->stopwatch->start($this->getName() . '.interact', 'command');
+ $this->command->interact($input, $output);
+ $event->stop();
+ }
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $event = $this->stopwatch->start($this->getName() . '.execute', 'command');
+ $exitCode = $this->command->execute($input, $output);
+ $event->stop();
+ return $exitCode;
+ }
+ private function extractInteractiveInputs(array $arguments, array $options) : void
+ {
+ foreach ($arguments as $argName => $argValue) {
+ if (\array_key_exists($argName, $this->arguments) && $this->arguments[$argName] === $argValue) {
+ continue;
+ }
+ $this->interactiveInputs[$argName] = $argValue;
+ }
+ foreach ($options as $optName => $optValue) {
+ if (\array_key_exists($optName, $this->options) && $this->options[$optName] === $optValue) {
+ continue;
+ }
+ $this->interactiveInputs['--' . $optName] = $optValue;
+ }
+ }
+}
diff --git a/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php b/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php
new file mode 100644
index 00000000..c19121e9
--- /dev/null
+++ b/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php
@@ -0,0 +1,34 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\CommandLoader;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Exception\CommandNotFoundException;
+/**
+ * @author Robin Chalas
+ */
+interface CommandLoaderInterface
+{
+ /**
+ * Loads a command.
+ *
+ * @throws CommandNotFoundException
+ */
+ public function get(string $name) : Command;
+ /**
+ * Checks if a command exists.
+ */
+ public function has(string $name) : bool;
+ /**
+ * @return string[]
+ */
+ public function getNames() : array;
+}
diff --git a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php
new file mode 100644
index 00000000..3bfb9957
--- /dev/null
+++ b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php
@@ -0,0 +1,54 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\CommandLoader;
+
+use VendorPatches202401\Psr\Container\ContainerInterface;
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Exception\CommandNotFoundException;
+/**
+ * Loads commands from a PSR-11 container.
+ *
+ * @author Robin Chalas
+ */
+class ContainerCommandLoader implements CommandLoaderInterface
+{
+ /**
+ * @var \Psr\Container\ContainerInterface
+ */
+ private $container;
+ /**
+ * @var mixed[]
+ */
+ private $commandMap;
+ /**
+ * @param array $commandMap An array with command names as keys and service ids as values
+ */
+ public function __construct(ContainerInterface $container, array $commandMap)
+ {
+ $this->container = $container;
+ $this->commandMap = $commandMap;
+ }
+ public function get(string $name) : Command
+ {
+ if (!$this->has($name)) {
+ throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name));
+ }
+ return $this->container->get($this->commandMap[$name]);
+ }
+ public function has(string $name) : bool
+ {
+ return isset($this->commandMap[$name]) && $this->container->has($this->commandMap[$name]);
+ }
+ public function getNames() : array
+ {
+ return \array_keys($this->commandMap);
+ }
+}
diff --git a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php
new file mode 100644
index 00000000..518c7e10
--- /dev/null
+++ b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\CommandLoader;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Exception\CommandNotFoundException;
+/**
+ * A simple command loader using factories to instantiate commands lazily.
+ *
+ * @author Maxime Steinhausser
+ */
+class FactoryCommandLoader implements CommandLoaderInterface
+{
+ /**
+ * @var mixed[]
+ */
+ private $factories;
+ /**
+ * @param callable[] $factories Indexed by command names
+ */
+ public function __construct(array $factories)
+ {
+ $this->factories = $factories;
+ }
+ public function has(string $name) : bool
+ {
+ return isset($this->factories[$name]);
+ }
+ public function get(string $name) : Command
+ {
+ if (!isset($this->factories[$name])) {
+ throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name));
+ }
+ $factory = $this->factories[$name];
+ return $factory();
+ }
+ public function getNames() : array
+ {
+ return \array_keys($this->factories);
+ }
+}
diff --git a/vendor/symfony/console/Completion/CompletionInput.php b/vendor/symfony/console/Completion/CompletionInput.php
new file mode 100644
index 00000000..ad12d688
--- /dev/null
+++ b/vendor/symfony/console/Completion/CompletionInput.php
@@ -0,0 +1,227 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Completion;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\RuntimeException;
+use VendorPatches202401\Symfony\Component\Console\Input\ArgvInput;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+/**
+ * An input specialized for shell completion.
+ *
+ * This input allows unfinished option names or values and exposes what kind of
+ * completion is expected.
+ *
+ * @author Wouter de Jong
+ */
+final class CompletionInput extends ArgvInput
+{
+ public const TYPE_ARGUMENT_VALUE = 'argument_value';
+ public const TYPE_OPTION_VALUE = 'option_value';
+ public const TYPE_OPTION_NAME = 'option_name';
+ public const TYPE_NONE = 'none';
+ /**
+ * @var mixed[]
+ */
+ private $tokens;
+ /**
+ * @var int
+ */
+ private $currentIndex;
+ /**
+ * @var string
+ */
+ private $completionType;
+ /**
+ * @var string|null
+ */
+ private $completionName;
+ /**
+ * @var string
+ */
+ private $completionValue = '';
+ /**
+ * Converts a terminal string into tokens.
+ *
+ * This is required for shell completions without COMP_WORDS support.
+ */
+ public static function fromString(string $inputStr, int $currentIndex) : self
+ {
+ \preg_match_all('/(?<=^|\\s)([\'"]?)(.+?)(?tokens = $tokens;
+ $input->currentIndex = $currentIndex;
+ return $input;
+ }
+ public function bind(InputDefinition $definition) : void
+ {
+ parent::bind($definition);
+ $relevantToken = $this->getRelevantToken();
+ if ('-' === $relevantToken[0]) {
+ // the current token is an input option: complete either option name or option value
+ [$optionToken, $optionValue] = \explode('=', $relevantToken, 2) + ['', ''];
+ $option = $this->getOptionFromToken($optionToken);
+ if (null === $option && !$this->isCursorFree()) {
+ $this->completionType = self::TYPE_OPTION_NAME;
+ $this->completionValue = $relevantToken;
+ return;
+ }
+ if (($nullsafeVariable1 = $option) ? $nullsafeVariable1->acceptValue() : null) {
+ $this->completionType = self::TYPE_OPTION_VALUE;
+ $this->completionName = $option->getName();
+ $this->completionValue = $optionValue ?: (\strncmp($optionToken, '--', \strlen('--')) !== 0 ? \substr($optionToken, 2) : '');
+ return;
+ }
+ }
+ $previousToken = $this->tokens[$this->currentIndex - 1];
+ if ('-' === $previousToken[0] && '' !== \trim($previousToken, '-')) {
+ // check if previous option accepted a value
+ $previousOption = $this->getOptionFromToken($previousToken);
+ if (($nullsafeVariable2 = $previousOption) ? $nullsafeVariable2->acceptValue() : null) {
+ $this->completionType = self::TYPE_OPTION_VALUE;
+ $this->completionName = $previousOption->getName();
+ $this->completionValue = $relevantToken;
+ return;
+ }
+ }
+ // complete argument value
+ $this->completionType = self::TYPE_ARGUMENT_VALUE;
+ foreach ($this->definition->getArguments() as $argumentName => $argument) {
+ if (!isset($this->arguments[$argumentName])) {
+ break;
+ }
+ $argumentValue = $this->arguments[$argumentName];
+ $this->completionName = $argumentName;
+ if (\is_array($argumentValue)) {
+ \end($argumentValue);
+ $this->completionValue = $argumentValue ? $argumentValue[\key($argumentValue)] : null;
+ } else {
+ $this->completionValue = $argumentValue;
+ }
+ }
+ if ($this->currentIndex >= \count($this->tokens)) {
+ if (!isset($this->arguments[$argumentName]) || $this->definition->getArgument($argumentName)->isArray()) {
+ $this->completionName = $argumentName;
+ $this->completionValue = '';
+ } else {
+ // we've reached the end
+ $this->completionType = self::TYPE_NONE;
+ $this->completionName = null;
+ $this->completionValue = '';
+ }
+ }
+ }
+ /**
+ * Returns the type of completion required.
+ *
+ * TYPE_ARGUMENT_VALUE when completing the value of an input argument
+ * TYPE_OPTION_VALUE when completing the value of an input option
+ * TYPE_OPTION_NAME when completing the name of an input option
+ * TYPE_NONE when nothing should be completed
+ *
+ * TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component.
+ *
+ * @return self::TYPE_*
+ */
+ public function getCompletionType() : string
+ {
+ return $this->completionType;
+ }
+ /**
+ * The name of the input option or argument when completing a value.
+ *
+ * @return string|null returns null when completing an option name
+ */
+ public function getCompletionName() : ?string
+ {
+ return $this->completionName;
+ }
+ /**
+ * The value already typed by the user (or empty string).
+ */
+ public function getCompletionValue() : string
+ {
+ return $this->completionValue;
+ }
+ public function mustSuggestOptionValuesFor(string $optionName) : bool
+ {
+ return self::TYPE_OPTION_VALUE === $this->getCompletionType() && $optionName === $this->getCompletionName();
+ }
+ public function mustSuggestArgumentValuesFor(string $argumentName) : bool
+ {
+ return self::TYPE_ARGUMENT_VALUE === $this->getCompletionType() && $argumentName === $this->getCompletionName();
+ }
+ protected function parseToken(string $token, bool $parseOptions) : bool
+ {
+ try {
+ return parent::parseToken($token, $parseOptions);
+ } catch (RuntimeException $exception) {
+ // suppress errors, completed input is almost never valid
+ }
+ return $parseOptions;
+ }
+ private function getOptionFromToken(string $optionToken) : ?InputOption
+ {
+ $optionName = \ltrim($optionToken, '-');
+ if (!$optionName) {
+ return null;
+ }
+ if ('-' === ($optionToken[1] ?? ' ')) {
+ // long option name
+ return $this->definition->hasOption($optionName) ? $this->definition->getOption($optionName) : null;
+ }
+ // short option name
+ return $this->definition->hasShortcut($optionName[0]) ? $this->definition->getOptionForShortcut($optionName[0]) : null;
+ }
+ /**
+ * The token of the cursor, or the last token if the cursor is at the end of the input.
+ */
+ private function getRelevantToken() : string
+ {
+ return $this->tokens[$this->isCursorFree() ? $this->currentIndex - 1 : $this->currentIndex];
+ }
+ /**
+ * Whether the cursor is "free" (i.e. at the end of the input preceded by a space).
+ */
+ private function isCursorFree() : bool
+ {
+ $nrOfTokens = \count($this->tokens);
+ if ($this->currentIndex > $nrOfTokens) {
+ throw new \LogicException('Current index is invalid, it must be the number of input tokens or one more.');
+ }
+ return $this->currentIndex >= $nrOfTokens;
+ }
+ public function __toString() : string
+ {
+ $str = '';
+ foreach ($this->tokens as $i => $token) {
+ $str .= $token;
+ if ($this->currentIndex === $i) {
+ $str .= '|';
+ }
+ $str .= ' ';
+ }
+ if ($this->currentIndex > $i) {
+ $str .= '|';
+ }
+ return \rtrim($str);
+ }
+}
diff --git a/vendor/symfony/console/Completion/CompletionSuggestions.php b/vendor/symfony/console/Completion/CompletionSuggestions.php
new file mode 100644
index 00000000..85c7c807
--- /dev/null
+++ b/vendor/symfony/console/Completion/CompletionSuggestions.php
@@ -0,0 +1,92 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Completion;
+
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+/**
+ * Stores all completion suggestions for the current input.
+ *
+ * @author Wouter de Jong
+ */
+final class CompletionSuggestions
+{
+ /**
+ * @var mixed[]
+ */
+ private $valueSuggestions = [];
+ /**
+ * @var mixed[]
+ */
+ private $optionSuggestions = [];
+ /**
+ * Add a suggested value for an input option or argument.
+ *
+ * @return $this
+ * @param string|\Symfony\Component\Console\Completion\Suggestion $value
+ */
+ public function suggestValue($value)
+ {
+ $this->valueSuggestions[] = !$value instanceof Suggestion ? new Suggestion($value) : $value;
+ return $this;
+ }
+ /**
+ * Add multiple suggested values at once for an input option or argument.
+ *
+ * @param list $values
+ *
+ * @return $this
+ */
+ public function suggestValues(array $values)
+ {
+ foreach ($values as $value) {
+ $this->suggestValue($value);
+ }
+ return $this;
+ }
+ /**
+ * Add a suggestion for an input option name.
+ *
+ * @return $this
+ */
+ public function suggestOption(InputOption $option)
+ {
+ $this->optionSuggestions[] = $option;
+ return $this;
+ }
+ /**
+ * Add multiple suggestions for input option names at once.
+ *
+ * @param InputOption[] $options
+ *
+ * @return $this
+ */
+ public function suggestOptions(array $options)
+ {
+ foreach ($options as $option) {
+ $this->suggestOption($option);
+ }
+ return $this;
+ }
+ /**
+ * @return InputOption[]
+ */
+ public function getOptionSuggestions() : array
+ {
+ return $this->optionSuggestions;
+ }
+ /**
+ * @return Suggestion[]
+ */
+ public function getValueSuggestions() : array
+ {
+ return $this->valueSuggestions;
+ }
+}
diff --git a/vendor/symfony/console/Completion/Output/BashCompletionOutput.php b/vendor/symfony/console/Completion/Output/BashCompletionOutput.php
new file mode 100644
index 00000000..8106e54d
--- /dev/null
+++ b/vendor/symfony/console/Completion/Output/BashCompletionOutput.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Completion\Output;
+
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionSuggestions;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * @author Wouter de Jong
+ */
+class BashCompletionOutput implements CompletionOutputInterface
+{
+ public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void
+ {
+ $values = $suggestions->getValueSuggestions();
+ foreach ($suggestions->getOptionSuggestions() as $option) {
+ $values[] = '--' . $option->getName();
+ if ($option->isNegatable()) {
+ $values[] = '--no-' . $option->getName();
+ }
+ }
+ $output->writeln(\implode("\n", $values));
+ }
+}
diff --git a/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php b/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php
new file mode 100644
index 00000000..f8453315
--- /dev/null
+++ b/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php
@@ -0,0 +1,23 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Completion\Output;
+
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionSuggestions;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * Transforms the {@see CompletionSuggestions} object into output readable by the shell completion.
+ *
+ * @author Wouter de Jong
+ */
+interface CompletionOutputInterface
+{
+ public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void;
+}
diff --git a/vendor/symfony/console/Completion/Output/FishCompletionOutput.php b/vendor/symfony/console/Completion/Output/FishCompletionOutput.php
new file mode 100644
index 00000000..988c305f
--- /dev/null
+++ b/vendor/symfony/console/Completion/Output/FishCompletionOutput.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Completion\Output;
+
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionSuggestions;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * @author Guillaume Aveline
+ */
+class FishCompletionOutput implements CompletionOutputInterface
+{
+ public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void
+ {
+ $values = $suggestions->getValueSuggestions();
+ foreach ($suggestions->getOptionSuggestions() as $option) {
+ $values[] = '--' . $option->getName();
+ if ($option->isNegatable()) {
+ $values[] = '--no-' . $option->getName();
+ }
+ }
+ $output->write(\implode("\n", $values));
+ }
+}
diff --git a/vendor/symfony/console/Completion/Output/ZshCompletionOutput.php b/vendor/symfony/console/Completion/Output/ZshCompletionOutput.php
new file mode 100644
index 00000000..0bfc8c0e
--- /dev/null
+++ b/vendor/symfony/console/Completion/Output/ZshCompletionOutput.php
@@ -0,0 +1,34 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Completion\Output;
+
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionSuggestions;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * @author Jitendra A
+ */
+class ZshCompletionOutput implements CompletionOutputInterface
+{
+ public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void
+ {
+ $values = [];
+ foreach ($suggestions->getValueSuggestions() as $value) {
+ $values[] = $value->getValue() . ($value->getDescription() ? "\t" . $value->getDescription() : '');
+ }
+ foreach ($suggestions->getOptionSuggestions() as $option) {
+ $values[] = '--' . $option->getName() . ($option->getDescription() ? "\t" . $option->getDescription() : '');
+ if ($option->isNegatable()) {
+ $values[] = '--no-' . $option->getName() . ($option->getDescription() ? "\t" . $option->getDescription() : '');
+ }
+ }
+ $output->write(\implode("\n", $values) . "\n");
+ }
+}
diff --git a/vendor/symfony/console/Completion/Suggestion.php b/vendor/symfony/console/Completion/Suggestion.php
new file mode 100644
index 00000000..327fe0ea
--- /dev/null
+++ b/vendor/symfony/console/Completion/Suggestion.php
@@ -0,0 +1,47 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Completion;
+
+/**
+ * Represents a single suggested value.
+ *
+ * @author Wouter de Jong
+ */
+class Suggestion
+{
+ /**
+ * @readonly
+ * @var string
+ */
+ private $value;
+ /**
+ * @readonly
+ * @var string
+ */
+ private $description = '';
+ public function __construct(string $value, string $description = '')
+ {
+ $this->value = $value;
+ $this->description = $description;
+ }
+ public function getValue() : string
+ {
+ return $this->value;
+ }
+ public function getDescription() : string
+ {
+ return $this->description;
+ }
+ public function __toString() : string
+ {
+ return $this->getValue();
+ }
+}
diff --git a/vendor/symfony/console/ConsoleEvents.php b/vendor/symfony/console/ConsoleEvents.php
new file mode 100644
index 00000000..302bfc54
--- /dev/null
+++ b/vendor/symfony/console/ConsoleEvents.php
@@ -0,0 +1,61 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console;
+
+use VendorPatches202401\Symfony\Component\Console\Event\ConsoleCommandEvent;
+use VendorPatches202401\Symfony\Component\Console\Event\ConsoleErrorEvent;
+use VendorPatches202401\Symfony\Component\Console\Event\ConsoleSignalEvent;
+use VendorPatches202401\Symfony\Component\Console\Event\ConsoleTerminateEvent;
+/**
+ * Contains all events dispatched by an Application.
+ *
+ * @author Francesco Levorato
+ */
+final class ConsoleEvents
+{
+ /**
+ * The COMMAND event allows you to attach listeners before any command is
+ * executed by the console. It also allows you to modify the command, input and output
+ * before they are handed to the command.
+ *
+ * @Event("Symfony\Component\Console\Event\ConsoleCommandEvent")
+ */
+ public const COMMAND = 'console.command';
+ /**
+ * The SIGNAL event allows you to perform some actions
+ * after the command execution was interrupted.
+ *
+ * @Event("Symfony\Component\Console\Event\ConsoleSignalEvent")
+ */
+ public const SIGNAL = 'console.signal';
+ /**
+ * The TERMINATE event allows you to attach listeners after a command is
+ * executed by the console.
+ *
+ * @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent")
+ */
+ public const TERMINATE = 'console.terminate';
+ /**
+ * The ERROR event occurs when an uncaught exception or error appears.
+ *
+ * This event allows you to deal with the exception/error or
+ * to modify the thrown exception.
+ *
+ * @Event("Symfony\Component\Console\Event\ConsoleErrorEvent")
+ */
+ public const ERROR = 'console.error';
+ /**
+ * Event aliases.
+ *
+ * These aliases can be consumed by RegisterListenersPass.
+ */
+ public const ALIASES = [ConsoleCommandEvent::class => self::COMMAND, ConsoleErrorEvent::class => self::ERROR, ConsoleSignalEvent::class => self::SIGNAL, ConsoleTerminateEvent::class => self::TERMINATE];
+}
diff --git a/vendor/symfony/console/Cursor.php b/vendor/symfony/console/Cursor.php
new file mode 100644
index 00000000..9b9274c2
--- /dev/null
+++ b/vendor/symfony/console/Cursor.php
@@ -0,0 +1,168 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console;
+
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * @author Pierre du Plessis
+ */
+final class Cursor
+{
+ /**
+ * @var \Symfony\Component\Console\Output\OutputInterface
+ */
+ private $output;
+ /** @var resource */
+ private $input;
+ /**
+ * @param resource|null $input
+ */
+ public function __construct(OutputInterface $output, $input = null)
+ {
+ $this->output = $output;
+ $this->input = $input ?? (\defined('STDIN') ? \STDIN : \fopen('php://input', 'r+'));
+ }
+ /**
+ * @return $this
+ */
+ public function moveUp(int $lines = 1)
+ {
+ $this->output->write(\sprintf("\x1b[%dA", $lines));
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function moveDown(int $lines = 1)
+ {
+ $this->output->write(\sprintf("\x1b[%dB", $lines));
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function moveRight(int $columns = 1)
+ {
+ $this->output->write(\sprintf("\x1b[%dC", $columns));
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function moveLeft(int $columns = 1)
+ {
+ $this->output->write(\sprintf("\x1b[%dD", $columns));
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function moveToColumn(int $column)
+ {
+ $this->output->write(\sprintf("\x1b[%dG", $column));
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function moveToPosition(int $column, int $row)
+ {
+ $this->output->write(\sprintf("\x1b[%d;%dH", $row + 1, $column));
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function savePosition()
+ {
+ $this->output->write("\x1b7");
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function restorePosition()
+ {
+ $this->output->write("\x1b8");
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function hide()
+ {
+ $this->output->write("\x1b[?25l");
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function show()
+ {
+ $this->output->write("\x1b[?25h\x1b[?0c");
+ return $this;
+ }
+ /**
+ * Clears all the output from the current line.
+ *
+ * @return $this
+ */
+ public function clearLine()
+ {
+ $this->output->write("\x1b[2K");
+ return $this;
+ }
+ /**
+ * Clears all the output from the current line after the current position.
+ */
+ public function clearLineAfter() : self
+ {
+ $this->output->write("\x1b[K");
+ return $this;
+ }
+ /**
+ * Clears all the output from the cursors' current position to the end of the screen.
+ *
+ * @return $this
+ */
+ public function clearOutput()
+ {
+ $this->output->write("\x1b[0J");
+ return $this;
+ }
+ /**
+ * Clears the entire screen.
+ *
+ * @return $this
+ */
+ public function clearScreen()
+ {
+ $this->output->write("\x1b[2J");
+ return $this;
+ }
+ /**
+ * Returns the current cursor position as x,y coordinates.
+ */
+ public function getCurrentPosition() : array
+ {
+ static $isTtySupported;
+ if (!($isTtySupported = $isTtySupported ?? '/' === \DIRECTORY_SEPARATOR && \stream_isatty(\STDOUT))) {
+ return [1, 1];
+ }
+ $sttyMode = \shell_exec('stty -g');
+ \shell_exec('stty -icanon -echo');
+ @\fwrite($this->input, "\x1b[6n");
+ $code = \trim(\fread($this->input, 1024));
+ \shell_exec(\sprintf('stty %s', $sttyMode));
+ \sscanf($code, "\x1b[%d;%dR", $row, $col);
+ return [$col, $row];
+ }
+}
diff --git a/vendor/symfony/console/DataCollector/CommandDataCollector.php b/vendor/symfony/console/DataCollector/CommandDataCollector.php
new file mode 100644
index 00000000..44cd4030
--- /dev/null
+++ b/vendor/symfony/console/DataCollector/CommandDataCollector.php
@@ -0,0 +1,182 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\DataCollector;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Debug\CliRequest;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Component\Console\SignalRegistry\SignalMap;
+use VendorPatches202401\Symfony\Component\HttpFoundation\Request;
+use VendorPatches202401\Symfony\Component\HttpFoundation\Response;
+use VendorPatches202401\Symfony\Component\HttpKernel\DataCollector\DataCollector;
+use VendorPatches202401\Symfony\Component\VarDumper\Cloner\Data;
+/**
+ * @internal
+ *
+ * @author Jules Pietri
+ */
+final class CommandDataCollector extends DataCollector
+{
+ public function collect(Request $request, Response $response, \Throwable $exception = null) : void
+ {
+ if (!$request instanceof CliRequest) {
+ return;
+ }
+ $command = $request->command;
+ $application = $command->getApplication();
+ $this->data = ['command' => $this->cloneVar($command->command), 'exit_code' => $command->exitCode, 'interrupted_by_signal' => $command->interruptedBySignal, 'duration' => $command->duration, 'max_memory_usage' => $command->maxMemoryUsage, 'verbosity_level' => (function () use($command) {
+ switch ($command->output->getVerbosity()) {
+ case OutputInterface::VERBOSITY_QUIET:
+ return 'quiet';
+ case OutputInterface::VERBOSITY_NORMAL:
+ return 'normal';
+ case OutputInterface::VERBOSITY_VERBOSE:
+ return 'verbose';
+ case OutputInterface::VERBOSITY_VERY_VERBOSE:
+ return 'very verbose';
+ case OutputInterface::VERBOSITY_DEBUG:
+ return 'debug';
+ }
+ })(), 'interactive' => $command->isInteractive, 'validate_input' => !$command->ignoreValidation, 'enabled' => $command->isEnabled(), 'visible' => !$command->isHidden(), 'input' => $this->cloneVar($command->input), 'output' => $this->cloneVar($command->output), 'interactive_inputs' => \array_map(\Closure::fromCallable([$this, 'cloneVar']), $command->interactiveInputs), 'signalable' => $command->getSubscribedSignals(), 'handled_signals' => $command->handledSignals, 'helper_set' => \array_map(\Closure::fromCallable([$this, 'cloneVar']), \iterator_to_array($command->getHelperSet()))];
+ $baseDefinition = $application->getDefinition();
+ foreach ($command->arguments as $argName => $argValue) {
+ if ($baseDefinition->hasArgument($argName)) {
+ $this->data['application_inputs'][$argName] = $this->cloneVar($argValue);
+ } else {
+ $this->data['arguments'][$argName] = $this->cloneVar($argValue);
+ }
+ }
+ foreach ($command->options as $optName => $optValue) {
+ if ($baseDefinition->hasOption($optName)) {
+ $this->data['application_inputs']['--' . $optName] = $this->cloneVar($optValue);
+ } else {
+ $this->data['options'][$optName] = $this->cloneVar($optValue);
+ }
+ }
+ }
+ public function getName() : string
+ {
+ return 'command';
+ }
+ /**
+ * @return array{
+ * class?: class-string,
+ * executor?: string,
+ * file: string,
+ * line: int,
+ * }
+ */
+ public function getCommand() : array
+ {
+ $class = $this->data['command']->getType();
+ $r = new \ReflectionMethod($class, 'execute');
+ if (Command::class !== $r->getDeclaringClass()) {
+ return ['executor' => $class . '::' . $r->name, 'file' => $r->getFileName(), 'line' => $r->getStartLine()];
+ }
+ $r = new \ReflectionClass($class);
+ return ['class' => $class, 'file' => $r->getFileName(), 'line' => $r->getStartLine()];
+ }
+ public function getInterruptedBySignal() : ?string
+ {
+ if (isset($this->data['interrupted_by_signal'])) {
+ return \sprintf('%s (%d)', SignalMap::getSignalName($this->data['interrupted_by_signal']), $this->data['interrupted_by_signal']);
+ }
+ return null;
+ }
+ public function getDuration() : string
+ {
+ return $this->data['duration'];
+ }
+ public function getMaxMemoryUsage() : string
+ {
+ return $this->data['max_memory_usage'];
+ }
+ public function getVerbosityLevel() : string
+ {
+ return $this->data['verbosity_level'];
+ }
+ public function getInteractive() : bool
+ {
+ return $this->data['interactive'];
+ }
+ public function getValidateInput() : bool
+ {
+ return $this->data['validate_input'];
+ }
+ public function getEnabled() : bool
+ {
+ return $this->data['enabled'];
+ }
+ public function getVisible() : bool
+ {
+ return $this->data['visible'];
+ }
+ public function getInput() : Data
+ {
+ return $this->data['input'];
+ }
+ public function getOutput() : Data
+ {
+ return $this->data['output'];
+ }
+ /**
+ * @return Data[]
+ */
+ public function getArguments() : array
+ {
+ return $this->data['arguments'] ?? [];
+ }
+ /**
+ * @return Data[]
+ */
+ public function getOptions() : array
+ {
+ return $this->data['options'] ?? [];
+ }
+ /**
+ * @return Data[]
+ */
+ public function getApplicationInputs() : array
+ {
+ return $this->data['application_inputs'] ?? [];
+ }
+ /**
+ * @return Data[]
+ */
+ public function getInteractiveInputs() : array
+ {
+ return $this->data['interactive_inputs'] ?? [];
+ }
+ public function getSignalable() : array
+ {
+ return \array_map(static function (int $signal) : string {
+ return \sprintf('%s (%d)', SignalMap::getSignalName($signal), $signal);
+ }, $this->data['signalable']);
+ }
+ public function getHandledSignals() : array
+ {
+ $keys = \array_map(static function (int $signal) : string {
+ return \sprintf('%s (%d)', SignalMap::getSignalName($signal), $signal);
+ }, \array_keys($this->data['handled_signals']));
+ return \array_combine($keys, \array_values($this->data['handled_signals']));
+ }
+ /**
+ * @return Data[]
+ */
+ public function getHelperSet() : array
+ {
+ return $this->data['helper_set'] ?? [];
+ }
+ public function reset() : void
+ {
+ $this->data = [];
+ }
+}
diff --git a/vendor/symfony/console/Debug/CliRequest.php b/vendor/symfony/console/Debug/CliRequest.php
new file mode 100644
index 00000000..c732b56d
--- /dev/null
+++ b/vendor/symfony/console/Debug/CliRequest.php
@@ -0,0 +1,70 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Debug;
+
+use VendorPatches202401\Symfony\Component\Console\Command\TraceableCommand;
+use VendorPatches202401\Symfony\Component\HttpFoundation\Request;
+use VendorPatches202401\Symfony\Component\HttpFoundation\Response;
+/**
+ * @internal
+ */
+final class CliRequest extends Request
+{
+ /**
+ * @readonly
+ * @var \Symfony\Component\Console\Command\TraceableCommand
+ */
+ public $command;
+ public function __construct(TraceableCommand $command)
+ {
+ $this->command = $command;
+ parent::__construct(attributes: ['_controller' => \get_class($command->command), '_virtual_type' => 'command'], server: $_SERVER);
+ }
+ // Methods below allow to populate a profile, thus enable search and filtering
+ public function getUri() : string
+ {
+ if ($this->server->has('SYMFONY_CLI_BINARY_NAME')) {
+ $binary = $this->server->get('SYMFONY_CLI_BINARY_NAME') . ' console';
+ } else {
+ $binary = $this->server->get('argv')[0];
+ }
+ return $binary . ' ' . $this->command->input;
+ }
+ public function getMethod() : string
+ {
+ return $this->command->isInteractive ? 'INTERACTIVE' : 'BATCH';
+ }
+ public function getResponse() : Response
+ {
+ return new class($this->command->exitCode) extends Response
+ {
+ /**
+ * @readonly
+ * @var int
+ */
+ private $exitCode;
+ public function __construct(int $exitCode)
+ {
+ $this->exitCode = $exitCode;
+ parent::__construct();
+ }
+ public function getStatusCode() : int
+ {
+ return $this->exitCode;
+ }
+ };
+ }
+ public function getClientIp() : string
+ {
+ $application = $this->command->getApplication();
+ return $application->getName() . ' ' . $application->getVersion();
+ }
+}
diff --git a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php
new file mode 100644
index 00000000..2d722dcf
--- /dev/null
+++ b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php
@@ -0,0 +1,107 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\DependencyInjection;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Command\LazyCommand;
+use VendorPatches202401\Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
+use VendorPatches202401\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
+use VendorPatches202401\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use VendorPatches202401\Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
+use VendorPatches202401\Symfony\Component\DependencyInjection\ContainerBuilder;
+use VendorPatches202401\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\DependencyInjection\Reference;
+use VendorPatches202401\Symfony\Component\DependencyInjection\TypedReference;
+/**
+ * Registers console commands.
+ *
+ * @author Grégoire Pineau
+ */
+class AddConsoleCommandPass implements CompilerPassInterface
+{
+ /**
+ * @return void
+ */
+ public function process(ContainerBuilder $container)
+ {
+ $commandServices = $container->findTaggedServiceIds('console.command', \true);
+ $lazyCommandMap = [];
+ $lazyCommandRefs = [];
+ $serviceIds = [];
+ foreach ($commandServices as $id => $tags) {
+ $definition = $container->getDefinition($id);
+ $definition->addTag('container.no_preload');
+ $class = $container->getParameterBag()->resolveValue($definition->getClass());
+ if (isset($tags[0]['command'])) {
+ $aliases = $tags[0]['command'];
+ } else {
+ if (!($r = $container->getReflectionClass($class))) {
+ throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
+ }
+ if (!$r->isSubclassOf(Command::class)) {
+ throw new InvalidArgumentException(\sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, 'console.command', Command::class));
+ }
+ $aliases = \str_replace('%', '%%', $class::getDefaultName() ?? '');
+ }
+ $aliases = \explode('|', $aliases ?? '');
+ $commandName = \array_shift($aliases);
+ if ($isHidden = '' === $commandName) {
+ $commandName = \array_shift($aliases);
+ }
+ if (null === $commandName) {
+ if (!$definition->isPublic() || $definition->isPrivate() || $definition->hasTag('container.private')) {
+ $commandId = 'console.command.public_alias.' . $id;
+ $container->setAlias($commandId, $id)->setPublic(\true);
+ $id = $commandId;
+ }
+ $serviceIds[] = $id;
+ continue;
+ }
+ $description = $tags[0]['description'] ?? null;
+ unset($tags[0]);
+ $lazyCommandMap[$commandName] = $id;
+ $lazyCommandRefs[$id] = new TypedReference($id, $class);
+ foreach ($aliases as $alias) {
+ $lazyCommandMap[$alias] = $id;
+ }
+ foreach ($tags as $tag) {
+ if (isset($tag['command'])) {
+ $aliases[] = $tag['command'];
+ $lazyCommandMap[$tag['command']] = $id;
+ }
+ $description = $description ?? $tag['description'] ?? null;
+ }
+ $definition->addMethodCall('setName', [$commandName]);
+ if ($aliases) {
+ $definition->addMethodCall('setAliases', [$aliases]);
+ }
+ if ($isHidden) {
+ $definition->addMethodCall('setHidden', [\true]);
+ }
+ if (!$description) {
+ if (!($r = $container->getReflectionClass($class))) {
+ throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
+ }
+ if (!$r->isSubclassOf(Command::class)) {
+ throw new InvalidArgumentException(\sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, 'console.command', Command::class));
+ }
+ $description = \str_replace('%', '%%', $class::getDefaultDescription() ?? '');
+ }
+ if ($description) {
+ $definition->addMethodCall('setDescription', [$description]);
+ $container->register('.' . $id . '.lazy', LazyCommand::class)->setArguments([$commandName, $aliases, $description, $isHidden, new ServiceClosureArgument($lazyCommandRefs[$id])]);
+ $lazyCommandRefs[$id] = new Reference('.' . $id . '.lazy');
+ }
+ }
+ $container->register('console.command_loader', ContainerCommandLoader::class)->setPublic(\true)->addTag('container.no_preload')->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]);
+ $container->setParameter('console.command.ids', $serviceIds);
+ }
+}
diff --git a/vendor/symfony/console/Descriptor/ApplicationDescription.php b/vendor/symfony/console/Descriptor/ApplicationDescription.php
new file mode 100644
index 00000000..7318dae6
--- /dev/null
+++ b/vendor/symfony/console/Descriptor/ApplicationDescription.php
@@ -0,0 +1,129 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Descriptor;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Exception\CommandNotFoundException;
+/**
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class ApplicationDescription
+{
+ public const GLOBAL_NAMESPACE = '_global';
+ /**
+ * @var \Symfony\Component\Console\Application
+ */
+ private $application;
+ /**
+ * @var string|null
+ */
+ private $namespace;
+ /**
+ * @var bool
+ */
+ private $showHidden;
+ /**
+ * @var mixed[]
+ */
+ private $namespaces;
+ /**
+ * @var array
+ */
+ private $commands;
+ /**
+ * @var array
+ */
+ private $aliases = [];
+ public function __construct(Application $application, string $namespace = null, bool $showHidden = \false)
+ {
+ $this->application = $application;
+ $this->namespace = $namespace;
+ $this->showHidden = $showHidden;
+ }
+ public function getNamespaces() : array
+ {
+ if (!isset($this->namespaces)) {
+ $this->inspectApplication();
+ }
+ return $this->namespaces;
+ }
+ /**
+ * @return Command[]
+ */
+ public function getCommands() : array
+ {
+ if (!isset($this->commands)) {
+ $this->inspectApplication();
+ }
+ return $this->commands;
+ }
+ /**
+ * @throws CommandNotFoundException
+ */
+ public function getCommand(string $name) : Command
+ {
+ if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
+ throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name));
+ }
+ return $this->commands[$name] ?? $this->aliases[$name];
+ }
+ private function inspectApplication() : void
+ {
+ $this->commands = [];
+ $this->namespaces = [];
+ $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
+ foreach ($this->sortCommands($all) as $namespace => $commands) {
+ $names = [];
+ /** @var Command $command */
+ foreach ($commands as $name => $command) {
+ if (!$command->getName() || !$this->showHidden && $command->isHidden()) {
+ continue;
+ }
+ if ($command->getName() === $name) {
+ $this->commands[$name] = $command;
+ } else {
+ $this->aliases[$name] = $command;
+ }
+ $names[] = $name;
+ }
+ $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names];
+ }
+ }
+ private function sortCommands(array $commands) : array
+ {
+ $namespacedCommands = [];
+ $globalCommands = [];
+ $sortedCommands = [];
+ foreach ($commands as $name => $command) {
+ $key = $this->application->extractNamespace($name, 1);
+ if (\in_array($key, ['', self::GLOBAL_NAMESPACE], \true)) {
+ $globalCommands[$name] = $command;
+ } else {
+ $namespacedCommands[$key][$name] = $command;
+ }
+ }
+ if ($globalCommands) {
+ \ksort($globalCommands);
+ $sortedCommands[self::GLOBAL_NAMESPACE] = $globalCommands;
+ }
+ if ($namespacedCommands) {
+ \ksort($namespacedCommands, \SORT_STRING);
+ foreach ($namespacedCommands as $key => $commandsSet) {
+ \ksort($commandsSet);
+ $sortedCommands[$key] = $commandsSet;
+ }
+ }
+ return $sortedCommands;
+ }
+}
diff --git a/vendor/symfony/console/Descriptor/Descriptor.php b/vendor/symfony/console/Descriptor/Descriptor.php
new file mode 100644
index 00000000..1c2b4632
--- /dev/null
+++ b/vendor/symfony/console/Descriptor/Descriptor.php
@@ -0,0 +1,78 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Descriptor;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Input\InputArgument;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+abstract class Descriptor implements DescriptorInterface
+{
+ /**
+ * @var \Symfony\Component\Console\Output\OutputInterface
+ */
+ protected $output;
+ public function describe(OutputInterface $output, object $object, array $options = []) : void
+ {
+ $this->output = $output;
+ switch (\true) {
+ case $object instanceof InputArgument:
+ $this->describeInputArgument($object, $options);
+ break;
+ case $object instanceof InputOption:
+ $this->describeInputOption($object, $options);
+ break;
+ case $object instanceof InputDefinition:
+ $this->describeInputDefinition($object, $options);
+ break;
+ case $object instanceof Command:
+ $this->describeCommand($object, $options);
+ break;
+ case $object instanceof Application:
+ $this->describeApplication($object, $options);
+ break;
+ default:
+ throw new InvalidArgumentException(\sprintf('Object of type "%s" is not describable.', \get_debug_type($object)));
+ }
+ }
+ protected function write(string $content, bool $decorated = \false) : void
+ {
+ $this->output->write($content, \false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
+ }
+ /**
+ * Describes an InputArgument instance.
+ */
+ protected abstract function describeInputArgument(InputArgument $argument, array $options = []) : void;
+ /**
+ * Describes an InputOption instance.
+ */
+ protected abstract function describeInputOption(InputOption $option, array $options = []) : void;
+ /**
+ * Describes an InputDefinition instance.
+ */
+ protected abstract function describeInputDefinition(InputDefinition $definition, array $options = []) : void;
+ /**
+ * Describes a Command instance.
+ */
+ protected abstract function describeCommand(Command $command, array $options = []) : void;
+ /**
+ * Describes an Application instance.
+ */
+ protected abstract function describeApplication(Application $application, array $options = []) : void;
+}
diff --git a/vendor/symfony/console/Descriptor/DescriptorInterface.php b/vendor/symfony/console/Descriptor/DescriptorInterface.php
new file mode 100644
index 00000000..50f47e50
--- /dev/null
+++ b/vendor/symfony/console/Descriptor/DescriptorInterface.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Descriptor;
+
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * Descriptor interface.
+ *
+ * @author Jean-François Simon
+ */
+interface DescriptorInterface
+{
+ /**
+ * @return void
+ */
+ public function describe(OutputInterface $output, object $object, array $options = []);
+}
diff --git a/vendor/symfony/console/Descriptor/JsonDescriptor.php b/vendor/symfony/console/Descriptor/JsonDescriptor.php
new file mode 100644
index 00000000..24f2a4c1
--- /dev/null
+++ b/vendor/symfony/console/Descriptor/JsonDescriptor.php
@@ -0,0 +1,112 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Descriptor;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Input\InputArgument;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+/**
+ * JSON descriptor.
+ *
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class JsonDescriptor extends Descriptor
+{
+ protected function describeInputArgument(InputArgument $argument, array $options = []) : void
+ {
+ $this->writeData($this->getInputArgumentData($argument), $options);
+ }
+ protected function describeInputOption(InputOption $option, array $options = []) : void
+ {
+ $this->writeData($this->getInputOptionData($option), $options);
+ if ($option->isNegatable()) {
+ $this->writeData($this->getInputOptionData($option, \true), $options);
+ }
+ }
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void
+ {
+ $this->writeData($this->getInputDefinitionData($definition), $options);
+ }
+ protected function describeCommand(Command $command, array $options = []) : void
+ {
+ $this->writeData($this->getCommandData($command, $options['short'] ?? \false), $options);
+ }
+ protected function describeApplication(Application $application, array $options = []) : void
+ {
+ $describedNamespace = $options['namespace'] ?? null;
+ $description = new ApplicationDescription($application, $describedNamespace, \true);
+ $commands = [];
+ foreach ($description->getCommands() as $command) {
+ $commands[] = $this->getCommandData($command, $options['short'] ?? \false);
+ }
+ $data = [];
+ if ('UNKNOWN' !== $application->getName()) {
+ $data['application']['name'] = $application->getName();
+ if ('UNKNOWN' !== $application->getVersion()) {
+ $data['application']['version'] = $application->getVersion();
+ }
+ }
+ $data['commands'] = $commands;
+ if ($describedNamespace) {
+ $data['namespace'] = $describedNamespace;
+ } else {
+ $data['namespaces'] = \array_values($description->getNamespaces());
+ }
+ $this->writeData($data, $options);
+ }
+ /**
+ * Writes data as json.
+ */
+ private function writeData(array $data, array $options) : void
+ {
+ $flags = $options['json_encoding'] ?? 0;
+ $this->write(\json_encode($data, $flags));
+ }
+ private function getInputArgumentData(InputArgument $argument) : array
+ {
+ return ['name' => $argument->getName(), 'is_required' => $argument->isRequired(), 'is_array' => $argument->isArray(), 'description' => \preg_replace('/\\s*[\\r\\n]\\s*/', ' ', $argument->getDescription()), 'default' => \INF === $argument->getDefault() ? 'INF' : $argument->getDefault()];
+ }
+ private function getInputOptionData(InputOption $option, bool $negated = \false) : array
+ {
+ return $negated ? ['name' => '--no-' . $option->getName(), 'shortcut' => '', 'accept_value' => \false, 'is_value_required' => \false, 'is_multiple' => \false, 'description' => 'Negate the "--' . $option->getName() . '" option', 'default' => \false] : ['name' => '--' . $option->getName(), 'shortcut' => $option->getShortcut() ? '-' . \str_replace('|', '|-', $option->getShortcut()) : '', 'accept_value' => $option->acceptValue(), 'is_value_required' => $option->isValueRequired(), 'is_multiple' => $option->isArray(), 'description' => \preg_replace('/\\s*[\\r\\n]\\s*/', ' ', $option->getDescription()), 'default' => \INF === $option->getDefault() ? 'INF' : $option->getDefault()];
+ }
+ private function getInputDefinitionData(InputDefinition $definition) : array
+ {
+ $inputArguments = [];
+ foreach ($definition->getArguments() as $name => $argument) {
+ $inputArguments[$name] = $this->getInputArgumentData($argument);
+ }
+ $inputOptions = [];
+ foreach ($definition->getOptions() as $name => $option) {
+ $inputOptions[$name] = $this->getInputOptionData($option);
+ if ($option->isNegatable()) {
+ $inputOptions['no-' . $name] = $this->getInputOptionData($option, \true);
+ }
+ }
+ return ['arguments' => $inputArguments, 'options' => $inputOptions];
+ }
+ private function getCommandData(Command $command, bool $short = \false) : array
+ {
+ $data = ['name' => $command->getName(), 'description' => $command->getDescription()];
+ if ($short) {
+ $data += ['usage' => $command->getAliases()];
+ } else {
+ $command->mergeApplicationDefinition(\false);
+ $data += ['usage' => \array_merge([$command->getSynopsis()], $command->getUsages(), $command->getAliases()), 'help' => $command->getProcessedHelp(), 'definition' => $this->getInputDefinitionData($command->getDefinition())];
+ }
+ $data['hidden'] = $command->isHidden();
+ return $data;
+ }
+}
diff --git a/vendor/symfony/console/Descriptor/MarkdownDescriptor.php b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php
new file mode 100644
index 00000000..84e57f01
--- /dev/null
+++ b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php
@@ -0,0 +1,128 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Descriptor;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Helper\Helper;
+use VendorPatches202401\Symfony\Component\Console\Input\InputArgument;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * Markdown descriptor.
+ *
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class MarkdownDescriptor extends Descriptor
+{
+ public function describe(OutputInterface $output, object $object, array $options = []) : void
+ {
+ $decorated = $output->isDecorated();
+ $output->setDecorated(\false);
+ parent::describe($output, $object, $options);
+ $output->setDecorated($decorated);
+ }
+ protected function write(string $content, bool $decorated = \true) : void
+ {
+ parent::write($content, $decorated);
+ }
+ protected function describeInputArgument(InputArgument $argument, array $options = []) : void
+ {
+ $this->write('#### `' . ($argument->getName() ?: '') . "`\n\n" . ($argument->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n", $argument->getDescription()) . "\n\n" : '') . '* Is required: ' . ($argument->isRequired() ? 'yes' : 'no') . "\n" . '* Is array: ' . ($argument->isArray() ? 'yes' : 'no') . "\n" . '* Default: `' . \str_replace("\n", '', \var_export($argument->getDefault(), \true)) . '`');
+ }
+ protected function describeInputOption(InputOption $option, array $options = []) : void
+ {
+ $name = '--' . $option->getName();
+ if ($option->isNegatable()) {
+ $name .= '|--no-' . $option->getName();
+ }
+ if ($option->getShortcut()) {
+ $name .= '|-' . \str_replace('|', '|-', $option->getShortcut()) . '';
+ }
+ $this->write('#### `' . $name . '`' . "\n\n" . ($option->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n", $option->getDescription()) . "\n\n" : '') . '* Accept value: ' . ($option->acceptValue() ? 'yes' : 'no') . "\n" . '* Is value required: ' . ($option->isValueRequired() ? 'yes' : 'no') . "\n" . '* Is multiple: ' . ($option->isArray() ? 'yes' : 'no') . "\n" . '* Is negatable: ' . ($option->isNegatable() ? 'yes' : 'no') . "\n" . '* Default: `' . \str_replace("\n", '', \var_export($option->getDefault(), \true)) . '`');
+ }
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void
+ {
+ if ($showArguments = \count($definition->getArguments()) > 0) {
+ $this->write('### Arguments');
+ foreach ($definition->getArguments() as $argument) {
+ $this->write("\n\n");
+ $this->describeInputArgument($argument);
+ }
+ }
+ if (\count($definition->getOptions()) > 0) {
+ if ($showArguments) {
+ $this->write("\n\n");
+ }
+ $this->write('### Options');
+ foreach ($definition->getOptions() as $option) {
+ $this->write("\n\n");
+ $this->describeInputOption($option);
+ }
+ }
+ }
+ protected function describeCommand(Command $command, array $options = []) : void
+ {
+ if ($options['short'] ?? \false) {
+ $this->write('`' . $command->getName() . "`\n" . \str_repeat('-', Helper::width($command->getName()) + 2) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . '### Usage' . "\n\n" . \array_reduce($command->getAliases(), function ($carry, $usage) {
+ return $carry . '* `' . $usage . '`' . "\n";
+ }));
+ return;
+ }
+ $command->mergeApplicationDefinition(\false);
+ $this->write('`' . $command->getName() . "`\n" . \str_repeat('-', Helper::width($command->getName()) + 2) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . '### Usage' . "\n\n" . \array_reduce(\array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
+ return $carry . '* `' . $usage . '`' . "\n";
+ }));
+ if ($help = $command->getProcessedHelp()) {
+ $this->write("\n");
+ $this->write($help);
+ }
+ $definition = $command->getDefinition();
+ if ($definition->getOptions() || $definition->getArguments()) {
+ $this->write("\n\n");
+ $this->describeInputDefinition($definition);
+ }
+ }
+ protected function describeApplication(Application $application, array $options = []) : void
+ {
+ $describedNamespace = $options['namespace'] ?? null;
+ $description = new ApplicationDescription($application, $describedNamespace);
+ $title = $this->getApplicationTitle($application);
+ $this->write($title . "\n" . \str_repeat('=', Helper::width($title)));
+ foreach ($description->getNamespaces() as $namespace) {
+ if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
+ $this->write("\n\n");
+ $this->write('**' . $namespace['id'] . ':**');
+ }
+ $this->write("\n\n");
+ $this->write(\implode("\n", \array_map(function ($commandName) use($description) {
+ return \sprintf('* [`%s`](#%s)', $commandName, \str_replace(':', '', $description->getCommand($commandName)->getName()));
+ }, $namespace['commands'])));
+ }
+ foreach ($description->getCommands() as $command) {
+ $this->write("\n\n");
+ $this->describeCommand($command, $options);
+ }
+ }
+ private function getApplicationTitle(Application $application) : string
+ {
+ if ('UNKNOWN' !== $application->getName()) {
+ if ('UNKNOWN' !== $application->getVersion()) {
+ return \sprintf('%s %s', $application->getName(), $application->getVersion());
+ }
+ return $application->getName();
+ }
+ return 'Console Tool';
+ }
+}
diff --git a/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php b/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php
new file mode 100644
index 00000000..7c4a338c
--- /dev/null
+++ b/vendor/symfony/console/Descriptor/ReStructuredTextDescriptor.php
@@ -0,0 +1,234 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Descriptor;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Helper\Helper;
+use VendorPatches202401\Symfony\Component\Console\Input\InputArgument;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Component\String\UnicodeString;
+class ReStructuredTextDescriptor extends Descriptor
+{
+ //
+ /**
+ * @var string
+ */
+ private $partChar = '=';
+ //
+ /**
+ * @var string
+ */
+ private $chapterChar = '-';
+ //
+ /**
+ * @var string
+ */
+ private $sectionChar = '~';
+ //
+ /**
+ * @var string
+ */
+ private $subsectionChar = '.';
+ //
+ /**
+ * @var string
+ */
+ private $subsubsectionChar = '^';
+ //
+ /**
+ * @var string
+ */
+ private $paragraphsChar = '"';
+ /**
+ * @var mixed[]
+ */
+ private $visibleNamespaces = [];
+ public function describe(OutputInterface $output, object $object, array $options = []) : void
+ {
+ $decorated = $output->isDecorated();
+ $output->setDecorated(\false);
+ parent::describe($output, $object, $options);
+ $output->setDecorated($decorated);
+ }
+ /**
+ * Override parent method to set $decorated = true.
+ */
+ protected function write(string $content, bool $decorated = \true) : void
+ {
+ parent::write($content, $decorated);
+ }
+ protected function describeInputArgument(InputArgument $argument, array $options = []) : void
+ {
+ $this->write($argument->getName() ?: '' . "\n" . \str_repeat($this->paragraphsChar, Helper::width($argument->getName())) . "\n\n" . ($argument->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n", $argument->getDescription()) . "\n\n" : '') . '- **Is required**: ' . ($argument->isRequired() ? 'yes' : 'no') . "\n" . '- **Is array**: ' . ($argument->isArray() ? 'yes' : 'no') . "\n" . '- **Default**: ``' . \str_replace("\n", '', \var_export($argument->getDefault(), \true)) . '``');
+ }
+ protected function describeInputOption(InputOption $option, array $options = []) : void
+ {
+ $name = '\\-\\-' . $option->getName();
+ if ($option->isNegatable()) {
+ $name .= '|\\-\\-no-' . $option->getName();
+ }
+ if ($option->getShortcut()) {
+ $name .= '|-' . \str_replace('|', '|-', $option->getShortcut());
+ }
+ $optionDescription = $option->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n\n", $option->getDescription()) . "\n\n" : '';
+ $optionDescription = (new UnicodeString($optionDescription))->ascii();
+ $this->write($name . "\n" . \str_repeat($this->paragraphsChar, Helper::width($name)) . "\n\n" . $optionDescription . '- **Accept value**: ' . ($option->acceptValue() ? 'yes' : 'no') . "\n" . '- **Is value required**: ' . ($option->isValueRequired() ? 'yes' : 'no') . "\n" . '- **Is multiple**: ' . ($option->isArray() ? 'yes' : 'no') . "\n" . '- **Is negatable**: ' . ($option->isNegatable() ? 'yes' : 'no') . "\n" . '- **Default**: ``' . \str_replace("\n", '', \var_export($option->getDefault(), \true)) . '``' . "\n");
+ }
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void
+ {
+ if ($showArguments = (bool) $definition->getArguments()) {
+ $this->write("Arguments\n" . \str_repeat($this->subsubsectionChar, 9)) . "\n\n";
+ foreach ($definition->getArguments() as $argument) {
+ $this->write("\n\n");
+ $this->describeInputArgument($argument);
+ }
+ }
+ if ($nonDefaultOptions = $this->getNonDefaultOptions($definition)) {
+ if ($showArguments) {
+ $this->write("\n\n");
+ }
+ $this->write("Options\n" . \str_repeat($this->subsubsectionChar, 7) . "\n\n");
+ foreach ($nonDefaultOptions as $option) {
+ $this->describeInputOption($option);
+ $this->write("\n");
+ }
+ }
+ }
+ protected function describeCommand(Command $command, array $options = []) : void
+ {
+ if ($options['short'] ?? \false) {
+ $this->write('``' . $command->getName() . "``\n" . \str_repeat($this->subsectionChar, Helper::width($command->getName())) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . "Usage\n" . \str_repeat($this->paragraphsChar, 5) . "\n\n" . \array_reduce($command->getAliases(), static function ($carry, $usage) {
+ return $carry . '- ``' . $usage . '``' . "\n";
+ }));
+ return;
+ }
+ $command->mergeApplicationDefinition(\false);
+ foreach ($command->getAliases() as $alias) {
+ $this->write('.. _' . $alias . ":\n\n");
+ }
+ $this->write($command->getName() . "\n" . \str_repeat($this->subsectionChar, Helper::width($command->getName())) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . "Usage\n" . \str_repeat($this->subsubsectionChar, 5) . "\n\n" . \array_reduce(\array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), static function ($carry, $usage) {
+ return $carry . '- ``' . $usage . '``' . "\n";
+ }));
+ if ($help = $command->getProcessedHelp()) {
+ $this->write("\n");
+ $this->write($help);
+ }
+ $definition = $command->getDefinition();
+ if ($definition->getOptions() || $definition->getArguments()) {
+ $this->write("\n\n");
+ $this->describeInputDefinition($definition);
+ }
+ }
+ protected function describeApplication(Application $application, array $options = []) : void
+ {
+ $description = new ApplicationDescription($application, $options['namespace'] ?? null);
+ $title = $this->getApplicationTitle($application);
+ $this->write($title . "\n" . \str_repeat($this->partChar, Helper::width($title)));
+ $this->createTableOfContents($description, $application);
+ $this->describeCommands($application, $options);
+ }
+ private function getApplicationTitle(Application $application) : string
+ {
+ if ('UNKNOWN' === $application->getName()) {
+ return 'Console Tool';
+ }
+ if ('UNKNOWN' !== $application->getVersion()) {
+ return \sprintf('%s %s', $application->getName(), $application->getVersion());
+ }
+ return $application->getName();
+ }
+ private function describeCommands($application, array $options) : void
+ {
+ $title = 'Commands';
+ $this->write("\n\n{$title}\n" . \str_repeat($this->chapterChar, Helper::width($title)) . "\n\n");
+ foreach ($this->visibleNamespaces as $namespace) {
+ if ('_global' === $namespace) {
+ $commands = $application->all('');
+ $this->write('Global' . "\n" . \str_repeat($this->sectionChar, Helper::width('Global')) . "\n\n");
+ } else {
+ $commands = $application->all($namespace);
+ $this->write($namespace . "\n" . \str_repeat($this->sectionChar, Helper::width($namespace)) . "\n\n");
+ }
+ foreach ($this->removeAliasesAndHiddenCommands($commands) as $command) {
+ $this->describeCommand($command, $options);
+ $this->write("\n\n");
+ }
+ }
+ }
+ private function createTableOfContents(ApplicationDescription $description, Application $application) : void
+ {
+ $this->setVisibleNamespaces($description);
+ $chapterTitle = 'Table of Contents';
+ $this->write("\n\n{$chapterTitle}\n" . \str_repeat($this->chapterChar, Helper::width($chapterTitle)) . "\n\n");
+ foreach ($this->visibleNamespaces as $namespace) {
+ if ('_global' === $namespace) {
+ $commands = $application->all('');
+ } else {
+ $commands = $application->all($namespace);
+ $this->write("\n\n");
+ $this->write($namespace . "\n" . \str_repeat($this->sectionChar, Helper::width($namespace)) . "\n\n");
+ }
+ $commands = $this->removeAliasesAndHiddenCommands($commands);
+ $this->write("\n\n");
+ $this->write(\implode("\n", \array_map(static function ($commandName) {
+ return \sprintf('- `%s`_', $commandName);
+ }, \array_keys($commands))));
+ }
+ }
+ private function getNonDefaultOptions(InputDefinition $definition) : array
+ {
+ $globalOptions = ['help', 'quiet', 'verbose', 'version', 'ansi', 'no-interaction'];
+ $nonDefaultOptions = [];
+ foreach ($definition->getOptions() as $option) {
+ // Skip global options.
+ if (!\in_array($option->getName(), $globalOptions)) {
+ $nonDefaultOptions[] = $option;
+ }
+ }
+ return $nonDefaultOptions;
+ }
+ private function setVisibleNamespaces(ApplicationDescription $description) : void
+ {
+ $commands = $description->getCommands();
+ foreach ($description->getNamespaces() as $namespace) {
+ try {
+ $namespaceCommands = $namespace['commands'];
+ foreach ($namespaceCommands as $key => $commandName) {
+ if (!\array_key_exists($commandName, $commands)) {
+ // If the array key does not exist, then this is an alias.
+ unset($namespaceCommands[$key]);
+ } elseif ($commands[$commandName]->isHidden()) {
+ unset($namespaceCommands[$key]);
+ }
+ }
+ if (!$namespaceCommands) {
+ // If the namespace contained only aliases or hidden commands, skip the namespace.
+ continue;
+ }
+ } catch (\Exception $exception) {
+ }
+ $this->visibleNamespaces[] = $namespace['id'];
+ }
+ }
+ private function removeAliasesAndHiddenCommands(array $commands) : array
+ {
+ foreach ($commands as $key => $command) {
+ if ($command->isHidden() || \in_array($key, $command->getAliases(), \true)) {
+ unset($commands[$key]);
+ }
+ }
+ unset($commands['completion']);
+ return $commands;
+ }
+}
diff --git a/vendor/symfony/console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Descriptor/TextDescriptor.php
new file mode 100644
index 00000000..9cc1c8bd
--- /dev/null
+++ b/vendor/symfony/console/Descriptor/TextDescriptor.php
@@ -0,0 +1,274 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Descriptor;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Formatter\OutputFormatter;
+use VendorPatches202401\Symfony\Component\Console\Helper\Helper;
+use VendorPatches202401\Symfony\Component\Console\Input\InputArgument;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+/**
+ * Text descriptor.
+ *
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class TextDescriptor extends Descriptor
+{
+ protected function describeInputArgument(InputArgument $argument, array $options = []) : void
+ {
+ if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) {
+ $default = \sprintf(' [default: %s]', $this->formatDefaultValue($argument->getDefault()));
+ } else {
+ $default = '';
+ }
+ $totalWidth = $options['total_width'] ?? Helper::width($argument->getName());
+ $spacingWidth = $totalWidth - \strlen($argument->getName());
+ $this->writeText(\sprintf(
+ ' %s %s%s%s',
+ $argument->getName(),
+ \str_repeat(' ', $spacingWidth),
+ // + 4 = 2 spaces before , 2 spaces after
+ \preg_replace('/\\s*[\\r\\n]\\s*/', "\n" . \str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
+ $default
+ ), $options);
+ }
+ protected function describeInputOption(InputOption $option, array $options = []) : void
+ {
+ if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) {
+ $default = \sprintf(' [default: %s]', $this->formatDefaultValue($option->getDefault()));
+ } else {
+ $default = '';
+ }
+ $value = '';
+ if ($option->acceptValue()) {
+ $value = '=' . \strtoupper($option->getName());
+ if ($option->isValueOptional()) {
+ $value = '[' . $value . ']';
+ }
+ }
+ $totalWidth = $options['total_width'] ?? $this->calculateTotalWidthForOptions([$option]);
+ $synopsis = \sprintf('%s%s', $option->getShortcut() ? \sprintf('-%s, ', $option->getShortcut()) : ' ', \sprintf($option->isNegatable() ? '--%1$s|--no-%1$s' : '--%1$s%2$s', $option->getName(), $value));
+ $spacingWidth = $totalWidth - Helper::width($synopsis);
+ $this->writeText(\sprintf(
+ ' %s %s%s%s%s',
+ $synopsis,
+ \str_repeat(' ', $spacingWidth),
+ // + 4 = 2 spaces before , 2 spaces after
+ \preg_replace('/\\s*[\\r\\n]\\s*/', "\n" . \str_repeat(' ', $totalWidth + 4), $option->getDescription()),
+ $default,
+ $option->isArray() ? ' (multiple values allowed)' : ''
+ ), $options);
+ }
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void
+ {
+ $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
+ foreach ($definition->getArguments() as $argument) {
+ $totalWidth = \max($totalWidth, Helper::width($argument->getName()));
+ }
+ if ($definition->getArguments()) {
+ $this->writeText('Arguments:', $options);
+ $this->writeText("\n");
+ foreach ($definition->getArguments() as $argument) {
+ $this->describeInputArgument($argument, \array_merge($options, ['total_width' => $totalWidth]));
+ $this->writeText("\n");
+ }
+ }
+ if ($definition->getArguments() && $definition->getOptions()) {
+ $this->writeText("\n");
+ }
+ if ($definition->getOptions()) {
+ $laterOptions = [];
+ $this->writeText('Options:', $options);
+ foreach ($definition->getOptions() as $option) {
+ if (\strlen($option->getShortcut() ?? '') > 1) {
+ $laterOptions[] = $option;
+ continue;
+ }
+ $this->writeText("\n");
+ $this->describeInputOption($option, \array_merge($options, ['total_width' => $totalWidth]));
+ }
+ foreach ($laterOptions as $option) {
+ $this->writeText("\n");
+ $this->describeInputOption($option, \array_merge($options, ['total_width' => $totalWidth]));
+ }
+ }
+ }
+ protected function describeCommand(Command $command, array $options = []) : void
+ {
+ $command->mergeApplicationDefinition(\false);
+ if ($description = $command->getDescription()) {
+ $this->writeText('Description:', $options);
+ $this->writeText("\n");
+ $this->writeText(' ' . $description);
+ $this->writeText("\n\n");
+ }
+ $this->writeText('Usage:', $options);
+ foreach (\array_merge([$command->getSynopsis(\true)], $command->getAliases(), $command->getUsages()) as $usage) {
+ $this->writeText("\n");
+ $this->writeText(' ' . OutputFormatter::escape($usage), $options);
+ }
+ $this->writeText("\n");
+ $definition = $command->getDefinition();
+ if ($definition->getOptions() || $definition->getArguments()) {
+ $this->writeText("\n");
+ $this->describeInputDefinition($definition, $options);
+ $this->writeText("\n");
+ }
+ $help = $command->getProcessedHelp();
+ if ($help && $help !== $description) {
+ $this->writeText("\n");
+ $this->writeText('Help:', $options);
+ $this->writeText("\n");
+ $this->writeText(' ' . \str_replace("\n", "\n ", $help), $options);
+ $this->writeText("\n");
+ }
+ }
+ protected function describeApplication(Application $application, array $options = []) : void
+ {
+ $describedNamespace = $options['namespace'] ?? null;
+ $description = new ApplicationDescription($application, $describedNamespace);
+ if (isset($options['raw_text']) && $options['raw_text']) {
+ $width = $this->getColumnWidth($description->getCommands());
+ foreach ($description->getCommands() as $command) {
+ $this->writeText(\sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options);
+ $this->writeText("\n");
+ }
+ } else {
+ if ('' != ($help = $application->getHelp())) {
+ $this->writeText("{$help}\n\n", $options);
+ }
+ $this->writeText("Usage:\n", $options);
+ $this->writeText(" command [options] [arguments]\n\n", $options);
+ $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options);
+ $this->writeText("\n");
+ $this->writeText("\n");
+ $commands = $description->getCommands();
+ $namespaces = $description->getNamespaces();
+ if ($describedNamespace && $namespaces) {
+ // make sure all alias commands are included when describing a specific namespace
+ $describedNamespaceInfo = \reset($namespaces);
+ foreach ($describedNamespaceInfo['commands'] as $name) {
+ $commands[$name] = $description->getCommand($name);
+ }
+ }
+ // calculate max. width based on available commands per namespace
+ $width = $this->getColumnWidth(\array_merge(...\array_values(\array_map(function ($namespace) use($commands) {
+ return \array_intersect($namespace['commands'], \array_keys($commands));
+ }, \array_values($namespaces)))));
+ if ($describedNamespace) {
+ $this->writeText(\sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options);
+ } else {
+ $this->writeText('Available commands:', $options);
+ }
+ foreach ($namespaces as $namespace) {
+ $namespace['commands'] = \array_filter($namespace['commands'], function ($name) use($commands) {
+ return isset($commands[$name]);
+ });
+ if (!$namespace['commands']) {
+ continue;
+ }
+ if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
+ $this->writeText("\n");
+ $this->writeText(' ' . $namespace['id'] . '', $options);
+ }
+ foreach ($namespace['commands'] as $name) {
+ $this->writeText("\n");
+ $spacingWidth = $width - Helper::width($name);
+ $command = $commands[$name];
+ $commandAliases = $name === $command->getName() ? $this->getCommandAliasesText($command) : '';
+ $this->writeText(\sprintf(' %s%s%s', $name, \str_repeat(' ', $spacingWidth), $commandAliases . $command->getDescription()), $options);
+ }
+ }
+ $this->writeText("\n");
+ }
+ }
+ private function writeText(string $content, array $options = []) : void
+ {
+ $this->write(isset($options['raw_text']) && $options['raw_text'] ? \strip_tags($content) : $content, isset($options['raw_output']) ? !$options['raw_output'] : \true);
+ }
+ /**
+ * Formats command aliases to show them in the command description.
+ */
+ private function getCommandAliasesText(Command $command) : string
+ {
+ $text = '';
+ $aliases = $command->getAliases();
+ if ($aliases) {
+ $text = '[' . \implode('|', $aliases) . '] ';
+ }
+ return $text;
+ }
+ /**
+ * Formats input option/argument default value.
+ * @param mixed $default
+ */
+ private function formatDefaultValue($default) : string
+ {
+ if (\INF === $default) {
+ return 'INF';
+ }
+ if (\is_string($default)) {
+ $default = OutputFormatter::escape($default);
+ } elseif (\is_array($default)) {
+ foreach ($default as $key => $value) {
+ if (\is_string($value)) {
+ $default[$key] = OutputFormatter::escape($value);
+ }
+ }
+ }
+ return \str_replace('\\\\', '\\', \json_encode($default, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE));
+ }
+ /**
+ * @param array $commands
+ */
+ private function getColumnWidth(array $commands) : int
+ {
+ $widths = [];
+ foreach ($commands as $command) {
+ if ($command instanceof Command) {
+ $widths[] = Helper::width($command->getName());
+ foreach ($command->getAliases() as $alias) {
+ $widths[] = Helper::width($alias);
+ }
+ } else {
+ $widths[] = Helper::width($command);
+ }
+ }
+ return $widths ? \max($widths) + 2 : 0;
+ }
+ /**
+ * @param InputOption[] $options
+ */
+ private function calculateTotalWidthForOptions(array $options) : int
+ {
+ $totalWidth = 0;
+ foreach ($options as $option) {
+ // "-" + shortcut + ", --" + name
+ $nameLength = 1 + \max(Helper::width($option->getShortcut()), 1) + 4 + Helper::width($option->getName());
+ if ($option->isNegatable()) {
+ $nameLength += 6 + Helper::width($option->getName());
+ // |--no- + name
+ } elseif ($option->acceptValue()) {
+ $valueLength = 1 + Helper::width($option->getName());
+ // = + value
+ $valueLength += $option->isValueOptional() ? 2 : 0;
+ // [ + ]
+ $nameLength += $valueLength;
+ }
+ $totalWidth = \max($totalWidth, $nameLength);
+ }
+ return $totalWidth;
+ }
+}
diff --git a/vendor/symfony/console/Descriptor/XmlDescriptor.php b/vendor/symfony/console/Descriptor/XmlDescriptor.php
new file mode 100644
index 00000000..88a2747c
--- /dev/null
+++ b/vendor/symfony/console/Descriptor/XmlDescriptor.php
@@ -0,0 +1,191 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Descriptor;
+
+use VendorPatches202401\Symfony\Component\Console\Application;
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Input\InputArgument;
+use VendorPatches202401\Symfony\Component\Console\Input\InputDefinition;
+use VendorPatches202401\Symfony\Component\Console\Input\InputOption;
+/**
+ * XML descriptor.
+ *
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class XmlDescriptor extends Descriptor
+{
+ public function getInputDefinitionDocument(InputDefinition $definition) : \DOMDocument
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($definitionXML = $dom->createElement('definition'));
+ $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
+ foreach ($definition->getArguments() as $argument) {
+ $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument));
+ }
+ $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
+ foreach ($definition->getOptions() as $option) {
+ $this->appendDocument($optionsXML, $this->getInputOptionDocument($option));
+ }
+ return $dom;
+ }
+ public function getCommandDocument(Command $command, bool $short = \false) : \DOMDocument
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($commandXML = $dom->createElement('command'));
+ $commandXML->setAttribute('id', $command->getName());
+ $commandXML->setAttribute('name', $command->getName());
+ $commandXML->setAttribute('hidden', $command->isHidden() ? 1 : 0);
+ $commandXML->appendChild($usagesXML = $dom->createElement('usages'));
+ $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode(\str_replace("\n", "\n ", $command->getDescription())));
+ if ($short) {
+ foreach ($command->getAliases() as $usage) {
+ $usagesXML->appendChild($dom->createElement('usage', $usage));
+ }
+ } else {
+ $command->mergeApplicationDefinition(\false);
+ foreach (\array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()) as $usage) {
+ $usagesXML->appendChild($dom->createElement('usage', $usage));
+ }
+ $commandXML->appendChild($helpXML = $dom->createElement('help'));
+ $helpXML->appendChild($dom->createTextNode(\str_replace("\n", "\n ", $command->getProcessedHelp())));
+ $definitionXML = $this->getInputDefinitionDocument($command->getDefinition());
+ $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));
+ }
+ return $dom;
+ }
+ public function getApplicationDocument(Application $application, string $namespace = null, bool $short = \false) : \DOMDocument
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($rootXml = $dom->createElement('symfony'));
+ if ('UNKNOWN' !== $application->getName()) {
+ $rootXml->setAttribute('name', $application->getName());
+ if ('UNKNOWN' !== $application->getVersion()) {
+ $rootXml->setAttribute('version', $application->getVersion());
+ }
+ }
+ $rootXml->appendChild($commandsXML = $dom->createElement('commands'));
+ $description = new ApplicationDescription($application, $namespace, \true);
+ if ($namespace) {
+ $commandsXML->setAttribute('namespace', $namespace);
+ }
+ foreach ($description->getCommands() as $command) {
+ $this->appendDocument($commandsXML, $this->getCommandDocument($command, $short));
+ }
+ if (!$namespace) {
+ $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));
+ foreach ($description->getNamespaces() as $namespaceDescription) {
+ $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
+ $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']);
+ foreach ($namespaceDescription['commands'] as $name) {
+ $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
+ $commandXML->appendChild($dom->createTextNode($name));
+ }
+ }
+ }
+ return $dom;
+ }
+ protected function describeInputArgument(InputArgument $argument, array $options = []) : void
+ {
+ $this->writeDocument($this->getInputArgumentDocument($argument));
+ }
+ protected function describeInputOption(InputOption $option, array $options = []) : void
+ {
+ $this->writeDocument($this->getInputOptionDocument($option));
+ }
+ protected function describeInputDefinition(InputDefinition $definition, array $options = []) : void
+ {
+ $this->writeDocument($this->getInputDefinitionDocument($definition));
+ }
+ protected function describeCommand(Command $command, array $options = []) : void
+ {
+ $this->writeDocument($this->getCommandDocument($command, $options['short'] ?? \false));
+ }
+ protected function describeApplication(Application $application, array $options = []) : void
+ {
+ $this->writeDocument($this->getApplicationDocument($application, $options['namespace'] ?? null, $options['short'] ?? \false));
+ }
+ /**
+ * Appends document children to parent node.
+ */
+ private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent) : void
+ {
+ foreach ($importedParent->childNodes as $childNode) {
+ $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, \true));
+ }
+ }
+ /**
+ * Writes DOM document.
+ */
+ private function writeDocument(\DOMDocument $dom) : void
+ {
+ $dom->formatOutput = \true;
+ $this->write($dom->saveXML());
+ }
+ private function getInputArgumentDocument(InputArgument $argument) : \DOMDocument
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($objectXML = $dom->createElement('argument'));
+ $objectXML->setAttribute('name', $argument->getName());
+ $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
+ $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
+ $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
+ $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+ $defaults = \is_array($argument->getDefault()) ? $argument->getDefault() : (\is_bool($argument->getDefault()) ? [\var_export($argument->getDefault(), \true)] : ($argument->getDefault() ? [$argument->getDefault()] : []));
+ foreach ($defaults as $default) {
+ $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+ $defaultXML->appendChild($dom->createTextNode($default));
+ }
+ return $dom;
+ }
+ private function getInputOptionDocument(InputOption $option) : \DOMDocument
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($objectXML = $dom->createElement('option'));
+ $objectXML->setAttribute('name', '--' . $option->getName());
+ $pos = \strpos($option->getShortcut() ?? '', '|');
+ if (\false !== $pos) {
+ $objectXML->setAttribute('shortcut', '-' . \substr($option->getShortcut(), 0, $pos));
+ $objectXML->setAttribute('shortcuts', '-' . \str_replace('|', '|-', $option->getShortcut()));
+ } else {
+ $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-' . $option->getShortcut() : '');
+ }
+ $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
+ $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
+ $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
+ $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
+ if ($option->acceptValue()) {
+ $defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? [\var_export($option->getDefault(), \true)] : ($option->getDefault() ? [$option->getDefault()] : []));
+ $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+ if (!empty($defaults)) {
+ foreach ($defaults as $default) {
+ $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+ $defaultXML->appendChild($dom->createTextNode($default));
+ }
+ }
+ }
+ if ($option->isNegatable()) {
+ $dom->appendChild($objectXML = $dom->createElement('option'));
+ $objectXML->setAttribute('name', '--no-' . $option->getName());
+ $objectXML->setAttribute('shortcut', '');
+ $objectXML->setAttribute('accept_value', 0);
+ $objectXML->setAttribute('is_value_required', 0);
+ $objectXML->setAttribute('is_multiple', 0);
+ $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode('Negate the "--' . $option->getName() . '" option'));
+ }
+ return $dom;
+ }
+}
diff --git a/vendor/symfony/console/Event/ConsoleCommandEvent.php b/vendor/symfony/console/Event/ConsoleCommandEvent.php
new file mode 100644
index 00000000..f7b4e0cd
--- /dev/null
+++ b/vendor/symfony/console/Event/ConsoleCommandEvent.php
@@ -0,0 +1,50 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Event;
+
+/**
+ * Allows to do things before the command is executed, like skipping the command or executing code before the command is
+ * going to be executed.
+ *
+ * Changing the input arguments will have no effect.
+ *
+ * @author Fabien Potencier
+ */
+final class ConsoleCommandEvent extends ConsoleEvent
+{
+ /**
+ * The return code for skipped commands, this will also be passed into the terminate event.
+ */
+ public const RETURN_CODE_DISABLED = 113;
+ /**
+ * Indicates if the command should be run or skipped.
+ * @var bool
+ */
+ private $commandShouldRun = \true;
+ /**
+ * Disables the command, so it won't be run.
+ */
+ public function disableCommand() : bool
+ {
+ return $this->commandShouldRun = \false;
+ }
+ public function enableCommand() : bool
+ {
+ return $this->commandShouldRun = \true;
+ }
+ /**
+ * Returns true if the command is runnable, false otherwise.
+ */
+ public function commandShouldRun() : bool
+ {
+ return $this->commandShouldRun;
+ }
+}
diff --git a/vendor/symfony/console/Event/ConsoleErrorEvent.php b/vendor/symfony/console/Event/ConsoleErrorEvent.php
new file mode 100644
index 00000000..32df698d
--- /dev/null
+++ b/vendor/symfony/console/Event/ConsoleErrorEvent.php
@@ -0,0 +1,55 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Event;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * Allows to handle throwables thrown while running a command.
+ *
+ * @author Wouter de Jong
+ */
+final class ConsoleErrorEvent extends ConsoleEvent
+{
+ /**
+ * @var \Throwable
+ */
+ private $error;
+ /**
+ * @var int
+ */
+ private $exitCode;
+ public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, Command $command = null)
+ {
+ parent::__construct($command, $input, $output);
+ $this->error = $error;
+ }
+ public function getError() : \Throwable
+ {
+ return $this->error;
+ }
+ public function setError(\Throwable $error) : void
+ {
+ $this->error = $error;
+ }
+ public function setExitCode(int $exitCode) : void
+ {
+ $this->exitCode = $exitCode;
+ $r = new \ReflectionProperty($this->error, 'code');
+ $r->setAccessible(\true);
+ $r->setValue($this->error, $this->exitCode);
+ }
+ public function getExitCode() : int
+ {
+ return $this->exitCode ?? (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1);
+ }
+}
diff --git a/vendor/symfony/console/Event/ConsoleEvent.php b/vendor/symfony/console/Event/ConsoleEvent.php
new file mode 100644
index 00000000..4d0395f4
--- /dev/null
+++ b/vendor/symfony/console/Event/ConsoleEvent.php
@@ -0,0 +1,60 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Event;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Contracts\EventDispatcher\Event;
+/**
+ * Allows to inspect input and output of a command.
+ *
+ * @author Francesco Levorato
+ */
+class ConsoleEvent extends Event
+{
+ protected $command;
+ /**
+ * @var \Symfony\Component\Console\Input\InputInterface
+ */
+ private $input;
+ /**
+ * @var \Symfony\Component\Console\Output\OutputInterface
+ */
+ private $output;
+ public function __construct(?Command $command, InputInterface $input, OutputInterface $output)
+ {
+ $this->command = $command;
+ $this->input = $input;
+ $this->output = $output;
+ }
+ /**
+ * Gets the command that is executed.
+ */
+ public function getCommand() : ?Command
+ {
+ return $this->command;
+ }
+ /**
+ * Gets the input instance.
+ */
+ public function getInput() : InputInterface
+ {
+ return $this->input;
+ }
+ /**
+ * Gets the output instance.
+ */
+ public function getOutput() : OutputInterface
+ {
+ return $this->output;
+ }
+}
diff --git a/vendor/symfony/console/Event/ConsoleSignalEvent.php b/vendor/symfony/console/Event/ConsoleSignalEvent.php
new file mode 100644
index 00000000..402b76ba
--- /dev/null
+++ b/vendor/symfony/console/Event/ConsoleSignalEvent.php
@@ -0,0 +1,60 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Event;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * @author marie
+ */
+final class ConsoleSignalEvent extends ConsoleEvent
+{
+ /**
+ * @var int
+ */
+ private $handlingSignal;
+ /**
+ * @var int|false
+ */
+ private $exitCode;
+ /**
+ * @param int|false $exitCode
+ */
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $handlingSignal, $exitCode = 0)
+ {
+ parent::__construct($command, $input, $output);
+ $this->handlingSignal = $handlingSignal;
+ $this->exitCode = $exitCode;
+ }
+ public function getHandlingSignal() : int
+ {
+ return $this->handlingSignal;
+ }
+ public function setExitCode(int $exitCode) : void
+ {
+ if ($exitCode < 0 || $exitCode > 255) {
+ throw new \InvalidArgumentException('Exit code must be between 0 and 255.');
+ }
+ $this->exitCode = $exitCode;
+ }
+ public function abortExit() : void
+ {
+ $this->exitCode = \false;
+ }
+ /**
+ * @return int|false
+ */
+ public function getExitCode()
+ {
+ return $this->exitCode;
+ }
+}
diff --git a/vendor/symfony/console/Event/ConsoleTerminateEvent.php b/vendor/symfony/console/Event/ConsoleTerminateEvent.php
new file mode 100644
index 00000000..d45c4d00
--- /dev/null
+++ b/vendor/symfony/console/Event/ConsoleTerminateEvent.php
@@ -0,0 +1,51 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Event;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * Allows to manipulate the exit code of a command after its execution.
+ *
+ * @author Francesco Levorato
+ * @author Jules Pietri
+ */
+final class ConsoleTerminateEvent extends ConsoleEvent
+{
+ /**
+ * @var int
+ */
+ private $exitCode;
+ /**
+ * @readonly
+ * @var int|null
+ */
+ private $interruptingSignal;
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $exitCode, ?int $interruptingSignal = null)
+ {
+ $this->exitCode = $exitCode;
+ $this->interruptingSignal = $interruptingSignal;
+ parent::__construct($command, $input, $output);
+ }
+ public function setExitCode(int $exitCode) : void
+ {
+ $this->exitCode = $exitCode;
+ }
+ public function getExitCode() : int
+ {
+ return $this->exitCode;
+ }
+ public function getInterruptingSignal() : ?int
+ {
+ return $this->interruptingSignal;
+ }
+}
diff --git a/vendor/symfony/console/EventListener/ErrorListener.php b/vendor/symfony/console/EventListener/ErrorListener.php
new file mode 100644
index 00000000..04fd96be
--- /dev/null
+++ b/vendor/symfony/console/EventListener/ErrorListener.php
@@ -0,0 +1,82 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\EventListener;
+
+use VendorPatches202401\Psr\Log\LoggerInterface;
+use VendorPatches202401\Symfony\Component\Console\ConsoleEvents;
+use VendorPatches202401\Symfony\Component\Console\Event\ConsoleErrorEvent;
+use VendorPatches202401\Symfony\Component\Console\Event\ConsoleEvent;
+use VendorPatches202401\Symfony\Component\Console\Event\ConsoleTerminateEvent;
+use VendorPatches202401\Symfony\Component\EventDispatcher\EventSubscriberInterface;
+/**
+ * @author James Halsall
+ * @author Robin Chalas
+ */
+class ErrorListener implements EventSubscriberInterface
+{
+ /**
+ * @var \Psr\Log\LoggerInterface|null
+ */
+ private $logger;
+ public function __construct(LoggerInterface $logger = null)
+ {
+ $this->logger = $logger;
+ }
+ /**
+ * @return void
+ */
+ public function onConsoleError(ConsoleErrorEvent $event)
+ {
+ if (null === $this->logger) {
+ return;
+ }
+ $error = $event->getError();
+ if (!($inputString = $this->getInputString($event))) {
+ $this->logger->critical('An error occurred while using the console. Message: "{message}"', ['exception' => $error, 'message' => $error->getMessage()]);
+ return;
+ }
+ $this->logger->critical('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]);
+ }
+ /**
+ * @return void
+ */
+ public function onConsoleTerminate(ConsoleTerminateEvent $event)
+ {
+ if (null === $this->logger) {
+ return;
+ }
+ $exitCode = $event->getExitCode();
+ if (0 === $exitCode) {
+ return;
+ }
+ if (!($inputString = $this->getInputString($event))) {
+ $this->logger->debug('The console exited with code "{code}"', ['code' => $exitCode]);
+ return;
+ }
+ $this->logger->debug('Command "{command}" exited with code "{code}"', ['command' => $inputString, 'code' => $exitCode]);
+ }
+ public static function getSubscribedEvents() : array
+ {
+ return [ConsoleEvents::ERROR => ['onConsoleError', -128], ConsoleEvents::TERMINATE => ['onConsoleTerminate', -128]];
+ }
+ private static function getInputString(ConsoleEvent $event) : ?string
+ {
+ $commandName = ($nullsafeVariable1 = $event->getCommand()) ? $nullsafeVariable1->getName() : null;
+ $input = $event->getInput();
+ if ($input instanceof \Stringable) {
+ if ($commandName) {
+ return \str_replace(["'{$commandName}'", "\"{$commandName}\""], $commandName, (string) $input);
+ }
+ return (string) $input;
+ }
+ return $commandName;
+ }
+}
diff --git a/vendor/symfony/console/Exception/CommandNotFoundException.php b/vendor/symfony/console/Exception/CommandNotFoundException.php
new file mode 100644
index 00000000..0654b5a4
--- /dev/null
+++ b/vendor/symfony/console/Exception/CommandNotFoundException.php
@@ -0,0 +1,42 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+/**
+ * Represents an incorrect command name typed in the console.
+ *
+ * @author Jérôme Tamarelle
+ */
+class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface
+{
+ /**
+ * @var mixed[]
+ */
+ private $alternatives;
+ /**
+ * @param string $message Exception message to throw
+ * @param string[] $alternatives List of similar defined names
+ * @param int $code Exception code
+ * @param \Throwable|null $previous Previous exception used for the exception chaining
+ */
+ public function __construct(string $message, array $alternatives = [], int $code = 0, \Throwable $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+ $this->alternatives = $alternatives;
+ }
+ /**
+ * @return string[]
+ */
+ public function getAlternatives() : array
+ {
+ return $this->alternatives;
+ }
+}
diff --git a/vendor/symfony/console/Exception/ExceptionInterface.php b/vendor/symfony/console/Exception/ExceptionInterface.php
new file mode 100644
index 00000000..33cb2828
--- /dev/null
+++ b/vendor/symfony/console/Exception/ExceptionInterface.php
@@ -0,0 +1,20 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+/**
+ * ExceptionInterface.
+ *
+ * @author Jérôme Tamarelle
+ */
+interface ExceptionInterface extends \Throwable
+{
+}
diff --git a/vendor/symfony/console/Exception/InvalidArgumentException.php b/vendor/symfony/console/Exception/InvalidArgumentException.php
new file mode 100644
index 00000000..9d83cc2b
--- /dev/null
+++ b/vendor/symfony/console/Exception/InvalidArgumentException.php
@@ -0,0 +1,18 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+/**
+ * @author Jérôme Tamarelle
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/console/Exception/InvalidOptionException.php b/vendor/symfony/console/Exception/InvalidOptionException.php
new file mode 100644
index 00000000..3c7579a9
--- /dev/null
+++ b/vendor/symfony/console/Exception/InvalidOptionException.php
@@ -0,0 +1,20 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+/**
+ * Represents an incorrect option name or value typed in the console.
+ *
+ * @author Jérôme Tamarelle
+ */
+class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/console/Exception/LogicException.php b/vendor/symfony/console/Exception/LogicException.php
new file mode 100644
index 00000000..92c3a6bd
--- /dev/null
+++ b/vendor/symfony/console/Exception/LogicException.php
@@ -0,0 +1,18 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+/**
+ * @author Jérôme Tamarelle
+ */
+class LogicException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/console/Exception/MissingInputException.php b/vendor/symfony/console/Exception/MissingInputException.php
new file mode 100644
index 00000000..437a24e2
--- /dev/null
+++ b/vendor/symfony/console/Exception/MissingInputException.php
@@ -0,0 +1,20 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+/**
+ * Represents failure to read input from stdin.
+ *
+ * @author Gabriel Ostrolucký
+ */
+class MissingInputException extends RuntimeException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/console/Exception/NamespaceNotFoundException.php b/vendor/symfony/console/Exception/NamespaceNotFoundException.php
new file mode 100644
index 00000000..ba4d626c
--- /dev/null
+++ b/vendor/symfony/console/Exception/NamespaceNotFoundException.php
@@ -0,0 +1,20 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+/**
+ * Represents an incorrect namespace typed in the console.
+ *
+ * @author Pierre du Plessis
+ */
+class NamespaceNotFoundException extends CommandNotFoundException
+{
+}
diff --git a/vendor/symfony/console/Exception/RunCommandFailedException.php b/vendor/symfony/console/Exception/RunCommandFailedException.php
new file mode 100644
index 00000000..9ade1870
--- /dev/null
+++ b/vendor/symfony/console/Exception/RunCommandFailedException.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+use VendorPatches202401\Symfony\Component\Console\Messenger\RunCommandContext;
+/**
+ * @author Kevin Bond
+ */
+final class RunCommandFailedException extends RuntimeException
+{
+ /**
+ * @readonly
+ * @var \Symfony\Component\Console\Messenger\RunCommandContext
+ */
+ public $context;
+ /**
+ * @param \Throwable|string $exception
+ */
+ public function __construct($exception, RunCommandContext $context)
+ {
+ $this->context = $context;
+ parent::__construct($exception instanceof \Throwable ? $exception->getMessage() : $exception, $exception instanceof \Throwable ? $exception->getCode() : 0, $exception instanceof \Throwable ? $exception : null);
+ }
+}
diff --git a/vendor/symfony/console/Exception/RuntimeException.php b/vendor/symfony/console/Exception/RuntimeException.php
new file mode 100644
index 00000000..232ce6bd
--- /dev/null
+++ b/vendor/symfony/console/Exception/RuntimeException.php
@@ -0,0 +1,18 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Exception;
+
+/**
+ * @author Jérôme Tamarelle
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/console/Formatter/NullOutputFormatter.php b/vendor/symfony/console/Formatter/NullOutputFormatter.php
new file mode 100644
index 00000000..f12e2752
--- /dev/null
+++ b/vendor/symfony/console/Formatter/NullOutputFormatter.php
@@ -0,0 +1,47 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Formatter;
+
+/**
+ * @author Tien Xuan Vo
+ */
+final class NullOutputFormatter implements OutputFormatterInterface
+{
+ /**
+ * @var \Symfony\Component\Console\Formatter\NullOutputFormatterStyle
+ */
+ private $style;
+ public function format(?string $message) : ?string
+ {
+ return null;
+ }
+ public function getStyle(string $name) : OutputFormatterStyleInterface
+ {
+ // to comply with the interface we must return a OutputFormatterStyleInterface
+ return $this->style = $this->style ?? new NullOutputFormatterStyle();
+ }
+ public function hasStyle(string $name) : bool
+ {
+ return \false;
+ }
+ public function isDecorated() : bool
+ {
+ return \false;
+ }
+ public function setDecorated(bool $decorated) : void
+ {
+ // do nothing
+ }
+ public function setStyle(string $name, OutputFormatterStyleInterface $style) : void
+ {
+ // do nothing
+ }
+}
diff --git a/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php
new file mode 100644
index 00000000..84278820
--- /dev/null
+++ b/vendor/symfony/console/Formatter/NullOutputFormatterStyle.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Formatter;
+
+/**
+ * @author Tien Xuan Vo
+ */
+final class NullOutputFormatterStyle implements OutputFormatterStyleInterface
+{
+ public function apply(string $text) : string
+ {
+ return $text;
+ }
+ public function setBackground(string $color = null) : void
+ {
+ if (1 > \func_num_args()) {
+ trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
+ }
+ // do nothing
+ }
+ public function setForeground(string $color = null) : void
+ {
+ if (1 > \func_num_args()) {
+ trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
+ }
+ // do nothing
+ }
+ public function setOption(string $option) : void
+ {
+ // do nothing
+ }
+ public function setOptions(array $options) : void
+ {
+ // do nothing
+ }
+ public function unsetOption(string $option) : void
+ {
+ // do nothing
+ }
+}
diff --git a/vendor/symfony/console/Formatter/OutputFormatter.php b/vendor/symfony/console/Formatter/OutputFormatter.php
new file mode 100644
index 00000000..c043ee72
--- /dev/null
+++ b/vendor/symfony/console/Formatter/OutputFormatter.php
@@ -0,0 +1,241 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Formatter;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use function VendorPatches202401\Symfony\Component\String\b;
+/**
+ * Formatter class for console output.
+ *
+ * @author Konstantin Kudryashov
+ * @author Roland Franssen
+ */
+class OutputFormatter implements WrappableOutputFormatterInterface
+{
+ /**
+ * @var bool
+ */
+ private $decorated;
+ /**
+ * @var mixed[]
+ */
+ private $styles = [];
+ /**
+ * @var \Symfony\Component\Console\Formatter\OutputFormatterStyleStack
+ */
+ private $styleStack;
+ public function __clone()
+ {
+ $this->styleStack = clone $this->styleStack;
+ foreach ($this->styles as $key => $value) {
+ $this->styles[$key] = clone $value;
+ }
+ }
+ /**
+ * Escapes "<" and ">" special chars in given text.
+ */
+ public static function escape(string $text) : string
+ {
+ $text = \preg_replace('/([^\\\\]|^)([<>])/', '$1\\\\$2', $text);
+ return self::escapeTrailingBackslash($text);
+ }
+ /**
+ * Escapes trailing "\" in given text.
+ *
+ * @internal
+ */
+ public static function escapeTrailingBackslash(string $text) : string
+ {
+ if (\substr_compare($text, '\\', -\strlen('\\')) === 0) {
+ $len = \strlen($text);
+ $text = \rtrim($text, '\\');
+ $text = \str_replace("\x00", '', $text);
+ $text .= \str_repeat("\x00", $len - \strlen($text));
+ }
+ return $text;
+ }
+ /**
+ * Initializes console output formatter.
+ *
+ * @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances
+ */
+ public function __construct(bool $decorated = \false, array $styles = [])
+ {
+ $this->decorated = $decorated;
+ $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
+ $this->setStyle('info', new OutputFormatterStyle('green'));
+ $this->setStyle('comment', new OutputFormatterStyle('yellow'));
+ $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
+ foreach ($styles as $name => $style) {
+ $this->setStyle($name, $style);
+ }
+ $this->styleStack = new OutputFormatterStyleStack();
+ }
+ /**
+ * @return void
+ */
+ public function setDecorated(bool $decorated)
+ {
+ $this->decorated = $decorated;
+ }
+ public function isDecorated() : bool
+ {
+ return $this->decorated;
+ }
+ /**
+ * @return void
+ */
+ public function setStyle(string $name, OutputFormatterStyleInterface $style)
+ {
+ $this->styles[\strtolower($name)] = $style;
+ }
+ public function hasStyle(string $name) : bool
+ {
+ return isset($this->styles[\strtolower($name)]);
+ }
+ public function getStyle(string $name) : OutputFormatterStyleInterface
+ {
+ if (!$this->hasStyle($name)) {
+ throw new InvalidArgumentException(\sprintf('Undefined style: "%s".', $name));
+ }
+ return $this->styles[\strtolower($name)];
+ }
+ public function format(?string $message) : ?string
+ {
+ return $this->formatAndWrap($message, 0);
+ }
+ /**
+ * @return string
+ */
+ public function formatAndWrap(?string $message, int $width)
+ {
+ if (null === $message) {
+ return '';
+ }
+ $offset = 0;
+ $output = '';
+ $openTagRegex = '[a-z](?:[^\\\\<>]*+ | \\\\.)*';
+ $closeTagRegex = '[a-z][^<>]*+';
+ $currentLineLength = 0;
+ \preg_match_all("#<(({$openTagRegex}) | /({$closeTagRegex})?)>#ix", $message, $matches, \PREG_OFFSET_CAPTURE);
+ foreach ($matches[0] as $i => $match) {
+ $pos = $match[1];
+ $text = $match[0];
+ if (0 != $pos && '\\' == $message[$pos - 1]) {
+ continue;
+ }
+ // add the text up to the next tag
+ $output .= $this->applyCurrentStyle(\substr($message, $offset, $pos - $offset), $output, $width, $currentLineLength);
+ $offset = $pos + \strlen($text);
+ // opening tag?
+ if ($open = '/' !== $text[1]) {
+ $tag = $matches[1][$i][0];
+ } else {
+ $tag = $matches[3][$i][0] ?? '';
+ }
+ if (!$open && !$tag) {
+ // >
+ $this->styleStack->pop();
+ } elseif (null === ($style = $this->createStyleFromString($tag))) {
+ $output .= $this->applyCurrentStyle($text, $output, $width, $currentLineLength);
+ } elseif ($open) {
+ $this->styleStack->push($style);
+ } else {
+ $this->styleStack->pop($style);
+ }
+ }
+ $output .= $this->applyCurrentStyle(\substr($message, $offset), $output, $width, $currentLineLength);
+ return \strtr($output, ["\x00" => '\\', '\\<' => '<', '\\>' => '>']);
+ }
+ public function getStyleStack() : OutputFormatterStyleStack
+ {
+ return $this->styleStack;
+ }
+ /**
+ * Tries to create new style instance from string.
+ */
+ private function createStyleFromString(string $string) : ?OutputFormatterStyleInterface
+ {
+ if (isset($this->styles[$string])) {
+ return $this->styles[$string];
+ }
+ if (!\preg_match_all('/([^=]+)=([^;]+)(;|$)/', $string, $matches, \PREG_SET_ORDER)) {
+ return null;
+ }
+ $style = new OutputFormatterStyle();
+ foreach ($matches as $match) {
+ \array_shift($match);
+ $match[0] = \strtolower($match[0]);
+ if ('fg' == $match[0]) {
+ $style->setForeground(\strtolower($match[1]));
+ } elseif ('bg' == $match[0]) {
+ $style->setBackground(\strtolower($match[1]));
+ } elseif ('href' === $match[0]) {
+ $url = \preg_replace('{\\\\([<>])}', '$1', $match[1]);
+ $style->setHref($url);
+ } elseif ('options' === $match[0]) {
+ \preg_match_all('([^,;]+)', \strtolower($match[1]), $options);
+ $options = \array_shift($options);
+ foreach ($options as $option) {
+ $style->setOption($option);
+ }
+ } else {
+ return null;
+ }
+ }
+ return $style;
+ }
+ /**
+ * Applies current style from stack to text, if must be applied.
+ */
+ private function applyCurrentStyle(string $text, string $current, int $width, int &$currentLineLength) : string
+ {
+ if ('' === $text) {
+ return '';
+ }
+ if (!$width) {
+ return $this->isDecorated() ? $this->styleStack->getCurrent()->apply($text) : $text;
+ }
+ if (!$currentLineLength && '' !== $current) {
+ $text = \ltrim($text);
+ }
+ if ($currentLineLength) {
+ $prefix = \substr($text, 0, $i = $width - $currentLineLength) . "\n";
+ $text = \substr($text, $i);
+ } else {
+ $prefix = '';
+ }
+ \preg_match('~(\\n)$~', $text, $matches);
+ $text = $prefix . $this->addLineBreaks($text, $width);
+ $text = \rtrim($text, "\n") . ($matches[1] ?? '');
+ if (!$currentLineLength && '' !== $current && \substr_compare($current, "\n", -\strlen("\n")) !== 0) {
+ $text = "\n" . $text;
+ }
+ $lines = \explode("\n", $text);
+ foreach ($lines as $line) {
+ $currentLineLength += \strlen($line);
+ if ($width <= $currentLineLength) {
+ $currentLineLength = 0;
+ }
+ }
+ if ($this->isDecorated()) {
+ foreach ($lines as $i => $line) {
+ $lines[$i] = $this->styleStack->getCurrent()->apply($line);
+ }
+ }
+ return \implode("\n", $lines);
+ }
+ private function addLineBreaks(string $text, int $width) : string
+ {
+ $encoding = \mb_detect_encoding($text, null, \true) ?: 'UTF-8';
+ return b($text)->toCodePointString($encoding)->wordwrap($width, "\n", \true)->toByteString($encoding);
+ }
+}
diff --git a/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Formatter/OutputFormatterInterface.php
new file mode 100644
index 00000000..9a5a80e6
--- /dev/null
+++ b/vendor/symfony/console/Formatter/OutputFormatterInterface.php
@@ -0,0 +1,50 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter interface for console output.
+ *
+ * @author Konstantin Kudryashov
+ */
+interface OutputFormatterInterface
+{
+ /**
+ * Sets the decorated flag.
+ *
+ * @return void
+ */
+ public function setDecorated(bool $decorated);
+ /**
+ * Whether the output will decorate messages.
+ */
+ public function isDecorated() : bool;
+ /**
+ * Sets a new style.
+ *
+ * @return void
+ */
+ public function setStyle(string $name, OutputFormatterStyleInterface $style);
+ /**
+ * Checks if output formatter has style with specified name.
+ */
+ public function hasStyle(string $name) : bool;
+ /**
+ * Gets style options from style with specified name.
+ *
+ * @throws \InvalidArgumentException When style isn't defined
+ */
+ public function getStyle(string $name) : OutputFormatterStyleInterface;
+ /**
+ * Formats a message according to the given styles.
+ */
+ public function format(?string $message) : ?string;
+}
diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyle.php b/vendor/symfony/console/Formatter/OutputFormatterStyle.php
new file mode 100644
index 00000000..9ceb9dae
--- /dev/null
+++ b/vendor/symfony/console/Formatter/OutputFormatterStyle.php
@@ -0,0 +1,113 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Formatter;
+
+use VendorPatches202401\Symfony\Component\Console\Color;
+/**
+ * Formatter style class for defining styles.
+ *
+ * @author Konstantin Kudryashov
+ */
+class OutputFormatterStyle implements OutputFormatterStyleInterface
+{
+ /**
+ * @var \Symfony\Component\Console\Color
+ */
+ private $color;
+ /**
+ * @var string
+ */
+ private $foreground;
+ /**
+ * @var string
+ */
+ private $background;
+ /**
+ * @var mixed[]
+ */
+ private $options;
+ /**
+ * @var string|null
+ */
+ private $href;
+ /**
+ * @var bool
+ */
+ private $handlesHrefGracefully;
+ /**
+ * Initializes output formatter style.
+ *
+ * @param string|null $foreground The style foreground color name
+ * @param string|null $background The style background color name
+ */
+ public function __construct(string $foreground = null, string $background = null, array $options = [])
+ {
+ $this->color = new Color($this->foreground = $foreground ?: '', $this->background = $background ?: '', $this->options = $options);
+ }
+ /**
+ * @return void
+ */
+ public function setForeground(string $color = null)
+ {
+ if (1 > \func_num_args()) {
+ trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
+ }
+ $this->color = new Color($this->foreground = $color ?: '', $this->background, $this->options);
+ }
+ /**
+ * @return void
+ */
+ public function setBackground(string $color = null)
+ {
+ if (1 > \func_num_args()) {
+ trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
+ }
+ $this->color = new Color($this->foreground, $this->background = $color ?: '', $this->options);
+ }
+ public function setHref(string $url) : void
+ {
+ $this->href = $url;
+ }
+ /**
+ * @return void
+ */
+ public function setOption(string $option)
+ {
+ $this->options[] = $option;
+ $this->color = new Color($this->foreground, $this->background, $this->options);
+ }
+ /**
+ * @return void
+ */
+ public function unsetOption(string $option)
+ {
+ $pos = \array_search($option, $this->options);
+ if (\false !== $pos) {
+ unset($this->options[$pos]);
+ }
+ $this->color = new Color($this->foreground, $this->background, $this->options);
+ }
+ /**
+ * @return void
+ */
+ public function setOptions(array $options)
+ {
+ $this->color = new Color($this->foreground, $this->background, $this->options = $options);
+ }
+ public function apply(string $text) : string
+ {
+ $this->handlesHrefGracefully = $this->handlesHrefGracefully ?? 'JetBrains-JediTerm' !== \getenv('TERMINAL_EMULATOR') && (!\getenv('KONSOLE_VERSION') || (int) \getenv('KONSOLE_VERSION') > 201100) && !isset($_SERVER['IDEA_INITIAL_DIRECTORY']);
+ if (null !== $this->href && $this->handlesHrefGracefully) {
+ $text = "\x1b]8;;{$this->href}\x1b\\{$text}\x1b]8;;\x1b\\";
+ }
+ return $this->color->apply($text);
+ }
+}
diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php
new file mode 100644
index 00000000..023bcba1
--- /dev/null
+++ b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php
@@ -0,0 +1,54 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter style interface for defining styles.
+ *
+ * @author Konstantin Kudryashov
+ */
+interface OutputFormatterStyleInterface
+{
+ /**
+ * Sets style foreground color.
+ *
+ * @return void
+ */
+ public function setForeground(?string $color);
+ /**
+ * Sets style background color.
+ *
+ * @return void
+ */
+ public function setBackground(?string $color);
+ /**
+ * Sets some specific style option.
+ *
+ * @return void
+ */
+ public function setOption(string $option);
+ /**
+ * Unsets some specific style option.
+ *
+ * @return void
+ */
+ public function unsetOption(string $option);
+ /**
+ * Sets multiple style options at once.
+ *
+ * @return void
+ */
+ public function setOptions(array $options);
+ /**
+ * Applies the style to a given text.
+ */
+ public function apply(string $text) : string;
+}
diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php
new file mode 100644
index 00000000..cdf733c5
--- /dev/null
+++ b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php
@@ -0,0 +1,94 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Formatter;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Contracts\Service\ResetInterface;
+/**
+ * @author Jean-François Simon
+ */
+class OutputFormatterStyleStack implements ResetInterface
+{
+ /**
+ * @var OutputFormatterStyleInterface[]
+ */
+ private $styles = [];
+ /**
+ * @var \Symfony\Component\Console\Formatter\OutputFormatterStyleInterface
+ */
+ private $emptyStyle;
+ public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
+ {
+ $this->emptyStyle = $emptyStyle ?? new OutputFormatterStyle();
+ $this->reset();
+ }
+ /**
+ * Resets stack (ie. empty internal arrays).
+ *
+ * @return void
+ */
+ public function reset()
+ {
+ $this->styles = [];
+ }
+ /**
+ * Pushes a style in the stack.
+ *
+ * @return void
+ */
+ public function push(OutputFormatterStyleInterface $style)
+ {
+ $this->styles[] = $style;
+ }
+ /**
+ * Pops a style from the stack.
+ *
+ * @throws InvalidArgumentException When style tags incorrectly nested
+ */
+ public function pop(OutputFormatterStyleInterface $style = null) : OutputFormatterStyleInterface
+ {
+ if (!$this->styles) {
+ return $this->emptyStyle;
+ }
+ if (null === $style) {
+ return \array_pop($this->styles);
+ }
+ foreach (\array_reverse($this->styles, \true) as $index => $stackedStyle) {
+ if ($style->apply('') === $stackedStyle->apply('')) {
+ $this->styles = \array_slice($this->styles, 0, $index);
+ return $stackedStyle;
+ }
+ }
+ throw new InvalidArgumentException('Incorrectly nested style tag found.');
+ }
+ /**
+ * Computes current style with stacks top codes.
+ */
+ public function getCurrent() : OutputFormatterStyleInterface
+ {
+ if (!$this->styles) {
+ return $this->emptyStyle;
+ }
+ return $this->styles[\count($this->styles) - 1];
+ }
+ /**
+ * @return $this
+ */
+ public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
+ {
+ $this->emptyStyle = $emptyStyle;
+ return $this;
+ }
+ public function getEmptyStyle() : OutputFormatterStyleInterface
+ {
+ return $this->emptyStyle;
+ }
+}
diff --git a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php
new file mode 100644
index 00000000..0c4c1c77
--- /dev/null
+++ b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter interface for console output that supports word wrapping.
+ *
+ * @author Roland Franssen
+ */
+interface WrappableOutputFormatterInterface extends OutputFormatterInterface
+{
+ /**
+ * Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping).
+ *
+ * @return string
+ */
+ public function formatAndWrap(?string $message, int $width);
+}
diff --git a/vendor/symfony/console/Helper/DebugFormatterHelper.php b/vendor/symfony/console/Helper/DebugFormatterHelper.php
new file mode 100644
index 00000000..58ee2cb4
--- /dev/null
+++ b/vendor/symfony/console/Helper/DebugFormatterHelper.php
@@ -0,0 +1,89 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+/**
+ * Helps outputting debug information when running an external program from a command.
+ *
+ * An external program can be a Process, an HTTP request, or anything else.
+ *
+ * @author Fabien Potencier
+ */
+class DebugFormatterHelper extends Helper
+{
+ private const COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default'];
+ /**
+ * @var mixed[]
+ */
+ private $started = [];
+ /**
+ * @var int
+ */
+ private $count = -1;
+ /**
+ * Starts a debug formatting session.
+ */
+ public function start(string $id, string $message, string $prefix = 'RUN') : string
+ {
+ $this->started[$id] = ['border' => ++$this->count % \count(self::COLORS)];
+ return \sprintf("%s %s > %s>\n", $this->getBorder($id), $prefix, $message);
+ }
+ /**
+ * Adds progress to a formatting session.
+ */
+ public function progress(string $id, string $buffer, bool $error = \false, string $prefix = 'OUT', string $errorPrefix = 'ERR') : string
+ {
+ $message = '';
+ if ($error) {
+ if (isset($this->started[$id]['out'])) {
+ $message .= "\n";
+ unset($this->started[$id]['out']);
+ }
+ if (!isset($this->started[$id]['err'])) {
+ $message .= \sprintf('%s %s > ', $this->getBorder($id), $errorPrefix);
+ $this->started[$id]['err'] = \true;
+ }
+ $message .= \str_replace("\n", \sprintf("\n%s %s > ", $this->getBorder($id), $errorPrefix), $buffer);
+ } else {
+ if (isset($this->started[$id]['err'])) {
+ $message .= "\n";
+ unset($this->started[$id]['err']);
+ }
+ if (!isset($this->started[$id]['out'])) {
+ $message .= \sprintf('%s %s > ', $this->getBorder($id), $prefix);
+ $this->started[$id]['out'] = \true;
+ }
+ $message .= \str_replace("\n", \sprintf("\n%s %s > ", $this->getBorder($id), $prefix), $buffer);
+ }
+ return $message;
+ }
+ /**
+ * Stops a formatting session.
+ */
+ public function stop(string $id, string $message, bool $successful, string $prefix = 'RES') : string
+ {
+ $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';
+ if ($successful) {
+ return \sprintf("%s%s %s > %s>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
+ }
+ $message = \sprintf("%s%s %s > %s>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
+ unset($this->started[$id]['out'], $this->started[$id]['err']);
+ return $message;
+ }
+ private function getBorder(string $id) : string
+ {
+ return \sprintf(' >', self::COLORS[$this->started[$id]['border']]);
+ }
+ public function getName() : string
+ {
+ return 'debug_formatter';
+ }
+}
diff --git a/vendor/symfony/console/Helper/DescriptorHelper.php b/vendor/symfony/console/Helper/DescriptorHelper.php
new file mode 100644
index 00000000..60dd1be1
--- /dev/null
+++ b/vendor/symfony/console/Helper/DescriptorHelper.php
@@ -0,0 +1,74 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Descriptor\DescriptorInterface;
+use VendorPatches202401\Symfony\Component\Console\Descriptor\JsonDescriptor;
+use VendorPatches202401\Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+use VendorPatches202401\Symfony\Component\Console\Descriptor\ReStructuredTextDescriptor;
+use VendorPatches202401\Symfony\Component\Console\Descriptor\TextDescriptor;
+use VendorPatches202401\Symfony\Component\Console\Descriptor\XmlDescriptor;
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * This class adds helper method to describe objects in various formats.
+ *
+ * @author Jean-François Simon
+ */
+class DescriptorHelper extends Helper
+{
+ /**
+ * @var DescriptorInterface[]
+ */
+ private $descriptors = [];
+ public function __construct()
+ {
+ $this->register('txt', new TextDescriptor())->register('xml', new XmlDescriptor())->register('json', new JsonDescriptor())->register('md', new MarkdownDescriptor())->register('rst', new ReStructuredTextDescriptor());
+ }
+ /**
+ * Describes an object if supported.
+ *
+ * Available options are:
+ * * format: string, the output format name
+ * * raw_text: boolean, sets output type as raw
+ *
+ * @return void
+ *
+ * @throws InvalidArgumentException when the given format is not supported
+ */
+ public function describe(OutputInterface $output, ?object $object, array $options = [])
+ {
+ $options = \array_merge(['raw_text' => \false, 'format' => 'txt'], $options);
+ if (!isset($this->descriptors[$options['format']])) {
+ throw new InvalidArgumentException(\sprintf('Unsupported format "%s".', $options['format']));
+ }
+ $descriptor = $this->descriptors[$options['format']];
+ $descriptor->describe($output, $object, $options);
+ }
+ /**
+ * Registers a descriptor.
+ *
+ * @return $this
+ */
+ public function register(string $format, DescriptorInterface $descriptor)
+ {
+ $this->descriptors[$format] = $descriptor;
+ return $this;
+ }
+ public function getName() : string
+ {
+ return 'descriptor';
+ }
+ public function getFormats() : array
+ {
+ return \array_keys($this->descriptors);
+ }
+}
diff --git a/vendor/symfony/console/Helper/Dumper.php b/vendor/symfony/console/Helper/Dumper.php
new file mode 100644
index 00000000..1c1b2078
--- /dev/null
+++ b/vendor/symfony/console/Helper/Dumper.php
@@ -0,0 +1,73 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Component\VarDumper\Cloner\ClonerInterface;
+use VendorPatches202401\Symfony\Component\VarDumper\Cloner\VarCloner;
+use VendorPatches202401\Symfony\Component\VarDumper\Dumper\CliDumper;
+/**
+ * @author Roland Franssen
+ */
+final class Dumper
+{
+ /**
+ * @var \Symfony\Component\Console\Output\OutputInterface
+ */
+ private $output;
+ /**
+ * @var \Symfony\Component\VarDumper\Dumper\CliDumper|null
+ */
+ private $dumper;
+ /**
+ * @var \Symfony\Component\VarDumper\Cloner\ClonerInterface|null
+ */
+ private $cloner;
+ /**
+ * @var \Closure
+ */
+ private $handler;
+ public function __construct(OutputInterface $output, CliDumper $dumper = null, ClonerInterface $cloner = null)
+ {
+ $this->output = $output;
+ $this->dumper = $dumper;
+ $this->cloner = $cloner;
+ if (\class_exists(CliDumper::class)) {
+ $this->handler = function ($var) : string {
+ $dumper = $this->dumper = $this->dumper ?? new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR);
+ $dumper->setColors($this->output->isDecorated());
+ return \rtrim($dumper->dump(($this->cloner = $this->cloner ?? new VarCloner())->cloneVar($var)->withRefHandles(\false), \true));
+ };
+ } else {
+ $this->handler = function ($var) : string {
+ switch (\true) {
+ case null === $var:
+ return 'null';
+ case \true === $var:
+ return 'true';
+ case \false === $var:
+ return 'false';
+ case \is_string($var):
+ return '"' . $var . '"';
+ default:
+ return \rtrim(\print_r($var, \true));
+ }
+ };
+ }
+ }
+ /**
+ * @param mixed $var
+ */
+ public function __invoke($var) : string
+ {
+ return ($this->handler)($var);
+ }
+}
diff --git a/vendor/symfony/console/Helper/FormatterHelper.php b/vendor/symfony/console/Helper/FormatterHelper.php
new file mode 100644
index 00000000..e209ba1e
--- /dev/null
+++ b/vendor/symfony/console/Helper/FormatterHelper.php
@@ -0,0 +1,71 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Formatter\OutputFormatter;
+/**
+ * The Formatter class provides helpers to format messages.
+ *
+ * @author Fabien Potencier
+ */
+class FormatterHelper extends Helper
+{
+ /**
+ * Formats a message within a section.
+ */
+ public function formatSection(string $section, string $message, string $style = 'info') : string
+ {
+ return \sprintf('<%s>[%s]%s> %s', $style, $section, $style, $message);
+ }
+ /**
+ * Formats a message as a block of text.
+ * @param string|mixed[] $messages
+ */
+ public function formatBlock($messages, string $style, bool $large = \false) : string
+ {
+ if (!\is_array($messages)) {
+ $messages = [$messages];
+ }
+ $len = 0;
+ $lines = [];
+ foreach ($messages as $message) {
+ $message = OutputFormatter::escape($message);
+ $lines[] = \sprintf($large ? ' %s ' : ' %s ', $message);
+ $len = \max(self::width($message) + ($large ? 4 : 2), $len);
+ }
+ $messages = $large ? [\str_repeat(' ', $len)] : [];
+ for ($i = 0; isset($lines[$i]); ++$i) {
+ $messages[] = $lines[$i] . \str_repeat(' ', $len - self::width($lines[$i]));
+ }
+ if ($large) {
+ $messages[] = \str_repeat(' ', $len);
+ }
+ for ($i = 0; isset($messages[$i]); ++$i) {
+ $messages[$i] = \sprintf('<%s>%s%s>', $style, $messages[$i], $style);
+ }
+ return \implode("\n", $messages);
+ }
+ /**
+ * Truncates a message to the given length.
+ */
+ public function truncate(string $message, int $length, string $suffix = '...') : string
+ {
+ $computedLength = $length - self::width($suffix);
+ if ($computedLength > self::width($message)) {
+ return $message;
+ }
+ return self::substr($message, 0, $length) . $suffix;
+ }
+ public function getName() : string
+ {
+ return 'formatter';
+ }
+}
diff --git a/vendor/symfony/console/Helper/Helper.php b/vendor/symfony/console/Helper/Helper.php
new file mode 100644
index 00000000..08a34d65
--- /dev/null
+++ b/vendor/symfony/console/Helper/Helper.php
@@ -0,0 +1,139 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Formatter\OutputFormatterInterface;
+use VendorPatches202401\Symfony\Component\String\UnicodeString;
+/**
+ * Helper is the base class for all helper classes.
+ *
+ * @author Fabien Potencier
+ */
+abstract class Helper implements HelperInterface
+{
+ protected $helperSet;
+ /**
+ * @return void
+ */
+ public function setHelperSet(HelperSet $helperSet = null)
+ {
+ if (1 > \func_num_args()) {
+ trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
+ }
+ $this->helperSet = $helperSet;
+ }
+ public function getHelperSet() : ?HelperSet
+ {
+ return $this->helperSet;
+ }
+ /**
+ * Returns the width of a string, using mb_strwidth if it is available.
+ * The width is how many characters positions the string will use.
+ */
+ public static function width(?string $string) : int
+ {
+ $string = $string ?? '';
+ if (\preg_match('//u', $string)) {
+ return (new UnicodeString($string))->width(\false);
+ }
+ if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) {
+ return \strlen($string);
+ }
+ return \mb_strwidth($string, $encoding);
+ }
+ /**
+ * Returns the length of a string, using mb_strlen if it is available.
+ * The length is related to how many bytes the string will use.
+ */
+ public static function length(?string $string) : int
+ {
+ $string = $string ?? '';
+ if (\preg_match('//u', $string)) {
+ return (new UnicodeString($string))->length();
+ }
+ if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) {
+ return \strlen($string);
+ }
+ return \mb_strlen($string, $encoding);
+ }
+ /**
+ * Returns the subset of a string, using mb_substr if it is available.
+ */
+ public static function substr(?string $string, int $from, int $length = null) : string
+ {
+ $string = $string ?? '';
+ if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) {
+ return \substr($string, $from, $length);
+ }
+ return \mb_substr($string, $from, $length, $encoding);
+ }
+ /**
+ * @return string
+ * @param int|float $secs
+ */
+ public static function formatTime($secs, int $precision = 1)
+ {
+ $secs = (int) \floor($secs);
+ if (0 === $secs) {
+ return '< 1 sec';
+ }
+ static $timeFormats = [[1, '1 sec', 'secs'], [60, '1 min', 'mins'], [3600, '1 hr', 'hrs'], [86400, '1 day', 'days']];
+ $times = [];
+ foreach ($timeFormats as $index => $format) {
+ $seconds = isset($timeFormats[$index + 1]) ? $secs % $timeFormats[$index + 1][0] : $secs;
+ if (isset($times[$index - $precision])) {
+ unset($times[$index - $precision]);
+ }
+ if (0 === $seconds) {
+ continue;
+ }
+ $unitCount = $seconds / $format[0];
+ $times[$index] = 1 === $unitCount ? $format[1] : $unitCount . ' ' . $format[2];
+ if ($secs === $seconds) {
+ break;
+ }
+ $secs -= $seconds;
+ }
+ return \implode(', ', \array_reverse($times));
+ }
+ /**
+ * @return string
+ */
+ public static function formatMemory(int $memory)
+ {
+ if ($memory >= 1024 * 1024 * 1024) {
+ return \sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
+ }
+ if ($memory >= 1024 * 1024) {
+ return \sprintf('%.1f MiB', $memory / 1024 / 1024);
+ }
+ if ($memory >= 1024) {
+ return \sprintf('%d KiB', $memory / 1024);
+ }
+ return \sprintf('%d B', $memory);
+ }
+ /**
+ * @return string
+ */
+ public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string)
+ {
+ $isDecorated = $formatter->isDecorated();
+ $formatter->setDecorated(\false);
+ // remove <...> formatting
+ $string = $formatter->format($string ?? '');
+ // remove already formatted characters
+ $string = \preg_replace("/\x1b\\[[^m]*m/", '', $string ?? '');
+ // remove terminal hyperlinks
+ $string = \preg_replace('/\\033]8;[^;]*;[^\\033]*\\033\\\\/', '', $string ?? '');
+ $formatter->setDecorated($isDecorated);
+ return $string;
+ }
+}
diff --git a/vendor/symfony/console/Helper/HelperInterface.php b/vendor/symfony/console/Helper/HelperInterface.php
new file mode 100644
index 00000000..592487da
--- /dev/null
+++ b/vendor/symfony/console/Helper/HelperInterface.php
@@ -0,0 +1,36 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+/**
+ * HelperInterface is the interface all helpers must implement.
+ *
+ * @author Fabien Potencier
+ */
+interface HelperInterface
+{
+ /**
+ * Sets the helper set associated with this helper.
+ *
+ * @return void
+ */
+ public function setHelperSet(?HelperSet $helperSet);
+ /**
+ * Gets the helper set associated with this helper.
+ */
+ public function getHelperSet() : ?HelperSet;
+ /**
+ * Returns the canonical name of this helper.
+ *
+ * @return string
+ */
+ public function getName();
+}
diff --git a/vendor/symfony/console/Helper/HelperSet.php b/vendor/symfony/console/Helper/HelperSet.php
new file mode 100644
index 00000000..ab82d152
--- /dev/null
+++ b/vendor/symfony/console/Helper/HelperSet.php
@@ -0,0 +1,68 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+/**
+ * HelperSet represents a set of helpers to be used with a command.
+ *
+ * @author Fabien Potencier
+ *
+ * @implements \IteratorAggregate
+ */
+class HelperSet implements \IteratorAggregate
+{
+ /** @var array */
+ private $helpers = [];
+ /**
+ * @param HelperInterface[] $helpers
+ */
+ public function __construct(array $helpers = [])
+ {
+ foreach ($helpers as $alias => $helper) {
+ $this->set($helper, \is_int($alias) ? null : $alias);
+ }
+ }
+ /**
+ * @return void
+ */
+ public function set(HelperInterface $helper, string $alias = null)
+ {
+ $this->helpers[$helper->getName()] = $helper;
+ if (null !== $alias) {
+ $this->helpers[$alias] = $helper;
+ }
+ $helper->setHelperSet($this);
+ }
+ /**
+ * Returns true if the helper if defined.
+ */
+ public function has(string $name) : bool
+ {
+ return isset($this->helpers[$name]);
+ }
+ /**
+ * Gets a helper value.
+ *
+ * @throws InvalidArgumentException if the helper is not defined
+ */
+ public function get(string $name) : HelperInterface
+ {
+ if (!$this->has($name)) {
+ throw new InvalidArgumentException(\sprintf('The helper "%s" is not defined.', $name));
+ }
+ return $this->helpers[$name];
+ }
+ public function getIterator() : \Traversable
+ {
+ return new \ArrayIterator($this->helpers);
+ }
+}
diff --git a/vendor/symfony/console/Helper/InputAwareHelper.php b/vendor/symfony/console/Helper/InputAwareHelper.php
new file mode 100644
index 00000000..c15109fc
--- /dev/null
+++ b/vendor/symfony/console/Helper/InputAwareHelper.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Input\InputAwareInterface;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+/**
+ * An implementation of InputAwareInterface for Helpers.
+ *
+ * @author Wouter J
+ */
+abstract class InputAwareHelper extends Helper implements InputAwareInterface
+{
+ protected $input;
+ /**
+ * @return void
+ */
+ public function setInput(InputInterface $input)
+ {
+ $this->input = $input;
+ }
+}
diff --git a/vendor/symfony/console/Helper/OutputWrapper.php b/vendor/symfony/console/Helper/OutputWrapper.php
new file mode 100644
index 00000000..1cc75096
--- /dev/null
+++ b/vendor/symfony/console/Helper/OutputWrapper.php
@@ -0,0 +1,75 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+/**
+ * Simple output wrapper for "tagged outputs" instead of wordwrap(). This solution is based on a StackOverflow
+ * answer: https://stackoverflow.com/a/20434776/1476819 from user557597 (alias SLN).
+ *
+ * (?:
+ * # -- Words/Characters
+ * ( # (1 start)
+ * (?> # Atomic Group - Match words with valid breaks
+ * .{1,16} # 1-N characters
+ * # Followed by one of 4 prioritized, non-linebreak whitespace
+ * (?: # break types:
+ * (?<= [^\S\r\n] ) # 1. - Behind a non-linebreak whitespace
+ * [^\S\r\n]? # ( optionally accept an extra non-linebreak whitespace )
+ * | (?= \r? \n ) # 2. - Ahead a linebreak
+ * | $ # 3. - EOS
+ * | [^\S\r\n] # 4. - Accept an extra non-linebreak whitespace
+ * )
+ * ) # End atomic group
+ * |
+ * .{1,16} # No valid word breaks, just break on the N'th character
+ * ) # (1 end)
+ * (?: \r? \n )? # Optional linebreak after Words/Characters
+ * |
+ * # -- Or, Linebreak
+ * (?: \r? \n | $ ) # Stand alone linebreak or at EOS
+ * )
+ *
+ * @author Krisztián Ferenczi
+ *
+ * @see https://stackoverflow.com/a/20434776/1476819
+ */
+final class OutputWrapper
+{
+ /**
+ * @var bool
+ */
+ private $allowCutUrls = \false;
+ private const TAG_OPEN_REGEX_SEGMENT = '[a-z](?:[^\\\\<>]*+ | \\\\.)*';
+ private const TAG_CLOSE_REGEX_SEGMENT = '[a-z][^<>]*+';
+ private const URL_PATTERN = 'https?://\\S+';
+ public function __construct(bool $allowCutUrls = \false)
+ {
+ $this->allowCutUrls = $allowCutUrls;
+ }
+ public function wrap(string $text, int $width, string $break = "\n") : string
+ {
+ if (!$width) {
+ return $text;
+ }
+ $tagPattern = \sprintf('<(?:(?:%s)|/(?:%s)?)>', self::TAG_OPEN_REGEX_SEGMENT, self::TAG_CLOSE_REGEX_SEGMENT);
+ $limitPattern = "{1,{$width}}";
+ $patternBlocks = [$tagPattern];
+ if (!$this->allowCutUrls) {
+ $patternBlocks[] = self::URL_PATTERN;
+ }
+ $patternBlocks[] = '.';
+ $blocks = \implode('|', $patternBlocks);
+ $rowPattern = "(?:{$blocks}){$limitPattern}";
+ $pattern = \sprintf('#(?:((?>(%1$s)((?<=[^\\S\\r\\n])[^\\S\\r\\n]?|(?=\\r?\\n)|$|[^\\S\\r\\n]))|(%1$s))(?:\\r?\\n)?|(?:\\r?\\n|$))#imux', $rowPattern);
+ $output = \rtrim(\preg_replace($pattern, '\\1' . $break, $text), $break);
+ return \str_replace(' ' . $break, $break, $output);
+ }
+}
diff --git a/vendor/symfony/console/Helper/ProcessHelper.php b/vendor/symfony/console/Helper/ProcessHelper.php
new file mode 100644
index 00000000..6b48397c
--- /dev/null
+++ b/vendor/symfony/console/Helper/ProcessHelper.php
@@ -0,0 +1,116 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Output\ConsoleOutputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Component\Process\Exception\ProcessFailedException;
+use VendorPatches202401\Symfony\Component\Process\Process;
+/**
+ * The ProcessHelper class provides helpers to run external processes.
+ *
+ * @author Fabien Potencier
+ *
+ * @final
+ */
+class ProcessHelper extends Helper
+{
+ /**
+ * Runs an external process.
+ *
+ * @param array|Process $cmd An instance of Process or an array of the command and arguments
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ */
+ public function run(OutputInterface $output, $cmd, string $error = null, callable $callback = null, int $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) : Process
+ {
+ if (!\class_exists(Process::class)) {
+ throw new \LogicException('The ProcessHelper cannot be run as the Process component is not installed. Try running "compose require symfony/process".');
+ }
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+ $formatter = $this->getHelperSet()->get('debug_formatter');
+ if ($cmd instanceof Process) {
+ $cmd = [$cmd];
+ }
+ if (\is_string($cmd[0] ?? null)) {
+ $process = new Process($cmd);
+ $cmd = [];
+ } elseif (($cmd[0] ?? null) instanceof Process) {
+ $process = $cmd[0];
+ unset($cmd[0]);
+ } else {
+ throw new \InvalidArgumentException(\sprintf('Invalid command provided to "%s()": the command should be an array whose first element is either the path to the binary to run or a "Process" object.', __METHOD__));
+ }
+ if ($verbosity <= $output->getVerbosity()) {
+ $output->write($formatter->start(\spl_object_hash($process), $this->escapeString($process->getCommandLine())));
+ }
+ if ($output->isDebug()) {
+ $callback = $this->wrapCallback($output, $process, $callback);
+ }
+ $process->run($callback, $cmd);
+ if ($verbosity <= $output->getVerbosity()) {
+ $message = $process->isSuccessful() ? 'Command ran successfully' : \sprintf('%s Command did not run successfully', $process->getExitCode());
+ $output->write($formatter->stop(\spl_object_hash($process), $message, $process->isSuccessful()));
+ }
+ if (!$process->isSuccessful() && null !== $error) {
+ $output->writeln(\sprintf('%s', $this->escapeString($error)));
+ }
+ return $process;
+ }
+ /**
+ * Runs the process.
+ *
+ * This is identical to run() except that an exception is thrown if the process
+ * exits with a non-zero exit code.
+ *
+ * @param array|Process $cmd An instance of Process or a command to run
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ *
+ * @throws ProcessFailedException
+ *
+ * @see run()
+ */
+ public function mustRun(OutputInterface $output, $cmd, string $error = null, callable $callback = null) : Process
+ {
+ $process = $this->run($output, $cmd, $error, $callback);
+ if (!$process->isSuccessful()) {
+ throw new ProcessFailedException($process);
+ }
+ return $process;
+ }
+ /**
+ * Wraps a Process callback to add debugging output.
+ */
+ public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null) : callable
+ {
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+ $formatter = $this->getHelperSet()->get('debug_formatter');
+ return function ($type, $buffer) use($output, $process, $callback, $formatter) {
+ $output->write($formatter->progress(\spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type));
+ if (null !== $callback) {
+ $callback($type, $buffer);
+ }
+ };
+ }
+ private function escapeString(string $str) : string
+ {
+ return \str_replace('<', '\\<', $str);
+ }
+ public function getName() : string
+ {
+ return 'process';
+ }
+}
diff --git a/vendor/symfony/console/Helper/ProgressBar.php b/vendor/symfony/console/Helper/ProgressBar.php
new file mode 100644
index 00000000..101a9725
--- /dev/null
+++ b/vendor/symfony/console/Helper/ProgressBar.php
@@ -0,0 +1,597 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Cursor;
+use VendorPatches202401\Symfony\Component\Console\Exception\LogicException;
+use VendorPatches202401\Symfony\Component\Console\Output\ConsoleOutputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\ConsoleSectionOutput;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Component\Console\Terminal;
+/**
+ * The ProgressBar provides helpers to display progress output.
+ *
+ * @author Fabien Potencier
+ * @author Chris Jones
+ */
+final class ProgressBar
+{
+ public const FORMAT_VERBOSE = 'verbose';
+ public const FORMAT_VERY_VERBOSE = 'very_verbose';
+ public const FORMAT_DEBUG = 'debug';
+ public const FORMAT_NORMAL = 'normal';
+ private const FORMAT_VERBOSE_NOMAX = 'verbose_nomax';
+ private const FORMAT_VERY_VERBOSE_NOMAX = 'very_verbose_nomax';
+ private const FORMAT_DEBUG_NOMAX = 'debug_nomax';
+ private const FORMAT_NORMAL_NOMAX = 'normal_nomax';
+ /**
+ * @var int
+ */
+ private $barWidth = 28;
+ /**
+ * @var string
+ */
+ private $barChar;
+ /**
+ * @var string
+ */
+ private $emptyBarChar = '-';
+ /**
+ * @var string
+ */
+ private $progressChar = '>';
+ /**
+ * @var string|null
+ */
+ private $format;
+ /**
+ * @var string|null
+ */
+ private $internalFormat;
+ /**
+ * @var int|null
+ */
+ private $redrawFreq = 1;
+ /**
+ * @var int
+ */
+ private $writeCount = 0;
+ /**
+ * @var float
+ */
+ private $lastWriteTime = 0;
+ /**
+ * @var float
+ */
+ private $minSecondsBetweenRedraws = 0;
+ /**
+ * @var float
+ */
+ private $maxSecondsBetweenRedraws = 1;
+ /**
+ * @var \Symfony\Component\Console\Output\OutputInterface
+ */
+ private $output;
+ /**
+ * @var int
+ */
+ private $step = 0;
+ /**
+ * @var int
+ */
+ private $startingStep = 0;
+ /**
+ * @var int|null
+ */
+ private $max;
+ /**
+ * @var int
+ */
+ private $startTime;
+ /**
+ * @var int
+ */
+ private $stepWidth;
+ /**
+ * @var float
+ */
+ private $percent = 0.0;
+ /**
+ * @var mixed[]
+ */
+ private $messages = [];
+ /**
+ * @var bool
+ */
+ private $overwrite = \true;
+ /**
+ * @var \Symfony\Component\Console\Terminal
+ */
+ private $terminal;
+ /**
+ * @var string|null
+ */
+ private $previousMessage;
+ /**
+ * @var \Symfony\Component\Console\Cursor
+ */
+ private $cursor;
+ /**
+ * @var mixed[]
+ */
+ private $placeholders = [];
+ /**
+ * @var mixed[]
+ */
+ private static $formatters;
+ /**
+ * @var mixed[]
+ */
+ private static $formats;
+ /**
+ * @param int $max Maximum steps (0 if unknown)
+ */
+ public function __construct(OutputInterface $output, int $max = 0, float $minSecondsBetweenRedraws = 1 / 25)
+ {
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+ $this->output = $output;
+ $this->setMaxSteps($max);
+ $this->terminal = new Terminal();
+ if (0 < $minSecondsBetweenRedraws) {
+ $this->redrawFreq = null;
+ $this->minSecondsBetweenRedraws = $minSecondsBetweenRedraws;
+ }
+ if (!$this->output->isDecorated()) {
+ // disable overwrite when output does not support ANSI codes.
+ $this->overwrite = \false;
+ // set a reasonable redraw frequency so output isn't flooded
+ $this->redrawFreq = null;
+ }
+ $this->startTime = \time();
+ $this->cursor = new Cursor($output);
+ }
+ /**
+ * Sets a placeholder formatter for a given name, globally for all instances of ProgressBar.
+ *
+ * This method also allow you to override an existing placeholder.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ * @param callable(ProgressBar):string $callable A PHP callable
+ */
+ public static function setPlaceholderFormatterDefinition(string $name, callable $callable) : void
+ {
+ self::$formatters = self::$formatters ?? self::initPlaceholderFormatters();
+ self::$formatters[$name] = $callable;
+ }
+ /**
+ * Gets the placeholder formatter for a given name.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ */
+ public static function getPlaceholderFormatterDefinition(string $name) : ?callable
+ {
+ self::$formatters = self::$formatters ?? self::initPlaceholderFormatters();
+ return self::$formatters[$name] ?? null;
+ }
+ /**
+ * Sets a placeholder formatter for a given name, for this instance only.
+ *
+ * @param callable(ProgressBar):string $callable A PHP callable
+ */
+ public function setPlaceholderFormatter(string $name, callable $callable) : void
+ {
+ $this->placeholders[$name] = $callable;
+ }
+ /**
+ * Gets the placeholder formatter for a given name.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ */
+ public function getPlaceholderFormatter(string $name) : ?callable
+ {
+ return $this->placeholders[$name] ?? $this::getPlaceholderFormatterDefinition($name);
+ }
+ /**
+ * Sets a format for a given name.
+ *
+ * This method also allow you to override an existing format.
+ *
+ * @param string $name The format name
+ * @param string $format A format string
+ */
+ public static function setFormatDefinition(string $name, string $format) : void
+ {
+ self::$formats = self::$formats ?? self::initFormats();
+ self::$formats[$name] = $format;
+ }
+ /**
+ * Gets the format for a given name.
+ *
+ * @param string $name The format name
+ */
+ public static function getFormatDefinition(string $name) : ?string
+ {
+ self::$formats = self::$formats ?? self::initFormats();
+ return self::$formats[$name] ?? null;
+ }
+ /**
+ * Associates a text with a named placeholder.
+ *
+ * The text is displayed when the progress bar is rendered but only
+ * when the corresponding placeholder is part of the custom format line
+ * (by wrapping the name with %).
+ *
+ * @param string $message The text to associate with the placeholder
+ * @param string $name The name of the placeholder
+ */
+ public function setMessage(string $message, string $name = 'message') : void
+ {
+ $this->messages[$name] = $message;
+ }
+ public function getMessage(string $name = 'message') : string
+ {
+ return $this->messages[$name];
+ }
+ public function getStartTime() : int
+ {
+ return $this->startTime;
+ }
+ public function getMaxSteps() : int
+ {
+ return $this->max;
+ }
+ public function getProgress() : int
+ {
+ return $this->step;
+ }
+ private function getStepWidth() : int
+ {
+ return $this->stepWidth;
+ }
+ public function getProgressPercent() : float
+ {
+ return $this->percent;
+ }
+ public function getBarOffset() : float
+ {
+ return \floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (\min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth);
+ }
+ public function getEstimated() : float
+ {
+ if (0 === $this->step || $this->step === $this->startingStep) {
+ return 0;
+ }
+ return \round((\time() - $this->startTime) / ($this->step - $this->startingStep) * $this->max);
+ }
+ public function getRemaining() : float
+ {
+ if (!$this->step) {
+ return 0;
+ }
+ return \round((\time() - $this->startTime) / ($this->step - $this->startingStep) * ($this->max - $this->step));
+ }
+ public function setBarWidth(int $size) : void
+ {
+ $this->barWidth = \max(1, $size);
+ }
+ public function getBarWidth() : int
+ {
+ return $this->barWidth;
+ }
+ public function setBarCharacter(string $char) : void
+ {
+ $this->barChar = $char;
+ }
+ public function getBarCharacter() : string
+ {
+ return $this->barChar ?? ($this->max ? '=' : $this->emptyBarChar);
+ }
+ public function setEmptyBarCharacter(string $char) : void
+ {
+ $this->emptyBarChar = $char;
+ }
+ public function getEmptyBarCharacter() : string
+ {
+ return $this->emptyBarChar;
+ }
+ public function setProgressCharacter(string $char) : void
+ {
+ $this->progressChar = $char;
+ }
+ public function getProgressCharacter() : string
+ {
+ return $this->progressChar;
+ }
+ public function setFormat(string $format) : void
+ {
+ $this->format = null;
+ $this->internalFormat = $format;
+ }
+ /**
+ * Sets the redraw frequency.
+ *
+ * @param int|null $freq The frequency in steps
+ */
+ public function setRedrawFrequency(?int $freq) : void
+ {
+ $this->redrawFreq = null !== $freq ? \max(1, $freq) : null;
+ }
+ public function minSecondsBetweenRedraws(float $seconds) : void
+ {
+ $this->minSecondsBetweenRedraws = $seconds;
+ }
+ public function maxSecondsBetweenRedraws(float $seconds) : void
+ {
+ $this->maxSecondsBetweenRedraws = $seconds;
+ }
+ /**
+ * Returns an iterator that will automatically update the progress bar when iterated.
+ *
+ * @template TKey
+ * @template TValue
+ *
+ * @param iterable $iterable
+ * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
+ *
+ * @return iterable
+ */
+ public function iterate(iterable $iterable, int $max = null) : iterable
+ {
+ $this->start($max ?? (\is_array($iterable) || $iterable instanceof \Countable ? \count($iterable) : 0));
+ foreach ($iterable as $key => $value) {
+ (yield $key => $value);
+ $this->advance();
+ }
+ $this->finish();
+ }
+ /**
+ * Starts the progress output.
+ *
+ * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
+ * @param int $startAt The starting point of the bar (useful e.g. when resuming a previously started bar)
+ */
+ public function start(int $max = null, int $startAt = 0) : void
+ {
+ $this->startTime = \time();
+ $this->step = $startAt;
+ $this->startingStep = $startAt;
+ $startAt > 0 ? $this->setProgress($startAt) : ($this->percent = 0.0);
+ if (null !== $max) {
+ $this->setMaxSteps($max);
+ }
+ $this->display();
+ }
+ /**
+ * Advances the progress output X steps.
+ *
+ * @param int $step Number of steps to advance
+ */
+ public function advance(int $step = 1) : void
+ {
+ $this->setProgress($this->step + $step);
+ }
+ /**
+ * Sets whether to overwrite the progressbar, false for new line.
+ */
+ public function setOverwrite(bool $overwrite) : void
+ {
+ $this->overwrite = $overwrite;
+ }
+ public function setProgress(int $step) : void
+ {
+ if ($this->max && $step > $this->max) {
+ $this->max = $step;
+ } elseif ($step < 0) {
+ $step = 0;
+ }
+ $redrawFreq = $this->redrawFreq ?? ($this->max ?: 10) / 10;
+ $prevPeriod = (int) ($this->step / $redrawFreq);
+ $currPeriod = (int) ($step / $redrawFreq);
+ $this->step = $step;
+ $this->percent = $this->max ? (float) $this->step / $this->max : 0;
+ $timeInterval = \microtime(\true) - $this->lastWriteTime;
+ // Draw regardless of other limits
+ if ($this->max === $step) {
+ $this->display();
+ return;
+ }
+ // Throttling
+ if ($timeInterval < $this->minSecondsBetweenRedraws) {
+ return;
+ }
+ // Draw each step period, but not too late
+ if ($prevPeriod !== $currPeriod || $timeInterval >= $this->maxSecondsBetweenRedraws) {
+ $this->display();
+ }
+ }
+ public function setMaxSteps(int $max) : void
+ {
+ $this->format = null;
+ $this->max = \max(0, $max);
+ $this->stepWidth = $this->max ? Helper::width((string) $this->max) : 4;
+ }
+ /**
+ * Finishes the progress output.
+ */
+ public function finish() : void
+ {
+ if (!$this->max) {
+ $this->max = $this->step;
+ }
+ if ($this->step === $this->max && !$this->overwrite) {
+ // prevent double 100% output
+ return;
+ }
+ $this->setProgress($this->max);
+ }
+ /**
+ * Outputs the current progress string.
+ */
+ public function display() : void
+ {
+ if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
+ return;
+ }
+ if (null === $this->format) {
+ $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
+ }
+ $this->overwrite($this->buildLine());
+ }
+ /**
+ * Removes the progress bar from the current line.
+ *
+ * This is useful if you wish to write some output
+ * while a progress bar is running.
+ * Call display() to show the progress bar again.
+ */
+ public function clear() : void
+ {
+ if (!$this->overwrite) {
+ return;
+ }
+ if (null === $this->format) {
+ $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
+ }
+ $this->overwrite('');
+ }
+ private function setRealFormat(string $format) : void
+ {
+ // try to use the _nomax variant if available
+ if (!$this->max && null !== self::getFormatDefinition($format . '_nomax')) {
+ $this->format = self::getFormatDefinition($format . '_nomax');
+ } elseif (null !== self::getFormatDefinition($format)) {
+ $this->format = self::getFormatDefinition($format);
+ } else {
+ $this->format = $format;
+ }
+ }
+ /**
+ * Overwrites a previous message to the output.
+ */
+ private function overwrite(string $message) : void
+ {
+ if ($this->previousMessage === $message) {
+ return;
+ }
+ $originalMessage = $message;
+ if ($this->overwrite) {
+ if (null !== $this->previousMessage) {
+ if ($this->output instanceof ConsoleSectionOutput) {
+ $messageLines = \explode("\n", $this->previousMessage);
+ $lineCount = \count($messageLines);
+ foreach ($messageLines as $messageLine) {
+ $messageLineLength = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $messageLine));
+ if ($messageLineLength > $this->terminal->getWidth()) {
+ $lineCount += \floor($messageLineLength / $this->terminal->getWidth());
+ }
+ }
+ $this->output->clear($lineCount);
+ } else {
+ $lineCount = \substr_count($this->previousMessage, "\n");
+ for ($i = 0; $i < $lineCount; ++$i) {
+ $this->cursor->moveToColumn(1);
+ $this->cursor->clearLine();
+ $this->cursor->moveUp();
+ }
+ $this->cursor->moveToColumn(1);
+ $this->cursor->clearLine();
+ }
+ }
+ } elseif ($this->step > 0) {
+ $message = \PHP_EOL . $message;
+ }
+ $this->previousMessage = $originalMessage;
+ $this->lastWriteTime = \microtime(\true);
+ $this->output->write($message);
+ ++$this->writeCount;
+ }
+ private function determineBestFormat() : string
+ {
+ switch ($this->output->getVerbosity()) {
+ case OutputInterface::VERBOSITY_VERBOSE:
+ return $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX;
+ case OutputInterface::VERBOSITY_VERY_VERBOSE:
+ return $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX;
+ case OutputInterface::VERBOSITY_DEBUG:
+ return $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX;
+ default:
+ return $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX;
+ }
+ }
+ private static function initPlaceholderFormatters() : array
+ {
+ return ['bar' => function (self $bar, OutputInterface $output) {
+ $completeBars = $bar->getBarOffset();
+ $display = \str_repeat($bar->getBarCharacter(), $completeBars);
+ if ($completeBars < $bar->getBarWidth()) {
+ $emptyBars = $bar->getBarWidth() - $completeBars - Helper::length(Helper::removeDecoration($output->getFormatter(), $bar->getProgressCharacter()));
+ $display .= $bar->getProgressCharacter() . \str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
+ }
+ return $display;
+ }, 'elapsed' => function (self $bar) {
+ return Helper::formatTime(\time() - $bar->getStartTime(), 2);
+ }, 'remaining' => function (self $bar) {
+ if (!$bar->getMaxSteps()) {
+ throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
+ }
+ return Helper::formatTime($bar->getRemaining(), 2);
+ }, 'estimated' => function (self $bar) {
+ if (!$bar->getMaxSteps()) {
+ throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
+ }
+ return Helper::formatTime($bar->getEstimated(), 2);
+ }, 'memory' => function (self $bar) {
+ return Helper::formatMemory(\memory_get_usage(\true));
+ }, 'current' => function (self $bar) {
+ return \str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT);
+ }, 'max' => function (self $bar) {
+ return $bar->getMaxSteps();
+ }, 'percent' => function (self $bar) {
+ return \floor($bar->getProgressPercent() * 100);
+ }];
+ }
+ private static function initFormats() : array
+ {
+ return [self::FORMAT_NORMAL => ' %current%/%max% [%bar%] %percent:3s%%', self::FORMAT_NORMAL_NOMAX => ' %current% [%bar%]', self::FORMAT_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%', self::FORMAT_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%', self::FORMAT_VERY_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%', self::FORMAT_VERY_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%', self::FORMAT_DEBUG => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%', self::FORMAT_DEBUG_NOMAX => ' %current% [%bar%] %elapsed:6s% %memory:6s%'];
+ }
+ private function buildLine() : string
+ {
+ \assert(null !== $this->format);
+ $regex = "{%([a-z\\-_]+)(?:\\:([^%]+))?%}i";
+ $callback = function ($matches) {
+ if ($formatter = $this->getPlaceholderFormatter($matches[1])) {
+ $text = $formatter($this, $this->output);
+ } elseif (isset($this->messages[$matches[1]])) {
+ $text = $this->messages[$matches[1]];
+ } else {
+ return $matches[0];
+ }
+ if (isset($matches[2])) {
+ $text = \sprintf('%' . $matches[2], $text);
+ }
+ return $text;
+ };
+ $line = \preg_replace_callback($regex, $callback, $this->format);
+ // gets string length for each sub line with multiline format
+ $linesLength = \array_map(function ($subLine) {
+ return Helper::width(Helper::removeDecoration($this->output->getFormatter(), \rtrim($subLine, "\r")));
+ }, \explode("\n", $line));
+ $linesWidth = \max($linesLength);
+ $terminalWidth = $this->terminal->getWidth();
+ if ($linesWidth <= $terminalWidth) {
+ return $line;
+ }
+ $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth);
+ return \preg_replace_callback($regex, $callback, $this->format);
+ }
+}
diff --git a/vendor/symfony/console/Helper/ProgressIndicator.php b/vendor/symfony/console/Helper/ProgressIndicator.php
new file mode 100644
index 00000000..7f95814f
--- /dev/null
+++ b/vendor/symfony/console/Helper/ProgressIndicator.php
@@ -0,0 +1,225 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Exception\LogicException;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * @author Kevin Bond
+ */
+class ProgressIndicator
+{
+ private const FORMATS = ['normal' => ' %indicator% %message%', 'normal_no_ansi' => ' %message%', 'verbose' => ' %indicator% %message% (%elapsed:6s%)', 'verbose_no_ansi' => ' %message% (%elapsed:6s%)', 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)', 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)'];
+ /**
+ * @var \Symfony\Component\Console\Output\OutputInterface
+ */
+ private $output;
+ /**
+ * @var int
+ */
+ private $startTime;
+ /**
+ * @var string|null
+ */
+ private $format;
+ /**
+ * @var string|null
+ */
+ private $message;
+ /**
+ * @var mixed[]
+ */
+ private $indicatorValues;
+ /**
+ * @var int
+ */
+ private $indicatorCurrent;
+ /**
+ * @var int
+ */
+ private $indicatorChangeInterval;
+ /**
+ * @var float
+ */
+ private $indicatorUpdateTime;
+ /**
+ * @var bool
+ */
+ private $started = \false;
+ /**
+ * @var array
+ */
+ private static $formatters;
+ /**
+ * @param int $indicatorChangeInterval Change interval in milliseconds
+ * @param array|null $indicatorValues Animated indicator characters
+ */
+ public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null)
+ {
+ $this->output = $output;
+ $format = $format ?? $this->determineBestFormat();
+ $indicatorValues = $indicatorValues ?? ['-', '\\', '|', '/'];
+ $indicatorValues = \array_values($indicatorValues);
+ if (2 > \count($indicatorValues)) {
+ throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
+ }
+ $this->format = self::getFormatDefinition($format);
+ $this->indicatorChangeInterval = $indicatorChangeInterval;
+ $this->indicatorValues = $indicatorValues;
+ $this->startTime = \time();
+ }
+ /**
+ * Sets the current indicator message.
+ *
+ * @return void
+ */
+ public function setMessage(?string $message)
+ {
+ $this->message = $message;
+ $this->display();
+ }
+ /**
+ * Starts the indicator output.
+ *
+ * @return void
+ */
+ public function start(string $message)
+ {
+ if ($this->started) {
+ throw new LogicException('Progress indicator already started.');
+ }
+ $this->message = $message;
+ $this->started = \true;
+ $this->startTime = \time();
+ $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
+ $this->indicatorCurrent = 0;
+ $this->display();
+ }
+ /**
+ * Advances the indicator.
+ *
+ * @return void
+ */
+ public function advance()
+ {
+ if (!$this->started) {
+ throw new LogicException('Progress indicator has not yet been started.');
+ }
+ if (!$this->output->isDecorated()) {
+ return;
+ }
+ $currentTime = $this->getCurrentTimeInMilliseconds();
+ if ($currentTime < $this->indicatorUpdateTime) {
+ return;
+ }
+ $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
+ ++$this->indicatorCurrent;
+ $this->display();
+ }
+ /**
+ * Finish the indicator with message.
+ *
+ * @return void
+ */
+ public function finish(string $message)
+ {
+ if (!$this->started) {
+ throw new LogicException('Progress indicator has not yet been started.');
+ }
+ $this->message = $message;
+ $this->display();
+ $this->output->writeln('');
+ $this->started = \false;
+ }
+ /**
+ * Gets the format for a given name.
+ */
+ public static function getFormatDefinition(string $name) : ?string
+ {
+ return self::FORMATS[$name] ?? null;
+ }
+ /**
+ * Sets a placeholder formatter for a given name.
+ *
+ * This method also allow you to override an existing placeholder.
+ *
+ * @return void
+ */
+ public static function setPlaceholderFormatterDefinition(string $name, callable $callable)
+ {
+ self::$formatters = self::$formatters ?? self::initPlaceholderFormatters();
+ self::$formatters[$name] = $callable;
+ }
+ /**
+ * Gets the placeholder formatter for a given name (including the delimiter char like %).
+ */
+ public static function getPlaceholderFormatterDefinition(string $name) : ?callable
+ {
+ self::$formatters = self::$formatters ?? self::initPlaceholderFormatters();
+ return self::$formatters[$name] ?? null;
+ }
+ private function display() : void
+ {
+ if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
+ return;
+ }
+ $this->overwrite(\preg_replace_callback("{%([a-z\\-_]+)(?:\\:([^%]+))?%}i", function ($matches) {
+ if ($formatter = self::getPlaceholderFormatterDefinition($matches[1])) {
+ return $formatter($this);
+ }
+ return $matches[0];
+ }, $this->format ?? ''));
+ }
+ private function determineBestFormat() : string
+ {
+ switch ($this->output->getVerbosity()) {
+ case OutputInterface::VERBOSITY_VERBOSE:
+ return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
+ case OutputInterface::VERBOSITY_VERY_VERBOSE:
+ case OutputInterface::VERBOSITY_DEBUG:
+ return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
+ default:
+ return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
+ }
+ }
+ /**
+ * Overwrites a previous message to the output.
+ */
+ private function overwrite(string $message) : void
+ {
+ if ($this->output->isDecorated()) {
+ $this->output->write("\r\x1b[2K");
+ $this->output->write($message);
+ } else {
+ $this->output->writeln($message);
+ }
+ }
+ private function getCurrentTimeInMilliseconds() : float
+ {
+ return \round(\microtime(\true) * 1000);
+ }
+ /**
+ * @return array
+ */
+ private static function initPlaceholderFormatters() : array
+ {
+ return ['indicator' => function (self $indicator) {
+ return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)];
+ }, 'message' => function (self $indicator) {
+ return $indicator->message;
+ }, 'elapsed' => function (self $indicator) {
+ return Helper::formatTime(\time() - $indicator->startTime, 2);
+ }, 'memory' => function () {
+ return Helper::formatMemory(\memory_get_usage(\true));
+ }];
+ }
+}
diff --git a/vendor/symfony/console/Helper/QuestionHelper.php b/vendor/symfony/console/Helper/QuestionHelper.php
new file mode 100644
index 00000000..2479c006
--- /dev/null
+++ b/vendor/symfony/console/Helper/QuestionHelper.php
@@ -0,0 +1,517 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Cursor;
+use VendorPatches202401\Symfony\Component\Console\Exception\MissingInputException;
+use VendorPatches202401\Symfony\Component\Console\Exception\RuntimeException;
+use VendorPatches202401\Symfony\Component\Console\Formatter\OutputFormatter;
+use VendorPatches202401\Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use VendorPatches202401\Symfony\Component\Console\Input\InputInterface;
+use VendorPatches202401\Symfony\Component\Console\Input\StreamableInputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\ConsoleOutputInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\ConsoleSectionOutput;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Component\Console\Question\ChoiceQuestion;
+use VendorPatches202401\Symfony\Component\Console\Question\Question;
+use VendorPatches202401\Symfony\Component\Console\Terminal;
+use function VendorPatches202401\Symfony\Component\String\s;
+/**
+ * The QuestionHelper class provides helpers to interact with the user.
+ *
+ * @author Fabien Potencier
+ */
+class QuestionHelper extends Helper
+{
+ /**
+ * @var resource|null
+ */
+ private $inputStream;
+ /**
+ * @var bool
+ */
+ private static $stty = \true;
+ /**
+ * @var bool
+ */
+ private static $stdinIsInteractive;
+ /**
+ * Asks a question to the user.
+ *
+ * @return mixed The user answer
+ *
+ * @throws RuntimeException If there is no data to read in the input stream
+ */
+ public function ask(InputInterface $input, OutputInterface $output, Question $question)
+ {
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+ if (!$input->isInteractive()) {
+ return $this->getDefaultAnswer($question);
+ }
+ if ($input instanceof StreamableInputInterface && ($stream = $input->getStream())) {
+ $this->inputStream = $stream;
+ }
+ try {
+ if (!$question->getValidator()) {
+ return $this->doAsk($output, $question);
+ }
+ $interviewer = function () use($output, $question) {
+ return $this->doAsk($output, $question);
+ };
+ return $this->validateAttempts($interviewer, $output, $question);
+ } catch (MissingInputException $exception) {
+ $input->setInteractive(\false);
+ if (null === ($fallbackOutput = $this->getDefaultAnswer($question))) {
+ throw $exception;
+ }
+ return $fallbackOutput;
+ }
+ }
+ public function getName() : string
+ {
+ return 'question';
+ }
+ /**
+ * Prevents usage of stty.
+ *
+ * @return void
+ */
+ public static function disableStty()
+ {
+ self::$stty = \false;
+ }
+ /**
+ * Asks the question to the user.
+ *
+ * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
+ * @return mixed
+ */
+ private function doAsk(OutputInterface $output, Question $question)
+ {
+ $this->writePrompt($output, $question);
+ $inputStream = $this->inputStream ?: \STDIN;
+ $autocomplete = $question->getAutocompleterCallback();
+ if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) {
+ $ret = \false;
+ if ($question->isHidden()) {
+ try {
+ $hiddenResponse = $this->getHiddenResponse($output, $inputStream, $question->isTrimmable());
+ $ret = $question->isTrimmable() ? \trim($hiddenResponse) : $hiddenResponse;
+ } catch (RuntimeException $e) {
+ if (!$question->isHiddenFallback()) {
+ throw $e;
+ }
+ }
+ }
+ if (\false === $ret) {
+ $isBlocked = \stream_get_meta_data($inputStream)['blocked'] ?? \true;
+ if (!$isBlocked) {
+ \stream_set_blocking($inputStream, \true);
+ }
+ $ret = $this->readInput($inputStream, $question);
+ if (!$isBlocked) {
+ \stream_set_blocking($inputStream, \false);
+ }
+ if (\false === $ret) {
+ throw new MissingInputException('Aborted.');
+ }
+ if ($question->isTrimmable()) {
+ $ret = \trim($ret);
+ }
+ }
+ } else {
+ $autocomplete = $this->autocomplete($output, $question, $inputStream, $autocomplete);
+ $ret = $question->isTrimmable() ? \trim($autocomplete) : $autocomplete;
+ }
+ if ($output instanceof ConsoleSectionOutput) {
+ $output->addContent('');
+ // add EOL to the question
+ $output->addContent($ret);
+ }
+ $ret = \strlen($ret) > 0 ? $ret : $question->getDefault();
+ if ($normalizer = $question->getNormalizer()) {
+ return $normalizer($ret);
+ }
+ return $ret;
+ }
+ /**
+ * @return mixed
+ */
+ private function getDefaultAnswer(Question $question)
+ {
+ $default = $question->getDefault();
+ if (null === $default) {
+ return $default;
+ }
+ if ($validator = $question->getValidator()) {
+ return \call_user_func($validator, $default);
+ } elseif ($question instanceof ChoiceQuestion) {
+ $choices = $question->getChoices();
+ if (!$question->isMultiselect()) {
+ return $choices[$default] ?? $default;
+ }
+ $default = \explode(',', $default);
+ foreach ($default as $k => $v) {
+ $v = $question->isTrimmable() ? \trim($v) : $v;
+ $default[$k] = $choices[$v] ?? $v;
+ }
+ }
+ return $default;
+ }
+ /**
+ * Outputs the question prompt.
+ *
+ * @return void
+ */
+ protected function writePrompt(OutputInterface $output, Question $question)
+ {
+ $message = $question->getQuestion();
+ if ($question instanceof ChoiceQuestion) {
+ $output->writeln(\array_merge([$question->getQuestion()], $this->formatChoiceQuestionChoices($question, 'info')));
+ $message = $question->getPrompt();
+ }
+ $output->write($message);
+ }
+ /**
+ * @return string[]
+ */
+ protected function formatChoiceQuestionChoices(ChoiceQuestion $question, string $tag) : array
+ {
+ $messages = [];
+ $maxWidth = \max(\array_map([__CLASS__, 'width'], \array_keys($choices = $question->getChoices())));
+ foreach ($choices as $key => $value) {
+ $padding = \str_repeat(' ', $maxWidth - self::width($key));
+ $messages[] = \sprintf(" [<{$tag}>%s{$padding}{$tag}>] %s", $key, $value);
+ }
+ return $messages;
+ }
+ /**
+ * Outputs an error message.
+ *
+ * @return void
+ */
+ protected function writeError(OutputInterface $output, \Exception $error)
+ {
+ if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
+ $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
+ } else {
+ $message = '' . $error->getMessage() . '';
+ }
+ $output->writeln($message);
+ }
+ /**
+ * Autocompletes a question.
+ *
+ * @param resource $inputStream
+ */
+ private function autocomplete(OutputInterface $output, Question $question, $inputStream, callable $autocomplete) : string
+ {
+ $cursor = new Cursor($output, $inputStream);
+ $fullChoice = '';
+ $ret = '';
+ $i = 0;
+ $ofs = -1;
+ $matches = $autocomplete($ret);
+ $numMatches = \count($matches);
+ $sttyMode = \shell_exec('stty -g');
+ $isStdin = 'php://stdin' === (\stream_get_meta_data($inputStream)['uri'] ?? null);
+ $r = [$inputStream];
+ $w = [];
+ // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
+ \shell_exec('stty -icanon -echo');
+ // Add highlighted text style
+ $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
+ // Read a keypress
+ while (!\feof($inputStream)) {
+ while ($isStdin && 0 === @\stream_select($r, $w, $w, 0, 100)) {
+ // Give signal handlers a chance to run
+ $r = [$inputStream];
+ }
+ $c = \fread($inputStream, 1);
+ // as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
+ if (\false === $c || '' === $ret && '' === $c && null === $question->getDefault()) {
+ \shell_exec('stty ' . $sttyMode);
+ throw new MissingInputException('Aborted.');
+ } elseif ("" === $c) {
+ // Backspace Character
+ if (0 === $numMatches && 0 !== $i) {
+ --$i;
+ $cursor->moveLeft(s($fullChoice)->slice(-1)->width(\false));
+ $fullChoice = self::substr($fullChoice, 0, $i);
+ }
+ if (0 === $i) {
+ $ofs = -1;
+ $matches = $autocomplete($ret);
+ $numMatches = \count($matches);
+ } else {
+ $numMatches = 0;
+ }
+ // Pop the last character off the end of our string
+ $ret = self::substr($ret, 0, $i);
+ } elseif ("\x1b" === $c) {
+ // Did we read an escape sequence?
+ $c .= \fread($inputStream, 2);
+ // A = Up Arrow. B = Down Arrow
+ if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
+ if ('A' === $c[2] && -1 === $ofs) {
+ $ofs = 0;
+ }
+ if (0 === $numMatches) {
+ continue;
+ }
+ $ofs += 'A' === $c[2] ? -1 : 1;
+ $ofs = ($numMatches + $ofs) % $numMatches;
+ }
+ } elseif (\ord($c) < 32) {
+ if ("\t" === $c || "\n" === $c) {
+ if ($numMatches > 0 && -1 !== $ofs) {
+ $ret = (string) $matches[$ofs];
+ // Echo out remaining chars for current match
+ $remainingCharacters = \substr($ret, \strlen(\trim($this->mostRecentlyEnteredValue($fullChoice))));
+ $output->write($remainingCharacters);
+ $fullChoice .= $remainingCharacters;
+ $i = \false === ($encoding = \mb_detect_encoding($fullChoice, null, \true)) ? \strlen($fullChoice) : \mb_strlen($fullChoice, $encoding);
+ $matches = \array_filter($autocomplete($ret), function ($match) use($ret) {
+ return '' === $ret || \strncmp($match, $ret, \strlen($ret)) === 0;
+ });
+ $numMatches = \count($matches);
+ $ofs = -1;
+ }
+ if ("\n" === $c) {
+ $output->write($c);
+ break;
+ }
+ $numMatches = 0;
+ }
+ continue;
+ } else {
+ if ("\x80" <= $c) {
+ $c .= \fread($inputStream, ["\xc0" => 1, "\xd0" => 1, "\xe0" => 2, "\xf0" => 3][$c & "\xf0"]);
+ }
+ $output->write($c);
+ $ret .= $c;
+ $fullChoice .= $c;
+ ++$i;
+ $tempRet = $ret;
+ if ($question instanceof ChoiceQuestion && $question->isMultiselect()) {
+ $tempRet = $this->mostRecentlyEnteredValue($fullChoice);
+ }
+ $numMatches = 0;
+ $ofs = 0;
+ foreach ($autocomplete($ret) as $value) {
+ // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
+ if (\strncmp($value, $tempRet, \strlen($tempRet)) === 0) {
+ $matches[$numMatches++] = $value;
+ }
+ }
+ }
+ $cursor->clearLineAfter();
+ if ($numMatches > 0 && -1 !== $ofs) {
+ $cursor->savePosition();
+ // Write highlighted text, complete the partially entered response
+ $charactersEntered = \strlen(\trim($this->mostRecentlyEnteredValue($fullChoice)));
+ $output->write('' . OutputFormatter::escapeTrailingBackslash(\substr($matches[$ofs], $charactersEntered)) . '');
+ $cursor->restorePosition();
+ }
+ }
+ // Reset stty so it behaves normally again
+ \shell_exec('stty ' . $sttyMode);
+ return $fullChoice;
+ }
+ private function mostRecentlyEnteredValue(string $entered) : string
+ {
+ // Determine the most recent value that the user entered
+ if (\strpos($entered, ',') === \false) {
+ return $entered;
+ }
+ $choices = \explode(',', $entered);
+ if ('' !== ($lastChoice = \trim($choices[\count($choices) - 1]))) {
+ return $lastChoice;
+ }
+ return $entered;
+ }
+ /**
+ * Gets a hidden response from user.
+ *
+ * @param resource $inputStream The handler resource
+ * @param bool $trimmable Is the answer trimmable
+ *
+ * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
+ */
+ private function getHiddenResponse(OutputInterface $output, $inputStream, bool $trimmable = \true) : string
+ {
+ if ('\\' === \DIRECTORY_SEPARATOR) {
+ $exe = __DIR__ . '/../Resources/bin/hiddeninput.exe';
+ // handle code running from a phar
+ if (\strncmp(__FILE__, 'phar:', \strlen('phar:')) === 0) {
+ $tmpExe = \sys_get_temp_dir() . '/hiddeninput.exe';
+ \copy($exe, $tmpExe);
+ $exe = $tmpExe;
+ }
+ $sExec = \shell_exec('"' . $exe . '"');
+ $value = $trimmable ? \rtrim($sExec) : $sExec;
+ $output->writeln('');
+ if (isset($tmpExe)) {
+ \unlink($tmpExe);
+ }
+ return $value;
+ }
+ if (self::$stty && Terminal::hasSttyAvailable()) {
+ $sttyMode = \shell_exec('stty -g');
+ \shell_exec('stty -echo');
+ } elseif ($this->isInteractiveInput($inputStream)) {
+ throw new RuntimeException('Unable to hide the response.');
+ }
+ $value = \fgets($inputStream, 4096);
+ if (4095 === \strlen($value)) {
+ $errOutput = $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output;
+ $errOutput->warning('The value was possibly truncated by your shell or terminal emulator');
+ }
+ if (self::$stty && Terminal::hasSttyAvailable()) {
+ \shell_exec('stty ' . $sttyMode);
+ }
+ if (\false === $value) {
+ throw new MissingInputException('Aborted.');
+ }
+ if ($trimmable) {
+ $value = \trim($value);
+ }
+ $output->writeln('');
+ return $value;
+ }
+ /**
+ * Validates an attempt.
+ *
+ * @param callable $interviewer A callable that will ask for a question and return the result
+ *
+ * @throws \Exception In case the max number of attempts has been reached and no valid response has been given
+ * @return mixed
+ */
+ private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question)
+ {
+ $error = null;
+ $attempts = $question->getMaxAttempts();
+ while (null === $attempts || $attempts--) {
+ if (null !== $error) {
+ $this->writeError($output, $error);
+ }
+ try {
+ return $question->getValidator()($interviewer());
+ } catch (RuntimeException $e) {
+ throw $e;
+ } catch (\Exception $error) {
+ }
+ }
+ throw $error;
+ }
+ private function isInteractiveInput($inputStream) : bool
+ {
+ if ('php://stdin' !== (\stream_get_meta_data($inputStream)['uri'] ?? null)) {
+ return \false;
+ }
+ if (isset(self::$stdinIsInteractive)) {
+ return self::$stdinIsInteractive;
+ }
+ if (\function_exists('stream_isatty')) {
+ return self::$stdinIsInteractive = @\stream_isatty(\fopen('php://stdin', 'r'));
+ }
+ if (\function_exists('posix_isatty')) {
+ return self::$stdinIsInteractive = @\posix_isatty(\fopen('php://stdin', 'r'));
+ }
+ if (!\function_exists('shell_exec')) {
+ return self::$stdinIsInteractive = \true;
+ }
+ return self::$stdinIsInteractive = (bool) \shell_exec('stty 2> ' . ('\\' === \DIRECTORY_SEPARATOR ? 'NUL' : '/dev/null'));
+ }
+ /**
+ * Reads one or more lines of input and returns what is read.
+ *
+ * @param resource $inputStream The handler resource
+ * @param Question $question The question being asked
+ * @return string|false
+ */
+ private function readInput($inputStream, Question $question)
+ {
+ if (!$question->isMultiline()) {
+ $cp = $this->setIOCodepage();
+ $ret = \fgets($inputStream, 4096);
+ return $this->resetIOCodepage($cp, $ret);
+ }
+ $multiLineStreamReader = $this->cloneInputStream($inputStream);
+ if (null === $multiLineStreamReader) {
+ return \false;
+ }
+ $ret = '';
+ $cp = $this->setIOCodepage();
+ while (\false !== ($char = \fgetc($multiLineStreamReader))) {
+ if (\PHP_EOL === "{$ret}{$char}") {
+ break;
+ }
+ $ret .= $char;
+ }
+ return $this->resetIOCodepage($cp, $ret);
+ }
+ private function setIOCodepage() : int
+ {
+ if (\function_exists('sapi_windows_cp_set')) {
+ $cp = \sapi_windows_cp_get();
+ \sapi_windows_cp_set(\sapi_windows_cp_get('oem'));
+ return $cp;
+ }
+ return 0;
+ }
+ /**
+ * Sets console I/O to the specified code page and converts the user input.
+ * @param string|false $input
+ * @return string|false
+ */
+ private function resetIOCodepage(int $cp, $input)
+ {
+ if (0 !== $cp) {
+ \sapi_windows_cp_set($cp);
+ if (\false !== $input && '' !== $input) {
+ $input = \sapi_windows_cp_conv(\sapi_windows_cp_get('oem'), $cp, $input);
+ }
+ }
+ return $input;
+ }
+ /**
+ * Clones an input stream in order to act on one instance of the same
+ * stream without affecting the other instance.
+ *
+ * @param resource $inputStream The handler resource
+ *
+ * @return resource|null The cloned resource, null in case it could not be cloned
+ */
+ private function cloneInputStream($inputStream)
+ {
+ $streamMetaData = \stream_get_meta_data($inputStream);
+ $seekable = $streamMetaData['seekable'] ?? \false;
+ $mode = $streamMetaData['mode'] ?? 'rb';
+ $uri = $streamMetaData['uri'] ?? null;
+ if (null === $uri) {
+ return null;
+ }
+ $cloneStream = \fopen($uri, $mode);
+ // For seekable and writable streams, add all the same data to the
+ // cloned stream and then seek to the same offset.
+ if (\true === $seekable && !\in_array($mode, ['r', 'rb', 'rt'])) {
+ $offset = \ftell($inputStream);
+ \rewind($inputStream);
+ \stream_copy_to_stream($inputStream, $cloneStream);
+ \fseek($inputStream, $offset);
+ \fseek($cloneStream, $offset);
+ }
+ return $cloneStream;
+ }
+}
diff --git a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
new file mode 100644
index 00000000..f34dfd61
--- /dev/null
+++ b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
@@ -0,0 +1,85 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Formatter\OutputFormatter;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+use VendorPatches202401\Symfony\Component\Console\Question\ChoiceQuestion;
+use VendorPatches202401\Symfony\Component\Console\Question\ConfirmationQuestion;
+use VendorPatches202401\Symfony\Component\Console\Question\Question;
+use VendorPatches202401\Symfony\Component\Console\Style\SymfonyStyle;
+/**
+ * Symfony Style Guide compliant question helper.
+ *
+ * @author Kevin Bond
+ */
+class SymfonyQuestionHelper extends QuestionHelper
+{
+ /**
+ * @return void
+ */
+ protected function writePrompt(OutputInterface $output, Question $question)
+ {
+ $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
+ $default = $question->getDefault();
+ if ($question->isMultiline()) {
+ $text .= \sprintf(' (press %s to continue)', $this->getEofShortcut());
+ }
+ switch (\true) {
+ case null === $default:
+ $text = \sprintf(' %s:', $text);
+ break;
+ case $question instanceof ConfirmationQuestion:
+ $text = \sprintf(' %s (yes/no) [%s]:', $text, $default ? 'yes' : 'no');
+ break;
+ case $question instanceof ChoiceQuestion && $question->isMultiselect():
+ $choices = $question->getChoices();
+ $default = \explode(',', $default);
+ foreach ($default as $key => $value) {
+ $default[$key] = $choices[\trim($value)];
+ }
+ $text = \sprintf(' %s [%s]:', $text, OutputFormatter::escape(\implode(', ', $default)));
+ break;
+ case $question instanceof ChoiceQuestion:
+ $choices = $question->getChoices();
+ $text = \sprintf(' %s [%s]:', $text, OutputFormatter::escape($choices[$default] ?? $default));
+ break;
+ default:
+ $text = \sprintf(' %s [%s]:', $text, OutputFormatter::escape($default));
+ }
+ $output->writeln($text);
+ $prompt = ' > ';
+ if ($question instanceof ChoiceQuestion) {
+ $output->writeln($this->formatChoiceQuestionChoices($question, 'comment'));
+ $prompt = $question->getPrompt();
+ }
+ $output->write($prompt);
+ }
+ /**
+ * @return void
+ */
+ protected function writeError(OutputInterface $output, \Exception $error)
+ {
+ if ($output instanceof SymfonyStyle) {
+ $output->newLine();
+ $output->error($error->getMessage());
+ return;
+ }
+ parent::writeError($output, $error);
+ }
+ private function getEofShortcut() : string
+ {
+ if ('Windows' === \PHP_OS_FAMILY) {
+ return 'Ctrl+Z then Enter';
+ }
+ return 'Ctrl+D';
+ }
+}
diff --git a/vendor/symfony/console/Helper/Table.php b/vendor/symfony/console/Helper/Table.php
new file mode 100644
index 00000000..eb36aaba
--- /dev/null
+++ b/vendor/symfony/console/Helper/Table.php
@@ -0,0 +1,808 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Exception\RuntimeException;
+use VendorPatches202401\Symfony\Component\Console\Formatter\OutputFormatter;
+use VendorPatches202401\Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface;
+use VendorPatches202401\Symfony\Component\Console\Output\ConsoleSectionOutput;
+use VendorPatches202401\Symfony\Component\Console\Output\OutputInterface;
+/**
+ * Provides helpers to display a table.
+ *
+ * @author Fabien Potencier
+ * @author Саша Стаменковић
+ * @author Abdellatif Ait boudad
+ * @author Max Grigorian
+ * @author Dany Maillard
+ */
+class Table
+{
+ private const SEPARATOR_TOP = 0;
+ private const SEPARATOR_TOP_BOTTOM = 1;
+ private const SEPARATOR_MID = 2;
+ private const SEPARATOR_BOTTOM = 3;
+ private const BORDER_OUTSIDE = 0;
+ private const BORDER_INSIDE = 1;
+ private const DISPLAY_ORIENTATION_DEFAULT = 'default';
+ private const DISPLAY_ORIENTATION_HORIZONTAL = 'horizontal';
+ private const DISPLAY_ORIENTATION_VERTICAL = 'vertical';
+ /**
+ * @var string|null
+ */
+ private $headerTitle;
+ /**
+ * @var string|null
+ */
+ private $footerTitle;
+ /**
+ * @var mixed[]
+ */
+ private $headers = [];
+ /**
+ * @var mixed[]
+ */
+ private $rows = [];
+ /**
+ * @var mixed[]
+ */
+ private $effectiveColumnWidths = [];
+ /**
+ * @var int
+ */
+ private $numberOfColumns;
+ /**
+ * @var \Symfony\Component\Console\Output\OutputInterface
+ */
+ private $output;
+ /**
+ * @var \Symfony\Component\Console\Helper\TableStyle
+ */
+ private $style;
+ /**
+ * @var mixed[]
+ */
+ private $columnStyles = [];
+ /**
+ * @var mixed[]
+ */
+ private $columnWidths = [];
+ /**
+ * @var mixed[]
+ */
+ private $columnMaxWidths = [];
+ /**
+ * @var bool
+ */
+ private $rendered = \false;
+ /**
+ * @var string
+ */
+ private $displayOrientation = self::DISPLAY_ORIENTATION_DEFAULT;
+ /**
+ * @var mixed[]
+ */
+ private static $styles;
+ public function __construct(OutputInterface $output)
+ {
+ $this->output = $output;
+ self::$styles = self::$styles ?? self::initStyles();
+ $this->setStyle('default');
+ }
+ /**
+ * Sets a style definition.
+ *
+ * @return void
+ */
+ public static function setStyleDefinition(string $name, TableStyle $style)
+ {
+ self::$styles = self::$styles ?? self::initStyles();
+ self::$styles[$name] = $style;
+ }
+ /**
+ * Gets a style definition by name.
+ */
+ public static function getStyleDefinition(string $name) : TableStyle
+ {
+ self::$styles = self::$styles ?? self::initStyles();
+ if (!isset(self::$styles[$name])) {
+ throw new InvalidArgumentException(\sprintf('Style "%s" is not defined.', $name));
+ }
+ return self::$styles[$name];
+ }
+ /**
+ * Sets table style.
+ *
+ * @return $this
+ * @param \Symfony\Component\Console\Helper\TableStyle|string $name
+ */
+ public function setStyle($name)
+ {
+ $this->style = $this->resolveStyle($name);
+ return $this;
+ }
+ /**
+ * Gets the current table style.
+ */
+ public function getStyle() : TableStyle
+ {
+ return $this->style;
+ }
+ /**
+ * Sets table column style.
+ *
+ * @param TableStyle|string $name The style name or a TableStyle instance
+ *
+ * @return $this
+ */
+ public function setColumnStyle(int $columnIndex, $name)
+ {
+ $this->columnStyles[$columnIndex] = $this->resolveStyle($name);
+ return $this;
+ }
+ /**
+ * Gets the current style for a column.
+ *
+ * If style was not set, it returns the global table style.
+ */
+ public function getColumnStyle(int $columnIndex) : TableStyle
+ {
+ return $this->columnStyles[$columnIndex] ?? $this->getStyle();
+ }
+ /**
+ * Sets the minimum width of a column.
+ *
+ * @return $this
+ */
+ public function setColumnWidth(int $columnIndex, int $width)
+ {
+ $this->columnWidths[$columnIndex] = $width;
+ return $this;
+ }
+ /**
+ * Sets the minimum width of all columns.
+ *
+ * @return $this
+ */
+ public function setColumnWidths(array $widths)
+ {
+ $this->columnWidths = [];
+ foreach ($widths as $index => $width) {
+ $this->setColumnWidth($index, $width);
+ }
+ return $this;
+ }
+ /**
+ * Sets the maximum width of a column.
+ *
+ * Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while
+ * formatted strings are preserved.
+ *
+ * @return $this
+ */
+ public function setColumnMaxWidth(int $columnIndex, int $width)
+ {
+ if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) {
+ throw new \LogicException(\sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, \get_debug_type($this->output->getFormatter())));
+ }
+ $this->columnMaxWidths[$columnIndex] = $width;
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function setHeaders(array $headers)
+ {
+ $headers = \array_values($headers);
+ if ($headers && !\is_array($headers[0])) {
+ $headers = [$headers];
+ }
+ $this->headers = $headers;
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function setRows(array $rows)
+ {
+ $this->rows = [];
+ return $this->addRows($rows);
+ }
+ /**
+ * @return $this
+ */
+ public function addRows(array $rows)
+ {
+ foreach ($rows as $row) {
+ $this->addRow($row);
+ }
+ return $this;
+ }
+ /**
+ * @return $this
+ * @param \Symfony\Component\Console\Helper\TableSeparator|mixed[] $row
+ */
+ public function addRow($row)
+ {
+ if ($row instanceof TableSeparator) {
+ $this->rows[] = $row;
+ return $this;
+ }
+ $this->rows[] = \array_values($row);
+ return $this;
+ }
+ /**
+ * Adds a row to the table, and re-renders the table.
+ *
+ * @return $this
+ * @param \Symfony\Component\Console\Helper\TableSeparator|mixed[] $row
+ */
+ public function appendRow($row)
+ {
+ if (!$this->output instanceof ConsoleSectionOutput) {
+ throw new RuntimeException(\sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__));
+ }
+ if ($this->rendered) {
+ $this->output->clear($this->calculateRowCount());
+ }
+ $this->addRow($row);
+ $this->render();
+ return $this;
+ }
+ /**
+ * @return $this
+ * @param int|string $column
+ */
+ public function setRow($column, array $row)
+ {
+ $this->rows[$column] = $row;
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function setHeaderTitle(?string $title)
+ {
+ $this->headerTitle = $title;
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function setFooterTitle(?string $title)
+ {
+ $this->footerTitle = $title;
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function setHorizontal(bool $horizontal = \true)
+ {
+ $this->displayOrientation = $horizontal ? self::DISPLAY_ORIENTATION_HORIZONTAL : self::DISPLAY_ORIENTATION_DEFAULT;
+ return $this;
+ }
+ /**
+ * @return $this
+ */
+ public function setVertical(bool $vertical = \true)
+ {
+ $this->displayOrientation = $vertical ? self::DISPLAY_ORIENTATION_VERTICAL : self::DISPLAY_ORIENTATION_DEFAULT;
+ return $this;
+ }
+ /**
+ * Renders table to output.
+ *
+ * Example:
+ *
+ * +---------------+-----------------------+------------------+
+ * | ISBN | Title | Author |
+ * +---------------+-----------------------+------------------+
+ * | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+ * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+ * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+ * +---------------+-----------------------+------------------+
+ *
+ * @return void
+ */
+ public function render()
+ {
+ $divider = new TableSeparator();
+ $isCellWithColspan = static function ($cell) {
+ return $cell instanceof TableCell && $cell->getColspan() >= 2;
+ };
+ $horizontal = self::DISPLAY_ORIENTATION_HORIZONTAL === $this->displayOrientation;
+ $vertical = self::DISPLAY_ORIENTATION_VERTICAL === $this->displayOrientation;
+ $rows = [];
+ if ($horizontal) {
+ foreach ($this->headers[0] ?? [] as $i => $header) {
+ $rows[$i] = [$header];
+ foreach ($this->rows as $row) {
+ if ($row instanceof TableSeparator) {
+ continue;
+ }
+ if (isset($row[$i])) {
+ $rows[$i][] = $row[$i];
+ } elseif ($isCellWithColspan($rows[$i][0])) {
+ // Noop, there is a "title"
+ } else {
+ $rows[$i][] = null;
+ }
+ }
+ }
+ } elseif ($vertical) {
+ $formatter = $this->output->getFormatter();
+ $maxHeaderLength = \array_reduce($this->headers[0] ?? [], static function ($max, $header) use($formatter) {
+ return \max($max, Helper::width(Helper::removeDecoration($formatter, $header)));
+ }, 0);
+ foreach ($this->rows as $row) {
+ if ($row instanceof TableSeparator) {
+ continue;
+ }
+ if ($rows) {
+ $rows[] = [$divider];
+ }
+ $containsColspan = \false;
+ foreach ($row as $cell) {
+ if ($containsColspan = $isCellWithColspan($cell)) {
+ break;
+ }
+ }
+ $headers = $this->headers[0] ?? [];
+ $maxRows = \max(\count($headers), \count($row));
+ for ($i = 0; $i < $maxRows; ++$i) {
+ $cell = (string) ($row[$i] ?? '');
+ $parts = \explode("\n", $cell);
+ foreach ($parts as $idx => $part) {
+ if ($headers && !$containsColspan) {
+ if (0 === $idx) {
+ $rows[] = [\sprintf('%s>: %s', \str_pad($headers[$i] ?? '', $maxHeaderLength, ' ', \STR_PAD_LEFT), $part)];
+ } else {
+ $rows[] = [\sprintf('%s %s', \str_pad('', $maxHeaderLength, ' ', \STR_PAD_LEFT), $part)];
+ }
+ } elseif ('' !== $cell) {
+ $rows[] = [$part];
+ }
+ }
+ }
+ }
+ } else {
+ $rows = \array_merge($this->headers, [$divider], $this->rows);
+ }
+ $this->calculateNumberOfColumns($rows);
+ $rowGroups = $this->buildTableRows($rows);
+ $this->calculateColumnsWidth($rowGroups);
+ $isHeader = !$horizontal;
+ $isFirstRow = $horizontal;
+ $hasTitle = (bool) $this->headerTitle;
+ foreach ($rowGroups as $rowGroup) {
+ $isHeaderSeparatorRendered = \false;
+ foreach ($rowGroup as $row) {
+ if ($divider === $row) {
+ $isHeader = \false;
+ $isFirstRow = \true;
+ continue;
+ }
+ if ($row instanceof TableSeparator) {
+ $this->renderRowSeparator();
+ continue;
+ }
+ if (!$row) {
+ continue;
+ }
+ if ($isHeader && !$isHeaderSeparatorRendered) {
+ $this->renderRowSeparator(self::SEPARATOR_TOP, $hasTitle ? $this->headerTitle : null, $hasTitle ? $this->style->getHeaderTitleFormat() : null);
+ $hasTitle = \false;
+ $isHeaderSeparatorRendered = \true;
+ }
+ if ($isFirstRow) {
+ $this->renderRowSeparator($horizontal ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, $hasTitle ? $this->headerTitle : null, $hasTitle ? $this->style->getHeaderTitleFormat() : null);
+ $isFirstRow = \false;
+ $hasTitle = \false;
+ }
+ if ($vertical) {
+ $isHeader = \false;
+ $isFirstRow = \false;
+ }
+ if ($horizontal) {
+ $this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat());
+ } else {
+ $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
+ }
+ }
+ }
+ $this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat());
+ $this->cleanup();
+ $this->rendered = \true;
+ }
+ /**
+ * Renders horizontal header separator.
+ *
+ * Example:
+ *
+ * +-----+-----------+-------+
+ */
+ private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null) : void
+ {
+ if (!($count = $this->numberOfColumns)) {
+ return;
+ }
+ $borders = $this->style->getBorderChars();
+ if (!$borders[0] && !$borders[2] && !$this->style->getCrossingChar()) {
+ return;
+ }
+ $crossings = $this->style->getCrossingChars();
+ if (self::SEPARATOR_MID === $type) {
+ [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[2], $crossings[8], $crossings[0], $crossings[4]];
+ } elseif (self::SEPARATOR_TOP === $type) {
+ [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[1], $crossings[2], $crossings[3]];
+ } elseif (self::SEPARATOR_TOP_BOTTOM === $type) {
+ [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[9], $crossings[10], $crossings[11]];
+ } else {
+ [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[7], $crossings[6], $crossings[5]];
+ }
+ $markup = $leftChar;
+ for ($column = 0; $column < $count; ++$column) {
+ $markup .= \str_repeat($horizontal, $this->effectiveColumnWidths[$column]);
+ $markup .= $column === $count - 1 ? $rightChar : $midChar;
+ }
+ if (null !== $title) {
+ $titleLength = Helper::width(Helper::removeDecoration($formatter = $this->output->getFormatter(), $formattedTitle = \sprintf($titleFormat, $title)));
+ $markupLength = Helper::width($markup);
+ if ($titleLength > ($limit = $markupLength - 4)) {
+ $titleLength = $limit;
+ $formatLength = Helper::width(Helper::removeDecoration($formatter, \sprintf($titleFormat, '')));
+ $formattedTitle = \sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3) . '...');
+ }
+ $titleStart = \intdiv($markupLength - $titleLength, 2);
+ if (\false === \mb_detect_encoding($markup, null, \true)) {
+ $markup = \substr_replace($markup, $formattedTitle, $titleStart, $titleLength);
+ } else {
+ $markup = \mb_substr($markup, 0, $titleStart) . $formattedTitle . \mb_substr($markup, $titleStart + $titleLength);
+ }
+ }
+ $this->output->writeln(\sprintf($this->style->getBorderFormat(), $markup));
+ }
+ /**
+ * Renders vertical column separator.
+ */
+ private function renderColumnSeparator(int $type = self::BORDER_OUTSIDE) : string
+ {
+ $borders = $this->style->getBorderChars();
+ return \sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]);
+ }
+ /**
+ * Renders table row.
+ *
+ * Example:
+ *
+ * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+ */
+ private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null) : void
+ {
+ $rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE);
+ $columns = $this->getRowColumns($row);
+ $last = \count($columns) - 1;
+ foreach ($columns as $i => $column) {
+ if ($firstCellFormat && 0 === $i) {
+ $rowContent .= $this->renderCell($row, $column, $firstCellFormat);
+ } else {
+ $rowContent .= $this->renderCell($row, $column, $cellFormat);
+ }
+ $rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE);
+ }
+ $this->output->writeln($rowContent);
+ }
+ /**
+ * Renders table cell with padding.
+ */
+ private function renderCell(array $row, int $column, string $cellFormat) : string
+ {
+ $cell = $row[$column] ?? '';
+ $width = $this->effectiveColumnWidths[$column];
+ if ($cell instanceof TableCell && $cell->getColspan() > 1) {
+ // add the width of the following columns(numbers of colspan).
+ foreach (\range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
+ $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn];
+ }
+ }
+ // str_pad won't work properly with multi-byte strings, we need to fix the padding
+ if (\false !== ($encoding = \mb_detect_encoding($cell, null, \true))) {
+ $width += \strlen($cell) - \mb_strwidth($cell, $encoding);
+ }
+ $style = $this->getColumnStyle($column);
+ if ($cell instanceof TableSeparator) {
+ return \sprintf($style->getBorderFormat(), \str_repeat($style->getBorderChars()[2], $width));
+ }
+ $width += Helper::length($cell) - Helper::length(Helper::removeDecoration($this->output->getFormatter(), $cell));
+ $content = \sprintf($style->getCellRowContentFormat(), $cell);
+ $padType = $style->getPadType();
+ if ($cell instanceof TableCell && $cell->getStyle() instanceof TableCellStyle) {
+ $isNotStyledByTag = !\preg_match('/^<(\\w+|(\\w+=[\\w,]+;?)*)>.+<\\/(\\w+|(\\w+=\\w+;?)*)?>$/', $cell);
+ if ($isNotStyledByTag) {
+ $cellFormat = $cell->getStyle()->getCellFormat();
+ if (!\is_string($cellFormat)) {
+ $tag = \http_build_query($cell->getStyle()->getTagOptions(), '', ';');
+ $cellFormat = '<' . $tag . '>%s>';
+ }
+ if (\strpos($content, '>') !== \false) {
+ $content = \str_replace('>', '', $content);
+ $width -= 3;
+ }
+ if (\strpos($content, '') !== \false) {
+ $content = \str_replace('', '', $content);
+ $width -= \strlen('');
+ }
+ }
+ $padType = $cell->getStyle()->getPadByAlign();
+ }
+ return \sprintf($cellFormat, \str_pad($content, $width, $style->getPaddingChar(), $padType));
+ }
+ /**
+ * Calculate number of columns for this table.
+ */
+ private function calculateNumberOfColumns(array $rows) : void
+ {
+ $columns = [0];
+ foreach ($rows as $row) {
+ if ($row instanceof TableSeparator) {
+ continue;
+ }
+ $columns[] = $this->getNumberOfColumns($row);
+ }
+ $this->numberOfColumns = \max($columns);
+ }
+ private function buildTableRows(array $rows) : TableRows
+ {
+ /** @var WrappableOutputFormatterInterface $formatter */
+ $formatter = $this->output->getFormatter();
+ $unmergedRows = [];
+ for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) {
+ $rows = $this->fillNextRows($rows, $rowKey);
+ // Remove any new line breaks and replace it with a new line
+ foreach ($rows[$rowKey] as $column => $cell) {
+ $colspan = $cell instanceof TableCell ? $cell->getColspan() : 1;
+ if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) {
+ $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
+ }
+ if (\strpos($cell ?? '', "\n") === \false) {
+ continue;
+ }
+ $escaped = \implode("\n", \array_map(\Closure::fromCallable([OutputFormatter::class, 'escapeTrailingBackslash']), \explode("\n", $cell)));
+ $cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
+ $lines = \explode("\n", \str_replace("\n", ">\n", $cell));
+ foreach ($lines as $lineKey => $line) {
+ if ($colspan > 1) {
+ $line = new TableCell($line, ['colspan' => $colspan]);
+ }
+ if (0 === $lineKey) {
+ $rows[$rowKey][$column] = $line;
+ } else {
+ if (!\array_key_exists($rowKey, $unmergedRows) || !\array_key_exists($lineKey, $unmergedRows[$rowKey])) {
+ $unmergedRows[$rowKey][$lineKey] = $this->copyRow($rows, $rowKey);
+ }
+ $unmergedRows[$rowKey][$lineKey][$column] = $line;
+ }
+ }
+ }
+ }
+ return new TableRows(function () use($rows, $unmergedRows) : \Traversable {
+ foreach ($rows as $rowKey => $row) {
+ $rowGroup = [$row instanceof TableSeparator ? $row : $this->fillCells($row)];
+ if (isset($unmergedRows[$rowKey])) {
+ foreach ($unmergedRows[$rowKey] as $row) {
+ $rowGroup[] = $row instanceof TableSeparator ? $row : $this->fillCells($row);
+ }
+ }
+ (yield $rowGroup);
+ }
+ });
+ }
+ private function calculateRowCount() : int
+ {
+ $numberOfRows = \count(\iterator_to_array($this->buildTableRows(\array_merge($this->headers, [new TableSeparator()], $this->rows))));
+ if ($this->headers) {
+ ++$numberOfRows;
+ // Add row for header separator
+ }
+ if ($this->rows) {
+ ++$numberOfRows;
+ // Add row for footer separator
+ }
+ return $numberOfRows;
+ }
+ /**
+ * fill rows that contains rowspan > 1.
+ *
+ * @throws InvalidArgumentException
+ */
+ private function fillNextRows(array $rows, int $line) : array
+ {
+ $unmergedRows = [];
+ foreach ($rows[$line] as $column => $cell) {
+ if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !$cell instanceof \Stringable) {
+ throw new InvalidArgumentException(\sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', \get_debug_type($cell)));
+ }
+ if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
+ $nbLines = $cell->getRowspan() - 1;
+ $lines = [$cell];
+ if (\strpos($cell, "\n") !== \false) {
+ $lines = \explode("\n", \str_replace("\n", "\n>", $cell));
+ $nbLines = \count($lines) > $nbLines ? \substr_count($cell, "\n") : $nbLines;
+ $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]);
+ unset($lines[0]);
+ }
+ // create a two dimensional array (rowspan x colspan)
+ $unmergedRows = \array_replace_recursive(\array_fill($line + 1, $nbLines, []), $unmergedRows);
+ foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
+ $value = $lines[$unmergedRowKey - $line] ?? '';
+ $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]);
+ if ($nbLines === $unmergedRowKey - $line) {
+ break;
+ }
+ }
+ }
+ }
+ foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
+ // we need to know if $unmergedRow will be merged or inserted into $rows
+ if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && $this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns) {
+ foreach ($unmergedRow as $cellKey => $cell) {
+ // insert cell into row at cellKey position
+ \array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]);
+ }
+ } else {
+ $row = $this->copyRow($rows, $unmergedRowKey - 1);
+ foreach ($unmergedRow as $column => $cell) {
+ if (!empty($cell)) {
+ $row[$column] = $unmergedRow[$column];
+ }
+ }
+ \array_splice($rows, $unmergedRowKey, 0, [$row]);
+ }
+ }
+ return $rows;
+ }
+ /**
+ * fill cells for a row that contains colspan > 1.
+ */
+ private function fillCells(iterable $row) : iterable
+ {
+ $newRow = [];
+ foreach ($row as $column => $cell) {
+ $newRow[] = $cell;
+ if ($cell instanceof TableCell && $cell->getColspan() > 1) {
+ foreach (\range($column + 1, $column + $cell->getColspan() - 1) as $position) {
+ // insert empty value at column position
+ $newRow[] = '';
+ }
+ }
+ }
+ return $newRow ?: $row;
+ }
+ private function copyRow(array $rows, int $line) : array
+ {
+ $row = $rows[$line];
+ foreach ($row as $cellKey => $cellValue) {
+ $row[$cellKey] = '';
+ if ($cellValue instanceof TableCell) {
+ $row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]);
+ }
+ }
+ return $row;
+ }
+ /**
+ * Gets number of columns by row.
+ */
+ private function getNumberOfColumns(array $row) : int
+ {
+ $columns = \count($row);
+ foreach ($row as $column) {
+ $columns += $column instanceof TableCell ? $column->getColspan() - 1 : 0;
+ }
+ return $columns;
+ }
+ /**
+ * Gets list of columns for the given row.
+ */
+ private function getRowColumns(array $row) : array
+ {
+ $columns = \range(0, $this->numberOfColumns - 1);
+ foreach ($row as $cellKey => $cell) {
+ if ($cell instanceof TableCell && $cell->getColspan() > 1) {
+ // exclude grouped columns.
+ $columns = \array_diff($columns, \range($cellKey + 1, $cellKey + $cell->getColspan() - 1));
+ }
+ }
+ return $columns;
+ }
+ /**
+ * Calculates columns widths.
+ */
+ private function calculateColumnsWidth(iterable $groups) : void
+ {
+ for ($column = 0; $column < $this->numberOfColumns; ++$column) {
+ $lengths = [];
+ foreach ($groups as $group) {
+ foreach ($group as $row) {
+ if ($row instanceof TableSeparator) {
+ continue;
+ }
+ foreach ($row as $i => $cell) {
+ if ($cell instanceof TableCell) {
+ $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell);
+ $textLength = Helper::width($textContent);
+ if ($textLength > 0) {
+ $contentColumns = \mb_str_split($textContent, \ceil($textLength / $cell->getColspan()));
+ foreach ($contentColumns as $position => $content) {
+ $row[$i + $position] = $content;
+ }
+ }
+ }
+ }
+ $lengths[] = $this->getCellWidth($row, $column);
+ }
+ }
+ $this->effectiveColumnWidths[$column] = \max($lengths) + Helper::width($this->style->getCellRowContentFormat()) - 2;
+ }
+ }
+ private function getColumnSeparatorWidth() : int
+ {
+ return Helper::width(\sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3]));
+ }
+ private function getCellWidth(array $row, int $column) : int
+ {
+ $cellWidth = 0;
+ if (isset($row[$column])) {
+ $cell = $row[$column];
+ $cellWidth = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $cell));
+ }
+ $columnWidth = $this->columnWidths[$column] ?? 0;
+ $cellWidth = \max($cellWidth, $columnWidth);
+ return isset($this->columnMaxWidths[$column]) ? \min($this->columnMaxWidths[$column], $cellWidth) : $cellWidth;
+ }
+ /**
+ * Called after rendering to cleanup cache data.
+ */
+ private function cleanup() : void
+ {
+ $this->effectiveColumnWidths = [];
+ unset($this->numberOfColumns);
+ }
+ /**
+ * @return array
+ */
+ private static function initStyles() : array
+ {
+ $borderless = new TableStyle();
+ $borderless->setHorizontalBorderChars('=')->setVerticalBorderChars(' ')->setDefaultCrossingChar(' ');
+ $compact = new TableStyle();
+ $compact->setHorizontalBorderChars('')->setVerticalBorderChars('')->setDefaultCrossingChar('')->setCellRowContentFormat('%s ');
+ $styleGuide = new TableStyle();
+ $styleGuide->setHorizontalBorderChars('-')->setVerticalBorderChars(' ')->setDefaultCrossingChar(' ')->setCellHeaderFormat('%s');
+ $box = (new TableStyle())->setHorizontalBorderChars('─')->setVerticalBorderChars('│')->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├');
+ $boxDouble = (new TableStyle())->setHorizontalBorderChars('═', '─')->setVerticalBorderChars('║', '│')->setCrossingChars('┼', '╔', '╤', '╗', '╢', '╝', '╧', '╚', '╟', '╠', '╪', '╣');
+ return ['default' => new TableStyle(), 'borderless' => $borderless, 'compact' => $compact, 'symfony-style-guide' => $styleGuide, 'box' => $box, 'box-double' => $boxDouble];
+ }
+ /**
+ * @param \Symfony\Component\Console\Helper\TableStyle|string $name
+ */
+ private function resolveStyle($name) : TableStyle
+ {
+ if ($name instanceof TableStyle) {
+ return $name;
+ }
+ if (!isset(self::$styles[$name])) {
+ throw new InvalidArgumentException(\sprintf('Style "%s" is not defined.', $name));
+ }
+ return self::$styles[$name];
+ }
+}
diff --git a/vendor/symfony/console/Helper/TableCell.php b/vendor/symfony/console/Helper/TableCell.php
new file mode 100644
index 00000000..b65f0fb6
--- /dev/null
+++ b/vendor/symfony/console/Helper/TableCell.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+/**
+ * @author Abdellatif Ait boudad
+ */
+class TableCell
+{
+ /**
+ * @var string
+ */
+ private $value;
+ /**
+ * @var mixed[]
+ */
+ private $options = ['rowspan' => 1, 'colspan' => 1, 'style' => null];
+ public function __construct(string $value = '', array $options = [])
+ {
+ $this->value = $value;
+ // check option names
+ if ($diff = \array_diff(\array_keys($options), \array_keys($this->options))) {
+ throw new InvalidArgumentException(\sprintf('The TableCell does not support the following options: \'%s\'.', \implode('\', \'', $diff)));
+ }
+ if (isset($options['style']) && !$options['style'] instanceof TableCellStyle) {
+ throw new InvalidArgumentException('The style option must be an instance of "TableCellStyle".');
+ }
+ $this->options = \array_merge($this->options, $options);
+ }
+ /**
+ * Returns the cell value.
+ */
+ public function __toString() : string
+ {
+ return $this->value;
+ }
+ /**
+ * Gets number of colspan.
+ */
+ public function getColspan() : int
+ {
+ return (int) $this->options['colspan'];
+ }
+ /**
+ * Gets number of rowspan.
+ */
+ public function getRowspan() : int
+ {
+ return (int) $this->options['rowspan'];
+ }
+ public function getStyle() : ?TableCellStyle
+ {
+ return $this->options['style'];
+ }
+}
diff --git a/vendor/symfony/console/Helper/TableCellStyle.php b/vendor/symfony/console/Helper/TableCellStyle.php
new file mode 100644
index 00000000..73a07155
--- /dev/null
+++ b/vendor/symfony/console/Helper/TableCellStyle.php
@@ -0,0 +1,59 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+/**
+ * @author Yewhen Khoptynskyi
+ */
+class TableCellStyle
+{
+ public const DEFAULT_ALIGN = 'left';
+ private const TAG_OPTIONS = ['fg', 'bg', 'options'];
+ private const ALIGN_MAP = ['left' => \STR_PAD_RIGHT, 'center' => \STR_PAD_BOTH, 'right' => \STR_PAD_LEFT];
+ /**
+ * @var mixed[]
+ */
+ private $options = ['fg' => 'default', 'bg' => 'default', 'options' => null, 'align' => self::DEFAULT_ALIGN, 'cellFormat' => null];
+ public function __construct(array $options = [])
+ {
+ if ($diff = \array_diff(\array_keys($options), \array_keys($this->options))) {
+ throw new InvalidArgumentException(\sprintf('The TableCellStyle does not support the following options: \'%s\'.', \implode('\', \'', $diff)));
+ }
+ if (isset($options['align']) && !\array_key_exists($options['align'], self::ALIGN_MAP)) {
+ throw new InvalidArgumentException(\sprintf('Wrong align value. Value must be following: \'%s\'.', \implode('\', \'', \array_keys(self::ALIGN_MAP))));
+ }
+ $this->options = \array_merge($this->options, $options);
+ }
+ public function getOptions() : array
+ {
+ return $this->options;
+ }
+ /**
+ * Gets options we need for tag for example fg, bg.
+ *
+ * @return string[]
+ */
+ public function getTagOptions() : array
+ {
+ return \array_filter($this->getOptions(), function ($key) {
+ return \in_array($key, self::TAG_OPTIONS) && isset($this->options[$key]);
+ }, \ARRAY_FILTER_USE_KEY);
+ }
+ public function getPadByAlign() : int
+ {
+ return self::ALIGN_MAP[$this->getOptions()['align']];
+ }
+ public function getCellFormat() : ?string
+ {
+ return $this->getOptions()['cellFormat'];
+ }
+}
diff --git a/vendor/symfony/console/Helper/TableRows.php b/vendor/symfony/console/Helper/TableRows.php
new file mode 100644
index 00000000..8cad243d
--- /dev/null
+++ b/vendor/symfony/console/Helper/TableRows.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+/**
+ * @internal
+ */
+class TableRows implements \IteratorAggregate
+{
+ /**
+ * @var \Closure
+ */
+ private $generator;
+ public function __construct(\Closure $generator)
+ {
+ $this->generator = $generator;
+ }
+ public function getIterator() : \Traversable
+ {
+ return ($this->generator)();
+ }
+}
diff --git a/vendor/symfony/console/Helper/TableSeparator.php b/vendor/symfony/console/Helper/TableSeparator.php
new file mode 100644
index 00000000..40c67cbd
--- /dev/null
+++ b/vendor/symfony/console/Helper/TableSeparator.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+/**
+ * Marks a row as being a separator.
+ *
+ * @author Fabien Potencier
+ */
+class TableSeparator extends TableCell
+{
+ public function __construct(array $options = [])
+ {
+ parent::__construct('', $options);
+ }
+}
diff --git a/vendor/symfony/console/Helper/TableStyle.php b/vendor/symfony/console/Helper/TableStyle.php
new file mode 100644
index 00000000..17927cc5
--- /dev/null
+++ b/vendor/symfony/console/Helper/TableStyle.php
@@ -0,0 +1,378 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Helper;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Exception\LogicException;
+/**
+ * Defines the styles for a Table.
+ *
+ * @author Fabien Potencier
+ * @author Саша Стаменковић
+ * @author Dany Maillard
+ */
+class TableStyle
+{
+ /**
+ * @var string
+ */
+ private $paddingChar = ' ';
+ /**
+ * @var string
+ */
+ private $horizontalOutsideBorderChar = '-';
+ /**
+ * @var string
+ */
+ private $horizontalInsideBorderChar = '-';
+ /**
+ * @var string
+ */
+ private $verticalOutsideBorderChar = '|';
+ /**
+ * @var string
+ */
+ private $verticalInsideBorderChar = '|';
+ /**
+ * @var string
+ */
+ private $crossingChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingTopRightChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingTopMidChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingTopLeftChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingMidRightChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingBottomRightChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingBottomMidChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingBottomLeftChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingMidLeftChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingTopLeftBottomChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingTopMidBottomChar = '+';
+ /**
+ * @var string
+ */
+ private $crossingTopRightBottomChar = '+';
+ /**
+ * @var string
+ */
+ private $headerTitleFormat = ' %s >';
+ /**
+ * @var string
+ */
+ private $footerTitleFormat = ' %s >';
+ /**
+ * @var string
+ */
+ private $cellHeaderFormat = '%s';
+ /**
+ * @var string
+ */
+ private $cellRowFormat = '%s';
+ /**
+ * @var string
+ */
+ private $cellRowContentFormat = ' %s ';
+ /**
+ * @var string
+ */
+ private $borderFormat = '%s';
+ /**
+ * @var int
+ */
+ private $padType = \STR_PAD_RIGHT;
+ /**
+ * Sets padding character, used for cell padding.
+ *
+ * @return $this
+ */
+ public function setPaddingChar(string $paddingChar)
+ {
+ if (!$paddingChar) {
+ throw new LogicException('The padding char must not be empty.');
+ }
+ $this->paddingChar = $paddingChar;
+ return $this;
+ }
+ /**
+ * Gets padding character, used for cell padding.
+ */
+ public function getPaddingChar() : string
+ {
+ return $this->paddingChar;
+ }
+ /**
+ * Sets horizontal border characters.
+ *
+ *
+ * ╔═══════════════╤══════════════════════════╤══════════════════╗
+ * 1 ISBN 2 Title │ Author ║
+ * ╠═══════════════╪══════════════════════════╪══════════════════╣
+ * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║
+ * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║
+ * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║
+ * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║
+ * ╚═══════════════╧══════════════════════════╧══════════════════╝
+ *
+ *
+ * @return $this
+ */
+ public function setHorizontalBorderChars(string $outside, string $inside = null)
+ {
+ $this->horizontalOutsideBorderChar = $outside;
+ $this->horizontalInsideBorderChar = $inside ?? $outside;
+ return $this;
+ }
+ /**
+ * Sets vertical border characters.
+ *
+ *
+ * ╔═══════════════╤══════════════════════════╤══════════════════╗
+ * ║ ISBN │ Title │ Author ║
+ * ╠═══════1═══════╪══════════════════════════╪══════════════════╣
+ * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║
+ * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║
+ * ╟───────2───────┼──────────────────────────┼──────────────────╢
+ * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║
+ * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║
+ * ╚═══════════════╧══════════════════════════╧══════════════════╝
+ *
+ *
+ * @return $this
+ */
+ public function setVerticalBorderChars(string $outside, string $inside = null)
+ {
+ $this->verticalOutsideBorderChar = $outside;
+ $this->verticalInsideBorderChar = $inside ?? $outside;
+ return $this;
+ }
+ /**
+ * Gets border characters.
+ *
+ * @internal
+ */
+ public function getBorderChars() : array
+ {
+ return [$this->horizontalOutsideBorderChar, $this->verticalOutsideBorderChar, $this->horizontalInsideBorderChar, $this->verticalInsideBorderChar];
+ }
+ /**
+ * Sets crossing characters.
+ *
+ * Example:
+ *
+ * 1═══════════════2══════════════════════════2══════════════════3
+ * ║ ISBN │ Title │ Author ║
+ * 8'══════════════0'═════════════════════════0'═════════════════4'
+ * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║
+ * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║
+ * 8───────────────0──────────────────────────0──────────────────4
+ * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║
+ * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║
+ * 7═══════════════6══════════════════════════6══════════════════5
+ *
+ *
+ * @param string $cross Crossing char (see #0 of example)
+ * @param string $topLeft Top left char (see #1 of example)
+ * @param string $topMid Top mid char (see #2 of example)
+ * @param string $topRight Top right char (see #3 of example)
+ * @param string $midRight Mid right char (see #4 of example)
+ * @param string $bottomRight Bottom right char (see #5 of example)
+ * @param string $bottomMid Bottom mid char (see #6 of example)
+ * @param string $bottomLeft Bottom left char (see #7 of example)
+ * @param string $midLeft Mid left char (see #8 of example)
+ * @param string|null $topLeftBottom Top left bottom char (see #8' of example), equals to $midLeft if null
+ * @param string|null $topMidBottom Top mid bottom char (see #0' of example), equals to $cross if null
+ * @param string|null $topRightBottom Top right bottom char (see #4' of example), equals to $midRight if null
+ *
+ * @return $this
+ */
+ public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null)
+ {
+ $this->crossingChar = $cross;
+ $this->crossingTopLeftChar = $topLeft;
+ $this->crossingTopMidChar = $topMid;
+ $this->crossingTopRightChar = $topRight;
+ $this->crossingMidRightChar = $midRight;
+ $this->crossingBottomRightChar = $bottomRight;
+ $this->crossingBottomMidChar = $bottomMid;
+ $this->crossingBottomLeftChar = $bottomLeft;
+ $this->crossingMidLeftChar = $midLeft;
+ $this->crossingTopLeftBottomChar = $topLeftBottom ?? $midLeft;
+ $this->crossingTopMidBottomChar = $topMidBottom ?? $cross;
+ $this->crossingTopRightBottomChar = $topRightBottom ?? $midRight;
+ return $this;
+ }
+ /**
+ * Sets default crossing character used for each cross.
+ *
+ * @see {@link setCrossingChars()} for setting each crossing individually.
+ */
+ public function setDefaultCrossingChar(string $char) : self
+ {
+ return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char);
+ }
+ /**
+ * Gets crossing character.
+ */
+ public function getCrossingChar() : string
+ {
+ return $this->crossingChar;
+ }
+ /**
+ * Gets crossing characters.
+ *
+ * @internal
+ */
+ public function getCrossingChars() : array
+ {
+ return [$this->crossingChar, $this->crossingTopLeftChar, $this->crossingTopMidChar, $this->crossingTopRightChar, $this->crossingMidRightChar, $this->crossingBottomRightChar, $this->crossingBottomMidChar, $this->crossingBottomLeftChar, $this->crossingMidLeftChar, $this->crossingTopLeftBottomChar, $this->crossingTopMidBottomChar, $this->crossingTopRightBottomChar];
+ }
+ /**
+ * Sets header cell format.
+ *
+ * @return $this
+ */
+ public function setCellHeaderFormat(string $cellHeaderFormat)
+ {
+ $this->cellHeaderFormat = $cellHeaderFormat;
+ return $this;
+ }
+ /**
+ * Gets header cell format.
+ */
+ public function getCellHeaderFormat() : string
+ {
+ return $this->cellHeaderFormat;
+ }
+ /**
+ * Sets row cell format.
+ *
+ * @return $this
+ */
+ public function setCellRowFormat(string $cellRowFormat)
+ {
+ $this->cellRowFormat = $cellRowFormat;
+ return $this;
+ }
+ /**
+ * Gets row cell format.
+ */
+ public function getCellRowFormat() : string
+ {
+ return $this->cellRowFormat;
+ }
+ /**
+ * Sets row cell content format.
+ *
+ * @return $this
+ */
+ public function setCellRowContentFormat(string $cellRowContentFormat)
+ {
+ $this->cellRowContentFormat = $cellRowContentFormat;
+ return $this;
+ }
+ /**
+ * Gets row cell content format.
+ */
+ public function getCellRowContentFormat() : string
+ {
+ return $this->cellRowContentFormat;
+ }
+ /**
+ * Sets table border format.
+ *
+ * @return $this
+ */
+ public function setBorderFormat(string $borderFormat)
+ {
+ $this->borderFormat = $borderFormat;
+ return $this;
+ }
+ /**
+ * Gets table border format.
+ */
+ public function getBorderFormat() : string
+ {
+ return $this->borderFormat;
+ }
+ /**
+ * Sets cell padding type.
+ *
+ * @return $this
+ */
+ public function setPadType(int $padType)
+ {
+ if (!\in_array($padType, [\STR_PAD_LEFT, \STR_PAD_RIGHT, \STR_PAD_BOTH], \true)) {
+ throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).');
+ }
+ $this->padType = $padType;
+ return $this;
+ }
+ /**
+ * Gets cell padding type.
+ */
+ public function getPadType() : int
+ {
+ return $this->padType;
+ }
+ public function getHeaderTitleFormat() : string
+ {
+ return $this->headerTitleFormat;
+ }
+ /**
+ * @return $this
+ */
+ public function setHeaderTitleFormat(string $format)
+ {
+ $this->headerTitleFormat = $format;
+ return $this;
+ }
+ public function getFooterTitleFormat() : string
+ {
+ return $this->footerTitleFormat;
+ }
+ /**
+ * @return $this
+ */
+ public function setFooterTitleFormat(string $format)
+ {
+ $this->footerTitleFormat = $format;
+ return $this;
+ }
+}
diff --git a/vendor/symfony/console/Input/ArgvInput.php b/vendor/symfony/console/Input/ArgvInput.php
new file mode 100644
index 00000000..353aa888
--- /dev/null
+++ b/vendor/symfony/console/Input/ArgvInput.php
@@ -0,0 +1,336 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Input;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\RuntimeException;
+/**
+ * ArgvInput represents an input coming from the CLI arguments.
+ *
+ * Usage:
+ *
+ * $input = new ArgvInput();
+ *
+ * By default, the `$_SERVER['argv']` array is used for the input values.
+ *
+ * This can be overridden by explicitly passing the input values in the constructor:
+ *
+ * $input = new ArgvInput($_SERVER['argv']);
+ *
+ * If you pass it yourself, don't forget that the first element of the array
+ * is the name of the running application.
+ *
+ * When passing an argument to the constructor, be sure that it respects
+ * the same rules as the argv one. It's almost always better to use the
+ * `StringInput` when you want to provide your own input.
+ *
+ * @author Fabien Potencier
+ *
+ * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
+ * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
+ */
+class ArgvInput extends Input
+{
+ /**
+ * @var mixed[]
+ */
+ private $tokens;
+ /**
+ * @var mixed[]
+ */
+ private $parsed;
+ public function __construct(array $argv = null, InputDefinition $definition = null)
+ {
+ $argv = $argv ?? $_SERVER['argv'] ?? [];
+ // strip the application name
+ \array_shift($argv);
+ $this->tokens = $argv;
+ parent::__construct($definition);
+ }
+ /**
+ * @return void
+ */
+ protected function setTokens(array $tokens)
+ {
+ $this->tokens = $tokens;
+ }
+ /**
+ * @return void
+ */
+ protected function parse()
+ {
+ $parseOptions = \true;
+ $this->parsed = $this->tokens;
+ while (null !== ($token = \array_shift($this->parsed))) {
+ $parseOptions = $this->parseToken($token, $parseOptions);
+ }
+ }
+ protected function parseToken(string $token, bool $parseOptions) : bool
+ {
+ if ($parseOptions && '' == $token) {
+ $this->parseArgument($token);
+ } elseif ($parseOptions && '--' == $token) {
+ return \false;
+ } elseif ($parseOptions && \strncmp($token, '--', \strlen('--')) === 0) {
+ $this->parseLongOption($token);
+ } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
+ $this->parseShortOption($token);
+ } else {
+ $this->parseArgument($token);
+ }
+ return $parseOptions;
+ }
+ /**
+ * Parses a short option.
+ */
+ private function parseShortOption(string $token) : void
+ {
+ $name = \substr($token, 1);
+ if (\strlen($name) > 1) {
+ if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
+ // an option with a value (with no space)
+ $this->addShortOption($name[0], \substr($name, 1));
+ } else {
+ $this->parseShortOptionSet($name);
+ }
+ } else {
+ $this->addShortOption($name, null);
+ }
+ }
+ /**
+ * Parses a short option set.
+ *
+ * @throws RuntimeException When option given doesn't exist
+ */
+ private function parseShortOptionSet(string $name) : void
+ {
+ $len = \strlen($name);
+ for ($i = 0; $i < $len; ++$i) {
+ if (!$this->definition->hasShortcut($name[$i])) {
+ $encoding = \mb_detect_encoding($name, null, \true);
+ throw new RuntimeException(\sprintf('The "-%s" option does not exist.', \false === $encoding ? $name[$i] : \mb_substr($name, $i, 1, $encoding)));
+ }
+ $option = $this->definition->getOptionForShortcut($name[$i]);
+ if ($option->acceptValue()) {
+ $this->addLongOption($option->getName(), $i === $len - 1 ? null : \substr($name, $i + 1));
+ break;
+ } else {
+ $this->addLongOption($option->getName(), null);
+ }
+ }
+ }
+ /**
+ * Parses a long option.
+ */
+ private function parseLongOption(string $token) : void
+ {
+ $name = \substr($token, 2);
+ if (\false !== ($pos = \strpos($name, '='))) {
+ if ('' === ($value = \substr($name, $pos + 1))) {
+ \array_unshift($this->parsed, $value);
+ }
+ $this->addLongOption(\substr($name, 0, $pos), $value);
+ } else {
+ $this->addLongOption($name, null);
+ }
+ }
+ /**
+ * Parses an argument.
+ *
+ * @throws RuntimeException When too many arguments are given
+ */
+ private function parseArgument(string $token) : void
+ {
+ $c = \count($this->arguments);
+ // if input is expecting another argument, add it
+ if ($this->definition->hasArgument($c)) {
+ $arg = $this->definition->getArgument($c);
+ $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token;
+ // if last argument isArray(), append token to last argument
+ } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
+ $arg = $this->definition->getArgument($c - 1);
+ $this->arguments[$arg->getName()][] = $token;
+ // unexpected argument
+ } else {
+ $all = $this->definition->getArguments();
+ $symfonyCommandName = null;
+ \reset($all);
+ if (($inputArgument = $all[$key = \key($all)] ?? null) && 'command' === $inputArgument->getName()) {
+ $symfonyCommandName = $this->arguments['command'] ?? null;
+ unset($all[$key]);
+ }
+ if (\count($all)) {
+ if ($symfonyCommandName) {
+ $message = \sprintf('Too many arguments to "%s" command, expected arguments "%s".', $symfonyCommandName, \implode('" "', \array_keys($all)));
+ } else {
+ $message = \sprintf('Too many arguments, expected arguments "%s".', \implode('" "', \array_keys($all)));
+ }
+ } elseif ($symfonyCommandName) {
+ $message = \sprintf('No arguments expected for "%s" command, got "%s".', $symfonyCommandName, $token);
+ } else {
+ $message = \sprintf('No arguments expected, got "%s".', $token);
+ }
+ throw new RuntimeException($message);
+ }
+ }
+ /**
+ * Adds a short option value.
+ *
+ * @throws RuntimeException When option given doesn't exist
+ * @param mixed $value
+ */
+ private function addShortOption(string $shortcut, $value) : void
+ {
+ if (!$this->definition->hasShortcut($shortcut)) {
+ throw new RuntimeException(\sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+ $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+ }
+ /**
+ * Adds a long option value.
+ *
+ * @throws RuntimeException When option given doesn't exist
+ * @param mixed $value
+ */
+ private function addLongOption(string $name, $value) : void
+ {
+ if (!$this->definition->hasOption($name)) {
+ if (!$this->definition->hasNegation($name)) {
+ throw new RuntimeException(\sprintf('The "--%s" option does not exist.', $name));
+ }
+ $optionName = $this->definition->negationToName($name);
+ if (null !== $value) {
+ throw new RuntimeException(\sprintf('The "--%s" option does not accept a value.', $name));
+ }
+ $this->options[$optionName] = \false;
+ return;
+ }
+ $option = $this->definition->getOption($name);
+ if (null !== $value && !$option->acceptValue()) {
+ throw new RuntimeException(\sprintf('The "--%s" option does not accept a value.', $name));
+ }
+ if (\in_array($value, ['', null], \true) && $option->acceptValue() && \count($this->parsed)) {
+ // if option accepts an optional or mandatory argument
+ // let's see if there is one provided
+ $next = \array_shift($this->parsed);
+ if (isset($next[0]) && '-' !== $next[0] || \in_array($next, ['', null], \true)) {
+ $value = $next;
+ } else {
+ \array_unshift($this->parsed, $next);
+ }
+ }
+ if (null === $value) {
+ if ($option->isValueRequired()) {
+ throw new RuntimeException(\sprintf('The "--%s" option requires a value.', $name));
+ }
+ if (!$option->isArray() && !$option->isValueOptional()) {
+ $value = \true;
+ }
+ }
+ if ($option->isArray()) {
+ $this->options[$name][] = $value;
+ } else {
+ $this->options[$name] = $value;
+ }
+ }
+ public function getFirstArgument() : ?string
+ {
+ $isOption = \false;
+ foreach ($this->tokens as $i => $token) {
+ if ($token && '-' === $token[0]) {
+ if (\strpos($token, '=') !== \false || !isset($this->tokens[$i + 1])) {
+ continue;
+ }
+ // If it's a long option, consider that everything after "--" is the option name.
+ // Otherwise, use the last char (if it's a short option set, only the last one can take a value with space separator)
+ $name = '-' === $token[1] ? \substr($token, 2) : \substr($token, -1);
+ if (!isset($this->options[$name]) && !$this->definition->hasShortcut($name)) {
+ // noop
+ } elseif ((isset($this->options[$name]) || isset($this->options[$name = $this->definition->shortcutToName($name)])) && $this->tokens[$i + 1] === $this->options[$name]) {
+ $isOption = \true;
+ }
+ continue;
+ }
+ if ($isOption) {
+ $isOption = \false;
+ continue;
+ }
+ return $token;
+ }
+ return null;
+ }
+ /**
+ * @param string|mixed[] $values
+ */
+ public function hasParameterOption($values, bool $onlyParams = \false) : bool
+ {
+ $values = (array) $values;
+ foreach ($this->tokens as $token) {
+ if ($onlyParams && '--' === $token) {
+ return \false;
+ }
+ foreach ($values as $value) {
+ // Options with values:
+ // For long options, test for '--option=' at beginning
+ // For short options, test for '-o' at beginning
+ $leading = \strncmp($value, '--', \strlen('--')) === 0 ? $value . '=' : $value;
+ if ($token === $value || '' !== $leading && \strncmp($token, $leading, \strlen($leading)) === 0) {
+ return \true;
+ }
+ }
+ }
+ return \false;
+ }
+ /**
+ * @param string|mixed[] $values
+ * @param string|bool|int|float|mixed[]|null $default
+ * @return mixed
+ */
+ public function getParameterOption($values, $default = \false, bool $onlyParams = \false)
+ {
+ $values = (array) $values;
+ $tokens = $this->tokens;
+ while (0 < \count($tokens)) {
+ $token = \array_shift($tokens);
+ if ($onlyParams && '--' === $token) {
+ return $default;
+ }
+ foreach ($values as $value) {
+ if ($token === $value) {
+ return \array_shift($tokens);
+ }
+ // Options with values:
+ // For long options, test for '--option=' at beginning
+ // For short options, test for '-o' at beginning
+ $leading = \strncmp($value, '--', \strlen('--')) === 0 ? $value . '=' : $value;
+ if ('' !== $leading && \strncmp($token, $leading, \strlen($leading)) === 0) {
+ return \substr($token, \strlen($leading));
+ }
+ }
+ }
+ return $default;
+ }
+ /**
+ * Returns a stringified representation of the args passed to the command.
+ */
+ public function __toString() : string
+ {
+ $tokens = \array_map(function ($token) {
+ if (\preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
+ return $match[1] . $this->escapeToken($match[2]);
+ }
+ if ($token && '-' !== $token[0]) {
+ return $this->escapeToken($token);
+ }
+ return $token;
+ }, $this->tokens);
+ return \implode(' ', $tokens);
+ }
+}
diff --git a/vendor/symfony/console/Input/ArrayInput.php b/vendor/symfony/console/Input/ArrayInput.php
new file mode 100644
index 00000000..5be9b6d8
--- /dev/null
+++ b/vendor/symfony/console/Input/ArrayInput.php
@@ -0,0 +1,181 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Input;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidOptionException;
+/**
+ * ArrayInput represents an input provided as an array.
+ *
+ * Usage:
+ *
+ * $input = new ArrayInput(['command' => 'foo:bar', 'foo' => 'bar', '--bar' => 'foobar']);
+ *
+ * @author Fabien Potencier
+ */
+class ArrayInput extends Input
+{
+ /**
+ * @var mixed[]
+ */
+ private $parameters;
+ public function __construct(array $parameters, InputDefinition $definition = null)
+ {
+ $this->parameters = $parameters;
+ parent::__construct($definition);
+ }
+ public function getFirstArgument() : ?string
+ {
+ foreach ($this->parameters as $param => $value) {
+ if ($param && \is_string($param) && '-' === $param[0]) {
+ continue;
+ }
+ return $value;
+ }
+ return null;
+ }
+ /**
+ * @param string|mixed[] $values
+ */
+ public function hasParameterOption($values, bool $onlyParams = \false) : bool
+ {
+ $values = (array) $values;
+ foreach ($this->parameters as $k => $v) {
+ if (!\is_int($k)) {
+ $v = $k;
+ }
+ if ($onlyParams && '--' === $v) {
+ return \false;
+ }
+ if (\in_array($v, $values)) {
+ return \true;
+ }
+ }
+ return \false;
+ }
+ /**
+ * @param string|mixed[] $values
+ * @param string|bool|int|float|mixed[]|null $default
+ * @return mixed
+ */
+ public function getParameterOption($values, $default = \false, bool $onlyParams = \false)
+ {
+ $values = (array) $values;
+ foreach ($this->parameters as $k => $v) {
+ if ($onlyParams && ('--' === $k || \is_int($k) && '--' === $v)) {
+ return $default;
+ }
+ if (\is_int($k)) {
+ if (\in_array($v, $values)) {
+ return \true;
+ }
+ } elseif (\in_array($k, $values)) {
+ return $v;
+ }
+ }
+ return $default;
+ }
+ /**
+ * Returns a stringified representation of the args passed to the command.
+ */
+ public function __toString() : string
+ {
+ $params = [];
+ foreach ($this->parameters as $param => $val) {
+ if ($param && \is_string($param) && '-' === $param[0]) {
+ $glue = '-' === $param[1] ? '=' : ' ';
+ if (\is_array($val)) {
+ foreach ($val as $v) {
+ $params[] = $param . ('' != $v ? $glue . $this->escapeToken($v) : '');
+ }
+ } else {
+ $params[] = $param . ('' != $val ? $glue . $this->escapeToken($val) : '');
+ }
+ } else {
+ $params[] = \is_array($val) ? \implode(' ', \array_map(\Closure::fromCallable([$this, 'escapeToken']), $val)) : $this->escapeToken($val);
+ }
+ }
+ return \implode(' ', $params);
+ }
+ /**
+ * @return void
+ */
+ protected function parse()
+ {
+ foreach ($this->parameters as $key => $value) {
+ if ('--' === $key) {
+ return;
+ }
+ if (\strncmp($key, '--', \strlen('--')) === 0) {
+ $this->addLongOption(\substr($key, 2), $value);
+ } elseif (\strncmp($key, '-', \strlen('-')) === 0) {
+ $this->addShortOption(\substr($key, 1), $value);
+ } else {
+ $this->addArgument($key, $value);
+ }
+ }
+ }
+ /**
+ * Adds a short option value.
+ *
+ * @throws InvalidOptionException When option given doesn't exist
+ * @param mixed $value
+ */
+ private function addShortOption(string $shortcut, $value) : void
+ {
+ if (!$this->definition->hasShortcut($shortcut)) {
+ throw new InvalidOptionException(\sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+ $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+ }
+ /**
+ * Adds a long option value.
+ *
+ * @throws InvalidOptionException When option given doesn't exist
+ * @throws InvalidOptionException When a required value is missing
+ * @param mixed $value
+ */
+ private function addLongOption(string $name, $value) : void
+ {
+ if (!$this->definition->hasOption($name)) {
+ if (!$this->definition->hasNegation($name)) {
+ throw new InvalidOptionException(\sprintf('The "--%s" option does not exist.', $name));
+ }
+ $optionName = $this->definition->negationToName($name);
+ $this->options[$optionName] = \false;
+ return;
+ }
+ $option = $this->definition->getOption($name);
+ if (null === $value) {
+ if ($option->isValueRequired()) {
+ throw new InvalidOptionException(\sprintf('The "--%s" option requires a value.', $name));
+ }
+ if (!$option->isValueOptional()) {
+ $value = \true;
+ }
+ }
+ $this->options[$name] = $value;
+ }
+ /**
+ * Adds an argument value.
+ *
+ * @throws InvalidArgumentException When argument given doesn't exist
+ * @param string|int $name
+ * @param mixed $value
+ */
+ private function addArgument($name, $value) : void
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name));
+ }
+ $this->arguments[$name] = $value;
+ }
+}
diff --git a/vendor/symfony/console/Input/Input.php b/vendor/symfony/console/Input/Input.php
new file mode 100644
index 00000000..3624ffbb
--- /dev/null
+++ b/vendor/symfony/console/Input/Input.php
@@ -0,0 +1,174 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Input;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Exception\RuntimeException;
+/**
+ * Input is the base class for all concrete Input classes.
+ *
+ * Three concrete classes are provided by default:
+ *
+ * * `ArgvInput`: The input comes from the CLI arguments (argv)
+ * * `StringInput`: The input is provided as a string
+ * * `ArrayInput`: The input is provided as an array
+ *
+ * @author Fabien Potencier
+ */
+abstract class Input implements InputInterface, StreamableInputInterface
+{
+ protected $definition;
+ /** @var resource */
+ protected $stream;
+ protected $options = [];
+ protected $arguments = [];
+ protected $interactive = \true;
+ public function __construct(InputDefinition $definition = null)
+ {
+ if (null === $definition) {
+ $this->definition = new InputDefinition();
+ } else {
+ $this->bind($definition);
+ $this->validate();
+ }
+ }
+ /**
+ * @return void
+ */
+ public function bind(InputDefinition $definition)
+ {
+ $this->arguments = [];
+ $this->options = [];
+ $this->definition = $definition;
+ $this->parse();
+ }
+ /**
+ * Processes command line arguments.
+ *
+ * @return void
+ */
+ protected abstract function parse();
+ /**
+ * @return void
+ */
+ public function validate()
+ {
+ $definition = $this->definition;
+ $givenArguments = $this->arguments;
+ $missingArguments = \array_filter(\array_keys($definition->getArguments()), function ($argument) use($givenArguments, $definition) {
+ return !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
+ });
+ if (\count($missingArguments) > 0) {
+ throw new RuntimeException(\sprintf('Not enough arguments (missing: "%s").', \implode(', ', $missingArguments)));
+ }
+ }
+ public function isInteractive() : bool
+ {
+ return $this->interactive;
+ }
+ /**
+ * @return void
+ */
+ public function setInteractive(bool $interactive)
+ {
+ $this->interactive = $interactive;
+ }
+ public function getArguments() : array
+ {
+ return \array_merge($this->definition->getArgumentDefaults(), $this->arguments);
+ }
+ /**
+ * @return mixed
+ */
+ public function getArgument(string $name)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name));
+ }
+ return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault();
+ }
+ /**
+ * @return void
+ * @param mixed $value
+ */
+ public function setArgument(string $name, $value)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name));
+ }
+ $this->arguments[$name] = $value;
+ }
+ public function hasArgument(string $name) : bool
+ {
+ return $this->definition->hasArgument($name);
+ }
+ public function getOptions() : array
+ {
+ return \array_merge($this->definition->getOptionDefaults(), $this->options);
+ }
+ /**
+ * @return mixed
+ */
+ public function getOption(string $name)
+ {
+ if ($this->definition->hasNegation($name)) {
+ if (null === ($value = $this->getOption($this->definition->negationToName($name)))) {
+ return $value;
+ }
+ return !$value;
+ }
+ if (!$this->definition->hasOption($name)) {
+ throw new InvalidArgumentException(\sprintf('The "%s" option does not exist.', $name));
+ }
+ return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
+ }
+ /**
+ * @return void
+ * @param mixed $value
+ */
+ public function setOption(string $name, $value)
+ {
+ if ($this->definition->hasNegation($name)) {
+ $this->options[$this->definition->negationToName($name)] = !$value;
+ return;
+ } elseif (!$this->definition->hasOption($name)) {
+ throw new InvalidArgumentException(\sprintf('The "%s" option does not exist.', $name));
+ }
+ $this->options[$name] = $value;
+ }
+ public function hasOption(string $name) : bool
+ {
+ return $this->definition->hasOption($name) || $this->definition->hasNegation($name);
+ }
+ /**
+ * Escapes a token through escapeshellarg if it contains unsafe chars.
+ */
+ public function escapeToken(string $token) : string
+ {
+ return \preg_match('{^[\\w-]+$}', $token) ? $token : \escapeshellarg($token);
+ }
+ /**
+ * @param resource $stream
+ *
+ * @return void
+ */
+ public function setStream($stream)
+ {
+ $this->stream = $stream;
+ }
+ /**
+ * @return resource
+ */
+ public function getStream()
+ {
+ return $this->stream;
+ }
+}
diff --git a/vendor/symfony/console/Input/InputArgument.php b/vendor/symfony/console/Input/InputArgument.php
new file mode 100644
index 00000000..345f5270
--- /dev/null
+++ b/vendor/symfony/console/Input/InputArgument.php
@@ -0,0 +1,155 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Input;
+
+use VendorPatches202401\Symfony\Component\Console\Command\Command;
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionInput;
+use VendorPatches202401\Symfony\Component\Console\Completion\CompletionSuggestions;
+use VendorPatches202401\Symfony\Component\Console\Completion\Suggestion;
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Exception\LogicException;
+/**
+ * Represents a command line argument.
+ *
+ * @author Fabien Potencier
+ */
+class InputArgument
+{
+ public const REQUIRED = 1;
+ public const OPTIONAL = 2;
+ public const IS_ARRAY = 4;
+ /**
+ * @var string
+ */
+ private $name;
+ /**
+ * @var int
+ */
+ private $mode;
+ /**
+ * @var string|int|bool|mixed[]|null|float
+ */
+ private $default;
+ /**
+ * @var mixed[]|\Closure
+ */
+ private $suggestedValues;
+ /**
+ * @var string
+ */
+ private $description;
+ /**
+ * @param string $name The argument name
+ * @param int|null $mode The argument mode: a bit mask of self::REQUIRED, self::OPTIONAL and self::IS_ARRAY
+ * @param string $description A description text
+ * @param string|bool|int|float|array|null $default The default value (for self::OPTIONAL mode only)
+ * @param array|\Closure(CompletionInput,CompletionSuggestions):list $suggestedValues The values used for input completion
+ *
+ * @throws InvalidArgumentException When argument mode is not valid
+ */
+ public function __construct(string $name, int $mode = null, string $description = '', $default = null, $suggestedValues = [])
+ {
+ if (null === $mode) {
+ $mode = self::OPTIONAL;
+ } elseif ($mode > 7 || $mode < 1) {
+ throw new InvalidArgumentException(\sprintf('Argument mode "%s" is not valid.', $mode));
+ }
+ $this->name = $name;
+ $this->mode = $mode;
+ $this->description = $description;
+ $this->suggestedValues = $suggestedValues;
+ $this->setDefault($default);
+ }
+ /**
+ * Returns the argument name.
+ */
+ public function getName() : string
+ {
+ return $this->name;
+ }
+ /**
+ * Returns true if the argument is required.
+ *
+ * @return bool true if parameter mode is self::REQUIRED, false otherwise
+ */
+ public function isRequired() : bool
+ {
+ return self::REQUIRED === (self::REQUIRED & $this->mode);
+ }
+ /**
+ * Returns true if the argument can take multiple values.
+ *
+ * @return bool true if mode is self::IS_ARRAY, false otherwise
+ */
+ public function isArray() : bool
+ {
+ return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
+ }
+ /**
+ * Sets the default value.
+ *
+ * @return void
+ *
+ * @throws LogicException When incorrect default value is given
+ * @param string|bool|int|float|mixed[] $default
+ */
+ public function setDefault($default = null)
+ {
+ if (1 > \func_num_args()) {
+ trigger_deprecation('symfony/console', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
+ }
+ if ($this->isRequired() && null !== $default) {
+ throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
+ }
+ if ($this->isArray()) {
+ if (null === $default) {
+ $default = [];
+ } elseif (!\is_array($default)) {
+ throw new LogicException('A default value for an array argument must be an array.');
+ }
+ }
+ $this->default = $default;
+ }
+ /**
+ * Returns the default value.
+ * @return string|bool|int|float|mixed[]|null
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+ public function hasCompletion() : bool
+ {
+ return [] !== $this->suggestedValues;
+ }
+ /**
+ * Adds suggestions to $suggestions for the current completion input.
+ *
+ * @see Command::complete()
+ */
+ public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
+ {
+ $values = $this->suggestedValues;
+ if ($values instanceof \Closure && !\is_array($values = $values($input))) {
+ throw new LogicException(\sprintf('Closure for argument "%s" must return an array. Got "%s".', $this->name, \get_debug_type($values)));
+ }
+ if ($values) {
+ $suggestions->suggestValues($values);
+ }
+ }
+ /**
+ * Returns the description text.
+ */
+ public function getDescription() : string
+ {
+ return $this->description;
+ }
+}
diff --git a/vendor/symfony/console/Input/InputAwareInterface.php b/vendor/symfony/console/Input/InputAwareInterface.php
new file mode 100644
index 00000000..a918fc4a
--- /dev/null
+++ b/vendor/symfony/console/Input/InputAwareInterface.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Input;
+
+/**
+ * InputAwareInterface should be implemented by classes that depends on the
+ * Console Input.
+ *
+ * @author Wouter J
+ */
+interface InputAwareInterface
+{
+ /**
+ * Sets the Console Input.
+ *
+ * @return void
+ */
+ public function setInput(InputInterface $input);
+}
diff --git a/vendor/symfony/console/Input/InputDefinition.php b/vendor/symfony/console/Input/InputDefinition.php
new file mode 100644
index 00000000..ec2b3a7b
--- /dev/null
+++ b/vendor/symfony/console/Input/InputDefinition.php
@@ -0,0 +1,384 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Input;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Exception\LogicException;
+/**
+ * A InputDefinition represents a set of valid command line arguments and options.
+ *
+ * Usage:
+ *
+ * $definition = new InputDefinition([
+ * new InputArgument('name', InputArgument::REQUIRED),
+ * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
+ * ]);
+ *
+ * @author Fabien Potencier
+ */
+class InputDefinition
+{
+ /**
+ * @var mixed[]
+ */
+ private $arguments = [];
+ /**
+ * @var int
+ */
+ private $requiredCount = 0;
+ /**
+ * @var \Symfony\Component\Console\Input\InputArgument|null
+ */
+ private $lastArrayArgument;
+ /**
+ * @var \Symfony\Component\Console\Input\InputArgument|null
+ */
+ private $lastOptionalArgument;
+ /**
+ * @var mixed[]
+ */
+ private $options = [];
+ /**
+ * @var mixed[]
+ */
+ private $negations = [];
+ /**
+ * @var mixed[]
+ */
+ private $shortcuts = [];
+ /**
+ * @param array $definition An array of InputArgument and InputOption instance
+ */
+ public function __construct(array $definition = [])
+ {
+ $this->setDefinition($definition);
+ }
+ /**
+ * Sets the definition of the input.
+ *
+ * @return void
+ */
+ public function setDefinition(array $definition)
+ {
+ $arguments = [];
+ $options = [];
+ foreach ($definition as $item) {
+ if ($item instanceof InputOption) {
+ $options[] = $item;
+ } else {
+ $arguments[] = $item;
+ }
+ }
+ $this->setArguments($arguments);
+ $this->setOptions($options);
+ }
+ /**
+ * Sets the InputArgument objects.
+ *
+ * @param InputArgument[] $arguments An array of InputArgument objects
+ *
+ * @return void
+ */
+ public function setArguments(array $arguments = [])
+ {
+ $this->arguments = [];
+ $this->requiredCount = 0;
+ $this->lastOptionalArgument = null;
+ $this->lastArrayArgument = null;
+ $this->addArguments($arguments);
+ }
+ /**
+ * Adds an array of InputArgument objects.
+ *
+ * @param InputArgument[] $arguments An array of InputArgument objects
+ *
+ * @return void
+ */
+ public function addArguments(?array $arguments = [])
+ {
+ if (null !== $arguments) {
+ foreach ($arguments as $argument) {
+ $this->addArgument($argument);
+ }
+ }
+ }
+ /**
+ * @return void
+ *
+ * @throws LogicException When incorrect argument is given
+ */
+ public function addArgument(InputArgument $argument)
+ {
+ if (isset($this->arguments[$argument->getName()])) {
+ throw new LogicException(\sprintf('An argument with name "%s" already exists.', $argument->getName()));
+ }
+ if (null !== $this->lastArrayArgument) {
+ throw new LogicException(\sprintf('Cannot add a required argument "%s" after an array argument "%s".', $argument->getName(), $this->lastArrayArgument->getName()));
+ }
+ if ($argument->isRequired() && null !== $this->lastOptionalArgument) {
+ throw new LogicException(\sprintf('Cannot add a required argument "%s" after an optional one "%s".', $argument->getName(), $this->lastOptionalArgument->getName()));
+ }
+ if ($argument->isArray()) {
+ $this->lastArrayArgument = $argument;
+ }
+ if ($argument->isRequired()) {
+ ++$this->requiredCount;
+ } else {
+ $this->lastOptionalArgument = $argument;
+ }
+ $this->arguments[$argument->getName()] = $argument;
+ }
+ /**
+ * Returns an InputArgument by name or by position.
+ *
+ * @throws InvalidArgumentException When argument given doesn't exist
+ * @param string|int $name
+ */
+ public function getArgument($name) : InputArgument
+ {
+ if (!$this->hasArgument($name)) {
+ throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name));
+ }
+ $arguments = \is_int($name) ? \array_values($this->arguments) : $this->arguments;
+ return $arguments[$name];
+ }
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ * @param string|int $name
+ */
+ public function hasArgument($name) : bool
+ {
+ $arguments = \is_int($name) ? \array_values($this->arguments) : $this->arguments;
+ return isset($arguments[$name]);
+ }
+ /**
+ * Gets the array of InputArgument objects.
+ *
+ * @return InputArgument[]
+ */
+ public function getArguments() : array
+ {
+ return $this->arguments;
+ }
+ /**
+ * Returns the number of InputArguments.
+ */
+ public function getArgumentCount() : int
+ {
+ return null !== $this->lastArrayArgument ? \PHP_INT_MAX : \count($this->arguments);
+ }
+ /**
+ * Returns the number of required InputArguments.
+ */
+ public function getArgumentRequiredCount() : int
+ {
+ return $this->requiredCount;
+ }
+ /**
+ * @return array
+ */
+ public function getArgumentDefaults() : array
+ {
+ $values = [];
+ foreach ($this->arguments as $argument) {
+ $values[$argument->getName()] = $argument->getDefault();
+ }
+ return $values;
+ }
+ /**
+ * Sets the InputOption objects.
+ *
+ * @param InputOption[] $options An array of InputOption objects
+ *
+ * @return void
+ */
+ public function setOptions(array $options = [])
+ {
+ $this->options = [];
+ $this->shortcuts = [];
+ $this->negations = [];
+ $this->addOptions($options);
+ }
+ /**
+ * Adds an array of InputOption objects.
+ *
+ * @param InputOption[] $options An array of InputOption objects
+ *
+ * @return void
+ */
+ public function addOptions(array $options = [])
+ {
+ foreach ($options as $option) {
+ $this->addOption($option);
+ }
+ }
+ /**
+ * @return void
+ *
+ * @throws LogicException When option given already exist
+ */
+ public function addOption(InputOption $option)
+ {
+ if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
+ throw new LogicException(\sprintf('An option named "%s" already exists.', $option->getName()));
+ }
+ if (isset($this->negations[$option->getName()])) {
+ throw new LogicException(\sprintf('An option named "%s" already exists.', $option->getName()));
+ }
+ if ($option->getShortcut()) {
+ foreach (\explode('|', $option->getShortcut()) as $shortcut) {
+ if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
+ throw new LogicException(\sprintf('An option with shortcut "%s" already exists.', $shortcut));
+ }
+ }
+ }
+ $this->options[$option->getName()] = $option;
+ if ($option->getShortcut()) {
+ foreach (\explode('|', $option->getShortcut()) as $shortcut) {
+ $this->shortcuts[$shortcut] = $option->getName();
+ }
+ }
+ if ($option->isNegatable()) {
+ $negatedName = 'no-' . $option->getName();
+ if (isset($this->options[$negatedName])) {
+ throw new LogicException(\sprintf('An option named "%s" already exists.', $negatedName));
+ }
+ $this->negations[$negatedName] = $option->getName();
+ }
+ }
+ /**
+ * Returns an InputOption by name.
+ *
+ * @throws InvalidArgumentException When option given doesn't exist
+ */
+ public function getOption(string $name) : InputOption
+ {
+ if (!$this->hasOption($name)) {
+ throw new InvalidArgumentException(\sprintf('The "--%s" option does not exist.', $name));
+ }
+ return $this->options[$name];
+ }
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * This method can't be used to check if the user included the option when
+ * executing the command (use getOption() instead).
+ */
+ public function hasOption(string $name) : bool
+ {
+ return isset($this->options[$name]);
+ }
+ /**
+ * Gets the array of InputOption objects.
+ *
+ * @return InputOption[]
+ */
+ public function getOptions() : array
+ {
+ return $this->options;
+ }
+ /**
+ * Returns true if an InputOption object exists by shortcut.
+ */
+ public function hasShortcut(string $name) : bool
+ {
+ return isset($this->shortcuts[$name]);
+ }
+ /**
+ * Returns true if an InputOption object exists by negated name.
+ */
+ public function hasNegation(string $name) : bool
+ {
+ return isset($this->negations[$name]);
+ }
+ /**
+ * Gets an InputOption by shortcut.
+ */
+ public function getOptionForShortcut(string $shortcut) : InputOption
+ {
+ return $this->getOption($this->shortcutToName($shortcut));
+ }
+ /**
+ * @return array
+ */
+ public function getOptionDefaults() : array
+ {
+ $values = [];
+ foreach ($this->options as $option) {
+ $values[$option->getName()] = $option->getDefault();
+ }
+ return $values;
+ }
+ /**
+ * Returns the InputOption name given a shortcut.
+ *
+ * @throws InvalidArgumentException When option given does not exist
+ *
+ * @internal
+ */
+ public function shortcutToName(string $shortcut) : string
+ {
+ if (!isset($this->shortcuts[$shortcut])) {
+ throw new InvalidArgumentException(\sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+ return $this->shortcuts[$shortcut];
+ }
+ /**
+ * Returns the InputOption name given a negation.
+ *
+ * @throws InvalidArgumentException When option given does not exist
+ *
+ * @internal
+ */
+ public function negationToName(string $negation) : string
+ {
+ if (!isset($this->negations[$negation])) {
+ throw new InvalidArgumentException(\sprintf('The "--%s" option does not exist.', $negation));
+ }
+ return $this->negations[$negation];
+ }
+ /**
+ * Gets the synopsis.
+ */
+ public function getSynopsis(bool $short = \false) : string
+ {
+ $elements = [];
+ if ($short && $this->getOptions()) {
+ $elements[] = '[options]';
+ } elseif (!$short) {
+ foreach ($this->getOptions() as $option) {
+ $value = '';
+ if ($option->acceptValue()) {
+ $value = \sprintf(' %s%s%s', $option->isValueOptional() ? '[' : '', \strtoupper($option->getName()), $option->isValueOptional() ? ']' : '');
+ }
+ $shortcut = $option->getShortcut() ? \sprintf('-%s|', $option->getShortcut()) : '';
+ $negation = $option->isNegatable() ? \sprintf('|--no-%s', $option->getName()) : '';
+ $elements[] = \sprintf('[%s--%s%s%s]', $shortcut, $option->getName(), $value, $negation);
+ }
+ }
+ if (\count($elements) && $this->getArguments()) {
+ $elements[] = '[--]';
+ }
+ $tail = '';
+ foreach ($this->getArguments() as $argument) {
+ $element = '<' . $argument->getName() . '>';
+ if ($argument->isArray()) {
+ $element .= '...';
+ }
+ if (!$argument->isRequired()) {
+ $element = '[' . $element;
+ $tail .= ']';
+ }
+ $elements[] = $element;
+ }
+ return \implode(' ', $elements) . $tail;
+ }
+}
diff --git a/vendor/symfony/console/Input/InputInterface.php b/vendor/symfony/console/Input/InputInterface.php
new file mode 100644
index 00000000..bdf21393
--- /dev/null
+++ b/vendor/symfony/console/Input/InputInterface.php
@@ -0,0 +1,136 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace VendorPatches202401\Symfony\Component\Console\Input;
+
+use VendorPatches202401\Symfony\Component\Console\Exception\InvalidArgumentException;
+use VendorPatches202401\Symfony\Component\Console\Exception\RuntimeException;
+/**
+ * InputInterface is the interface implemented by all input classes.
+ *
+ * @author Fabien Potencier
+ *
+ * @method string __toString() Returns a stringified representation of the args passed to the command.
+ * InputArguments MUST be escaped as well as the InputOption values passed to the command.
+ */
+interface InputInterface
+{
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ */
+ public function getFirstArgument() : ?string;
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ * Does not necessarily return the correct result for short options
+ * when multiple flags are combined in the same option.
+ *
+ * @param string|array $values The values to look for in the raw parameters (can be an array)
+ * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
+ */
+ public function hasParameterOption($values, bool $onlyParams = \false) : bool;
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ * Does not necessarily return the correct result for short options
+ * when multiple flags are combined in the same option.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param string|bool|int|float|array|null $default The default value to return if no result is found
+ * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
+ *
+ * @return mixed
+ */
+ public function getParameterOption($values, $default = \false, bool $onlyParams = \false);
+ /**
+ * Binds the current Input instance with the given arguments and options.
+ *
+ * @return void
+ *
+ * @throws RuntimeException
+ */
+ public function bind(InputDefinition $definition);
+ /**
+ * Validates the input.
+ *
+ * @return void
+ *
+ * @throws RuntimeException When not enough arguments are given
+ */
+ public function validate();
+ /**
+ * Returns all the given arguments merged with the default values.
+ *
+ * @return array