+ */ +class ArgsStub extends EnumStub +{ + private static array $parameters = []; + + public function __construct(array $args, string $function, ?string $class) + { + [$variadic, $params] = self::getParameters($function, $class); + + $values = []; + foreach ($args as $k => $v) { + $values[$k] = !\is_scalar($v) && !$v instanceof Stub ? new CutStub($v) : $v; + } + if (null === $params) { + parent::__construct($values, false); + + return; + } + if (\count($values) < \count($params)) { + $params = \array_slice($params, 0, \count($values)); + } elseif (\count($values) > \count($params)) { + $values[] = new EnumStub(array_splice($values, \count($params)), false); + $params[] = $variadic; + } + if (['...'] === $params) { + $this->dumpKeys = false; + $this->value = $values[0]->value; + } else { + $this->value = array_combine($params, $values); + } + } + + private static function getParameters(string $function, ?string $class): array + { + if (isset(self::$parameters[$k = $class.'::'.$function])) { + return self::$parameters[$k]; + } + + try { + $r = null !== $class ? new \ReflectionMethod($class, $function) : new \ReflectionFunction($function); + } catch (\ReflectionException $e) { + return [null, null]; + } + + $variadic = '...'; + $params = []; + foreach ($r->getParameters() as $v) { + $k = '$'.$v->name; + if ($v->isPassedByReference()) { + $k = '&'.$k; + } + if ($v->isVariadic()) { + $variadic .= $k; + } else { + $params[] = $k; + } + } + + return self::$parameters[$k] = [$variadic, $params]; + } +} diff --git a/vendor/symfony/var-dumper/Caster/Caster.php b/vendor/symfony/var-dumper/Caster/Caster.php new file mode 100644 index 0000000..890f531 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/Caster.php @@ -0,0 +1,170 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Helper for filtering out properties in casters. + * + * @author Nicolas Grekas
+ * + * @final + */ +class Caster +{ + public const EXCLUDE_VERBOSE = 1; + public const EXCLUDE_VIRTUAL = 2; + public const EXCLUDE_DYNAMIC = 4; + public const EXCLUDE_PUBLIC = 8; + public const EXCLUDE_PROTECTED = 16; + public const EXCLUDE_PRIVATE = 32; + public const EXCLUDE_NULL = 64; + public const EXCLUDE_EMPTY = 128; + public const EXCLUDE_NOT_IMPORTANT = 256; + public const EXCLUDE_STRICT = 512; + + public const PREFIX_VIRTUAL = "\0~\0"; + public const PREFIX_DYNAMIC = "\0+\0"; + public const PREFIX_PROTECTED = "\0*\0"; + + /** + * Casts objects to arrays and adds the dynamic property prefix. + * + * @param bool $hasDebugInfo Whether the __debugInfo method exists on $obj or not + */ + public static function castObject(object $obj, string $class, bool $hasDebugInfo = false, string $debugClass = null): array + { + if ($hasDebugInfo) { + try { + $debugInfo = $obj->__debugInfo(); + } catch (\Throwable $e) { + // ignore failing __debugInfo() + $hasDebugInfo = false; + } + } + + $a = $obj instanceof \Closure ? [] : (array) $obj; + + if ($obj instanceof \__PHP_Incomplete_Class) { + return $a; + } + + if ($a) { + static $publicProperties = []; + $debugClass = $debugClass ?? get_debug_type($obj); + + $i = 0; + $prefixedKeys = []; + foreach ($a as $k => $v) { + if ("\0" !== ($k[0] ?? '')) { + if (!isset($publicProperties[$class])) { + foreach ((new \ReflectionClass($class))->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) { + $publicProperties[$class][$prop->name] = true; + } + } + if (!isset($publicProperties[$class][$k])) { + $prefixedKeys[$i] = self::PREFIX_DYNAMIC.$k; + } + } elseif ($debugClass !== $class && 1 === strpos($k, $class)) { + $prefixedKeys[$i] = "\0".$debugClass.strrchr($k, "\0"); + } + ++$i; + } + if ($prefixedKeys) { + $keys = array_keys($a); + foreach ($prefixedKeys as $i => $k) { + $keys[$i] = $k; + } + $a = array_combine($keys, $a); + } + } + + if ($hasDebugInfo && \is_array($debugInfo)) { + foreach ($debugInfo as $k => $v) { + if (!isset($k[0]) || "\0" !== $k[0]) { + if (\array_key_exists(self::PREFIX_DYNAMIC.$k, $a)) { + continue; + } + $k = self::PREFIX_VIRTUAL.$k; + } + + unset($a[$k]); + $a[$k] = $v; + } + } + + return $a; + } + + /** + * Filters out the specified properties. + * + * By default, a single match in the $filter bit field filters properties out, following an "or" logic. + * When EXCLUDE_STRICT is set, an "and" logic is applied: all bits must match for a property to be removed. + * + * @param array $a The array containing the properties to filter + * @param int $filter A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out + * @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set + * @param int &$count Set to the number of removed properties + */ + public static function filter(array $a, int $filter, array $listedProperties = [], ?int &$count = 0): array + { + $count = 0; + + foreach ($a as $k => $v) { + $type = self::EXCLUDE_STRICT & $filter; + + if (null === $v) { + $type |= self::EXCLUDE_NULL & $filter; + $type |= self::EXCLUDE_EMPTY & $filter; + } elseif (false === $v || '' === $v || '0' === $v || 0 === $v || 0.0 === $v || [] === $v) { + $type |= self::EXCLUDE_EMPTY & $filter; + } + if ((self::EXCLUDE_NOT_IMPORTANT & $filter) && !\in_array($k, $listedProperties, true)) { + $type |= self::EXCLUDE_NOT_IMPORTANT; + } + if ((self::EXCLUDE_VERBOSE & $filter) && \in_array($k, $listedProperties, true)) { + $type |= self::EXCLUDE_VERBOSE; + } + + if (!isset($k[1]) || "\0" !== $k[0]) { + $type |= self::EXCLUDE_PUBLIC & $filter; + } elseif ('~' === $k[1]) { + $type |= self::EXCLUDE_VIRTUAL & $filter; + } elseif ('+' === $k[1]) { + $type |= self::EXCLUDE_DYNAMIC & $filter; + } elseif ('*' === $k[1]) { + $type |= self::EXCLUDE_PROTECTED & $filter; + } else { + $type |= self::EXCLUDE_PRIVATE & $filter; + } + + if ((self::EXCLUDE_STRICT & $filter) ? $type === $filter : $type) { + unset($a[$k]); + ++$count; + } + } + + return $a; + } + + public static function castPhpIncompleteClass(\__PHP_Incomplete_Class $c, array $a, Stub $stub, bool $isNested): array + { + if (isset($a['__PHP_Incomplete_Class_Name'])) { + $stub->class .= '('.$a['__PHP_Incomplete_Class_Name'].')'; + unset($a['__PHP_Incomplete_Class_Name']); + } + + return $a; + } +} diff --git a/vendor/symfony/var-dumper/Caster/ClassStub.php b/vendor/symfony/var-dumper/Caster/ClassStub.php new file mode 100644 index 0000000..1ac6d0a --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ClassStub.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents a PHP class identifier. + * + * @author Nicolas Grekas
+ */ +class ClassStub extends ConstStub +{ + /** + * @param string $identifier A PHP identifier, e.g. a class, method, interface, etc. name + * @param callable $callable The callable targeted by the identifier when it is ambiguous or not a real PHP identifier + */ + public function __construct(string $identifier, callable|array|string $callable = null) + { + $this->value = $identifier; + + try { + if (null !== $callable) { + if ($callable instanceof \Closure) { + $r = new \ReflectionFunction($callable); + } elseif (\is_object($callable)) { + $r = [$callable, '__invoke']; + } elseif (\is_array($callable)) { + $r = $callable; + } elseif (false !== $i = strpos($callable, '::')) { + $r = [substr($callable, 0, $i), substr($callable, 2 + $i)]; + } else { + $r = new \ReflectionFunction($callable); + } + } elseif (0 < $i = strpos($identifier, '::') ?: strpos($identifier, '->')) { + $r = [substr($identifier, 0, $i), substr($identifier, 2 + $i)]; + } else { + $r = new \ReflectionClass($identifier); + } + + if (\is_array($r)) { + try { + $r = new \ReflectionMethod($r[0], $r[1]); + } catch (\ReflectionException $e) { + $r = new \ReflectionClass($r[0]); + } + } + + if (str_contains($identifier, "@anonymous\0")) { + $this->value = $identifier = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) { + return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0]; + }, $identifier); + } + + if (null !== $callable && $r instanceof \ReflectionFunctionAbstract) { + $s = ReflectionCaster::castFunctionAbstract($r, [], new Stub(), true, Caster::EXCLUDE_VERBOSE); + $s = ReflectionCaster::getSignature($s); + + if (str_ends_with($identifier, '()')) { + $this->value = substr_replace($identifier, $s, -2); + } else { + $this->value .= $s; + } + } + } catch (\ReflectionException $e) { + return; + } finally { + if (0 < $i = strrpos($this->value, '\\')) { + $this->attr['ellipsis'] = \strlen($this->value) - $i; + $this->attr['ellipsis-type'] = 'class'; + $this->attr['ellipsis-tail'] = 1; + } + } + + if ($f = $r->getFileName()) { + $this->attr['file'] = $f; + $this->attr['line'] = $r->getStartLine(); + } + } + + public static function wrapCallable(mixed $callable) + { + if (\is_object($callable) || !\is_callable($callable)) { + return $callable; + } + + if (!\is_array($callable)) { + $callable = new static($callable, $callable); + } elseif (\is_string($callable[0])) { + $callable[0] = new static($callable[0], $callable); + } else { + $callable[1] = new static($callable[1], $callable); + } + + return $callable; + } +} diff --git a/vendor/symfony/var-dumper/Caster/ConstStub.php b/vendor/symfony/var-dumper/Caster/ConstStub.php new file mode 100644 index 0000000..d7d1812 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/ConstStub.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents a PHP constant and its value. + * + * @author Nicolas Grekas
+ */ +class ConstStub extends Stub +{ + public function __construct(string $name, string|int|float $value = null) + { + $this->class = $name; + $this->value = 1 < \func_num_args() ? $value : $name; + } + + public function __toString(): string + { + return (string) $this->value; + } +} diff --git a/vendor/symfony/var-dumper/Caster/CutArrayStub.php b/vendor/symfony/var-dumper/Caster/CutArrayStub.php new file mode 100644 index 0000000..0e4fb36 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/CutArrayStub.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 Symfony\Component\VarDumper\Caster; + +/** + * Represents a cut array. + * + * @author Nicolas Grekas
+ */ +class CutArrayStub extends CutStub +{ + public $preservedSubset; + + public function __construct(array $value, array $preservedKeys) + { + parent::__construct($value); + + $this->preservedSubset = array_intersect_key($value, array_flip($preservedKeys)); + $this->cut -= \count($this->preservedSubset); + } +} diff --git a/vendor/symfony/var-dumper/Caster/CutStub.php b/vendor/symfony/var-dumper/Caster/CutStub.php new file mode 100644 index 0000000..b5a96a0 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/CutStub.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 Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents the main properties of a PHP variable, pre-casted by a caster. + * + * @author Nicolas Grekas
+ */ +class CutStub extends Stub +{ + public function __construct(mixed $value) + { + $this->value = $value; + + switch (\gettype($value)) { + case 'object': + $this->type = self::TYPE_OBJECT; + $this->class = \get_class($value); + + if ($value instanceof \Closure) { + ReflectionCaster::castClosure($value, [], $this, true, Caster::EXCLUDE_VERBOSE); + } + + $this->cut = -1; + break; + + case 'array': + $this->type = self::TYPE_ARRAY; + $this->class = self::ARRAY_ASSOC; + $this->cut = $this->value = \count($value); + break; + + case 'resource': + case 'unknown type': + case 'resource (closed)': + $this->type = self::TYPE_RESOURCE; + $this->handle = (int) $value; + if ('Unknown' === $this->class = @get_resource_type($value)) { + $this->class = 'Closed'; + } + $this->cut = -1; + break; + + case 'string': + $this->type = self::TYPE_STRING; + $this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY; + $this->cut = self::STRING_BINARY === $this->class ? \strlen($value) : mb_strlen($value, 'UTF-8'); + $this->value = ''; + break; + } + } +} diff --git a/vendor/symfony/var-dumper/Caster/DOMCaster.php b/vendor/symfony/var-dumper/Caster/DOMCaster.php new file mode 100644 index 0000000..4dd16e0 --- /dev/null +++ b/vendor/symfony/var-dumper/Caster/DOMCaster.php @@ -0,0 +1,304 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts DOM related classes to array representation. + * + * @author Nicolas Grekas
+ *
+ * @final
+ */
+class DOMCaster
+{
+ private const ERROR_CODES = [
+ \DOM_PHP_ERR => 'DOM_PHP_ERR',
+ \DOM_INDEX_SIZE_ERR => 'DOM_INDEX_SIZE_ERR',
+ \DOMSTRING_SIZE_ERR => 'DOMSTRING_SIZE_ERR',
+ \DOM_HIERARCHY_REQUEST_ERR => 'DOM_HIERARCHY_REQUEST_ERR',
+ \DOM_WRONG_DOCUMENT_ERR => 'DOM_WRONG_DOCUMENT_ERR',
+ \DOM_INVALID_CHARACTER_ERR => 'DOM_INVALID_CHARACTER_ERR',
+ \DOM_NO_DATA_ALLOWED_ERR => 'DOM_NO_DATA_ALLOWED_ERR',
+ \DOM_NO_MODIFICATION_ALLOWED_ERR => 'DOM_NO_MODIFICATION_ALLOWED_ERR',
+ \DOM_NOT_FOUND_ERR => 'DOM_NOT_FOUND_ERR',
+ \DOM_NOT_SUPPORTED_ERR => 'DOM_NOT_SUPPORTED_ERR',
+ \DOM_INUSE_ATTRIBUTE_ERR => 'DOM_INUSE_ATTRIBUTE_ERR',
+ \DOM_INVALID_STATE_ERR => 'DOM_INVALID_STATE_ERR',
+ \DOM_SYNTAX_ERR => 'DOM_SYNTAX_ERR',
+ \DOM_INVALID_MODIFICATION_ERR => 'DOM_INVALID_MODIFICATION_ERR',
+ \DOM_NAMESPACE_ERR => 'DOM_NAMESPACE_ERR',
+ \DOM_INVALID_ACCESS_ERR => 'DOM_INVALID_ACCESS_ERR',
+ \DOM_VALIDATION_ERR => 'DOM_VALIDATION_ERR',
+ ];
+
+ private const NODE_TYPES = [
+ \XML_ELEMENT_NODE => 'XML_ELEMENT_NODE',
+ \XML_ATTRIBUTE_NODE => 'XML_ATTRIBUTE_NODE',
+ \XML_TEXT_NODE => 'XML_TEXT_NODE',
+ \XML_CDATA_SECTION_NODE => 'XML_CDATA_SECTION_NODE',
+ \XML_ENTITY_REF_NODE => 'XML_ENTITY_REF_NODE',
+ \XML_ENTITY_NODE => 'XML_ENTITY_NODE',
+ \XML_PI_NODE => 'XML_PI_NODE',
+ \XML_COMMENT_NODE => 'XML_COMMENT_NODE',
+ \XML_DOCUMENT_NODE => 'XML_DOCUMENT_NODE',
+ \XML_DOCUMENT_TYPE_NODE => 'XML_DOCUMENT_TYPE_NODE',
+ \XML_DOCUMENT_FRAG_NODE => 'XML_DOCUMENT_FRAG_NODE',
+ \XML_NOTATION_NODE => 'XML_NOTATION_NODE',
+ \XML_HTML_DOCUMENT_NODE => 'XML_HTML_DOCUMENT_NODE',
+ \XML_DTD_NODE => 'XML_DTD_NODE',
+ \XML_ELEMENT_DECL_NODE => 'XML_ELEMENT_DECL_NODE',
+ \XML_ATTRIBUTE_DECL_NODE => 'XML_ATTRIBUTE_DECL_NODE',
+ \XML_ENTITY_DECL_NODE => 'XML_ENTITY_DECL_NODE',
+ \XML_NAMESPACE_DECL_NODE => 'XML_NAMESPACE_DECL_NODE',
+ ];
+
+ public static function castException(\DOMException $e, array $a, Stub $stub, bool $isNested)
+ {
+ $k = Caster::PREFIX_PROTECTED.'code';
+ if (isset($a[$k], self::ERROR_CODES[$a[$k]])) {
+ $a[$k] = new ConstStub(self::ERROR_CODES[$a[$k]], $a[$k]);
+ }
+
+ return $a;
+ }
+
+ public static function castLength($dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'length' => $dom->length,
+ ];
+
+ return $a;
+ }
+
+ public static function castImplementation(\DOMImplementation $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ Caster::PREFIX_VIRTUAL.'Core' => '1.0',
+ Caster::PREFIX_VIRTUAL.'XML' => '2.0',
+ ];
+
+ return $a;
+ }
+
+ public static function castNode(\DOMNode $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'nodeName' => $dom->nodeName,
+ 'nodeValue' => new CutStub($dom->nodeValue),
+ 'nodeType' => new ConstStub(self::NODE_TYPES[$dom->nodeType], $dom->nodeType),
+ 'parentNode' => new CutStub($dom->parentNode),
+ 'childNodes' => $dom->childNodes,
+ 'firstChild' => new CutStub($dom->firstChild),
+ 'lastChild' => new CutStub($dom->lastChild),
+ 'previousSibling' => new CutStub($dom->previousSibling),
+ 'nextSibling' => new CutStub($dom->nextSibling),
+ 'attributes' => $dom->attributes,
+ 'ownerDocument' => new CutStub($dom->ownerDocument),
+ 'namespaceURI' => $dom->namespaceURI,
+ 'prefix' => $dom->prefix,
+ 'localName' => $dom->localName,
+ 'baseURI' => $dom->baseURI ? new LinkStub($dom->baseURI) : $dom->baseURI,
+ 'textContent' => new CutStub($dom->textContent),
+ ];
+
+ return $a;
+ }
+
+ public static function castNameSpaceNode(\DOMNameSpaceNode $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'nodeName' => $dom->nodeName,
+ 'nodeValue' => new CutStub($dom->nodeValue),
+ 'nodeType' => new ConstStub(self::NODE_TYPES[$dom->nodeType], $dom->nodeType),
+ 'prefix' => $dom->prefix,
+ 'localName' => $dom->localName,
+ 'namespaceURI' => $dom->namespaceURI,
+ 'ownerDocument' => new CutStub($dom->ownerDocument),
+ 'parentNode' => new CutStub($dom->parentNode),
+ ];
+
+ return $a;
+ }
+
+ public static function castDocument(\DOMDocument $dom, array $a, Stub $stub, bool $isNested, int $filter = 0)
+ {
+ $a += [
+ 'doctype' => $dom->doctype,
+ 'implementation' => $dom->implementation,
+ 'documentElement' => new CutStub($dom->documentElement),
+ 'actualEncoding' => $dom->actualEncoding,
+ 'encoding' => $dom->encoding,
+ 'xmlEncoding' => $dom->xmlEncoding,
+ 'standalone' => $dom->standalone,
+ 'xmlStandalone' => $dom->xmlStandalone,
+ 'version' => $dom->version,
+ 'xmlVersion' => $dom->xmlVersion,
+ 'strictErrorChecking' => $dom->strictErrorChecking,
+ 'documentURI' => $dom->documentURI ? new LinkStub($dom->documentURI) : $dom->documentURI,
+ 'config' => $dom->config,
+ 'formatOutput' => $dom->formatOutput,
+ 'validateOnParse' => $dom->validateOnParse,
+ 'resolveExternals' => $dom->resolveExternals,
+ 'preserveWhiteSpace' => $dom->preserveWhiteSpace,
+ 'recover' => $dom->recover,
+ 'substituteEntities' => $dom->substituteEntities,
+ ];
+
+ if (!($filter & Caster::EXCLUDE_VERBOSE)) {
+ $formatOutput = $dom->formatOutput;
+ $dom->formatOutput = true;
+ $a += [Caster::PREFIX_VIRTUAL.'xml' => $dom->saveXML()];
+ $dom->formatOutput = $formatOutput;
+ }
+
+ return $a;
+ }
+
+ public static function castCharacterData(\DOMCharacterData $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'data' => $dom->data,
+ 'length' => $dom->length,
+ ];
+
+ return $a;
+ }
+
+ public static function castAttr(\DOMAttr $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'name' => $dom->name,
+ 'specified' => $dom->specified,
+ 'value' => $dom->value,
+ 'ownerElement' => $dom->ownerElement,
+ 'schemaTypeInfo' => $dom->schemaTypeInfo,
+ ];
+
+ return $a;
+ }
+
+ public static function castElement(\DOMElement $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'tagName' => $dom->tagName,
+ 'schemaTypeInfo' => $dom->schemaTypeInfo,
+ ];
+
+ return $a;
+ }
+
+ public static function castText(\DOMText $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'wholeText' => $dom->wholeText,
+ ];
+
+ return $a;
+ }
+
+ public static function castTypeinfo(\DOMTypeinfo $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'typeName' => $dom->typeName,
+ 'typeNamespace' => $dom->typeNamespace,
+ ];
+
+ return $a;
+ }
+
+ public static function castDomError(\DOMDomError $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'severity' => $dom->severity,
+ 'message' => $dom->message,
+ 'type' => $dom->type,
+ 'relatedException' => $dom->relatedException,
+ 'related_data' => $dom->related_data,
+ 'location' => $dom->location,
+ ];
+
+ return $a;
+ }
+
+ public static function castLocator(\DOMLocator $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'lineNumber' => $dom->lineNumber,
+ 'columnNumber' => $dom->columnNumber,
+ 'offset' => $dom->offset,
+ 'relatedNode' => $dom->relatedNode,
+ 'uri' => $dom->uri ? new LinkStub($dom->uri, $dom->lineNumber) : $dom->uri,
+ ];
+
+ return $a;
+ }
+
+ public static function castDocumentType(\DOMDocumentType $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'name' => $dom->name,
+ 'entities' => $dom->entities,
+ 'notations' => $dom->notations,
+ 'publicId' => $dom->publicId,
+ 'systemId' => $dom->systemId,
+ 'internalSubset' => $dom->internalSubset,
+ ];
+
+ return $a;
+ }
+
+ public static function castNotation(\DOMNotation $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'publicId' => $dom->publicId,
+ 'systemId' => $dom->systemId,
+ ];
+
+ return $a;
+ }
+
+ public static function castEntity(\DOMEntity $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'publicId' => $dom->publicId,
+ 'systemId' => $dom->systemId,
+ 'notationName' => $dom->notationName,
+ 'actualEncoding' => $dom->actualEncoding,
+ 'encoding' => $dom->encoding,
+ 'version' => $dom->version,
+ ];
+
+ return $a;
+ }
+
+ public static function castProcessingInstruction(\DOMProcessingInstruction $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'target' => $dom->target,
+ 'data' => $dom->data,
+ ];
+
+ return $a;
+ }
+
+ public static function castXPath(\DOMXPath $dom, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ 'document' => $dom->document,
+ ];
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/DateCaster.php b/vendor/symfony/var-dumper/Caster/DateCaster.php
new file mode 100644
index 0000000..18641fb
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/DateCaster.php
@@ -0,0 +1,127 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts DateTimeInterface related classes to array representation.
+ *
+ * @author Dany Maillard
+ *
+ * @final
+ */
+class DoctrineCaster
+{
+ public static function castCommonProxy(CommonProxy $proxy, array $a, Stub $stub, bool $isNested)
+ {
+ foreach (['__cloner__', '__initializer__'] as $k) {
+ if (\array_key_exists($k, $a)) {
+ unset($a[$k]);
+ ++$stub->cut;
+ }
+ }
+
+ return $a;
+ }
+
+ public static function castOrmProxy(OrmProxy $proxy, array $a, Stub $stub, bool $isNested)
+ {
+ foreach (['_entityPersister', '_identifier'] as $k) {
+ if (\array_key_exists($k = "\0Doctrine\\ORM\\Proxy\\Proxy\0".$k, $a)) {
+ unset($a[$k]);
+ ++$stub->cut;
+ }
+ }
+
+ return $a;
+ }
+
+ public static function castPersistentCollection(PersistentCollection $coll, array $a, Stub $stub, bool $isNested)
+ {
+ foreach (['snapshot', 'association', 'typeClass'] as $k) {
+ if (\array_key_exists($k = "\0Doctrine\\ORM\\PersistentCollection\0".$k, $a)) {
+ $a[$k] = new CutStub($a[$k]);
+ }
+ }
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/DsCaster.php b/vendor/symfony/var-dumper/Caster/DsCaster.php
new file mode 100644
index 0000000..b34b670
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/DsCaster.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 Symfony\Component\VarDumper\Caster;
+
+use Ds\Collection;
+use Ds\Map;
+use Ds\Pair;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts Ds extension classes to array representation.
+ *
+ * @author Jáchym Toušek
+ */
+class DsPairStub extends Stub
+{
+ public function __construct(string|int $key, mixed $value)
+ {
+ $this->value = [
+ Caster::PREFIX_VIRTUAL.'key' => $key,
+ Caster::PREFIX_VIRTUAL.'value' => $value,
+ ];
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/EnumStub.php b/vendor/symfony/var-dumper/Caster/EnumStub.php
new file mode 100644
index 0000000..7a4e98a
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/EnumStub.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 Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Represents an enumeration of values.
+ *
+ * @author Nicolas Grekas
+ */
+class EnumStub extends Stub
+{
+ public $dumpKeys = true;
+
+ public function __construct(array $values, bool $dumpKeys = true)
+ {
+ $this->value = $values;
+ $this->dumpKeys = $dumpKeys;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/ExceptionCaster.php b/vendor/symfony/var-dumper/Caster/ExceptionCaster.php
new file mode 100644
index 0000000..8e517e0
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/ExceptionCaster.php
@@ -0,0 +1,388 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext;
+use Symfony\Component\VarDumper\Cloner\Stub;
+use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
+
+/**
+ * Casts common Exception classes to array representation.
+ *
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+class ExceptionCaster
+{
+ public static int $srcContext = 1;
+ public static bool $traceArgs = true;
+ public static array $errorTypes = [
+ \E_DEPRECATED => 'E_DEPRECATED',
+ \E_USER_DEPRECATED => 'E_USER_DEPRECATED',
+ \E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
+ \E_ERROR => 'E_ERROR',
+ \E_WARNING => 'E_WARNING',
+ \E_PARSE => 'E_PARSE',
+ \E_NOTICE => 'E_NOTICE',
+ \E_CORE_ERROR => 'E_CORE_ERROR',
+ \E_CORE_WARNING => 'E_CORE_WARNING',
+ \E_COMPILE_ERROR => 'E_COMPILE_ERROR',
+ \E_COMPILE_WARNING => 'E_COMPILE_WARNING',
+ \E_USER_ERROR => 'E_USER_ERROR',
+ \E_USER_WARNING => 'E_USER_WARNING',
+ \E_USER_NOTICE => 'E_USER_NOTICE',
+ \E_STRICT => 'E_STRICT',
+ ];
+
+ private static array $framesCache = [];
+
+ public static function castError(\Error $e, array $a, Stub $stub, bool $isNested, int $filter = 0)
+ {
+ return self::filterExceptionArray($stub->class, $a, "\0Error\0", $filter);
+ }
+
+ public static function castException(\Exception $e, array $a, Stub $stub, bool $isNested, int $filter = 0)
+ {
+ return self::filterExceptionArray($stub->class, $a, "\0Exception\0", $filter);
+ }
+
+ public static function castErrorException(\ErrorException $e, array $a, Stub $stub, bool $isNested)
+ {
+ if (isset($a[$s = Caster::PREFIX_PROTECTED.'severity'], self::$errorTypes[$a[$s]])) {
+ $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]);
+ }
+
+ return $a;
+ }
+
+ public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, bool $isNested)
+ {
+ $trace = Caster::PREFIX_VIRTUAL.'trace';
+ $prefix = Caster::PREFIX_PROTECTED;
+ $xPrefix = "\0Exception\0";
+
+ if (isset($a[$xPrefix.'previous'], $a[$trace]) && $a[$xPrefix.'previous'] instanceof \Exception) {
+ $b = (array) $a[$xPrefix.'previous'];
+ $class = get_debug_type($a[$xPrefix.'previous']);
+ self::traceUnshift($b[$xPrefix.'trace'], $class, $b[$prefix.'file'], $b[$prefix.'line']);
+ $a[$trace] = new TraceStub($b[$xPrefix.'trace'], false, 0, -\count($a[$trace]->value));
+ }
+
+ unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']);
+
+ return $a;
+ }
+
+ public static function castSilencedErrorContext(SilencedErrorContext $e, array $a, Stub $stub, bool $isNested)
+ {
+ $sPrefix = "\0".SilencedErrorContext::class."\0";
+
+ if (!isset($a[$s = $sPrefix.'severity'])) {
+ return $a;
+ }
+
+ if (isset(self::$errorTypes[$a[$s]])) {
+ $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]);
+ }
+
+ $trace = [[
+ 'file' => $a[$sPrefix.'file'],
+ 'line' => $a[$sPrefix.'line'],
+ ]];
+
+ if (isset($a[$sPrefix.'trace'])) {
+ $trace = array_merge($trace, $a[$sPrefix.'trace']);
+ }
+
+ unset($a[$sPrefix.'file'], $a[$sPrefix.'line'], $a[$sPrefix.'trace']);
+ $a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs);
+
+ return $a;
+ }
+
+ public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, bool $isNested)
+ {
+ if (!$isNested) {
+ return $a;
+ }
+ $stub->class = '';
+ $stub->handle = 0;
+ $frames = $trace->value;
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ $a = [];
+ $j = \count($frames);
+ if (0 > $i = $trace->sliceOffset) {
+ $i = max(0, $j + $i);
+ }
+ if (!isset($trace->value[$i])) {
+ return [];
+ }
+ $lastCall = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '';
+ $frames[] = ['function' => ''];
+ $collapse = false;
+
+ for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) {
+ $f = $frames[$i];
+ $call = isset($f['function']) ? (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'] : '???';
+
+ $frame = new FrameStub(
+ [
+ 'object' => $f['object'] ?? null,
+ 'class' => $f['class'] ?? null,
+ 'type' => $f['type'] ?? null,
+ 'function' => $f['function'] ?? null,
+ ] + $frames[$i - 1],
+ false,
+ true
+ );
+ $f = self::castFrameStub($frame, [], $frame, true);
+ if (isset($f[$prefix.'src'])) {
+ foreach ($f[$prefix.'src']->value as $label => $frame) {
+ if (str_starts_with($label, "\0~collapse=0")) {
+ if ($collapse) {
+ $label = substr_replace($label, '1', 11, 1);
+ } else {
+ $collapse = true;
+ }
+ }
+ $label = substr_replace($label, "title=Stack level $j.&", 2, 0);
+ }
+ $f = $frames[$i - 1];
+ if ($trace->keepArgs && !empty($f['args']) && $frame instanceof EnumStub) {
+ $frame->value['arguments'] = new ArgsStub($f['args'], $f['function'] ?? null, $f['class'] ?? null);
+ }
+ } elseif ('???' !== $lastCall) {
+ $label = new ClassStub($lastCall);
+ if (isset($label->attr['ellipsis'])) {
+ $label->attr['ellipsis'] += 2;
+ $label = substr_replace($prefix, "ellipsis-type=class&ellipsis={$label->attr['ellipsis']}&ellipsis-tail=1&title=Stack level $j.", 2, 0).$label->value.'()';
+ } else {
+ $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$label->value.'()';
+ }
+ } else {
+ $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$lastCall;
+ }
+ $a[substr_replace($label, sprintf('separator=%s&', $frame instanceof EnumStub ? ' ' : ':'), 2, 0)] = $frame;
+
+ $lastCall = $call;
+ }
+ if (null !== $trace->sliceLength) {
+ $a = \array_slice($a, 0, $trace->sliceLength, true);
+ }
+
+ return $a;
+ }
+
+ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, bool $isNested)
+ {
+ if (!$isNested) {
+ return $a;
+ }
+ $f = $frame->value;
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ if (isset($f['file'], $f['line'])) {
+ $cacheKey = $f;
+ unset($cacheKey['object'], $cacheKey['args']);
+ $cacheKey[] = self::$srcContext;
+ $cacheKey = implode('-', $cacheKey);
+
+ if (isset(self::$framesCache[$cacheKey])) {
+ $a[$prefix.'src'] = self::$framesCache[$cacheKey];
+ } else {
+ if (preg_match('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\)\'d code|runtime-created function)$/', $f['file'], $match)) {
+ $f['file'] = substr($f['file'], 0, -\strlen($match[0]));
+ $f['line'] = (int) $match[1];
+ }
+ $src = $f['line'];
+ $srcKey = $f['file'];
+ $ellipsis = new LinkStub($srcKey, 0);
+ $srcAttr = 'collapse='.(int) $ellipsis->inVendor;
+ $ellipsisTail = $ellipsis->attr['ellipsis-tail'] ?? 0;
+ $ellipsis = $ellipsis->attr['ellipsis'] ?? 0;
+
+ if (is_file($f['file']) && 0 <= self::$srcContext) {
+ if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {
+ $template = null;
+ if (isset($f['object'])) {
+ $template = $f['object'];
+ } elseif ((new \ReflectionClass($f['class']))->isInstantiable()) {
+ $template = unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
+ }
+ if (null !== $template) {
+ $ellipsis = 0;
+ $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
+ $templateInfo = $template->getDebugInfo();
+ if (isset($templateInfo[$f['line']])) {
+ if (!method_exists($template, 'getSourceContext') || !is_file($templatePath = $template->getSourceContext()->getPath())) {
+ $templatePath = null;
+ }
+ if ($templateSrc) {
+ $src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, 'twig', $templatePath, $f);
+ $srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']];
+ }
+ }
+ }
+ }
+ if ($srcKey == $f['file']) {
+ $src = self::extractSource(file_get_contents($f['file']), $f['line'], self::$srcContext, 'php', $f['file'], $f);
+ $srcKey .= ':'.$f['line'];
+ if ($ellipsis) {
+ $ellipsis += 1 + \strlen($f['line']);
+ }
+ }
+ $srcAttr .= sprintf('&separator= &file=%s&line=%d', rawurlencode($f['file']), $f['line']);
+ } else {
+ $srcAttr .= '&separator=:';
+ }
+ $srcAttr .= $ellipsis ? '&ellipsis-type=path&ellipsis='.$ellipsis.'&ellipsis-tail='.$ellipsisTail : '';
+ self::$framesCache[$cacheKey] = $a[$prefix.'src'] = new EnumStub(["\0~$srcAttr\0$srcKey" => $src]);
+ }
+ }
+
+ unset($a[$prefix.'args'], $a[$prefix.'line'], $a[$prefix.'file']);
+ if ($frame->inTraceStub) {
+ unset($a[$prefix.'class'], $a[$prefix.'type'], $a[$prefix.'function']);
+ }
+ foreach ($a as $k => $v) {
+ if (!$v) {
+ unset($a[$k]);
+ }
+ }
+ if ($frame->keepArgs && !empty($f['args'])) {
+ $a[$prefix.'arguments'] = new ArgsStub($f['args'], $f['function'], $f['class']);
+ }
+
+ return $a;
+ }
+
+ private static function filterExceptionArray(string $xClass, array $a, string $xPrefix, int $filter): array
+ {
+ if (isset($a[$xPrefix.'trace'])) {
+ $trace = $a[$xPrefix.'trace'];
+ unset($a[$xPrefix.'trace']); // Ensures the trace is always last
+ } else {
+ $trace = [];
+ }
+
+ if (!($filter & Caster::EXCLUDE_VERBOSE) && $trace) {
+ if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) {
+ self::traceUnshift($trace, $xClass, $a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']);
+ }
+ $a[Caster::PREFIX_VIRTUAL.'trace'] = new TraceStub($trace, self::$traceArgs);
+ }
+ if (empty($a[$xPrefix.'previous'])) {
+ unset($a[$xPrefix.'previous']);
+ }
+ unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message'], $a[Caster::PREFIX_DYNAMIC.'__destructorException']);
+
+ if (isset($a[Caster::PREFIX_PROTECTED.'message']) && str_contains($a[Caster::PREFIX_PROTECTED.'message'], "@anonymous\0")) {
+ $a[Caster::PREFIX_PROTECTED.'message'] = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
+ return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
+ }, $a[Caster::PREFIX_PROTECTED.'message']);
+ }
+
+ if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) {
+ $a[Caster::PREFIX_PROTECTED.'file'] = new LinkStub($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']);
+ }
+
+ return $a;
+ }
+
+ private static function traceUnshift(array &$trace, ?string $class, string $file, int $line): void
+ {
+ if (isset($trace[0]['file'], $trace[0]['line']) && $trace[0]['file'] === $file && $trace[0]['line'] === $line) {
+ return;
+ }
+ array_unshift($trace, [
+ 'function' => $class ? 'new '.$class : null,
+ 'file' => $file,
+ 'line' => $line,
+ ]);
+ }
+
+ private static function extractSource(string $srcLines, int $line, int $srcContext, string $lang, ?string $file, array $frame): EnumStub
+ {
+ $srcLines = explode("\n", $srcLines);
+ $src = [];
+
+ for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) {
+ $src[] = ($srcLines[$i] ?? '')."\n";
+ }
+
+ if ($frame['function'] ?? false) {
+ $stub = new CutStub(new \stdClass());
+ $stub->class = (isset($frame['class']) ? $frame['class'].$frame['type'] : '').$frame['function'];
+ $stub->type = Stub::TYPE_OBJECT;
+ $stub->attr['cut_hash'] = true;
+ $stub->attr['file'] = $frame['file'];
+ $stub->attr['line'] = $frame['line'];
+
+ try {
+ $caller = isset($frame['class']) ? new \ReflectionMethod($frame['class'], $frame['function']) : new \ReflectionFunction($frame['function']);
+ $stub->class .= ReflectionCaster::getSignature(ReflectionCaster::castFunctionAbstract($caller, [], $stub, true, Caster::EXCLUDE_VERBOSE));
+
+ if ($f = $caller->getFileName()) {
+ $stub->attr['file'] = $f;
+ $stub->attr['line'] = $caller->getStartLine();
+ }
+ } catch (\ReflectionException $e) {
+ // ignore fake class/function
+ }
+
+ $srcLines = ["\0~separator=\0" => $stub];
+ } else {
+ $stub = null;
+ $srcLines = [];
+ }
+
+ $ltrim = 0;
+ do {
+ $pad = null;
+ for ($i = $srcContext << 1; $i >= 0; --$i) {
+ if (isset($src[$i][$ltrim]) && "\r" !== ($c = $src[$i][$ltrim]) && "\n" !== $c) {
+ if (null === $pad) {
+ $pad = $c;
+ }
+ if ((' ' !== $c && "\t" !== $c) || $pad !== $c) {
+ break;
+ }
+ }
+ }
+ ++$ltrim;
+ } while (0 > $i && null !== $pad);
+
+ --$ltrim;
+
+ foreach ($src as $i => $c) {
+ if ($ltrim) {
+ $c = isset($c[$ltrim]) && "\r" !== $c[$ltrim] ? substr($c, $ltrim) : ltrim($c, " \t");
+ }
+ $c = substr($c, 0, -1);
+ if ($i !== $srcContext) {
+ $c = new ConstStub('default', $c);
+ } else {
+ $c = new ConstStub($c, $stub ? 'in '.$stub->class : '');
+ if (null !== $file) {
+ $c->attr['file'] = $file;
+ $c->attr['line'] = $line;
+ }
+ }
+ $c->attr['lang'] = $lang;
+ $srcLines[sprintf("\0~separator=› &%d\0", $i + $line - $srcContext)] = $c;
+ }
+
+ return new EnumStub($srcLines);
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/FiberCaster.php b/vendor/symfony/var-dumper/Caster/FiberCaster.php
new file mode 100644
index 0000000..c74a9e5
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/FiberCaster.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts Fiber related classes to array representation.
+ *
+ * @author Grégoire Pineau
+ */
+class FrameStub extends EnumStub
+{
+ public $keepArgs;
+ public $inTraceStub;
+
+ public function __construct(array $frame, bool $keepArgs = true, bool $inTraceStub = false)
+ {
+ $this->value = $frame;
+ $this->keepArgs = $keepArgs;
+ $this->inTraceStub = $inTraceStub;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/GmpCaster.php b/vendor/symfony/var-dumper/Caster/GmpCaster.php
new file mode 100644
index 0000000..b018cc7
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/GmpCaster.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 Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts GMP objects to array representation.
+ *
+ * @author Hamza Amrouche
+ *
+ * @final
+ */
+class GmpCaster
+{
+ public static function castGmp(\GMP $gmp, array $a, Stub $stub, bool $isNested, int $filter): array
+ {
+ $a[Caster::PREFIX_VIRTUAL.'value'] = new ConstStub(gmp_strval($gmp), gmp_strval($gmp));
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/ImagineCaster.php b/vendor/symfony/var-dumper/Caster/ImagineCaster.php
new file mode 100644
index 0000000..d1289da
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/ImagineCaster.php
@@ -0,0 +1,37 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Imagine\Image\ImageInterface;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Grégoire Pineau
+ * @author Jan Schädlich
+ */
+class LinkStub extends ConstStub
+{
+ public $inVendor = false;
+
+ private static array $vendorRoots;
+ private static array $composerRoots = [];
+
+ public function __construct(string $label, int $line = 0, string $href = null)
+ {
+ $this->value = $label;
+
+ if (null === $href) {
+ $href = $label;
+ }
+ if (!\is_string($href)) {
+ return;
+ }
+ if (str_starts_with($href, 'file://')) {
+ if ($href === $label) {
+ $label = substr($label, 7);
+ }
+ $href = substr($href, 7);
+ } elseif (str_contains($href, '://')) {
+ $this->attr['href'] = $href;
+
+ return;
+ }
+ if (!is_file($href)) {
+ return;
+ }
+ if ($line) {
+ $this->attr['line'] = $line;
+ }
+ if ($label !== $this->attr['file'] = realpath($href) ?: $href) {
+ return;
+ }
+ if ($composerRoot = $this->getComposerRoot($href, $this->inVendor)) {
+ $this->attr['ellipsis'] = \strlen($href) - \strlen($composerRoot) + 1;
+ $this->attr['ellipsis-type'] = 'path';
+ $this->attr['ellipsis-tail'] = 1 + ($this->inVendor ? 2 + \strlen(implode('', \array_slice(explode(\DIRECTORY_SEPARATOR, substr($href, 1 - $this->attr['ellipsis'])), 0, 2))) : 0);
+ } elseif (3 < \count($ellipsis = explode(\DIRECTORY_SEPARATOR, $href))) {
+ $this->attr['ellipsis'] = 2 + \strlen(implode('', \array_slice($ellipsis, -2)));
+ $this->attr['ellipsis-type'] = 'path';
+ $this->attr['ellipsis-tail'] = 1;
+ }
+ }
+
+ private function getComposerRoot(string $file, bool &$inVendor)
+ {
+ if (!isset(self::$vendorRoots)) {
+ self::$vendorRoots = [];
+
+ foreach (get_declared_classes() as $class) {
+ if ('C' === $class[0] && str_starts_with($class, 'ComposerAutoloaderInit')) {
+ $r = new \ReflectionClass($class);
+ $v = \dirname($r->getFileName(), 2);
+ if (is_file($v.'/composer/installed.json')) {
+ self::$vendorRoots[] = $v.\DIRECTORY_SEPARATOR;
+ }
+ }
+ }
+ }
+ $inVendor = false;
+
+ if (isset(self::$composerRoots[$dir = \dirname($file)])) {
+ return self::$composerRoots[$dir];
+ }
+
+ foreach (self::$vendorRoots as $root) {
+ if ($inVendor = str_starts_with($file, $root)) {
+ return $root;
+ }
+ }
+
+ $parent = $dir;
+ while (!@is_file($parent.'/composer.json')) {
+ if (!@file_exists($parent)) {
+ // open_basedir restriction in effect
+ break;
+ }
+ if ($parent === \dirname($parent)) {
+ return self::$composerRoots[$dir] = false;
+ }
+
+ $parent = \dirname($parent);
+ }
+
+ return self::$composerRoots[$dir] = $parent.\DIRECTORY_SEPARATOR;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/MemcachedCaster.php b/vendor/symfony/var-dumper/Caster/MemcachedCaster.php
new file mode 100644
index 0000000..d6baa25
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/MemcachedCaster.php
@@ -0,0 +1,81 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Jan Schädlich
+ *
+ * @internal
+ */
+final class MysqliCaster
+{
+ public static function castMysqliDriver(\mysqli_driver $c, array $a, Stub $stub, bool $isNested): array
+ {
+ foreach ($a as $k => $v) {
+ if (isset($c->$k)) {
+ $a[$k] = $c->$k;
+ }
+ }
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/PdoCaster.php b/vendor/symfony/var-dumper/Caster/PdoCaster.php
new file mode 100644
index 0000000..140473b
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/PdoCaster.php
@@ -0,0 +1,122 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts PDO related classes to array representation.
+ *
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+class PdoCaster
+{
+ private const PDO_ATTRIBUTES = [
+ 'CASE' => [
+ \PDO::CASE_LOWER => 'LOWER',
+ \PDO::CASE_NATURAL => 'NATURAL',
+ \PDO::CASE_UPPER => 'UPPER',
+ ],
+ 'ERRMODE' => [
+ \PDO::ERRMODE_SILENT => 'SILENT',
+ \PDO::ERRMODE_WARNING => 'WARNING',
+ \PDO::ERRMODE_EXCEPTION => 'EXCEPTION',
+ ],
+ 'TIMEOUT',
+ 'PREFETCH',
+ 'AUTOCOMMIT',
+ 'PERSISTENT',
+ 'DRIVER_NAME',
+ 'SERVER_INFO',
+ 'ORACLE_NULLS' => [
+ \PDO::NULL_NATURAL => 'NATURAL',
+ \PDO::NULL_EMPTY_STRING => 'EMPTY_STRING',
+ \PDO::NULL_TO_STRING => 'TO_STRING',
+ ],
+ 'CLIENT_VERSION',
+ 'SERVER_VERSION',
+ 'STATEMENT_CLASS',
+ 'EMULATE_PREPARES',
+ 'CONNECTION_STATUS',
+ 'STRINGIFY_FETCHES',
+ 'DEFAULT_FETCH_MODE' => [
+ \PDO::FETCH_ASSOC => 'ASSOC',
+ \PDO::FETCH_BOTH => 'BOTH',
+ \PDO::FETCH_LAZY => 'LAZY',
+ \PDO::FETCH_NUM => 'NUM',
+ \PDO::FETCH_OBJ => 'OBJ',
+ ],
+ ];
+
+ public static function castPdo(\PDO $c, array $a, Stub $stub, bool $isNested)
+ {
+ $attr = [];
+ $errmode = $c->getAttribute(\PDO::ATTR_ERRMODE);
+ $c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+ foreach (self::PDO_ATTRIBUTES as $k => $v) {
+ if (!isset($k[0])) {
+ $k = $v;
+ $v = [];
+ }
+
+ try {
+ $attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(\constant('PDO::ATTR_'.$k));
+ if ($v && isset($v[$attr[$k]])) {
+ $attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]);
+ }
+ } catch (\Exception $e) {
+ }
+ }
+ if (isset($attr[$k = 'STATEMENT_CLASS'][1])) {
+ if ($attr[$k][1]) {
+ $attr[$k][1] = new ArgsStub($attr[$k][1], '__construct', $attr[$k][0]);
+ }
+ $attr[$k][0] = new ClassStub($attr[$k][0]);
+ }
+
+ $prefix = Caster::PREFIX_VIRTUAL;
+ $a += [
+ $prefix.'inTransaction' => method_exists($c, 'inTransaction'),
+ $prefix.'errorInfo' => $c->errorInfo(),
+ $prefix.'attributes' => new EnumStub($attr),
+ ];
+
+ if ($a[$prefix.'inTransaction']) {
+ $a[$prefix.'inTransaction'] = $c->inTransaction();
+ } else {
+ unset($a[$prefix.'inTransaction']);
+ }
+
+ if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) {
+ unset($a[$prefix.'errorInfo']);
+ }
+
+ $c->setAttribute(\PDO::ATTR_ERRMODE, $errmode);
+
+ return $a;
+ }
+
+ public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, bool $isNested)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+ $a[$prefix.'errorInfo'] = $c->errorInfo();
+
+ if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) {
+ unset($a[$prefix.'errorInfo']);
+ }
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/PgSqlCaster.php b/vendor/symfony/var-dumper/Caster/PgSqlCaster.php
new file mode 100644
index 0000000..d8e5b52
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/PgSqlCaster.php
@@ -0,0 +1,156 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts pqsql resources to array representation.
+ *
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+class PgSqlCaster
+{
+ private const PARAM_CODES = [
+ 'server_encoding',
+ 'client_encoding',
+ 'is_superuser',
+ 'session_authorization',
+ 'DateStyle',
+ 'TimeZone',
+ 'IntervalStyle',
+ 'integer_datetimes',
+ 'application_name',
+ 'standard_conforming_strings',
+ ];
+
+ private const TRANSACTION_STATUS = [
+ \PGSQL_TRANSACTION_IDLE => 'PGSQL_TRANSACTION_IDLE',
+ \PGSQL_TRANSACTION_ACTIVE => 'PGSQL_TRANSACTION_ACTIVE',
+ \PGSQL_TRANSACTION_INTRANS => 'PGSQL_TRANSACTION_INTRANS',
+ \PGSQL_TRANSACTION_INERROR => 'PGSQL_TRANSACTION_INERROR',
+ \PGSQL_TRANSACTION_UNKNOWN => 'PGSQL_TRANSACTION_UNKNOWN',
+ ];
+
+ private const RESULT_STATUS = [
+ \PGSQL_EMPTY_QUERY => 'PGSQL_EMPTY_QUERY',
+ \PGSQL_COMMAND_OK => 'PGSQL_COMMAND_OK',
+ \PGSQL_TUPLES_OK => 'PGSQL_TUPLES_OK',
+ \PGSQL_COPY_OUT => 'PGSQL_COPY_OUT',
+ \PGSQL_COPY_IN => 'PGSQL_COPY_IN',
+ \PGSQL_BAD_RESPONSE => 'PGSQL_BAD_RESPONSE',
+ \PGSQL_NONFATAL_ERROR => 'PGSQL_NONFATAL_ERROR',
+ \PGSQL_FATAL_ERROR => 'PGSQL_FATAL_ERROR',
+ ];
+
+ private const DIAG_CODES = [
+ 'severity' => \PGSQL_DIAG_SEVERITY,
+ 'sqlstate' => \PGSQL_DIAG_SQLSTATE,
+ 'message' => \PGSQL_DIAG_MESSAGE_PRIMARY,
+ 'detail' => \PGSQL_DIAG_MESSAGE_DETAIL,
+ 'hint' => \PGSQL_DIAG_MESSAGE_HINT,
+ 'statement position' => \PGSQL_DIAG_STATEMENT_POSITION,
+ 'internal position' => \PGSQL_DIAG_INTERNAL_POSITION,
+ 'internal query' => \PGSQL_DIAG_INTERNAL_QUERY,
+ 'context' => \PGSQL_DIAG_CONTEXT,
+ 'file' => \PGSQL_DIAG_SOURCE_FILE,
+ 'line' => \PGSQL_DIAG_SOURCE_LINE,
+ 'function' => \PGSQL_DIAG_SOURCE_FUNCTION,
+ ];
+
+ public static function castLargeObject($lo, array $a, Stub $stub, bool $isNested)
+ {
+ $a['seek position'] = pg_lo_tell($lo);
+
+ return $a;
+ }
+
+ public static function castLink($link, array $a, Stub $stub, bool $isNested)
+ {
+ $a['status'] = pg_connection_status($link);
+ $a['status'] = new ConstStub(\PGSQL_CONNECTION_OK === $a['status'] ? 'PGSQL_CONNECTION_OK' : 'PGSQL_CONNECTION_BAD', $a['status']);
+ $a['busy'] = pg_connection_busy($link);
+
+ $a['transaction'] = pg_transaction_status($link);
+ if (isset(self::TRANSACTION_STATUS[$a['transaction']])) {
+ $a['transaction'] = new ConstStub(self::TRANSACTION_STATUS[$a['transaction']], $a['transaction']);
+ }
+
+ $a['pid'] = pg_get_pid($link);
+ $a['last error'] = pg_last_error($link);
+ $a['last notice'] = pg_last_notice($link);
+ $a['host'] = pg_host($link);
+ $a['port'] = pg_port($link);
+ $a['dbname'] = pg_dbname($link);
+ $a['options'] = pg_options($link);
+ $a['version'] = pg_version($link);
+
+ foreach (self::PARAM_CODES as $v) {
+ if (false !== $s = pg_parameter_status($link, $v)) {
+ $a['param'][$v] = $s;
+ }
+ }
+
+ $a['param']['client_encoding'] = pg_client_encoding($link);
+ $a['param'] = new EnumStub($a['param']);
+
+ return $a;
+ }
+
+ public static function castResult($result, array $a, Stub $stub, bool $isNested)
+ {
+ $a['num rows'] = pg_num_rows($result);
+ $a['status'] = pg_result_status($result);
+ if (isset(self::RESULT_STATUS[$a['status']])) {
+ $a['status'] = new ConstStub(self::RESULT_STATUS[$a['status']], $a['status']);
+ }
+ $a['command-completion tag'] = pg_result_status($result, \PGSQL_STATUS_STRING);
+
+ if (-1 === $a['num rows']) {
+ foreach (self::DIAG_CODES as $k => $v) {
+ $a['error'][$k] = pg_result_error_field($result, $v);
+ }
+ }
+
+ $a['affected rows'] = pg_affected_rows($result);
+ $a['last OID'] = pg_last_oid($result);
+
+ $fields = pg_num_fields($result);
+
+ for ($i = 0; $i < $fields; ++$i) {
+ $field = [
+ 'name' => pg_field_name($result, $i),
+ 'table' => sprintf('%s (OID: %s)', pg_field_table($result, $i), pg_field_table($result, $i, true)),
+ 'type' => sprintf('%s (OID: %s)', pg_field_type($result, $i), pg_field_type_oid($result, $i)),
+ 'nullable' => (bool) pg_field_is_null($result, $i),
+ 'storage' => pg_field_size($result, $i).' bytes',
+ 'display' => pg_field_prtlen($result, $i).' chars',
+ ];
+ if (' (OID: )' === $field['table']) {
+ $field['table'] = null;
+ }
+ if ('-1 bytes' === $field['storage']) {
+ $field['storage'] = 'variable size';
+ } elseif ('1 bytes' === $field['storage']) {
+ $field['storage'] = '1 byte';
+ }
+ if ('1 chars' === $field['display']) {
+ $field['display'] = '1 char';
+ }
+ $a['fields'][] = new EnumStub($field);
+ }
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php b/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php
new file mode 100644
index 0000000..e712019
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/ProxyManagerCaster.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use ProxyManager\Proxy\ProxyInterface;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+class ProxyManagerCaster
+{
+ public static function castProxy(ProxyInterface $c, array $a, Stub $stub, bool $isNested)
+ {
+ if ($parent = get_parent_class($c)) {
+ $stub->class .= ' - '.$parent;
+ }
+ $stub->class .= '@proxy';
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php b/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php
new file mode 100644
index 0000000..8053363
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/RdKafkaCaster.php
@@ -0,0 +1,186 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use RdKafka\Conf;
+use RdKafka\Exception as RdKafkaException;
+use RdKafka\KafkaConsumer;
+use RdKafka\Message;
+use RdKafka\Metadata\Broker as BrokerMetadata;
+use RdKafka\Metadata\Collection as CollectionMetadata;
+use RdKafka\Metadata\Partition as PartitionMetadata;
+use RdKafka\Metadata\Topic as TopicMetadata;
+use RdKafka\Topic;
+use RdKafka\TopicConf;
+use RdKafka\TopicPartition;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts RdKafka related classes to array representation.
+ *
+ * @author Romain Neutron
+ *
+ * @final
+ */
+class RedisCaster
+{
+ private const SERIALIZERS = [
+ \Redis::SERIALIZER_NONE => 'NONE',
+ \Redis::SERIALIZER_PHP => 'PHP',
+ 2 => 'IGBINARY', // Optional Redis::SERIALIZER_IGBINARY
+ ];
+
+ private const MODES = [
+ \Redis::ATOMIC => 'ATOMIC',
+ \Redis::MULTI => 'MULTI',
+ \Redis::PIPELINE => 'PIPELINE',
+ ];
+
+ private const COMPRESSION_MODES = [
+ 0 => 'NONE', // Redis::COMPRESSION_NONE
+ 1 => 'LZF', // Redis::COMPRESSION_LZF
+ ];
+
+ private const FAILOVER_OPTIONS = [
+ \RedisCluster::FAILOVER_NONE => 'NONE',
+ \RedisCluster::FAILOVER_ERROR => 'ERROR',
+ \RedisCluster::FAILOVER_DISTRIBUTE => 'DISTRIBUTE',
+ \RedisCluster::FAILOVER_DISTRIBUTE_SLAVES => 'DISTRIBUTE_SLAVES',
+ ];
+
+ public static function castRedis(\Redis $c, array $a, Stub $stub, bool $isNested)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ if (!$connected = $c->isConnected()) {
+ return $a + [
+ $prefix.'isConnected' => $connected,
+ ];
+ }
+
+ $mode = $c->getMode();
+
+ return $a + [
+ $prefix.'isConnected' => $connected,
+ $prefix.'host' => $c->getHost(),
+ $prefix.'port' => $c->getPort(),
+ $prefix.'auth' => $c->getAuth(),
+ $prefix.'mode' => isset(self::MODES[$mode]) ? new ConstStub(self::MODES[$mode], $mode) : $mode,
+ $prefix.'dbNum' => $c->getDbNum(),
+ $prefix.'timeout' => $c->getTimeout(),
+ $prefix.'lastError' => $c->getLastError(),
+ $prefix.'persistentId' => $c->getPersistentID(),
+ $prefix.'options' => self::getRedisOptions($c),
+ ];
+ }
+
+ public static function castRedisArray(\RedisArray $c, array $a, Stub $stub, bool $isNested)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ return $a + [
+ $prefix.'hosts' => $c->_hosts(),
+ $prefix.'function' => ClassStub::wrapCallable($c->_function()),
+ $prefix.'lastError' => $c->getLastError(),
+ $prefix.'options' => self::getRedisOptions($c),
+ ];
+ }
+
+ public static function castRedisCluster(\RedisCluster $c, array $a, Stub $stub, bool $isNested)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+ $failover = $c->getOption(\RedisCluster::OPT_SLAVE_FAILOVER);
+
+ $a += [
+ $prefix.'_masters' => $c->_masters(),
+ $prefix.'_redir' => $c->_redir(),
+ $prefix.'mode' => new ConstStub($c->getMode() ? 'MULTI' : 'ATOMIC', $c->getMode()),
+ $prefix.'lastError' => $c->getLastError(),
+ $prefix.'options' => self::getRedisOptions($c, [
+ 'SLAVE_FAILOVER' => isset(self::FAILOVER_OPTIONS[$failover]) ? new ConstStub(self::FAILOVER_OPTIONS[$failover], $failover) : $failover,
+ ]),
+ ];
+
+ return $a;
+ }
+
+ private static function getRedisOptions(\Redis|\RedisArray|\RedisCluster $redis, array $options = []): EnumStub
+ {
+ $serializer = $redis->getOption(\Redis::OPT_SERIALIZER);
+ if (\is_array($serializer)) {
+ foreach ($serializer as &$v) {
+ if (isset(self::SERIALIZERS[$v])) {
+ $v = new ConstStub(self::SERIALIZERS[$v], $v);
+ }
+ }
+ } elseif (isset(self::SERIALIZERS[$serializer])) {
+ $serializer = new ConstStub(self::SERIALIZERS[$serializer], $serializer);
+ }
+
+ $compression = \defined('Redis::OPT_COMPRESSION') ? $redis->getOption(\Redis::OPT_COMPRESSION) : 0;
+ if (\is_array($compression)) {
+ foreach ($compression as &$v) {
+ if (isset(self::COMPRESSION_MODES[$v])) {
+ $v = new ConstStub(self::COMPRESSION_MODES[$v], $v);
+ }
+ }
+ } elseif (isset(self::COMPRESSION_MODES[$compression])) {
+ $compression = new ConstStub(self::COMPRESSION_MODES[$compression], $compression);
+ }
+
+ $retry = \defined('Redis::OPT_SCAN') ? $redis->getOption(\Redis::OPT_SCAN) : 0;
+ if (\is_array($retry)) {
+ foreach ($retry as &$v) {
+ $v = new ConstStub($v ? 'RETRY' : 'NORETRY', $v);
+ }
+ } else {
+ $retry = new ConstStub($retry ? 'RETRY' : 'NORETRY', $retry);
+ }
+
+ $options += [
+ 'TCP_KEEPALIVE' => \defined('Redis::OPT_TCP_KEEPALIVE') ? $redis->getOption(\Redis::OPT_TCP_KEEPALIVE) : 0,
+ 'READ_TIMEOUT' => $redis->getOption(\Redis::OPT_READ_TIMEOUT),
+ 'COMPRESSION' => $compression,
+ 'SERIALIZER' => $serializer,
+ 'PREFIX' => $redis->getOption(\Redis::OPT_PREFIX),
+ 'SCAN' => $retry,
+ ];
+
+ return new EnumStub($options);
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/ReflectionCaster.php b/vendor/symfony/var-dumper/Caster/ReflectionCaster.php
new file mode 100644
index 0000000..ef5f15d
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/ReflectionCaster.php
@@ -0,0 +1,440 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts Reflector related classes to array representation.
+ *
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+class ReflectionCaster
+{
+ public const UNSET_CLOSURE_FILE_INFO = ['Closure' => __CLASS__.'::unsetClosureFileInfo'];
+
+ private const EXTRA_MAP = [
+ 'docComment' => 'getDocComment',
+ 'extension' => 'getExtensionName',
+ 'isDisabled' => 'isDisabled',
+ 'isDeprecated' => 'isDeprecated',
+ 'isInternal' => 'isInternal',
+ 'isUserDefined' => 'isUserDefined',
+ 'isGenerator' => 'isGenerator',
+ 'isVariadic' => 'isVariadic',
+ ];
+
+ public static function castClosure(\Closure $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+ $c = new \ReflectionFunction($c);
+
+ $a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter);
+
+ if (!str_contains($c->name, '{closure}')) {
+ $stub->class = isset($a[$prefix.'class']) ? $a[$prefix.'class']->value.'::'.$c->name : $c->name;
+ unset($a[$prefix.'class']);
+ }
+ unset($a[$prefix.'extra']);
+
+ $stub->class .= self::getSignature($a);
+
+ if ($f = $c->getFileName()) {
+ $stub->attr['file'] = $f;
+ $stub->attr['line'] = $c->getStartLine();
+ }
+
+ unset($a[$prefix.'parameters']);
+
+ if ($filter & Caster::EXCLUDE_VERBOSE) {
+ $stub->cut += ($c->getFileName() ? 2 : 0) + \count($a);
+
+ return [];
+ }
+
+ if ($f) {
+ $a[$prefix.'file'] = new LinkStub($f, $c->getStartLine());
+ $a[$prefix.'line'] = $c->getStartLine().' to '.$c->getEndLine();
+ }
+
+ return $a;
+ }
+
+ public static function unsetClosureFileInfo(\Closure $c, array $a)
+ {
+ unset($a[Caster::PREFIX_VIRTUAL.'file'], $a[Caster::PREFIX_VIRTUAL.'line']);
+
+ return $a;
+ }
+
+ public static function castGenerator(\Generator $c, array $a, Stub $stub, bool $isNested)
+ {
+ // Cannot create ReflectionGenerator based on a terminated Generator
+ try {
+ $reflectionGenerator = new \ReflectionGenerator($c);
+ } catch (\Exception $e) {
+ $a[Caster::PREFIX_VIRTUAL.'closed'] = true;
+
+ return $a;
+ }
+
+ return self::castReflectionGenerator($reflectionGenerator, $a, $stub, $isNested);
+ }
+
+ public static function castType(\ReflectionType $c, array $a, Stub $stub, bool $isNested)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ if ($c instanceof \ReflectionNamedType) {
+ $a += [
+ $prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c,
+ $prefix.'allowsNull' => $c->allowsNull(),
+ $prefix.'isBuiltin' => $c->isBuiltin(),
+ ];
+ } elseif ($c instanceof \ReflectionUnionType || $c instanceof \ReflectionIntersectionType) {
+ $a[$prefix.'allowsNull'] = $c->allowsNull();
+ self::addMap($a, $c, [
+ 'types' => 'getTypes',
+ ]);
+ } else {
+ $a[$prefix.'allowsNull'] = $c->allowsNull();
+ }
+
+ return $a;
+ }
+
+ public static function castAttribute(\ReflectionAttribute $c, array $a, Stub $stub, bool $isNested)
+ {
+ self::addMap($a, $c, [
+ 'name' => 'getName',
+ 'arguments' => 'getArguments',
+ ]);
+
+ return $a;
+ }
+
+ public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, bool $isNested)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ if ($c->getThis()) {
+ $a[$prefix.'this'] = new CutStub($c->getThis());
+ }
+ $function = $c->getFunction();
+ $frame = [
+ 'class' => $function->class ?? null,
+ 'type' => isset($function->class) ? ($function->isStatic() ? '::' : '->') : null,
+ 'function' => $function->name,
+ 'file' => $c->getExecutingFile(),
+ 'line' => $c->getExecutingLine(),
+ ];
+ if ($trace = $c->getTrace(\DEBUG_BACKTRACE_IGNORE_ARGS)) {
+ $function = new \ReflectionGenerator($c->getExecutingGenerator());
+ array_unshift($trace, [
+ 'function' => 'yield',
+ 'file' => $function->getExecutingFile(),
+ 'line' => $function->getExecutingLine() - (int) (\PHP_VERSION_ID < 80100),
+ ]);
+ $trace[] = $frame;
+ $a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
+ } else {
+ $function = new FrameStub($frame, false, true);
+ $function = ExceptionCaster::castFrameStub($function, [], $function, true);
+ $a[$prefix.'executing'] = $function[$prefix.'src'];
+ }
+
+ $a[Caster::PREFIX_VIRTUAL.'closed'] = false;
+
+ return $a;
+ }
+
+ public static function castClass(\ReflectionClass $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ if ($n = \Reflection::getModifierNames($c->getModifiers())) {
+ $a[$prefix.'modifiers'] = implode(' ', $n);
+ }
+
+ self::addMap($a, $c, [
+ 'extends' => 'getParentClass',
+ 'implements' => 'getInterfaceNames',
+ 'constants' => 'getReflectionConstants',
+ ]);
+
+ foreach ($c->getProperties() as $n) {
+ $a[$prefix.'properties'][$n->name] = $n;
+ }
+
+ foreach ($c->getMethods() as $n) {
+ $a[$prefix.'methods'][$n->name] = $n;
+ }
+
+ self::addAttributes($a, $c, $prefix);
+
+ if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
+ self::addExtra($a, $c);
+ }
+
+ return $a;
+ }
+
+ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, bool $isNested, int $filter = 0)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ self::addMap($a, $c, [
+ 'returnsReference' => 'returnsReference',
+ 'returnType' => 'getReturnType',
+ 'class' => \PHP_VERSION_ID >= 80111 ? 'getClosureCalledClass' : 'getClosureScopeClass',
+ 'this' => 'getClosureThis',
+ ]);
+
+ if (isset($a[$prefix.'returnType'])) {
+ $v = $a[$prefix.'returnType'];
+ $v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
+ $a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && 'mixed' !== $v ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
+ }
+ if (isset($a[$prefix.'class'])) {
+ $a[$prefix.'class'] = new ClassStub($a[$prefix.'class']);
+ }
+ if (isset($a[$prefix.'this'])) {
+ $a[$prefix.'this'] = new CutStub($a[$prefix.'this']);
+ }
+
+ foreach ($c->getParameters() as $v) {
+ $k = '$'.$v->name;
+ if ($v->isVariadic()) {
+ $k = '...'.$k;
+ }
+ if ($v->isPassedByReference()) {
+ $k = '&'.$k;
+ }
+ $a[$prefix.'parameters'][$k] = $v;
+ }
+ if (isset($a[$prefix.'parameters'])) {
+ $a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']);
+ }
+
+ self::addAttributes($a, $c, $prefix);
+
+ if (!($filter & Caster::EXCLUDE_VERBOSE) && $v = $c->getStaticVariables()) {
+ foreach ($v as $k => &$v) {
+ if (\is_object($v)) {
+ $a[$prefix.'use']['$'.$k] = new CutStub($v);
+ } else {
+ $a[$prefix.'use']['$'.$k] = &$v;
+ }
+ }
+ unset($v);
+ $a[$prefix.'use'] = new EnumStub($a[$prefix.'use']);
+ }
+
+ if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
+ self::addExtra($a, $c);
+ }
+
+ return $a;
+ }
+
+ public static function castClassConstant(\ReflectionClassConstant $c, array $a, Stub $stub, bool $isNested)
+ {
+ $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
+ $a[Caster::PREFIX_VIRTUAL.'value'] = $c->getValue();
+
+ self::addAttributes($a, $c);
+
+ return $a;
+ }
+
+ public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, bool $isNested)
+ {
+ $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
+
+ return $a;
+ }
+
+ public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, bool $isNested)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ self::addMap($a, $c, [
+ 'position' => 'getPosition',
+ 'isVariadic' => 'isVariadic',
+ 'byReference' => 'isPassedByReference',
+ 'allowsNull' => 'allowsNull',
+ ]);
+
+ self::addAttributes($a, $c, $prefix);
+
+ if ($v = $c->getType()) {
+ $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
+ }
+
+ if (isset($a[$prefix.'typeHint'])) {
+ $v = $a[$prefix.'typeHint'];
+ $a[$prefix.'typeHint'] = new ClassStub($v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
+ } else {
+ unset($a[$prefix.'allowsNull']);
+ }
+
+ if ($c->isOptional()) {
+ try {
+ $a[$prefix.'default'] = $v = $c->getDefaultValue();
+ if ($c->isDefaultValueConstant()) {
+ $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v);
+ }
+ if (null === $v) {
+ unset($a[$prefix.'allowsNull']);
+ }
+ } catch (\ReflectionException $e) {
+ }
+ }
+
+ return $a;
+ }
+
+ public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, bool $isNested)
+ {
+ $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
+
+ self::addAttributes($a, $c);
+ self::addExtra($a, $c);
+
+ return $a;
+ }
+
+ public static function castReference(\ReflectionReference $c, array $a, Stub $stub, bool $isNested)
+ {
+ $a[Caster::PREFIX_VIRTUAL.'id'] = $c->getId();
+
+ return $a;
+ }
+
+ public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, bool $isNested)
+ {
+ self::addMap($a, $c, [
+ 'version' => 'getVersion',
+ 'dependencies' => 'getDependencies',
+ 'iniEntries' => 'getIniEntries',
+ 'isPersistent' => 'isPersistent',
+ 'isTemporary' => 'isTemporary',
+ 'constants' => 'getConstants',
+ 'functions' => 'getFunctions',
+ 'classes' => 'getClasses',
+ ]);
+
+ return $a;
+ }
+
+ public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, bool $isNested)
+ {
+ self::addMap($a, $c, [
+ 'version' => 'getVersion',
+ 'author' => 'getAuthor',
+ 'copyright' => 'getCopyright',
+ 'url' => 'getURL',
+ ]);
+
+ return $a;
+ }
+
+ public static function getSignature(array $a)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+ $signature = '';
+
+ if (isset($a[$prefix.'parameters'])) {
+ foreach ($a[$prefix.'parameters']->value as $k => $param) {
+ $signature .= ', ';
+ if ($type = $param->getType()) {
+ if (!$type instanceof \ReflectionNamedType) {
+ $signature .= $type.' ';
+ } else {
+ if (!$param->isOptional() && $param->allowsNull() && 'mixed' !== $type->getName()) {
+ $signature .= '?';
+ }
+ $signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';
+ }
+ }
+ $signature .= $k;
+
+ if (!$param->isDefaultValueAvailable()) {
+ continue;
+ }
+ $v = $param->getDefaultValue();
+ $signature .= ' = ';
+
+ if ($param->isDefaultValueConstant()) {
+ $signature .= substr(strrchr('\\'.$param->getDefaultValueConstantName(), '\\'), 1);
+ } elseif (null === $v) {
+ $signature .= 'null';
+ } elseif (\is_array($v)) {
+ $signature .= $v ? '[…'.\count($v).']' : '[]';
+ } elseif (\is_string($v)) {
+ $signature .= 10 > \strlen($v) && !str_contains($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'";
+ } elseif (\is_bool($v)) {
+ $signature .= $v ? 'true' : 'false';
+ } elseif (\is_object($v)) {
+ $signature .= 'new '.substr(strrchr('\\'.get_debug_type($v), '\\'), 1);
+ } else {
+ $signature .= $v;
+ }
+ }
+ }
+ $signature = (empty($a[$prefix.'returnsReference']) ? '' : '&').'('.substr($signature, 2).')';
+
+ if (isset($a[$prefix.'returnType'])) {
+ $signature .= ': '.substr(strrchr('\\'.$a[$prefix.'returnType'], '\\'), 1);
+ }
+
+ return $signature;
+ }
+
+ private static function addExtra(array &$a, \Reflector $c)
+ {
+ $x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : [];
+
+ if (method_exists($c, 'getFileName') && $m = $c->getFileName()) {
+ $x['file'] = new LinkStub($m, $c->getStartLine());
+ $x['line'] = $c->getStartLine().' to '.$c->getEndLine();
+ }
+
+ self::addMap($x, $c, self::EXTRA_MAP, '');
+
+ if ($x) {
+ $a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x);
+ }
+ }
+
+ private static function addMap(array &$a, object $c, array $map, string $prefix = Caster::PREFIX_VIRTUAL)
+ {
+ foreach ($map as $k => $m) {
+ if ('isDisabled' === $k) {
+ continue;
+ }
+
+ if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) {
+ $a[$prefix.$k] = $m instanceof \Reflector ? $m->name : $m;
+ }
+ }
+ }
+
+ private static function addAttributes(array &$a, \Reflector $c, string $prefix = Caster::PREFIX_VIRTUAL): void
+ {
+ foreach ($c->getAttributes() as $n) {
+ $a[$prefix.'attributes'][] = $n;
+ }
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/ResourceCaster.php b/vendor/symfony/var-dumper/Caster/ResourceCaster.php
new file mode 100644
index 0000000..4e597f8
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/ResourceCaster.php
@@ -0,0 +1,100 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts common resource types to array representation.
+ *
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+class ResourceCaster
+{
+ public static function castCurl(\CurlHandle $h, array $a, Stub $stub, bool $isNested): array
+ {
+ return curl_getinfo($h);
+ }
+
+ public static function castDba($dba, array $a, Stub $stub, bool $isNested)
+ {
+ $list = dba_list();
+ $a['file'] = $list[(int) $dba];
+
+ return $a;
+ }
+
+ public static function castProcess($process, array $a, Stub $stub, bool $isNested)
+ {
+ return proc_get_status($process);
+ }
+
+ public static function castStream($stream, array $a, Stub $stub, bool $isNested)
+ {
+ $a = stream_get_meta_data($stream) + static::castStreamContext($stream, $a, $stub, $isNested);
+ if ($a['uri'] ?? false) {
+ $a['uri'] = new LinkStub($a['uri']);
+ }
+
+ return $a;
+ }
+
+ public static function castStreamContext($stream, array $a, Stub $stub, bool $isNested)
+ {
+ return @stream_context_get_params($stream) ?: $a;
+ }
+
+ public static function castGd($gd, array $a, Stub $stub, bool $isNested)
+ {
+ $a['size'] = imagesx($gd).'x'.imagesy($gd);
+ $a['trueColor'] = imageistruecolor($gd);
+
+ return $a;
+ }
+
+ public static function castMysqlLink($h, array $a, Stub $stub, bool $isNested)
+ {
+ $a['host'] = mysql_get_host_info($h);
+ $a['protocol'] = mysql_get_proto_info($h);
+ $a['server'] = mysql_get_server_info($h);
+
+ return $a;
+ }
+
+ public static function castOpensslX509($h, array $a, Stub $stub, bool $isNested)
+ {
+ $stub->cut = -1;
+ $info = openssl_x509_parse($h, false);
+
+ $pin = openssl_pkey_get_public($h);
+ $pin = openssl_pkey_get_details($pin)['key'];
+ $pin = \array_slice(explode("\n", $pin), 1, -2);
+ $pin = base64_decode(implode('', $pin));
+ $pin = base64_encode(hash('sha256', $pin, true));
+
+ $a += [
+ 'subject' => new EnumStub(array_intersect_key($info['subject'], ['organizationName' => true, 'commonName' => true])),
+ 'issuer' => new EnumStub(array_intersect_key($info['issuer'], ['organizationName' => true, 'commonName' => true])),
+ 'expiry' => new ConstStub(date(\DateTime::ISO8601, $info['validTo_time_t']), $info['validTo_time_t']),
+ 'fingerprint' => new EnumStub([
+ 'md5' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'md5')), 2, ':', true)),
+ 'sha1' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha1')), 2, ':', true)),
+ 'sha256' => new ConstStub(wordwrap(strtoupper(openssl_x509_fingerprint($h, 'sha256')), 2, ':', true)),
+ 'pin-sha256' => new ConstStub($pin),
+ ]),
+ ];
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/SplCaster.php b/vendor/symfony/var-dumper/Caster/SplCaster.php
new file mode 100644
index 0000000..a51cace
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/SplCaster.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 Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts SPL related classes to array representation.
+ *
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+class SplCaster
+{
+ private const SPL_FILE_OBJECT_FLAGS = [
+ \SplFileObject::DROP_NEW_LINE => 'DROP_NEW_LINE',
+ \SplFileObject::READ_AHEAD => 'READ_AHEAD',
+ \SplFileObject::SKIP_EMPTY => 'SKIP_EMPTY',
+ \SplFileObject::READ_CSV => 'READ_CSV',
+ ];
+
+ public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, bool $isNested)
+ {
+ return self::castSplArray($c, $a, $stub, $isNested);
+ }
+
+ public static function castArrayIterator(\ArrayIterator $c, array $a, Stub $stub, bool $isNested)
+ {
+ return self::castSplArray($c, $a, $stub, $isNested);
+ }
+
+ public static function castHeap(\Iterator $c, array $a, Stub $stub, bool $isNested)
+ {
+ $a += [
+ Caster::PREFIX_VIRTUAL.'heap' => iterator_to_array(clone $c),
+ ];
+
+ return $a;
+ }
+
+ public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, Stub $stub, bool $isNested)
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+ $mode = $c->getIteratorMode();
+ $c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE);
+
+ $a += [
+ $prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_DELETE) ? 'IT_MODE_DELETE' : 'IT_MODE_KEEP'), $mode),
+ $prefix.'dllist' => iterator_to_array($c),
+ ];
+ $c->setIteratorMode($mode);
+
+ return $a;
+ }
+
+ public static function castFileInfo(\SplFileInfo $c, array $a, Stub $stub, bool $isNested)
+ {
+ static $map = [
+ 'path' => 'getPath',
+ 'filename' => 'getFilename',
+ 'basename' => 'getBasename',
+ 'pathname' => 'getPathname',
+ 'extension' => 'getExtension',
+ 'realPath' => 'getRealPath',
+ 'aTime' => 'getATime',
+ 'mTime' => 'getMTime',
+ 'cTime' => 'getCTime',
+ 'inode' => 'getInode',
+ 'size' => 'getSize',
+ 'perms' => 'getPerms',
+ 'owner' => 'getOwner',
+ 'group' => 'getGroup',
+ 'type' => 'getType',
+ 'writable' => 'isWritable',
+ 'readable' => 'isReadable',
+ 'executable' => 'isExecutable',
+ 'file' => 'isFile',
+ 'dir' => 'isDir',
+ 'link' => 'isLink',
+ 'linkTarget' => 'getLinkTarget',
+ ];
+
+ $prefix = Caster::PREFIX_VIRTUAL;
+ unset($a["\0SplFileInfo\0fileName"]);
+ unset($a["\0SplFileInfo\0pathName"]);
+
+ try {
+ $c->isReadable();
+ } catch (\RuntimeException $e) {
+ if ('Object not initialized' !== $e->getMessage()) {
+ throw $e;
+ }
+
+ $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
+
+ return $a;
+ } catch (\Error $e) {
+ if ('Object not initialized' !== $e->getMessage()) {
+ throw $e;
+ }
+
+ $a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
+
+ return $a;
+ }
+
+ foreach ($map as $key => $accessor) {
+ try {
+ $a[$prefix.$key] = $c->$accessor();
+ } catch (\Exception $e) {
+ }
+ }
+
+ if ($a[$prefix.'realPath'] ?? false) {
+ $a[$prefix.'realPath'] = new LinkStub($a[$prefix.'realPath']);
+ }
+
+ if (isset($a[$prefix.'perms'])) {
+ $a[$prefix.'perms'] = new ConstStub(sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']);
+ }
+
+ static $mapDate = ['aTime', 'mTime', 'cTime'];
+ foreach ($mapDate as $key) {
+ if (isset($a[$prefix.$key])) {
+ $a[$prefix.$key] = new ConstStub(date('Y-m-d H:i:s', $a[$prefix.$key]), $a[$prefix.$key]);
+ }
+ }
+
+ return $a;
+ }
+
+ public static function castFileObject(\SplFileObject $c, array $a, Stub $stub, bool $isNested)
+ {
+ static $map = [
+ 'csvControl' => 'getCsvControl',
+ 'flags' => 'getFlags',
+ 'maxLineLen' => 'getMaxLineLen',
+ 'fstat' => 'fstat',
+ 'eof' => 'eof',
+ 'key' => 'key',
+ ];
+
+ $prefix = Caster::PREFIX_VIRTUAL;
+
+ foreach ($map as $key => $accessor) {
+ try {
+ $a[$prefix.$key] = $c->$accessor();
+ } catch (\Exception $e) {
+ }
+ }
+
+ if (isset($a[$prefix.'flags'])) {
+ $flagsArray = [];
+ foreach (self::SPL_FILE_OBJECT_FLAGS as $value => $name) {
+ if ($a[$prefix.'flags'] & $value) {
+ $flagsArray[] = $name;
+ }
+ }
+ $a[$prefix.'flags'] = new ConstStub(implode('|', $flagsArray), $a[$prefix.'flags']);
+ }
+
+ if (isset($a[$prefix.'fstat'])) {
+ $a[$prefix.'fstat'] = new CutArrayStub($a[$prefix.'fstat'], ['dev', 'ino', 'nlink', 'rdev', 'blksize', 'blocks']);
+ }
+
+ return $a;
+ }
+
+ public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $stub, bool $isNested)
+ {
+ $storage = [];
+ unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967
+ unset($a["\0SplObjectStorage\0storage"]);
+
+ $clone = clone $c;
+ foreach ($clone as $obj) {
+ $storage[] = [
+ 'object' => $obj,
+ 'info' => $clone->getInfo(),
+ ];
+ }
+
+ $a += [
+ Caster::PREFIX_VIRTUAL.'storage' => $storage,
+ ];
+
+ return $a;
+ }
+
+ public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub, bool $isNested)
+ {
+ $a[Caster::PREFIX_VIRTUAL.'innerIterator'] = $c->getInnerIterator();
+
+ return $a;
+ }
+
+ public static function castWeakReference(\WeakReference $c, array $a, Stub $stub, bool $isNested)
+ {
+ $a[Caster::PREFIX_VIRTUAL.'object'] = $c->get();
+
+ return $a;
+ }
+
+ private static function castSplArray(\ArrayObject|\ArrayIterator $c, array $a, Stub $stub, bool $isNested): array
+ {
+ $prefix = Caster::PREFIX_VIRTUAL;
+ $flags = $c->getFlags();
+
+ if (!($flags & \ArrayObject::STD_PROP_LIST)) {
+ $c->setFlags(\ArrayObject::STD_PROP_LIST);
+ $a = Caster::castObject($c, \get_class($c), method_exists($c, '__debugInfo'), $stub->class);
+ $c->setFlags($flags);
+ }
+ $a += [
+ $prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
+ $prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),
+ ];
+ if ($c instanceof \ArrayObject) {
+ $a[$prefix.'iteratorClass'] = new ClassStub($c->getIteratorClass());
+ }
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/StubCaster.php b/vendor/symfony/var-dumper/Caster/StubCaster.php
new file mode 100644
index 0000000..32ead7c
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/StubCaster.php
@@ -0,0 +1,84 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Casts a caster's Stub.
+ *
+ * @author Nicolas Grekas
+ *
+ * @final
+ */
+class StubCaster
+{
+ public static function castStub(Stub $c, array $a, Stub $stub, bool $isNested)
+ {
+ if ($isNested) {
+ $stub->type = $c->type;
+ $stub->class = $c->class;
+ $stub->value = $c->value;
+ $stub->handle = $c->handle;
+ $stub->cut = $c->cut;
+ $stub->attr = $c->attr;
+
+ if (Stub::TYPE_REF === $c->type && !$c->class && \is_string($c->value) && !preg_match('//u', $c->value)) {
+ $stub->type = Stub::TYPE_STRING;
+ $stub->class = Stub::STRING_BINARY;
+ }
+
+ $a = [];
+ }
+
+ return $a;
+ }
+
+ public static function castCutArray(CutArrayStub $c, array $a, Stub $stub, bool $isNested)
+ {
+ return $isNested ? $c->preservedSubset : $a;
+ }
+
+ public static function cutInternals($obj, array $a, Stub $stub, bool $isNested)
+ {
+ if ($isNested) {
+ $stub->cut += \count($a);
+
+ return [];
+ }
+
+ return $a;
+ }
+
+ public static function castEnum(EnumStub $c, array $a, Stub $stub, bool $isNested)
+ {
+ if ($isNested) {
+ $stub->class = $c->dumpKeys ? '' : null;
+ $stub->handle = 0;
+ $stub->value = null;
+ $stub->cut = $c->cut;
+ $stub->attr = $c->attr;
+
+ $a = [];
+
+ if ($c->value) {
+ foreach (array_keys($c->value) as $k) {
+ $keys[] = !isset($k[0]) || "\0" !== $k[0] ? Caster::PREFIX_VIRTUAL.$k : $k;
+ }
+ // Preserve references with array_combine()
+ $a = array_combine($keys, $c->value);
+ }
+ }
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/SymfonyCaster.php b/vendor/symfony/var-dumper/Caster/SymfonyCaster.php
new file mode 100644
index 0000000..08428b9
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/SymfonyCaster.php
@@ -0,0 +1,97 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Uid\Ulid;
+use Symfony\Component\Uid\Uuid;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @final
+ */
+class SymfonyCaster
+{
+ private const REQUEST_GETTERS = [
+ 'pathInfo' => 'getPathInfo',
+ 'requestUri' => 'getRequestUri',
+ 'baseUrl' => 'getBaseUrl',
+ 'basePath' => 'getBasePath',
+ 'method' => 'getMethod',
+ 'format' => 'getRequestFormat',
+ ];
+
+ public static function castRequest(Request $request, array $a, Stub $stub, bool $isNested)
+ {
+ $clone = null;
+
+ foreach (self::REQUEST_GETTERS as $prop => $getter) {
+ $key = Caster::PREFIX_PROTECTED.$prop;
+ if (\array_key_exists($key, $a) && null === $a[$key]) {
+ if (null === $clone) {
+ $clone = clone $request;
+ }
+ $a[Caster::PREFIX_VIRTUAL.$prop] = $clone->{$getter}();
+ }
+ }
+
+ return $a;
+ }
+
+ public static function castHttpClient($client, array $a, Stub $stub, bool $isNested)
+ {
+ $multiKey = sprintf("\0%s\0multi", \get_class($client));
+ if (isset($a[$multiKey])) {
+ $a[$multiKey] = new CutStub($a[$multiKey]);
+ }
+
+ return $a;
+ }
+
+ public static function castHttpClientResponse($response, array $a, Stub $stub, bool $isNested)
+ {
+ $stub->cut += \count($a);
+ $a = [];
+
+ foreach ($response->getInfo() as $k => $v) {
+ $a[Caster::PREFIX_VIRTUAL.$k] = $v;
+ }
+
+ return $a;
+ }
+
+ public static function castUuid(Uuid $uuid, array $a, Stub $stub, bool $isNested)
+ {
+ $a[Caster::PREFIX_VIRTUAL.'toBase58'] = $uuid->toBase58();
+ $a[Caster::PREFIX_VIRTUAL.'toBase32'] = $uuid->toBase32();
+
+ // symfony/uid >= 5.3
+ if (method_exists($uuid, 'getDateTime')) {
+ $a[Caster::PREFIX_VIRTUAL.'time'] = $uuid->getDateTime()->format('Y-m-d H:i:s.u \U\T\C');
+ }
+
+ return $a;
+ }
+
+ public static function castUlid(Ulid $ulid, array $a, Stub $stub, bool $isNested)
+ {
+ $a[Caster::PREFIX_VIRTUAL.'toBase58'] = $ulid->toBase58();
+ $a[Caster::PREFIX_VIRTUAL.'toRfc4122'] = $ulid->toRfc4122();
+
+ // symfony/uid >= 5.3
+ if (method_exists($ulid, 'getDateTime')) {
+ $a[Caster::PREFIX_VIRTUAL.'time'] = $ulid->getDateTime()->format('Y-m-d H:i:s.v \U\T\C');
+ }
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/TraceStub.php b/vendor/symfony/var-dumper/Caster/TraceStub.php
new file mode 100644
index 0000000..5eea1c8
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/TraceStub.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 Symfony\Component\VarDumper\Caster;
+
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * Represents a backtrace as returned by debug_backtrace() or Exception->getTrace().
+ *
+ * @author Nicolas Grekas
+ */
+class TraceStub extends Stub
+{
+ public $keepArgs;
+ public $sliceOffset;
+ public $sliceLength;
+ public $numberingOffset;
+
+ public function __construct(array $trace, bool $keepArgs = true, int $sliceOffset = 0, int $sliceLength = null, int $numberingOffset = 0)
+ {
+ $this->value = $trace;
+ $this->keepArgs = $keepArgs;
+ $this->sliceOffset = $sliceOffset;
+ $this->sliceLength = $sliceLength;
+ $this->numberingOffset = $numberingOffset;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Caster/UuidCaster.php b/vendor/symfony/var-dumper/Caster/UuidCaster.php
new file mode 100644
index 0000000..b102774
--- /dev/null
+++ b/vendor/symfony/var-dumper/Caster/UuidCaster.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 Symfony\Component\VarDumper\Caster;
+
+use Ramsey\Uuid\UuidInterface;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * @author Grégoire Pineau
+ *
+ * @final
+ */
+class XmlResourceCaster
+{
+ private const XML_ERRORS = [
+ \XML_ERROR_NONE => 'XML_ERROR_NONE',
+ \XML_ERROR_NO_MEMORY => 'XML_ERROR_NO_MEMORY',
+ \XML_ERROR_SYNTAX => 'XML_ERROR_SYNTAX',
+ \XML_ERROR_NO_ELEMENTS => 'XML_ERROR_NO_ELEMENTS',
+ \XML_ERROR_INVALID_TOKEN => 'XML_ERROR_INVALID_TOKEN',
+ \XML_ERROR_UNCLOSED_TOKEN => 'XML_ERROR_UNCLOSED_TOKEN',
+ \XML_ERROR_PARTIAL_CHAR => 'XML_ERROR_PARTIAL_CHAR',
+ \XML_ERROR_TAG_MISMATCH => 'XML_ERROR_TAG_MISMATCH',
+ \XML_ERROR_DUPLICATE_ATTRIBUTE => 'XML_ERROR_DUPLICATE_ATTRIBUTE',
+ \XML_ERROR_JUNK_AFTER_DOC_ELEMENT => 'XML_ERROR_JUNK_AFTER_DOC_ELEMENT',
+ \XML_ERROR_PARAM_ENTITY_REF => 'XML_ERROR_PARAM_ENTITY_REF',
+ \XML_ERROR_UNDEFINED_ENTITY => 'XML_ERROR_UNDEFINED_ENTITY',
+ \XML_ERROR_RECURSIVE_ENTITY_REF => 'XML_ERROR_RECURSIVE_ENTITY_REF',
+ \XML_ERROR_ASYNC_ENTITY => 'XML_ERROR_ASYNC_ENTITY',
+ \XML_ERROR_BAD_CHAR_REF => 'XML_ERROR_BAD_CHAR_REF',
+ \XML_ERROR_BINARY_ENTITY_REF => 'XML_ERROR_BINARY_ENTITY_REF',
+ \XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF => 'XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF',
+ \XML_ERROR_MISPLACED_XML_PI => 'XML_ERROR_MISPLACED_XML_PI',
+ \XML_ERROR_UNKNOWN_ENCODING => 'XML_ERROR_UNKNOWN_ENCODING',
+ \XML_ERROR_INCORRECT_ENCODING => 'XML_ERROR_INCORRECT_ENCODING',
+ \XML_ERROR_UNCLOSED_CDATA_SECTION => 'XML_ERROR_UNCLOSED_CDATA_SECTION',
+ \XML_ERROR_EXTERNAL_ENTITY_HANDLING => 'XML_ERROR_EXTERNAL_ENTITY_HANDLING',
+ ];
+
+ public static function castXml($h, array $a, Stub $stub, bool $isNested)
+ {
+ $a['current_byte_index'] = xml_get_current_byte_index($h);
+ $a['current_column_number'] = xml_get_current_column_number($h);
+ $a['current_line_number'] = xml_get_current_line_number($h);
+ $a['error_code'] = xml_get_error_code($h);
+
+ if (isset(self::XML_ERRORS[$a['error_code']])) {
+ $a['error_code'] = new ConstStub(self::XML_ERRORS[$a['error_code']], $a['error_code']);
+ }
+
+ return $a;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Cloner/AbstractCloner.php b/vendor/symfony/var-dumper/Cloner/AbstractCloner.php
new file mode 100644
index 0000000..b835c03
--- /dev/null
+++ b/vendor/symfony/var-dumper/Cloner/AbstractCloner.php
@@ -0,0 +1,388 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+use Symfony\Component\VarDumper\Caster\Caster;
+use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
+
+/**
+ * AbstractCloner implements a generic caster mechanism for objects and resources.
+ *
+ * @author Nicolas Grekas
+ */
+abstract class AbstractCloner implements ClonerInterface
+{
+ public static $defaultCasters = [
+ '__PHP_Incomplete_Class' => ['Symfony\Component\VarDumper\Caster\Caster', 'castPhpIncompleteClass'],
+
+ 'Symfony\Component\VarDumper\Caster\CutStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'],
+ 'Symfony\Component\VarDumper\Caster\CutArrayStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castCutArray'],
+ 'Symfony\Component\VarDumper\Caster\ConstStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'],
+ 'Symfony\Component\VarDumper\Caster\EnumStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castEnum'],
+
+ 'Fiber' => ['Symfony\Component\VarDumper\Caster\FiberCaster', 'castFiber'],
+
+ 'Closure' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClosure'],
+ 'Generator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castGenerator'],
+ 'ReflectionType' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castType'],
+ 'ReflectionAttribute' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castAttribute'],
+ 'ReflectionGenerator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReflectionGenerator'],
+ 'ReflectionClass' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClass'],
+ 'ReflectionClassConstant' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClassConstant'],
+ 'ReflectionFunctionAbstract' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castFunctionAbstract'],
+ 'ReflectionMethod' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castMethod'],
+ 'ReflectionParameter' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castParameter'],
+ 'ReflectionProperty' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castProperty'],
+ 'ReflectionReference' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReference'],
+ 'ReflectionExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castExtension'],
+ 'ReflectionZendExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castZendExtension'],
+
+ 'Doctrine\Common\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'Doctrine\Common\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castCommonProxy'],
+ 'Doctrine\ORM\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castOrmProxy'],
+ 'Doctrine\ORM\PersistentCollection' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster', 'castPersistentCollection'],
+ 'Doctrine\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+
+ 'DOMException' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castException'],
+ 'DOMStringList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+ 'DOMNameList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+ 'DOMImplementation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castImplementation'],
+ 'DOMImplementationList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+ 'DOMNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNode'],
+ 'DOMNameSpaceNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNameSpaceNode'],
+ 'DOMDocument' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocument'],
+ 'DOMNodeList' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+ 'DOMNamedNodeMap' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLength'],
+ 'DOMCharacterData' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castCharacterData'],
+ 'DOMAttr' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castAttr'],
+ 'DOMElement' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castElement'],
+ 'DOMText' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castText'],
+ 'DOMTypeinfo' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castTypeinfo'],
+ 'DOMDomError' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDomError'],
+ 'DOMLocator' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castLocator'],
+ 'DOMDocumentType' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castDocumentType'],
+ 'DOMNotation' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castNotation'],
+ 'DOMEntity' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castEntity'],
+ 'DOMProcessingInstruction' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castProcessingInstruction'],
+ 'DOMXPath' => ['Symfony\Component\VarDumper\Caster\DOMCaster', 'castXPath'],
+
+ 'XMLReader' => ['Symfony\Component\VarDumper\Caster\XmlReaderCaster', 'castXmlReader'],
+
+ 'ErrorException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castErrorException'],
+ 'Exception' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castException'],
+ 'Error' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castError'],
+ 'Symfony\Bridge\Monolog\Logger' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'Symfony\Component\DependencyInjection\ContainerInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'Symfony\Component\EventDispatcher\EventDispatcherInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'Symfony\Component\HttpClient\AmpHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
+ 'Symfony\Component\HttpClient\CurlHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
+ 'Symfony\Component\HttpClient\NativeHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
+ 'Symfony\Component\HttpClient\Response\AmpResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
+ 'Symfony\Component\HttpClient\Response\CurlResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
+ 'Symfony\Component\HttpClient\Response\NativeResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
+ 'Symfony\Component\HttpFoundation\Request' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castRequest'],
+ 'Symfony\Component\Uid\Ulid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castUlid'],
+ 'Symfony\Component\Uid\Uuid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castUuid'],
+ 'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castThrowingCasterException'],
+ 'Symfony\Component\VarDumper\Caster\TraceStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castTraceStub'],
+ 'Symfony\Component\VarDumper\Caster\FrameStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castFrameStub'],
+ 'Symfony\Component\VarDumper\Cloner\AbstractCloner' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'Symfony\Component\ErrorHandler\Exception\SilencedErrorContext' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castSilencedErrorContext'],
+
+ 'Imagine\Image\ImageInterface' => ['Symfony\Component\VarDumper\Caster\ImagineCaster', 'castImage'],
+
+ 'Ramsey\Uuid\UuidInterface' => ['Symfony\Component\VarDumper\Caster\UuidCaster', 'castRamseyUuid'],
+
+ 'ProxyManager\Proxy\ProxyInterface' => ['Symfony\Component\VarDumper\Caster\ProxyManagerCaster', 'castProxy'],
+ 'PHPUnit_Framework_MockObject_MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'PHPUnit\Framework\MockObject\MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'PHPUnit\Framework\MockObject\Stub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'Prophecy\Prophecy\ProphecySubjectInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+ 'Mockery\MockInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
+
+ 'PDO' => ['Symfony\Component\VarDumper\Caster\PdoCaster', 'castPdo'],
+ 'PDOStatement' => ['Symfony\Component\VarDumper\Caster\PdoCaster', 'castPdoStatement'],
+
+ 'AMQPConnection' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castConnection'],
+ 'AMQPChannel' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castChannel'],
+ 'AMQPQueue' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castQueue'],
+ 'AMQPExchange' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castExchange'],
+ 'AMQPEnvelope' => ['Symfony\Component\VarDumper\Caster\AmqpCaster', 'castEnvelope'],
+
+ 'ArrayObject' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castArrayObject'],
+ 'ArrayIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castArrayIterator'],
+ 'SplDoublyLinkedList' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castDoublyLinkedList'],
+ 'SplFileInfo' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFileInfo'],
+ 'SplFileObject' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castFileObject'],
+ 'SplHeap' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'],
+ 'SplObjectStorage' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castObjectStorage'],
+ 'SplPriorityQueue' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castHeap'],
+ 'OuterIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castOuterIterator'],
+ 'WeakReference' => ['Symfony\Component\VarDumper\Caster\SplCaster', 'castWeakReference'],
+
+ 'Redis' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedis'],
+ 'RedisArray' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisArray'],
+ 'RedisCluster' => ['Symfony\Component\VarDumper\Caster\RedisCaster', 'castRedisCluster'],
+
+ 'DateTimeInterface' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castDateTime'],
+ 'DateInterval' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castInterval'],
+ 'DateTimeZone' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castTimeZone'],
+ 'DatePeriod' => ['Symfony\Component\VarDumper\Caster\DateCaster', 'castPeriod'],
+
+ 'GMP' => ['Symfony\Component\VarDumper\Caster\GmpCaster', 'castGmp'],
+
+ 'MessageFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castMessageFormatter'],
+ 'NumberFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castNumberFormatter'],
+ 'IntlTimeZone' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlTimeZone'],
+ 'IntlCalendar' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlCalendar'],
+ 'IntlDateFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster', 'castIntlDateFormatter'],
+
+ 'Memcached' => ['Symfony\Component\VarDumper\Caster\MemcachedCaster', 'castMemcached'],
+
+ 'Ds\Collection' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castCollection'],
+ 'Ds\Map' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castMap'],
+ 'Ds\Pair' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPair'],
+ 'Symfony\Component\VarDumper\Caster\DsPairStub' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPairStub'],
+
+ 'mysqli_driver' => ['Symfony\Component\VarDumper\Caster\MysqliCaster', 'castMysqliDriver'],
+
+ 'CurlHandle' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'],
+
+ ':dba' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'],
+ ':dba persistent' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'],
+
+ 'GdImage' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'],
+ ':gd' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castGd'],
+
+ ':mysql link' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castMysqlLink'],
+ ':pgsql large object' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLargeObject'],
+ ':pgsql link' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'],
+ ':pgsql link persistent' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castLink'],
+ ':pgsql result' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster', 'castResult'],
+ ':process' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castProcess'],
+ ':stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'],
+
+ 'OpenSSLCertificate' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'],
+ ':OpenSSL X.509' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castOpensslX509'],
+
+ ':persistent stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStream'],
+ ':stream-context' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castStreamContext'],
+
+ 'XmlParser' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'],
+ ':xml' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster', 'castXml'],
+
+ 'RdKafka' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castRdKafka'],
+ 'RdKafka\Conf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castConf'],
+ 'RdKafka\KafkaConsumer' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castKafkaConsumer'],
+ 'RdKafka\Metadata\Broker' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castBrokerMetadata'],
+ 'RdKafka\Metadata\Collection' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castCollectionMetadata'],
+ 'RdKafka\Metadata\Partition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castPartitionMetadata'],
+ 'RdKafka\Metadata\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicMetadata'],
+ 'RdKafka\Message' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castMessage'],
+ 'RdKafka\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopic'],
+ 'RdKafka\TopicPartition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicPartition'],
+ 'RdKafka\TopicConf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster', 'castTopicConf'],
+ ];
+
+ protected $maxItems = 2500;
+ protected $maxString = -1;
+ protected $minDepth = 1;
+
+ /**
+ * @var array
+ */
+interface ClonerInterface
+{
+ /**
+ * Clones a PHP variable.
+ */
+ public function cloneVar(mixed $var): Data;
+}
diff --git a/vendor/symfony/var-dumper/Cloner/Cursor.php b/vendor/symfony/var-dumper/Cloner/Cursor.php
new file mode 100644
index 0000000..1fd796d
--- /dev/null
+++ b/vendor/symfony/var-dumper/Cloner/Cursor.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * Represents the current state of a dumper while dumping.
+ *
+ * @author Nicolas Grekas
+ */
+class Cursor
+{
+ public const HASH_INDEXED = Stub::ARRAY_INDEXED;
+ public const HASH_ASSOC = Stub::ARRAY_ASSOC;
+ public const HASH_OBJECT = Stub::TYPE_OBJECT;
+ public const HASH_RESOURCE = Stub::TYPE_RESOURCE;
+
+ public $depth = 0;
+ public $refIndex = 0;
+ public $softRefTo = 0;
+ public $softRefCount = 0;
+ public $softRefHandle = 0;
+ public $hardRefTo = 0;
+ public $hardRefCount = 0;
+ public $hardRefHandle = 0;
+ public $hashType;
+ public $hashKey;
+ public $hashKeyIsBinary;
+ public $hashIndex = 0;
+ public $hashLength = 0;
+ public $hashCut = 0;
+ public $stop = false;
+ public $attr = [];
+ public $skipChildren = false;
+}
diff --git a/vendor/symfony/var-dumper/Cloner/Data.php b/vendor/symfony/var-dumper/Cloner/Data.php
new file mode 100644
index 0000000..6ecb883
--- /dev/null
+++ b/vendor/symfony/var-dumper/Cloner/Data.php
@@ -0,0 +1,422 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+use Symfony\Component\VarDumper\Caster\Caster;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
+
+/**
+ * @author Nicolas Grekas
+ */
+class Data implements \ArrayAccess, \Countable, \IteratorAggregate
+{
+ private array $data;
+ private int $position = 0;
+ private int|string $key = 0;
+ private int $maxDepth = 20;
+ private int $maxItemsPerDepth = -1;
+ private int $useRefHandles = -1;
+ private array $context = [];
+
+ /**
+ * @param array $data An array as returned by ClonerInterface::cloneVar()
+ */
+ public function __construct(array $data)
+ {
+ $this->data = $data;
+ }
+
+ public function getType(): ?string
+ {
+ $item = $this->data[$this->position][$this->key];
+
+ if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) {
+ $item = $item->value;
+ }
+ if (!$item instanceof Stub) {
+ return \gettype($item);
+ }
+ if (Stub::TYPE_STRING === $item->type) {
+ return 'string';
+ }
+ if (Stub::TYPE_ARRAY === $item->type) {
+ return 'array';
+ }
+ if (Stub::TYPE_OBJECT === $item->type) {
+ return $item->class;
+ }
+ if (Stub::TYPE_RESOURCE === $item->type) {
+ return $item->class.' resource';
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a native representation of the original value.
+ *
+ * @param array|bool $recursive Whether values should be resolved recursively or not
+ *
+ * @return string|int|float|bool|array|Data[]|null
+ */
+ public function getValue(array|bool $recursive = false): string|int|float|bool|array|null
+ {
+ $item = $this->data[$this->position][$this->key];
+
+ if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) {
+ $item = $item->value;
+ }
+ if (!($item = $this->getStub($item)) instanceof Stub) {
+ return $item;
+ }
+ if (Stub::TYPE_STRING === $item->type) {
+ return $item->value;
+ }
+
+ $children = $item->position ? $this->data[$item->position] : [];
+
+ foreach ($children as $k => $v) {
+ if ($recursive && !($v = $this->getStub($v)) instanceof Stub) {
+ continue;
+ }
+ $children[$k] = clone $this;
+ $children[$k]->key = $k;
+ $children[$k]->position = $item->position;
+
+ if ($recursive) {
+ if (Stub::TYPE_REF === $v->type && ($v = $this->getStub($v->value)) instanceof Stub) {
+ $recursive = (array) $recursive;
+ if (isset($recursive[$v->position])) {
+ continue;
+ }
+ $recursive[$v->position] = true;
+ }
+ $children[$k] = $children[$k]->getValue($recursive);
+ }
+ }
+
+ return $children;
+ }
+
+ public function count(): int
+ {
+ return \count($this->getValue());
+ }
+
+ public function getIterator(): \Traversable
+ {
+ if (!\is_array($value = $this->getValue())) {
+ throw new \LogicException(sprintf('"%s" object holds non-iterable type "%s".', self::class, get_debug_type($value)));
+ }
+
+ yield from $value;
+ }
+
+ public function __get(string $key)
+ {
+ if (null !== $data = $this->seek($key)) {
+ $item = $this->getStub($data->data[$data->position][$data->key]);
+
+ return $item instanceof Stub || [] === $item ? $data : $item;
+ }
+
+ return null;
+ }
+
+ public function __isset(string $key): bool
+ {
+ return null !== $this->seek($key);
+ }
+
+ public function offsetExists(mixed $key): bool
+ {
+ return $this->__isset($key);
+ }
+
+ public function offsetGet(mixed $key): mixed
+ {
+ return $this->__get($key);
+ }
+
+ public function offsetSet(mixed $key, mixed $value): void
+ {
+ throw new \BadMethodCallException(self::class.' objects are immutable.');
+ }
+
+ public function offsetUnset(mixed $key): void
+ {
+ throw new \BadMethodCallException(self::class.' objects are immutable.');
+ }
+
+ public function __toString(): string
+ {
+ $value = $this->getValue();
+
+ if (!\is_array($value)) {
+ return (string) $value;
+ }
+
+ return sprintf('%s (count=%d)', $this->getType(), \count($value));
+ }
+
+ /**
+ * Returns a depth limited clone of $this.
+ */
+ public function withMaxDepth(int $maxDepth): static
+ {
+ $data = clone $this;
+ $data->maxDepth = $maxDepth;
+
+ return $data;
+ }
+
+ /**
+ * Limits the number of elements per depth level.
+ */
+ public function withMaxItemsPerDepth(int $maxItemsPerDepth): static
+ {
+ $data = clone $this;
+ $data->maxItemsPerDepth = $maxItemsPerDepth;
+
+ return $data;
+ }
+
+ /**
+ * Enables/disables objects' identifiers tracking.
+ *
+ * @param bool $useRefHandles False to hide global ref. handles
+ */
+ public function withRefHandles(bool $useRefHandles): static
+ {
+ $data = clone $this;
+ $data->useRefHandles = $useRefHandles ? -1 : 0;
+
+ return $data;
+ }
+
+ public function withContext(array $context): static
+ {
+ $data = clone $this;
+ $data->context = $context;
+
+ return $data;
+ }
+
+ /**
+ * Seeks to a specific key in nested data structures.
+ */
+ public function seek(string|int $key): ?static
+ {
+ $item = $this->data[$this->position][$this->key];
+
+ if ($item instanceof Stub && Stub::TYPE_REF === $item->type && !$item->position) {
+ $item = $item->value;
+ }
+ if (!($item = $this->getStub($item)) instanceof Stub || !$item->position) {
+ return null;
+ }
+ $keys = [$key];
+
+ switch ($item->type) {
+ case Stub::TYPE_OBJECT:
+ $keys[] = Caster::PREFIX_DYNAMIC.$key;
+ $keys[] = Caster::PREFIX_PROTECTED.$key;
+ $keys[] = Caster::PREFIX_VIRTUAL.$key;
+ $keys[] = "\0$item->class\0$key";
+ // no break
+ case Stub::TYPE_ARRAY:
+ case Stub::TYPE_RESOURCE:
+ break;
+ default:
+ return null;
+ }
+
+ $data = null;
+ $children = $this->data[$item->position];
+
+ foreach ($keys as $key) {
+ if (isset($children[$key]) || \array_key_exists($key, $children)) {
+ $data = clone $this;
+ $data->key = $key;
+ $data->position = $item->position;
+ break;
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Dumps data with a DumperInterface dumper.
+ */
+ public function dump(DumperInterface $dumper)
+ {
+ $refs = [0];
+ $cursor = new Cursor();
+
+ if ($cursor->attr = $this->context[SourceContextProvider::class] ?? []) {
+ $cursor->attr['if_links'] = true;
+ $cursor->hashType = -1;
+ $dumper->dumpScalar($cursor, 'default', '^');
+ $cursor->attr = ['if_links' => true];
+ $dumper->dumpScalar($cursor, 'default', ' ');
+ $cursor->hashType = 0;
+ }
+
+ $this->dumpItem($dumper, $cursor, $refs, $this->data[$this->position][$this->key]);
+ }
+
+ /**
+ * Depth-first dumping of items.
+ *
+ * @param mixed $item A Stub object or the original value being dumped
+ */
+ private function dumpItem(DumperInterface $dumper, Cursor $cursor, array &$refs, mixed $item)
+ {
+ $cursor->refIndex = 0;
+ $cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0;
+ $cursor->hardRefTo = $cursor->hardRefHandle = $cursor->hardRefCount = 0;
+ $firstSeen = true;
+
+ if (!$item instanceof Stub) {
+ $cursor->attr = [];
+ $type = \gettype($item);
+ if ($item && 'array' === $type) {
+ $item = $this->getStub($item);
+ }
+ } elseif (Stub::TYPE_REF === $item->type) {
+ if ($item->handle) {
+ if (!isset($refs[$r = $item->handle - (\PHP_INT_MAX >> 1)])) {
+ $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0];
+ } else {
+ $firstSeen = false;
+ }
+ $cursor->hardRefTo = $refs[$r];
+ $cursor->hardRefHandle = $this->useRefHandles & $item->handle;
+ $cursor->hardRefCount = 0 < $item->handle ? $item->refCount : 0;
+ }
+ $cursor->attr = $item->attr;
+ $type = $item->class ?: \gettype($item->value);
+ $item = $this->getStub($item->value);
+ }
+ if ($item instanceof Stub) {
+ if ($item->refCount) {
+ if (!isset($refs[$r = $item->handle])) {
+ $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0];
+ } else {
+ $firstSeen = false;
+ }
+ $cursor->softRefTo = $refs[$r];
+ }
+ $cursor->softRefHandle = $this->useRefHandles & $item->handle;
+ $cursor->softRefCount = $item->refCount;
+ $cursor->attr = $item->attr;
+ $cut = $item->cut;
+
+ if ($item->position && $firstSeen) {
+ $children = $this->data[$item->position];
+
+ if ($cursor->stop) {
+ if ($cut >= 0) {
+ $cut += \count($children);
+ }
+ $children = [];
+ }
+ } else {
+ $children = [];
+ }
+ switch ($item->type) {
+ case Stub::TYPE_STRING:
+ $dumper->dumpString($cursor, $item->value, Stub::STRING_BINARY === $item->class, $cut);
+ break;
+
+ case Stub::TYPE_ARRAY:
+ $item = clone $item;
+ $item->type = $item->class;
+ $item->class = $item->value;
+ // no break
+ case Stub::TYPE_OBJECT:
+ case Stub::TYPE_RESOURCE:
+ $withChildren = $children && $cursor->depth !== $this->maxDepth && $this->maxItemsPerDepth;
+ $dumper->enterHash($cursor, $item->type, $item->class, $withChildren);
+ if ($withChildren) {
+ if ($cursor->skipChildren) {
+ $withChildren = false;
+ $cut = -1;
+ } else {
+ $cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type, null !== $item->class);
+ }
+ } elseif ($children && 0 <= $cut) {
+ $cut += \count($children);
+ }
+ $cursor->skipChildren = false;
+ $dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut);
+ break;
+
+ default:
+ throw new \RuntimeException(sprintf('Unexpected Stub type: "%s".', $item->type));
+ }
+ } elseif ('array' === $type) {
+ $dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false);
+ $dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0);
+ } elseif ('string' === $type) {
+ $dumper->dumpString($cursor, $item, false, 0);
+ } else {
+ $dumper->dumpScalar($cursor, $type, $item);
+ }
+ }
+
+ /**
+ * Dumps children of hash structures.
+ *
+ * @return int The final number of removed items
+ */
+ private function dumpChildren(DumperInterface $dumper, Cursor $parentCursor, array &$refs, array $children, int $hashCut, int $hashType, bool $dumpKeys): int
+ {
+ $cursor = clone $parentCursor;
+ ++$cursor->depth;
+ $cursor->hashType = $hashType;
+ $cursor->hashIndex = 0;
+ $cursor->hashLength = \count($children);
+ $cursor->hashCut = $hashCut;
+ foreach ($children as $key => $child) {
+ $cursor->hashKeyIsBinary = isset($key[0]) && !preg_match('//u', $key);
+ $cursor->hashKey = $dumpKeys ? $key : null;
+ $this->dumpItem($dumper, $cursor, $refs, $child);
+ if (++$cursor->hashIndex === $this->maxItemsPerDepth || $cursor->stop) {
+ $parentCursor->stop = true;
+
+ return $hashCut >= 0 ? $hashCut + $cursor->hashLength - $cursor->hashIndex : $hashCut;
+ }
+ }
+
+ return $hashCut;
+ }
+
+ private function getStub(mixed $item)
+ {
+ if (!$item || !\is_array($item)) {
+ return $item;
+ }
+
+ $stub = new Stub();
+ $stub->type = Stub::TYPE_ARRAY;
+ foreach ($item as $stub->class => $stub->position) {
+ }
+ if (isset($item[0])) {
+ $stub->cut = $item[0];
+ }
+ $stub->value = $stub->cut + ($stub->position ? \count($this->data[$stub->position]) : 0);
+
+ return $stub;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Cloner/DumperInterface.php b/vendor/symfony/var-dumper/Cloner/DumperInterface.php
new file mode 100644
index 0000000..61d02d2
--- /dev/null
+++ b/vendor/symfony/var-dumper/Cloner/DumperInterface.php
@@ -0,0 +1,53 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * DumperInterface used by Data objects.
+ *
+ * @author Nicolas Grekas
+ */
+interface DumperInterface
+{
+ /**
+ * Dumps a scalar value.
+ */
+ public function dumpScalar(Cursor $cursor, string $type, string|int|float|bool|null $value);
+
+ /**
+ * Dumps a string.
+ *
+ * @param string $str The string being dumped
+ * @param bool $bin Whether $str is UTF-8 or binary encoded
+ * @param int $cut The number of characters $str has been cut by
+ */
+ public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut);
+
+ /**
+ * Dumps while entering an hash.
+ *
+ * @param int $type A Cursor::HASH_* const for the type of hash
+ * @param string|int|null $class The object class, resource type or array count
+ * @param bool $hasChild When the dump of the hash has child item
+ */
+ public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild);
+
+ /**
+ * Dumps while leaving an hash.
+ *
+ * @param int $type A Cursor::HASH_* const for the type of hash
+ * @param string|int|null $class The object class, resource type or array count
+ * @param bool $hasChild When the dump of the hash has child item
+ * @param int $cut The number of items the hash has been cut by
+ */
+ public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut);
+}
diff --git a/vendor/symfony/var-dumper/Cloner/Stub.php b/vendor/symfony/var-dumper/Cloner/Stub.php
new file mode 100644
index 0000000..1c5b887
--- /dev/null
+++ b/vendor/symfony/var-dumper/Cloner/Stub.php
@@ -0,0 +1,67 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * Represents the main properties of a PHP variable.
+ *
+ * @author Nicolas Grekas
+ */
+class Stub
+{
+ public const TYPE_REF = 1;
+ public const TYPE_STRING = 2;
+ public const TYPE_ARRAY = 3;
+ public const TYPE_OBJECT = 4;
+ public const TYPE_RESOURCE = 5;
+
+ public const STRING_BINARY = 1;
+ public const STRING_UTF8 = 2;
+
+ public const ARRAY_ASSOC = 1;
+ public const ARRAY_INDEXED = 2;
+
+ public $type = self::TYPE_REF;
+ public $class = '';
+ public $value;
+ public $cut = 0;
+ public $handle = 0;
+ public $refCount = 0;
+ public $position = 0;
+ public $attr = [];
+
+ private static array $defaultProperties = [];
+
+ /**
+ * @internal
+ */
+ public function __sleep(): array
+ {
+ $properties = [];
+
+ if (!isset(self::$defaultProperties[$c = static::class])) {
+ self::$defaultProperties[$c] = get_class_vars($c);
+
+ foreach ((new \ReflectionClass($c))->getStaticProperties() as $k => $v) {
+ unset(self::$defaultProperties[$c][$k]);
+ }
+ }
+
+ foreach (self::$defaultProperties[$c] as $k => $v) {
+ if ($this->$k !== $v) {
+ $properties[] = $k;
+ }
+ }
+
+ return $properties;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Cloner/VarCloner.php b/vendor/symfony/var-dumper/Cloner/VarCloner.php
new file mode 100644
index 0000000..9afcc34
--- /dev/null
+++ b/vendor/symfony/var-dumper/Cloner/VarCloner.php
@@ -0,0 +1,286 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Cloner;
+
+/**
+ * @author Nicolas Grekas
+ */
+class VarCloner extends AbstractCloner
+{
+ private static string $gid;
+ private static array $arrayCache = [];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doClone(mixed $var): array
+ {
+ $len = 1; // Length of $queue
+ $pos = 0; // Number of cloned items past the minimum depth
+ $refsCounter = 0; // Hard references counter
+ $queue = [[$var]]; // This breadth-first queue is the return value
+ $hardRefs = []; // Map of original zval ids to stub objects
+ $objRefs = []; // Map of original object handles to their stub object counterpart
+ $objects = []; // Keep a ref to objects to ensure their handle cannot be reused while cloning
+ $resRefs = []; // Map of original resource handles to their stub object counterpart
+ $values = []; // Map of stub objects' ids to original values
+ $maxItems = $this->maxItems;
+ $maxString = $this->maxString;
+ $minDepth = $this->minDepth;
+ $currentDepth = 0; // Current tree depth
+ $currentDepthFinalIndex = 0; // Final $queue index for current tree depth
+ $minimumDepthReached = 0 === $minDepth; // Becomes true when minimum tree depth has been reached
+ $cookie = (object) []; // Unique object used to detect hard references
+ $a = null; // Array cast for nested structures
+ $stub = null; // Stub capturing the main properties of an original item value
+ // or null if the original value is used directly
+
+ $gid = self::$gid ??= md5(random_bytes(6)); // Unique string used to detect the special $GLOBALS variable
+ $arrayStub = new Stub();
+ $arrayStub->type = Stub::TYPE_ARRAY;
+ $fromObjCast = false;
+
+ for ($i = 0; $i < $len; ++$i) {
+ // Detect when we move on to the next tree depth
+ if ($i > $currentDepthFinalIndex) {
+ ++$currentDepth;
+ $currentDepthFinalIndex = $len - 1;
+ if ($currentDepth >= $minDepth) {
+ $minimumDepthReached = true;
+ }
+ }
+
+ $refs = $vals = $queue[$i];
+ foreach ($vals as $k => $v) {
+ // $v is the original value or a stub object in case of hard references
+
+ $zvalRef = ($r = \ReflectionReference::fromArrayElement($vals, $k)) ? $r->getId() : null;
+
+ if ($zvalRef) {
+ $vals[$k] = &$stub; // Break hard references to make $queue completely
+ unset($stub); // independent from the original structure
+ if (null !== $vals[$k] = $hardRefs[$zvalRef] ?? null) {
+ $v = $vals[$k];
+ if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
+ ++$v->value->refCount;
+ }
+ ++$v->refCount;
+ continue;
+ }
+ $vals[$k] = new Stub();
+ $vals[$k]->value = $v;
+ $vals[$k]->handle = ++$refsCounter;
+ $hardRefs[$zvalRef] = $vals[$k];
+ }
+ // Create $stub when the original value $v cannot be used directly
+ // If $v is a nested structure, put that structure in array $a
+ switch (true) {
+ case null === $v:
+ case \is_bool($v):
+ case \is_int($v):
+ case \is_float($v):
+ continue 2;
+ case \is_string($v):
+ if ('' === $v) {
+ continue 2;
+ }
+ if (!preg_match('//u', $v)) {
+ $stub = new Stub();
+ $stub->type = Stub::TYPE_STRING;
+ $stub->class = Stub::STRING_BINARY;
+ if (0 <= $maxString && 0 < $cut = \strlen($v) - $maxString) {
+ $stub->cut = $cut;
+ $stub->value = substr($v, 0, -$cut);
+ } else {
+ $stub->value = $v;
+ }
+ } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = mb_strlen($v, 'UTF-8') - $maxString) {
+ $stub = new Stub();
+ $stub->type = Stub::TYPE_STRING;
+ $stub->class = Stub::STRING_UTF8;
+ $stub->cut = $cut;
+ $stub->value = mb_substr($v, 0, $maxString, 'UTF-8');
+ } else {
+ continue 2;
+ }
+ $a = null;
+ break;
+
+ case \is_array($v):
+ if (!$v) {
+ continue 2;
+ }
+ $stub = $arrayStub;
+
+ if (\PHP_VERSION_ID >= 80100) {
+ $stub->class = array_is_list($v) ? Stub::ARRAY_INDEXED : Stub::ARRAY_ASSOC;
+ $a = $v;
+ break;
+ }
+
+ $stub->class = Stub::ARRAY_INDEXED;
+
+ $j = -1;
+ foreach ($v as $gk => $gv) {
+ if ($gk !== ++$j) {
+ $stub->class = Stub::ARRAY_ASSOC;
+ $a = $v;
+ $a[$gid] = true;
+ break;
+ }
+ }
+
+ // Copies of $GLOBALS have very strange behavior,
+ // let's detect them with some black magic
+ if (isset($v[$gid])) {
+ unset($v[$gid]);
+ $a = [];
+ foreach ($v as $gk => &$gv) {
+ if ($v === $gv && !isset($hardRefs[\ReflectionReference::fromArrayElement($v, $gk)->getId()])) {
+ unset($v);
+ $v = new Stub();
+ $v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0];
+ $v->handle = -1;
+ $gv = &$a[$gk];
+ $hardRefs[\ReflectionReference::fromArrayElement($a, $gk)->getId()] = &$gv;
+ $gv = $v;
+ }
+
+ $a[$gk] = &$gv;
+ }
+ unset($gv);
+ } else {
+ $a = $v;
+ }
+ break;
+
+ case \is_object($v):
+ if (empty($objRefs[$h = spl_object_id($v)])) {
+ $stub = new Stub();
+ $stub->type = Stub::TYPE_OBJECT;
+ $stub->class = \get_class($v);
+ $stub->value = $v;
+ $stub->handle = $h;
+ $a = $this->castObject($stub, 0 < $i);
+ if ($v !== $stub->value) {
+ if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) {
+ break;
+ }
+ $stub->handle = $h = spl_object_id($stub->value);
+ }
+ $stub->value = null;
+ if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) {
+ $stub->cut = \count($a);
+ $a = null;
+ }
+ }
+ if (empty($objRefs[$h])) {
+ $objRefs[$h] = $stub;
+ $objects[] = $v;
+ } else {
+ $stub = $objRefs[$h];
+ ++$stub->refCount;
+ $a = null;
+ }
+ break;
+
+ default: // resource
+ if (empty($resRefs[$h = (int) $v])) {
+ $stub = new Stub();
+ $stub->type = Stub::TYPE_RESOURCE;
+ if ('Unknown' === $stub->class = @get_resource_type($v)) {
+ $stub->class = 'Closed';
+ }
+ $stub->value = $v;
+ $stub->handle = $h;
+ $a = $this->castResource($stub, 0 < $i);
+ $stub->value = null;
+ if (0 <= $maxItems && $maxItems <= $pos && $minimumDepthReached) {
+ $stub->cut = \count($a);
+ $a = null;
+ }
+ }
+ if (empty($resRefs[$h])) {
+ $resRefs[$h] = $stub;
+ } else {
+ $stub = $resRefs[$h];
+ ++$stub->refCount;
+ $a = null;
+ }
+ break;
+ }
+
+ if ($a) {
+ if (!$minimumDepthReached || 0 > $maxItems) {
+ $queue[$len] = $a;
+ $stub->position = $len++;
+ } elseif ($pos < $maxItems) {
+ if ($maxItems < $pos += \count($a)) {
+ $a = \array_slice($a, 0, $maxItems - $pos, true);
+ if ($stub->cut >= 0) {
+ $stub->cut += $pos - $maxItems;
+ }
+ }
+ $queue[$len] = $a;
+ $stub->position = $len++;
+ } elseif ($stub->cut >= 0) {
+ $stub->cut += \count($a);
+ $stub->position = 0;
+ }
+ }
+
+ if ($arrayStub === $stub) {
+ if ($arrayStub->cut) {
+ $stub = [$arrayStub->cut, $arrayStub->class => $arrayStub->position];
+ $arrayStub->cut = 0;
+ } elseif (isset(self::$arrayCache[$arrayStub->class][$arrayStub->position])) {
+ $stub = self::$arrayCache[$arrayStub->class][$arrayStub->position];
+ } else {
+ self::$arrayCache[$arrayStub->class][$arrayStub->position] = $stub = [$arrayStub->class => $arrayStub->position];
+ }
+ }
+
+ if (!$zvalRef) {
+ $vals[$k] = $stub;
+ } else {
+ $hardRefs[$zvalRef]->value = $stub;
+ }
+ }
+
+ if ($fromObjCast) {
+ $fromObjCast = false;
+ $refs = $vals;
+ $vals = [];
+ $j = -1;
+ foreach ($queue[$i] as $k => $v) {
+ foreach ([$k => true] as $gk => $gv) {
+ }
+ if ($gk !== $k) {
+ $vals = (object) $vals;
+ $vals->{$k} = $refs[++$j];
+ $vals = (array) $vals;
+ } else {
+ $vals[$k] = $refs[++$j];
+ }
+ }
+ }
+
+ $queue[$i] = $vals;
+ }
+
+ foreach ($values as $h => $v) {
+ $hardRefs[$h] = $v;
+ }
+
+ return $queue;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php b/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php
new file mode 100644
index 0000000..e3d5f1d
--- /dev/null
+++ b/vendor/symfony/var-dumper/Command/Descriptor/CliDescriptor.php
@@ -0,0 +1,79 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Command\Descriptor;
+
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\CliDumper;
+
+/**
+ * Describe collected data clones for cli output.
+ *
+ * @author Maxime Steinhausser
+ $sourceDescription
+
+ */
+abstract class AbstractDumper implements DataDumperInterface, DumperInterface
+{
+ public const DUMP_LIGHT_ARRAY = 1;
+ public const DUMP_STRING_LENGTH = 2;
+ public const DUMP_COMMA_SEPARATOR = 4;
+ public const DUMP_TRAILING_COMMA = 8;
+
+ public static $defaultOutput = 'php://output';
+
+ protected $line = '';
+ protected $lineDumper;
+ protected $outputStream;
+ protected $decimalPoint = '.';
+ protected $indentPad = ' ';
+ protected $flags;
+
+ private string $charset = '';
+
+ /**
+ * @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput
+ * @param string|null $charset The default character encoding to use for non-UTF8 strings
+ * @param int $flags A bit field of static::DUMP_* constants to fine tune dumps representation
+ */
+ public function __construct($output = null, string $charset = null, int $flags = 0)
+ {
+ $this->flags = $flags;
+ $this->setCharset($charset ?: \ini_get('php.output_encoding') ?: \ini_get('default_charset') ?: 'UTF-8');
+ $this->setOutput($output ?: static::$defaultOutput);
+ if (!$output && \is_string(static::$defaultOutput)) {
+ static::$defaultOutput = $this->outputStream;
+ }
+ }
+
+ /**
+ * Sets the output destination of the dumps.
+ *
+ * @param callable|resource|string $output A line dumper callable, an opened stream or an output path
+ *
+ * @return callable|resource|string The previous output destination
+ */
+ public function setOutput($output)
+ {
+ $prev = $this->outputStream ?? $this->lineDumper;
+
+ if (\is_callable($output)) {
+ $this->outputStream = null;
+ $this->lineDumper = $output;
+ } else {
+ if (\is_string($output)) {
+ $output = fopen($output, 'w');
+ }
+ $this->outputStream = $output;
+ $this->lineDumper = [$this, 'echoLine'];
+ }
+
+ return $prev;
+ }
+
+ /**
+ * Sets the default character encoding to use for non-UTF8 strings.
+ *
+ * @return string The previous charset
+ */
+ public function setCharset(string $charset): string
+ {
+ $prev = $this->charset;
+
+ $charset = strtoupper($charset);
+ $charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset;
+
+ $this->charset = $charset;
+
+ return $prev;
+ }
+
+ /**
+ * Sets the indentation pad string.
+ *
+ * @param string $pad A string that will be prepended to dumped lines, repeated by nesting level
+ *
+ * @return string The previous indent pad
+ */
+ public function setIndentPad(string $pad): string
+ {
+ $prev = $this->indentPad;
+ $this->indentPad = $pad;
+
+ return $prev;
+ }
+
+ /**
+ * Dumps a Data object.
+ *
+ * @param callable|resource|string|true|null $output A line dumper callable, an opened stream, an output path or true to return the dump
+ *
+ * @return string|null The dump as string when $output is true
+ */
+ public function dump(Data $data, $output = null): ?string
+ {
+ if ($locale = $this->flags & (self::DUMP_COMMA_SEPARATOR | self::DUMP_TRAILING_COMMA) ? setlocale(\LC_NUMERIC, 0) : null) {
+ setlocale(\LC_NUMERIC, 'C');
+ }
+
+ if ($returnDump = true === $output) {
+ $output = fopen('php://memory', 'r+');
+ }
+ if ($output) {
+ $prevOutput = $this->setOutput($output);
+ }
+ try {
+ $data->dump($this);
+ $this->dumpLine(-1);
+
+ if ($returnDump) {
+ $result = stream_get_contents($output, -1, 0);
+ fclose($output);
+
+ return $result;
+ }
+ } finally {
+ if ($output) {
+ $this->setOutput($prevOutput);
+ }
+ if ($locale) {
+ setlocale(\LC_NUMERIC, $locale);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Dumps the current line.
+ *
+ * @param int $depth The recursive depth in the dumped structure for the line being dumped,
+ * or -1 to signal the end-of-dump to the line dumper callable
+ */
+ protected function dumpLine(int $depth)
+ {
+ ($this->lineDumper)($this->line, $depth, $this->indentPad);
+ $this->line = '';
+ }
+
+ /**
+ * Generic line dumper callback.
+ */
+ protected function echoLine(string $line, int $depth, string $indentPad)
+ {
+ if (-1 !== $depth) {
+ fwrite($this->outputStream, str_repeat($indentPad, $depth).$line."\n");
+ }
+ }
+
+ /**
+ * Converts a non-UTF-8 string to UTF-8.
+ */
+ protected function utf8Encode(?string $s): ?string
+ {
+ if (null === $s || preg_match('//u', $s)) {
+ return $s;
+ }
+
+ if (!\function_exists('iconv')) {
+ throw new \RuntimeException('Unable to convert a non-UTF-8 string to UTF-8: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.');
+ }
+
+ if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) {
+ return $c;
+ }
+ if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) {
+ return $c;
+ }
+
+ return iconv('CP850', 'UTF-8', $s);
+ }
+}
diff --git a/vendor/symfony/var-dumper/Dumper/CliDumper.php b/vendor/symfony/var-dumper/Dumper/CliDumper.php
new file mode 100644
index 0000000..065b918
--- /dev/null
+++ b/vendor/symfony/var-dumper/Dumper/CliDumper.php
@@ -0,0 +1,643 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Cursor;
+use Symfony\Component\VarDumper\Cloner\Stub;
+
+/**
+ * CliDumper dumps variables for command line output.
+ *
+ * @author Nicolas Grekas
+ */
+class CliDumper extends AbstractDumper
+{
+ public static $defaultColors;
+ public static $defaultOutput = 'php://stdout';
+
+ protected $colors;
+ protected $maxStringWidth = 0;
+ protected $styles = [
+ // See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+ 'default' => '0;38;5;208',
+ 'num' => '1;38;5;38',
+ 'const' => '1;38;5;208',
+ 'str' => '1;38;5;113',
+ 'note' => '38;5;38',
+ 'ref' => '38;5;247',
+ 'public' => '',
+ 'protected' => '',
+ 'private' => '',
+ 'meta' => '38;5;170',
+ 'key' => '38;5;113',
+ 'index' => '38;5;38',
+ ];
+
+ protected static $controlCharsRx = '/[\x00-\x1F\x7F]+/';
+ protected static $controlCharsMap = [
+ "\t" => '\t',
+ "\n" => '\n',
+ "\v" => '\v',
+ "\f" => '\f',
+ "\r" => '\r',
+ "\033" => '\e',
+ ];
+
+ protected $collapseNextHash = false;
+ protected $expandNextHash = false;
+
+ private array $displayOptions = [
+ 'fileLinkFormat' => null,
+ ];
+
+ private bool $handlesHrefGracefully;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($output = null, string $charset = null, int $flags = 0)
+ {
+ parent::__construct($output, $charset, $flags);
+
+ if ('\\' === \DIRECTORY_SEPARATOR && !$this->isWindowsTrueColor()) {
+ // Use only the base 16 xterm colors when using ANSICON or standard Windows 10 CLI
+ $this->setStyles([
+ 'default' => '31',
+ 'num' => '1;34',
+ 'const' => '1;31',
+ 'str' => '1;32',
+ 'note' => '34',
+ 'ref' => '1;30',
+ 'meta' => '35',
+ 'key' => '32',
+ 'index' => '34',
+ ]);
+ }
+
+ $this->displayOptions['fileLinkFormat'] = \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l';
+ }
+
+ /**
+ * Enables/disables colored output.
+ */
+ public function setColors(bool $colors)
+ {
+ $this->colors = $colors;
+ }
+
+ /**
+ * Sets the maximum number of characters per line for dumped strings.
+ */
+ public function setMaxStringWidth(int $maxStringWidth)
+ {
+ $this->maxStringWidth = $maxStringWidth;
+ }
+
+ /**
+ * Configures styles.
+ *
+ * @param array $styles A map of style names to style definitions
+ */
+ public function setStyles(array $styles)
+ {
+ $this->styles = $styles + $this->styles;
+ }
+
+ /**
+ * Configures display options.
+ *
+ * @param array $displayOptions A map of display options to customize the behavior
+ */
+ public function setDisplayOptions(array $displayOptions)
+ {
+ $this->displayOptions = $displayOptions + $this->displayOptions;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function dumpScalar(Cursor $cursor, string $type, string|int|float|bool|null $value)
+ {
+ $this->dumpKey($cursor);
+
+ $style = 'const';
+ $attr = $cursor->attr;
+
+ switch ($type) {
+ case 'default':
+ $style = 'default';
+ break;
+
+ case 'integer':
+ $style = 'num';
+
+ if (isset($this->styles['integer'])) {
+ $style = 'integer';
+ }
+
+ break;
+
+ case 'double':
+ $style = 'num';
+
+ if (isset($this->styles['float'])) {
+ $style = 'float';
+ }
+
+ switch (true) {
+ case \INF === $value: $value = 'INF'; break;
+ case -\INF === $value: $value = '-INF'; break;
+ case is_nan($value): $value = 'NAN'; break;
+ default:
+ $value = (string) $value;
+ if (!str_contains($value, $this->decimalPoint)) {
+ $value .= $this->decimalPoint.'0';
+ }
+ break;
+ }
+ break;
+
+ case 'NULL':
+ $value = 'null';
+ break;
+
+ case 'boolean':
+ $value = $value ? 'true' : 'false';
+ break;
+
+ default:
+ $attr += ['value' => $this->utf8Encode($value)];
+ $value = $this->utf8Encode($type);
+ break;
+ }
+
+ $this->line .= $this->style($style, $value, $attr);
+
+ $this->endValue($cursor);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut)
+ {
+ $this->dumpKey($cursor);
+ $attr = $cursor->attr;
+
+ if ($bin) {
+ $str = $this->utf8Encode($str);
+ }
+ if ('' === $str) {
+ $this->line .= '""';
+ $this->endValue($cursor);
+ } else {
+ $attr += [
+ 'length' => 0 <= $cut ? mb_strlen($str, 'UTF-8') + $cut : 0,
+ 'binary' => $bin,
+ ];
+ $str = $bin && false !== strpos($str, "\0") ? [$str] : explode("\n", $str);
+ if (isset($str[1]) && !isset($str[2]) && !isset($str[1][0])) {
+ unset($str[1]);
+ $str[0] .= "\n";
+ }
+ $m = \count($str) - 1;
+ $i = $lineCut = 0;
+
+ if (self::DUMP_STRING_LENGTH & $this->flags) {
+ $this->line .= '('.$attr['length'].') ';
+ }
+ if ($bin) {
+ $this->line .= 'b';
+ }
+
+ if ($m) {
+ $this->line .= '"""';
+ $this->dumpLine($cursor->depth);
+ } else {
+ $this->line .= '"';
+ }
+
+ foreach ($str as $str) {
+ if ($i < $m) {
+ $str .= "\n";
+ }
+ if (0 < $this->maxStringWidth && $this->maxStringWidth < $len = mb_strlen($str, 'UTF-8')) {
+ $str = mb_substr($str, 0, $this->maxStringWidth, 'UTF-8');
+ $lineCut = $len - $this->maxStringWidth;
+ }
+ if ($m && 0 < $cursor->depth) {
+ $this->line .= $this->indentPad;
+ }
+ if ('' !== $str) {
+ $this->line .= $this->style('str', $str, $attr);
+ }
+ if ($i++ == $m) {
+ if ($m) {
+ if ('' !== $str) {
+ $this->dumpLine($cursor->depth);
+ if (0 < $cursor->depth) {
+ $this->line .= $this->indentPad;
+ }
+ }
+ $this->line .= '"""';
+ } else {
+ $this->line .= '"';
+ }
+ if ($cut < 0) {
+ $this->line .= '…';
+ $lineCut = 0;
+ } elseif ($cut) {
+ $lineCut += $cut;
+ }
+ }
+ if ($lineCut) {
+ $this->line .= '…'.$lineCut;
+ $lineCut = 0;
+ }
+
+ if ($i > $m) {
+ $this->endValue($cursor);
+ } else {
+ $this->dumpLine($cursor->depth);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild)
+ {
+ if (null === $this->colors) {
+ $this->colors = $this->supportsColors();
+ }
+
+ $this->dumpKey($cursor);
+ $attr = $cursor->attr;
+
+ if ($this->collapseNextHash) {
+ $cursor->skipChildren = true;
+ $this->collapseNextHash = $hasChild = false;
+ }
+
+ $class = $this->utf8Encode($class);
+ if (Cursor::HASH_OBJECT === $type) {
+ $prefix = $class && 'stdClass' !== $class ? $this->style('note', $class, $attr).(empty($attr['cut_hash']) ? ' {' : '') : '{';
+ } elseif (Cursor::HASH_RESOURCE === $type) {
+ $prefix = $this->style('note', $class.' resource', $attr).($hasChild ? ' {' : ' ');
+ } else {
+ $prefix = $class && !(self::DUMP_LIGHT_ARRAY & $this->flags) ? $this->style('note', 'array:'.$class).' [' : '[';
+ }
+
+ if (($cursor->softRefCount || 0 < $cursor->softRefHandle) && empty($attr['cut_hash'])) {
+ $prefix .= $this->style('ref', (Cursor::HASH_RESOURCE === $type ? '@' : '#').(0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->softRefTo), ['count' => $cursor->softRefCount]);
+ } elseif ($cursor->hardRefTo && !$cursor->refIndex && $class) {
+ $prefix .= $this->style('ref', '&'.$cursor->hardRefTo, ['count' => $cursor->hardRefCount]);
+ } elseif (!$hasChild && Cursor::HASH_RESOURCE === $type) {
+ $prefix = substr($prefix, 0, -1);
+ }
+
+ $this->line .= $prefix;
+
+ if ($hasChild) {
+ $this->dumpLine($cursor->depth);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut)
+ {
+ if (empty($cursor->attr['cut_hash'])) {
+ $this->dumpEllipsis($cursor, $hasChild, $cut);
+ $this->line .= Cursor::HASH_OBJECT === $type ? '}' : (Cursor::HASH_RESOURCE !== $type ? ']' : ($hasChild ? '}' : ''));
+ }
+
+ $this->endValue($cursor);
+ }
+
+ /**
+ * Dumps an ellipsis for cut children.
+ *
+ * @param bool $hasChild When the dump of the hash has child item
+ * @param int $cut The number of items the hash has been cut by
+ */
+ protected function dumpEllipsis(Cursor $cursor, bool $hasChild, int $cut)
+ {
+ if ($cut) {
+ $this->line .= ' …';
+ if (0 < $cut) {
+ $this->line .= $cut;
+ }
+ if ($hasChild) {
+ $this->dumpLine($cursor->depth + 1);
+ }
+ }
+ }
+
+ /**
+ * Dumps a key in a hash structure.
+ */
+ protected function dumpKey(Cursor $cursor)
+ {
+ if (null !== $key = $cursor->hashKey) {
+ if ($cursor->hashKeyIsBinary) {
+ $key = $this->utf8Encode($key);
+ }
+ $attr = ['binary' => $cursor->hashKeyIsBinary];
+ $bin = $cursor->hashKeyIsBinary ? 'b' : '';
+ $style = 'key';
+ switch ($cursor->hashType) {
+ default:
+ case Cursor::HASH_INDEXED:
+ if (self::DUMP_LIGHT_ARRAY & $this->flags) {
+ break;
+ }
+ $style = 'index';
+ // no break
+ case Cursor::HASH_ASSOC:
+ if (\is_int($key)) {
+ $this->line .= $this->style($style, $key).' => ';
+ } else {
+ $this->line .= $bin.'"'.$this->style($style, $key).'" => ';
+ }
+ break;
+
+ case Cursor::HASH_RESOURCE:
+ $key = "\0~\0".$key;
+ // no break
+ case Cursor::HASH_OBJECT:
+ if (!isset($key[0]) || "\0" !== $key[0]) {
+ $this->line .= '+'.$bin.$this->style('public', $key).': ';
+ } elseif (0 < strpos($key, "\0", 1)) {
+ $key = explode("\0", substr($key, 1), 2);
+
+ switch ($key[0][0]) {
+ case '+': // User inserted keys
+ $attr['dynamic'] = true;
+ $this->line .= '+'.$bin.'"'.$this->style('public', $key[1], $attr).'": ';
+ break 2;
+ case '~':
+ $style = 'meta';
+ if (isset($key[0][1])) {
+ parse_str(substr($key[0], 1), $attr);
+ $attr += ['binary' => $cursor->hashKeyIsBinary];
+ }
+ break;
+ case '*':
+ $style = 'protected';
+ $bin = '#'.$bin;
+ break;
+ default:
+ $attr['class'] = $key[0];
+ $style = 'private';
+ $bin = '-'.$bin;
+ break;
+ }
+
+ if (isset($attr['collapse'])) {
+ if ($attr['collapse']) {
+ $this->collapseNextHash = true;
+ } else {
+ $this->expandNextHash = true;
+ }
+ }
+
+ $this->line .= $bin.$this->style($style, $key[1], $attr).($attr['separator'] ?? ': ');
+ } else {
+ // This case should not happen
+ $this->line .= '-'.$bin.'"'.$this->style('private', $key, ['class' => '']).'": ';
+ }
+ break;
+ }
+
+ if ($cursor->hardRefTo) {
+ $this->line .= $this->style('ref', '&'.($cursor->hardRefCount ? $cursor->hardRefTo : ''), ['count' => $cursor->hardRefCount]).' ';
+ }
+ }
+ }
+
+ /**
+ * Decorates a value with some style.
+ *
+ * @param string $style The type of style being applied
+ * @param string $value The value being styled
+ * @param array $attr Optional context information
+ */
+ protected function style(string $style, string $value, array $attr = []): string
+ {
+ if (null === $this->colors) {
+ $this->colors = $this->supportsColors();
+ }
+
+ $this->handlesHrefGracefully ??= 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
+ && (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
+
+ if (isset($attr['ellipsis'], $attr['ellipsis-type'])) {
+ $prefix = substr($value, 0, -$attr['ellipsis']);
+ if ('cli' === \PHP_SAPI && 'path' === $attr['ellipsis-type'] && isset($_SERVER[$pwd = '\\' === \DIRECTORY_SEPARATOR ? 'CD' : 'PWD']) && str_starts_with($prefix, $_SERVER[$pwd])) {
+ $prefix = '.'.substr($prefix, \strlen($_SERVER[$pwd]));
+ }
+ if (!empty($attr['ellipsis-tail'])) {
+ $prefix .= substr($value, -$attr['ellipsis'], $attr['ellipsis-tail']);
+ $value = substr($value, -$attr['ellipsis'] + $attr['ellipsis-tail']);
+ } else {
+ $value = substr($value, -$attr['ellipsis']);
+ }
+
+ $value = $this->style('default', $prefix).$this->style($style, $value);
+
+ goto href;
+ }
+
+ $map = static::$controlCharsMap;
+ $startCchr = $this->colors ? "\033[m\033[{$this->styles['default']}m" : '';
+ $endCchr = $this->colors ? "\033[m\033[{$this->styles[$style]}m" : '';
+ $value = preg_replace_callback(static::$controlCharsRx, function ($c) use ($map, $startCchr, $endCchr) {
+ $s = $startCchr;
+ $c = $c[$i = 0];
+ do {
+ $s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i]));
+ } while (isset($c[++$i]));
+
+ return $s.$endCchr;
+ }, $value, -1, $cchrCount);
+
+ if ($this->colors) {
+ if ($cchrCount && "\033" === $value[0]) {
+ $value = substr($value, \strlen($startCchr));
+ } else {
+ $value = "\033[{$this->styles[$style]}m".$value;
+ }
+ if ($cchrCount && str_ends_with($value, $endCchr)) {
+ $value = substr($value, 0, -\strlen($endCchr));
+ } else {
+ $value .= "\033[{$this->styles['default']}m";
+ }
+ }
+
+ href:
+ if ($this->colors && $this->handlesHrefGracefully) {
+ if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], $attr['line'] ?? 0)) {
+ if ('note' === $style) {
+ $value .= "\033]8;;{$href}\033\\^\033]8;;\033\\";
+ } else {
+ $attr['href'] = $href;
+ }
+ }
+ if (isset($attr['href'])) {
+ $value = "\033]8;;{$attr['href']}\033\\{$value}\033]8;;\033\\";
+ }
+ } elseif ($attr['if_links'] ?? false) {
+ return '';
+ }
+
+ return $value;
+ }
+
+ protected function supportsColors(): bool
+ {
+ if ($this->outputStream !== static::$defaultOutput) {
+ return $this->hasColorSupport($this->outputStream);
+ }
+ if (null !== static::$defaultColors) {
+ return static::$defaultColors;
+ }
+ if (isset($_SERVER['argv'][1])) {
+ $colors = $_SERVER['argv'];
+ $i = \count($colors);
+ while (--$i > 0) {
+ if (isset($colors[$i][5])) {
+ switch ($colors[$i]) {
+ case '--ansi':
+ case '--color':
+ case '--color=yes':
+ case '--color=force':
+ case '--color=always':
+ case '--colors=always':
+ return static::$defaultColors = true;
+
+ case '--no-ansi':
+ case '--color=no':
+ case '--color=none':
+ case '--color=never':
+ case '--colors=never':
+ return static::$defaultColors = false;
+ }
+ }
+ }
+ }
+
+ $h = stream_get_meta_data($this->outputStream) + ['wrapper_type' => null];
+ $h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'w') : $this->outputStream;
+
+ return static::$defaultColors = $this->hasColorSupport($h);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function dumpLine(int $depth, bool $endOfValue = false)
+ {
+ if ($this->colors) {
+ $this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line);
+ }
+ parent::dumpLine($depth);
+ }
+
+ protected function endValue(Cursor $cursor)
+ {
+ if (-1 === $cursor->hashType) {
+ return;
+ }
+
+ if (Stub::ARRAY_INDEXED === $cursor->hashType || Stub::ARRAY_ASSOC === $cursor->hashType) {
+ if (self::DUMP_TRAILING_COMMA & $this->flags && 0 < $cursor->depth) {
+ $this->line .= ',';
+ } elseif (self::DUMP_COMMA_SEPARATOR & $this->flags && 1 < $cursor->hashLength - $cursor->hashIndex) {
+ $this->line .= ',';
+ }
+ }
+
+ $this->dumpLine($cursor->depth, true);
+ }
+
+ /**
+ * Returns true if the stream supports colorization.
+ *
+ * Reference: Composer\XdebugHandler\Process::supportsColor
+ * https://github.com/composer/xdebug-handler
+ */
+ private function hasColorSupport(mixed $stream): bool
+ {
+ if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
+ return false;
+ }
+
+ // Follow https://no-color.org/
+ if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
+ return false;
+ }
+
+ if ('Hyper' === getenv('TERM_PROGRAM')) {
+ return true;
+ }
+
+ if (\DIRECTORY_SEPARATOR === '\\') {
+ return (\function_exists('sapi_windows_vt100_support')
+ && @sapi_windows_vt100_support($stream))
+ || false !== getenv('ANSICON')
+ || 'ON' === getenv('ConEmuANSI')
+ || 'xterm' === getenv('TERM');
+ }
+
+ return stream_isatty($stream);
+ }
+
+ /**
+ * Returns true if the Windows terminal supports true color.
+ *
+ * Note that this does not check an output stream, but relies on environment
+ * variables from known implementations, or a PHP and Windows version that
+ * supports true color.
+ */
+ private function isWindowsTrueColor(): bool
+ {
+ $result = 183 <= getenv('ANSICON_VER')
+ || 'ON' === getenv('ConEmuANSI')
+ || 'xterm' === getenv('TERM')
+ || 'Hyper' === getenv('TERM_PROGRAM');
+
+ if (!$result) {
+ $version = sprintf(
+ '%s.%s.%s',
+ PHP_WINDOWS_VERSION_MAJOR,
+ PHP_WINDOWS_VERSION_MINOR,
+ PHP_WINDOWS_VERSION_BUILD
+ );
+ $result = $version >= '10.0.15063';
+ }
+
+ return $result;
+ }
+
+ private function getSourceLink(string $file, int $line)
+ {
+ if ($fmt = $this->displayOptions['fileLinkFormat']) {
+ return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : ($fmt->format($file, $line) ?: 'file://'.$file.'#L'.$line);
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php b/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.php
new file mode 100644
index 0000000..38f8789
--- /dev/null
+++ b/vendor/symfony/var-dumper/Dumper/ContextProvider/CliContextProvider.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 Symfony\Component\VarDumper\Dumper\ContextProvider;
+
+/**
+ * Tries to provide context on CLI.
+ *
+ * @author Maxime Steinhausser
+ * @author Maxime Steinhausser
+ */
+interface DataDumperInterface
+{
+ public function dump(Data $data);
+}
diff --git a/vendor/symfony/var-dumper/Dumper/HtmlDumper.php b/vendor/symfony/var-dumper/Dumper/HtmlDumper.php
new file mode 100644
index 0000000..e74888d
--- /dev/null
+++ b/vendor/symfony/var-dumper/Dumper/HtmlDumper.php
@@ -0,0 +1,986 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Cursor;
+use Symfony\Component\VarDumper\Cloner\Data;
+
+/**
+ * HtmlDumper dumps variables as HTML.
+ *
+ * @author Nicolas Grekas
+ */
+class HtmlDumper extends CliDumper
+{
+ public static $defaultOutput = 'php://output';
+
+ protected static $themes = [
+ 'dark' => [
+ 'default' => 'background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all',
+ 'num' => 'font-weight:bold; color:#1299DA',
+ 'const' => 'font-weight:bold',
+ 'str' => 'font-weight:bold; color:#56DB3A',
+ 'note' => 'color:#1299DA',
+ 'ref' => 'color:#A0A0A0',
+ 'public' => 'color:#FFFFFF',
+ 'protected' => 'color:#FFFFFF',
+ 'private' => 'color:#FFFFFF',
+ 'meta' => 'color:#B729D9',
+ 'key' => 'color:#56DB3A',
+ 'index' => 'color:#1299DA',
+ 'ellipsis' => 'color:#FF8400',
+ 'ns' => 'user-select:none;',
+ ],
+ 'light' => [
+ 'default' => 'background:none; color:#CC7832; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: break-all',
+ 'num' => 'font-weight:bold; color:#1299DA',
+ 'const' => 'font-weight:bold',
+ 'str' => 'font-weight:bold; color:#629755;',
+ 'note' => 'color:#6897BB',
+ 'ref' => 'color:#6E6E6E',
+ 'public' => 'color:#262626',
+ 'protected' => 'color:#262626',
+ 'private' => 'color:#262626',
+ 'meta' => 'color:#B729D9',
+ 'key' => 'color:#789339',
+ 'index' => 'color:#1299DA',
+ 'ellipsis' => 'color:#CC7832',
+ 'ns' => 'user-select:none;',
+ ],
+ ];
+
+ protected $dumpHeader;
+ protected $dumpPrefix = '
+ */
+class ThrowingCasterException extends \Exception
+{
+ /**
+ * @param \Throwable $prev The exception thrown from the caster
+ */
+ public function __construct(\Throwable $prev)
+ {
+ parent::__construct('Unexpected '.\get_class($prev).' thrown from a caster: '.$prev->getMessage(), 0, $prev);
+ }
+}
diff --git a/vendor/symfony/var-dumper/LICENSE b/vendor/symfony/var-dumper/LICENSE
new file mode 100644
index 0000000..72412a6
--- /dev/null
+++ b/vendor/symfony/var-dumper/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014-2023 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/symfony/var-dumper/README.md b/vendor/symfony/var-dumper/README.md
new file mode 100644
index 0000000..a0da8c9
--- /dev/null
+++ b/vendor/symfony/var-dumper/README.md
@@ -0,0 +1,15 @@
+VarDumper Component
+===================
+
+The VarDumper component provides mechanisms for walking through any arbitrary
+PHP variable. It provides a better `dump()` function that you can use instead
+of `var_dump()`.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/var_dumper/introduction.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/vendor/symfony/var-dumper/Resources/bin/var-dump-server b/vendor/symfony/var-dumper/Resources/bin/var-dump-server
new file mode 100755
index 0000000..f398fce
--- /dev/null
+++ b/vendor/symfony/var-dumper/Resources/bin/var-dump-server
@@ -0,0 +1,67 @@
+#!/usr/bin/env php
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if ('cli' !== PHP_SAPI) {
+ throw new Exception('This script must be run from the command line.');
+}
+
+/**
+ * Starts a dump server to collect and output dumps on a single place with multiple formats support.
+ *
+ * @author Maxime Steinhausser
+ */
+ function dump(mixed $var, mixed ...$moreVars): mixed
+ {
+ VarDumper::dump($var);
+
+ foreach ($moreVars as $v) {
+ VarDumper::dump($v);
+ }
+
+ if (1 < func_num_args()) {
+ return func_get_args();
+ }
+
+ return $var;
+ }
+}
+
+if (!function_exists('dd')) {
+ /**
+ * @return never
+ */
+ function dd(...$vars): void
+ {
+ if (!in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !headers_sent()) {
+ header('HTTP/1.1 500 Internal Server Error');
+ }
+
+ foreach ($vars as $v) {
+ VarDumper::dump($v);
+ }
+
+ exit(1);
+ }
+}
diff --git a/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js b/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js
new file mode 100644
index 0000000..63101e5
--- /dev/null
+++ b/vendor/symfony/var-dumper/Resources/js/htmlDescriptor.js
@@ -0,0 +1,10 @@
+document.addEventListener('DOMContentLoaded', function() {
+ let prev = null;
+ Array.from(document.getElementsByTagName('article')).reverse().forEach(function (article) {
+ const dedupId = article.dataset.dedupId;
+ if (dedupId === prev) {
+ article.getElementsByTagName('header')[0].classList.add('hidden');
+ }
+ prev = dedupId;
+ });
+});
diff --git a/vendor/symfony/var-dumper/Server/Connection.php b/vendor/symfony/var-dumper/Server/Connection.php
new file mode 100644
index 0000000..97b5b94
--- /dev/null
+++ b/vendor/symfony/var-dumper/Server/Connection.php
@@ -0,0 +1,99 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Server;
+
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
+
+/**
+ * Forwards serialized Data clones to a server.
+ *
+ * @author Maxime Steinhausser
+ */
+trait VarDumperTestTrait
+{
+ /**
+ * @internal
+ */
+ private array $varDumperConfig = [
+ 'casters' => [],
+ 'flags' => null,
+ ];
+
+ protected function setUpVarDumper(array $casters, int $flags = null): void
+ {
+ $this->varDumperConfig['casters'] = $casters;
+ $this->varDumperConfig['flags'] = $flags;
+ }
+
+ /**
+ * @after
+ */
+ protected function tearDownVarDumper(): void
+ {
+ $this->varDumperConfig['casters'] = [];
+ $this->varDumperConfig['flags'] = null;
+ }
+
+ public function assertDumpEquals(mixed $expected, mixed $data, int $filter = 0, string $message = '')
+ {
+ $this->assertSame($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message);
+ }
+
+ public function assertDumpMatchesFormat(mixed $expected, mixed $data, int $filter = 0, string $message = '')
+ {
+ $this->assertStringMatchesFormat($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message);
+ }
+
+ protected function getDump(mixed $data, string|int $key = null, int $filter = 0): ?string
+ {
+ if (null === $flags = $this->varDumperConfig['flags']) {
+ $flags = getenv('DUMP_LIGHT_ARRAY') ? CliDumper::DUMP_LIGHT_ARRAY : 0;
+ $flags |= getenv('DUMP_STRING_LENGTH') ? CliDumper::DUMP_STRING_LENGTH : 0;
+ $flags |= getenv('DUMP_COMMA_SEPARATOR') ? CliDumper::DUMP_COMMA_SEPARATOR : 0;
+ }
+
+ $cloner = new VarCloner();
+ $cloner->addCasters($this->varDumperConfig['casters']);
+ $cloner->setMaxItems(-1);
+ $dumper = new CliDumper(null, null, $flags);
+ $dumper->setColors(false);
+ $data = $cloner->cloneVar($data, $filter)->withRefHandles(false);
+ if (null !== $key && null === $data = $data->seek($key)) {
+ return null;
+ }
+
+ return rtrim($dumper->dump($data, true));
+ }
+
+ private function prepareExpectation(mixed $expected, int $filter): string
+ {
+ if (!\is_string($expected)) {
+ $expected = $this->getDump($expected, null, $filter);
+ }
+
+ return rtrim($expected);
+ }
+}
diff --git a/vendor/symfony/var-dumper/VarDumper.php b/vendor/symfony/var-dumper/VarDumper.php
new file mode 100644
index 0000000..c0d0741
--- /dev/null
+++ b/vendor/symfony/var-dumper/VarDumper.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 Symfony\Component\VarDumper;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
+use Symfony\Component\VarDumper\Caster\ReflectionCaster;
+use Symfony\Component\VarDumper\Cloner\VarCloner;
+use Symfony\Component\VarDumper\Dumper\CliDumper;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\CliContextProvider;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\RequestContextProvider;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
+use Symfony\Component\VarDumper\Dumper\ContextualizedDumper;
+use Symfony\Component\VarDumper\Dumper\HtmlDumper;
+use Symfony\Component\VarDumper\Dumper\ServerDumper;
+
+// Load the global dump() function
+require_once __DIR__.'/Resources/functions/dump.php';
+
+/**
+ * @author Nicolas Grekas
+ */
+class VarDumper
+{
+ /**
+ * @var callable|null
+ */
+ private static $handler;
+
+ public static function dump(mixed $var)
+ {
+ if (null === self::$handler) {
+ self::register();
+ }
+
+ return (self::$handler)($var);
+ }
+
+ public static function setHandler(callable $callable = null): ?callable
+ {
+ $prevHandler = self::$handler;
+
+ // Prevent replacing the handler with expected format as soon as the env var was set:
+ if (isset($_SERVER['VAR_DUMPER_FORMAT'])) {
+ return $prevHandler;
+ }
+
+ self::$handler = $callable;
+
+ return $prevHandler;
+ }
+
+ private static function register(): void
+ {
+ $cloner = new VarCloner();
+ $cloner->addCasters(ReflectionCaster::UNSET_CLOSURE_FILE_INFO);
+
+ $format = $_SERVER['VAR_DUMPER_FORMAT'] ?? null;
+ switch (true) {
+ case 'html' === $format:
+ $dumper = new HtmlDumper();
+ break;
+ case 'cli' === $format:
+ $dumper = new CliDumper();
+ break;
+ case 'server' === $format:
+ case $format && 'tcp' === parse_url($format, \PHP_URL_SCHEME):
+ $host = 'server' === $format ? $_SERVER['VAR_DUMPER_SERVER'] ?? '127.0.0.1:9912' : $format;
+ $dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? new CliDumper() : new HtmlDumper();
+ $dumper = new ServerDumper($host, $dumper, self::getDefaultContextProviders());
+ break;
+ default:
+ $dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? new CliDumper() : new HtmlDumper();
+ }
+
+ if (!$dumper instanceof ServerDumper) {
+ $dumper = new ContextualizedDumper($dumper, [new SourceContextProvider()]);
+ }
+
+ self::$handler = function ($var) use ($cloner, $dumper) {
+ $dumper->dump($cloner->cloneVar($var));
+ };
+ }
+
+ private static function getDefaultContextProviders(): array
+ {
+ $contextProviders = [];
+
+ if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && class_exists(Request::class)) {
+ $requestStack = new RequestStack();
+ $requestStack->push(Request::createFromGlobals());
+ $contextProviders['request'] = new RequestContextProvider($requestStack);
+ }
+
+ $fileLinkFormatter = class_exists(FileLinkFormatter::class) ? new FileLinkFormatter(null, $requestStack ?? null) : null;
+
+ return $contextProviders + [
+ 'cli' => new CliContextProvider(),
+ 'source' => new SourceContextProvider(null, null, $fileLinkFormatter),
+ ];
+ }
+}
diff --git a/vendor/symfony/var-dumper/composer.json b/vendor/symfony/var-dumper/composer.json
new file mode 100644
index 0000000..db04f58
--- /dev/null
+++ b/vendor/symfony/var-dumper/composer.json
@@ -0,0 +1,49 @@
+{
+ "name": "symfony/var-dumper",
+ "type": "library",
+ "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+ "keywords": ["dump", "debug"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.0.2",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "ext-iconv": "*",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/uid": "^5.4|^6.0",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.3",
+ "symfony/console": "<5.4"
+ },
+ "suggest": {
+ "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
+ "ext-intl": "To show region name in time zone dump",
+ "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
+ },
+ "autoload": {
+ "files": [ "Resources/functions/dump.php" ],
+ "psr-4": { "Symfony\\Component\\VarDumper\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
+ "minimum-stability": "dev"
+}
diff --git a/vendor/topthink/think-trace/.gitignore b/vendor/topthink/think-trace/.gitignore
new file mode 100644
index 0000000..485dee6
--- /dev/null
+++ b/vendor/topthink/think-trace/.gitignore
@@ -0,0 +1 @@
+.idea
diff --git a/vendor/topthink/think-trace/LICENSE b/vendor/topthink/think-trace/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/vendor/topthink/think-trace/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/vendor/topthink/think-trace/README.md b/vendor/topthink/think-trace/README.md
new file mode 100644
index 0000000..6ed63ec
--- /dev/null
+++ b/vendor/topthink/think-trace/README.md
@@ -0,0 +1,15 @@
+# think-trace
+
+用于ThinkPHP6+的页面Trace扩展,支持Html页面和浏览器控制台两种方式输出。
+
+## 安装
+
+~~~
+composer require topthink/think-trace
+~~~
+
+## 配置
+
+安装后config目录下会自带trace.php配置文件。
+
+type参数用于指定trace类型,支持html和console两种方式。
\ No newline at end of file
diff --git a/vendor/topthink/think-trace/composer.json b/vendor/topthink/think-trace/composer.json
new file mode 100644
index 0000000..e6cd16b
--- /dev/null
+++ b/vendor/topthink/think-trace/composer.json
@@ -0,0 +1,31 @@
+{
+ "name": "topthink/think-trace",
+ "description": "thinkphp debug trace",
+ "license": "Apache-2.0",
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.1.0",
+ "topthink/framework": "^6.0|^8.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "think\\trace\\": "src"
+ }
+ },
+ "extra": {
+ "think":{
+ "services":[
+ "think\\trace\\Service"
+ ],
+ "config":{
+ "trace": "src/config.php"
+ }
+ }
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/topthink/think-trace/src/Console.php b/vendor/topthink/think-trace/src/Console.php
new file mode 100644
index 0000000..179d4ea
--- /dev/null
+++ b/vendor/topthink/think-trace/src/Console.php
@@ -0,0 +1,173 @@
+
+// +----------------------------------------------------------------------
+declare (strict_types = 1);
+namespace think\trace;
+
+use think\App;
+use think\Response;
+
+/**
+ * 浏览器调试输出
+ */
+class Console
+{
+ protected $config = [
+ 'tabs' => ['base' => '基本', 'file' => '文件', 'info' => '流程', 'notice|error' => '错误', 'sql' => 'SQL', 'debug|log' => '调试'],
+ ];
+
+ // 实例化并传入参数
+ public function __construct(array $config = [])
+ {
+ $this->config = array_merge($this->config, $config);
+ }
+
+ /**
+ * 调试输出接口
+ * @access public
+ * @param Response $response Response对象
+ * @param array $log 日志信息
+ * @return string|bool
+ */
+ public function output(App $app, Response $response, array $log = [])
+ {
+ $request = $app->request;
+ $contentType = $response->getHeader('Content-Type');
+
+ if ($request->isJson() || $request->isAjax()) {
+ return false;
+ } elseif (!empty($contentType) && strpos($contentType, 'html') === false) {
+ return false;
+ } elseif ($response->getCode() == 204) {
+ return false;
+ }
+
+ // 获取基本信息
+ $runtime = number_format(microtime(true) - $app->getBeginTime(), 10, '.', '');
+ $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';
+ $mem = number_format((memory_get_usage() - $app->getBeginMem()) / 1024, 2);
+
+ if ($request->host()) {
+ $uri = $request->protocol() . ' ' . $request->method() . ' : ' . $request->url(true);
+ } else {
+ $uri = 'cmd:' . implode(' ', $_SERVER['argv']);
+ }
+
+ // 页面Trace信息
+ $base = [
+ '请求信息' => date('Y-m-d H:i:s', $request->time() ?: time()) . ' ' . $uri,
+ '运行时间' => number_format((float) $runtime, 6) . 's [ 吞吐率:' . $reqs . 'req/s ] 内存消耗:' . $mem . 'kb 文件加载:' . count(get_included_files()),
+ '查询信息' => $app->db->getQueryTimes() . ' queries',
+ '缓存信息' => $app->cache->getReadTimes() . ' reads,' . $app->cache->getWriteTimes() . ' writes',
+ ];
+
+ if (isset($app->session)) {
+ $base['会话信息'] = 'SESSION_ID=' . $app->session->getId();
+ }
+
+ $info = $this->getFileInfo();
+
+ // 页面Trace信息
+ $trace = [];
+ foreach ($this->config['tabs'] as $name => $title) {
+ $name = strtolower($name);
+ switch ($name) {
+ case 'base': // 基本信息
+ $trace[$title] = $base;
+ break;
+ case 'file': // 文件信息
+ $trace[$title] = $info;
+ break;
+ default: // 调试信息
+ if (strpos($name, '|')) {
+ // 多组信息
+ $names = explode('|', $name);
+ $result = [];
+ foreach ($names as $item) {
+ $result = array_merge($result, $log[$item] ?? []);
+ }
+ $trace[$title] = $result;
+ } else {
+ $trace[$title] = $log[$name] ?? '';
+ }
+ }
+ }
+
+ //输出到控制台
+ $lines = '';
+ foreach ($trace as $type => $msg) {
+ $lines .= $this->console($type, empty($msg) ? [] : $msg);
+ }
+ $js = <<%s %s', $request['method'], $uri = $request['uri'], $uri);
+ $dedupIdentifier = $request['identifier'];
+ } elseif (isset($context['cli'])) {
+ $title = '$ '.$context['cli']['command_line'];
+ $dedupIdentifier = $context['cli']['identifier'];
+ } else {
+ $dedupIdentifier = uniqid('', true);
+ }
+
+ $sourceDescription = '';
+ if (isset($context['source'])) {
+ $source = $context['source'];
+ $projectDir = $source['project_dir'] ?? null;
+ $sourceDescription = sprintf('%s on line %d', $source['name'], $source['line']);
+ if (isset($source['file_link'])) {
+ $sourceDescription = sprintf('%s', $source['file_link'], $sourceDescription);
+ }
+ }
+
+ $isoDate = $this->extractDate($context, 'c');
+ $tags = array_filter([
+ 'controller' => $controller ?? null,
+ 'project dir' => $projectDir ?? null,
+ ]);
+
+ $output->writeln(<<
+ $title
+
+ '.$this->htmlEncode($src[$i - 1]).''.implode("\n", $fileExcerpt).'
';
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ if (false === $name) {
+ $name = str_replace('\\', '/', $file);
+ $name = substr($name, strrpos($name, '/') + 1);
+ }
+
+ $context = ['name' => $name, 'file' => $file, 'line' => $line];
+ $context['file_excerpt'] = $fileExcerpt;
+
+ if (null !== $this->projectDir) {
+ $context['project_dir'] = $this->projectDir;
+ if (str_starts_with($file, $this->projectDir)) {
+ $context['file_relative'] = ltrim(substr($file, \strlen($this->projectDir)), \DIRECTORY_SEPARATOR);
+ }
+ }
+
+ if ($this->fileLinkFormatter && $fileLink = $this->fileLinkFormatter->format($context['file'], $context['line'])) {
+ $context['file_link'] = $fileLink;
+ }
+
+ return $context;
+ }
+
+ private function htmlEncode(string $s): string
+ {
+ $html = '';
+
+ $dumper = new HtmlDumper(function ($line) use (&$html) { $html .= $line; }, $this->charset);
+ $dumper->setDumpHeader('');
+ $dumper->setDumpBoundaries('', '');
+
+ $cloner = new VarCloner();
+ $dumper->dump($cloner->cloneVar($s));
+
+ return substr(strip_tags($html), 1, -1);
+ }
+}
diff --git a/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php b/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php
new file mode 100644
index 0000000..18ab56e
--- /dev/null
+++ b/vendor/symfony/var-dumper/Dumper/ContextualizedDumper.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
+
+/**
+ * @author Kévin Thérage ';
+ protected $dumpSuffix = '
';
+ protected $dumpId = 'sf-dump';
+ protected $colors = true;
+ protected $headerIsDumped = false;
+ protected $lastDepth = -1;
+ protected $styles;
+
+ private array $displayOptions = [
+ 'maxDepth' => 1,
+ 'maxStringLength' => 160,
+ 'fileLinkFormat' => null,
+ ];
+ private array $extraDisplayOptions = [];
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __construct($output = null, string $charset = null, int $flags = 0)
+ {
+ AbstractDumper::__construct($output, $charset, $flags);
+ $this->dumpId = 'sf-dump-'.mt_rand();
+ $this->displayOptions['fileLinkFormat'] = \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
+ $this->styles = static::$themes['dark'] ?? self::$themes['dark'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setStyles(array $styles)
+ {
+ $this->headerIsDumped = false;
+ $this->styles = $styles + $this->styles;
+ }
+
+ public function setTheme(string $themeName)
+ {
+ if (!isset(static::$themes[$themeName])) {
+ throw new \InvalidArgumentException(sprintf('Theme "%s" does not exist in class "%s".', $themeName, static::class));
+ }
+
+ $this->setStyles(static::$themes[$themeName]);
+ }
+
+ /**
+ * Configures display options.
+ *
+ * @param array $displayOptions A map of display options to customize the behavior
+ */
+ public function setDisplayOptions(array $displayOptions)
+ {
+ $this->headerIsDumped = false;
+ $this->displayOptions = $displayOptions + $this->displayOptions;
+ }
+
+ /**
+ * Sets an HTML header that will be dumped once in the output stream.
+ */
+ public function setDumpHeader(?string $header)
+ {
+ $this->dumpHeader = $header;
+ }
+
+ /**
+ * Sets an HTML prefix and suffix that will encapse every single dump.
+ */
+ public function setDumpBoundaries(string $prefix, string $suffix)
+ {
+ $this->dumpPrefix = $prefix;
+ $this->dumpSuffix = $suffix;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function dump(Data $data, $output = null, array $extraDisplayOptions = []): ?string
+ {
+ $this->extraDisplayOptions = $extraDisplayOptions;
+ $result = parent::dump($data, $output);
+ $this->dumpId = 'sf-dump-'.mt_rand();
+
+ return $result;
+ }
+
+ /**
+ * Dumps the HTML header.
+ */
+ protected function getDumpHeader()
+ {
+ $this->headerIsDumped = $this->outputStream ?? $this->lineDumper;
+
+ if (null !== $this->dumpHeader) {
+ return $this->dumpHeader;
+ }
+
+ $line = str_replace('{$options}', json_encode($this->displayOptions, \JSON_FORCE_OBJECT), <<<'EOHTML'
+'.$this->dumpHeader;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut)
+ {
+ if ('' === $str && isset($cursor->attr['img-data'], $cursor->attr['content-type'])) {
+ $this->dumpKey($cursor);
+ $this->line .= $this->style('default', $cursor->attr['img-size'] ?? '', []);
+ $this->line .= $cursor->depth >= $this->displayOptions['maxDepth'] ? ' ' : ' ';
+ $this->endValue($cursor);
+ $this->line .= $this->indentPad;
+ $this->line .= sprintf('', $cursor->attr['content-type'], base64_encode($cursor->attr['img-data']));
+ $this->endValue($cursor);
+ } else {
+ parent::dumpString($cursor, $str, $bin, $cut);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild)
+ {
+ if (Cursor::HASH_OBJECT === $type) {
+ $cursor->attr['depth'] = $cursor->depth;
+ }
+ parent::enterHash($cursor, $type, $class, false);
+
+ if ($cursor->skipChildren || $cursor->depth >= $this->displayOptions['maxDepth']) {
+ $cursor->skipChildren = false;
+ $eol = ' class=sf-dump-compact>';
+ } else {
+ $this->expandNextHash = false;
+ $eol = ' class=sf-dump-expanded>';
+ }
+
+ if ($hasChild) {
+ $this->line .= 'dumpId, $r);
+ }
+ $this->line .= $eol;
+ $this->dumpLine($cursor->depth);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut)
+ {
+ $this->dumpEllipsis($cursor, $hasChild, $cut);
+ if ($hasChild) {
+ $this->line .= '';
+ }
+ parent::leaveHash($cursor, $type, $class, $hasChild, 0);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function style(string $style, string $value, array $attr = []): string
+ {
+ if ('' === $value) {
+ return '';
+ }
+
+ $v = esc($value);
+
+ if ('ref' === $style) {
+ if (empty($attr['count'])) {
+ return sprintf('%s', $v);
+ }
+ $r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1);
+
+ return sprintf('%s', $this->dumpId, $r, 1 + $attr['count'], $v);
+ }
+
+ if ('const' === $style && isset($attr['value'])) {
+ $style .= sprintf(' title="%s"', esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])));
+ } elseif ('public' === $style) {
+ $style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property');
+ } elseif ('str' === $style && 1 < $attr['length']) {
+ $style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : '');
+ } elseif ('note' === $style && 0 < ($attr['depth'] ?? 0) && false !== $c = strrpos($value, '\\')) {
+ $style .= ' title=""';
+ $attr += [
+ 'ellipsis' => \strlen($value) - $c,
+ 'ellipsis-type' => 'note',
+ 'ellipsis-tail' => 1,
+ ];
+ } elseif ('protected' === $style) {
+ $style .= ' title="Protected property"';
+ } elseif ('meta' === $style && isset($attr['title'])) {
+ $style .= sprintf(' title="%s"', esc($this->utf8Encode($attr['title'])));
+ } elseif ('private' === $style) {
+ $style .= sprintf(' title="Private property defined in class:
`%s`"', esc($this->utf8Encode($attr['class'])));
+ }
+ $map = static::$controlCharsMap;
+
+ if (isset($attr['ellipsis'])) {
+ $class = 'sf-dump-ellipsis';
+ if (isset($attr['ellipsis-type'])) {
+ $class = sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']);
+ }
+ $label = esc(substr($value, -$attr['ellipsis']));
+ $style = str_replace(' title="', " title=\"$v\n", $style);
+ $v = sprintf('%s', $class, substr($v, 0, -\strlen($label)));
+
+ if (!empty($attr['ellipsis-tail'])) {
+ $tail = \strlen(esc(substr($value, -$attr['ellipsis'], $attr['ellipsis-tail'])));
+ $v .= sprintf('%s%s', $class, substr($label, 0, $tail), substr($label, $tail));
+ } else {
+ $v .= $label;
+ }
+ }
+
+ $v = "".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) {
+ $s = $b = '';
+ }, $v).'';
+
+ if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], $attr['line'] ?? 0)) {
+ $attr['href'] = $href;
+ }
+ if (isset($attr['href'])) {
+ $target = isset($attr['file']) ? '' : ' target="_blank"';
+ $v = sprintf('%s', esc($this->utf8Encode($attr['href'])), $target, $v);
+ }
+ if (isset($attr['lang'])) {
+ $v = sprintf('
%s', esc($attr['lang']), $v);
+ }
+
+ return $v;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function dumpLine(int $depth, bool $endOfValue = false)
+ {
+ if (-1 === $this->lastDepth) {
+ $this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line;
+ }
+ if ($this->headerIsDumped !== ($this->outputStream ?? $this->lineDumper)) {
+ $this->line = $this->getDumpHeader().$this->line;
+ }
+
+ if (-1 === $depth) {
+ $args = ['"'.$this->dumpId.'"'];
+ if ($this->extraDisplayOptions) {
+ $args[] = json_encode($this->extraDisplayOptions, \JSON_FORCE_OBJECT);
+ }
+ // Replace is for BC
+ $this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args));
+ }
+ $this->lastDepth = $depth;
+
+ $this->line = mb_encode_numericentity($this->line, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8');
+
+ if (-1 === $depth) {
+ AbstractDumper::dumpLine(0);
+ }
+ AbstractDumper::dumpLine($depth);
+ }
+
+ private function getSourceLink(string $file, int $line)
+ {
+ $options = $this->extraDisplayOptions + $this->displayOptions;
+
+ if ($fmt = $options['fileLinkFormat']) {
+ return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : $fmt->format($file, $line);
+ }
+
+ return false;
+ }
+}
+
+function esc(string $str)
+{
+ return htmlspecialchars($str, \ENT_QUOTES, 'UTF-8');
+}
diff --git a/vendor/symfony/var-dumper/Dumper/ServerDumper.php b/vendor/symfony/var-dumper/Dumper/ServerDumper.php
new file mode 100644
index 0000000..94795bf
--- /dev/null
+++ b/vendor/symfony/var-dumper/Dumper/ServerDumper.php
@@ -0,0 +1,53 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\VarDumper\Dumper;
+
+use Symfony\Component\VarDumper\Cloner\Data;
+use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
+use Symfony\Component\VarDumper\Server\Connection;
+
+/**
+ * ServerDumper forwards serialized Data clones to a server.
+ *
+ * @author Maxime Steinhausser
+