diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..1e5e2a2
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,25 @@
+
+ *
+ *
+ *
+ * @param string $string The string to operate on.
+ * @param string $delimiters A list of word separators.
+ *
+ * @return string The string with all delimeter-separated words capitalized.
+ */
+ public static function ucwords($string, $delimiters = " \n\t\r\0\x0B-")
+ {
+ return preg_replace_callback(
+ '/[^' . preg_quote($delimiters, '/') . ']+/',
+ function($matches) {
+ return ucfirst($matches[0]);
+ },
+ $string
+ );
+ }
+
+ /**
+ * Clears Inflectors inflected value caches, and resets the inflection
+ * rules to the initial values.
+ *
+ * @return void
+ */
+ public static function reset()
+ {
+ if (empty(self::$initialState)) {
+ self::$initialState = get_class_vars('Inflector');
+
+ return;
+ }
+
+ foreach (self::$initialState as $key => $val) {
+ if ($key != 'initialState') {
+ self::${$key} = $val;
+ }
+ }
+ }
+
+ /**
+ * Adds custom inflection $rules, of either 'plural' or 'singular' $type.
+ *
+ * ### Usage:
+ *
+ * {{{
+ * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
+ * Inflector::rules('plural', array(
+ * 'rules' => array('/^(inflect)ors$/i' => '\1ables'),
+ * 'uninflected' => array('dontinflectme'),
+ * 'irregular' => array('red' => 'redlings')
+ * ));
+ * }}}
+ *
+ * @param string $type The type of inflection, either 'plural' or 'singular'
+ * @param array $rules An array of rules to be added.
+ * @param boolean $reset If true, will unset default inflections for all
+ * new rules that are being defined in $rules.
+ *
+ * @return void
+ */
+ public static function rules($type, $rules, $reset = false)
+ {
+ foreach ($rules as $rule => $pattern) {
+ if ( ! is_array($pattern)) {
+ continue;
+ }
+
+ if ($reset) {
+ self::${$type}[$rule] = $pattern;
+ } else {
+ self::${$type}[$rule] = ($rule === 'uninflected')
+ ? array_merge($pattern, self::${$type}[$rule])
+ : $pattern + self::${$type}[$rule];
+ }
+
+ unset($rules[$rule], self::${$type}['cache' . ucfirst($rule)]);
+
+ if (isset(self::${$type}['merged'][$rule])) {
+ unset(self::${$type}['merged'][$rule]);
+ }
+
+ if ($type === 'plural') {
+ self::$cache['pluralize'] = self::$cache['tableize'] = array();
+ } elseif ($type === 'singular') {
+ self::$cache['singularize'] = array();
+ }
+ }
+
+ self::${$type}['rules'] = $rules + self::${$type}['rules'];
+ }
+
+ /**
+ * Returns a word in plural form.
+ *
+ * @param string $word The word in singular form.
+ *
+ * @return string The word in plural form.
+ */
+ public static function pluralize($word)
+ {
+ if (isset(self::$cache['pluralize'][$word])) {
+ return self::$cache['pluralize'][$word];
+ }
+
+ if (!isset(self::$plural['merged']['irregular'])) {
+ self::$plural['merged']['irregular'] = self::$plural['irregular'];
+ }
+
+ if (!isset(self::$plural['merged']['uninflected'])) {
+ self::$plural['merged']['uninflected'] = array_merge(self::$plural['uninflected'], self::$uninflected);
+ }
+
+ if (!isset(self::$plural['cacheUninflected']) || !isset(self::$plural['cacheIrregular'])) {
+ self::$plural['cacheUninflected'] = '(?:' . implode('|', self::$plural['merged']['uninflected']) . ')';
+ self::$plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$plural['merged']['irregular'])) . ')';
+ }
+
+ if (preg_match('/(.*)\\b(' . self::$plural['cacheIrregular'] . ')$/i', $word, $regs)) {
+ self::$cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$plural['merged']['irregular'][strtolower($regs[2])], 1);
+
+ return self::$cache['pluralize'][$word];
+ }
+
+ if (preg_match('/^(' . self::$plural['cacheUninflected'] . ')$/i', $word, $regs)) {
+ self::$cache['pluralize'][$word] = $word;
+
+ return $word;
+ }
+
+ foreach (self::$plural['rules'] as $rule => $replacement) {
+ if (preg_match($rule, $word)) {
+ self::$cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
+
+ return self::$cache['pluralize'][$word];
+ }
+ }
+ }
+
+ /**
+ * Returns a word in singular form.
+ *
+ * @param string $word The word in plural form.
+ *
+ * @return string The word in singular form.
+ */
+ public static function singularize($word)
+ {
+ if (isset(self::$cache['singularize'][$word])) {
+ return self::$cache['singularize'][$word];
+ }
+
+ if (!isset(self::$singular['merged']['uninflected'])) {
+ self::$singular['merged']['uninflected'] = array_merge(
+ self::$singular['uninflected'],
+ self::$uninflected
+ );
+ }
+
+ if (!isset(self::$singular['merged']['irregular'])) {
+ self::$singular['merged']['irregular'] = array_merge(
+ self::$singular['irregular'],
+ array_flip(self::$plural['irregular'])
+ );
+ }
+
+ if (!isset(self::$singular['cacheUninflected']) || !isset(self::$singular['cacheIrregular'])) {
+ self::$singular['cacheUninflected'] = '(?:' . join('|', self::$singular['merged']['uninflected']) . ')';
+ self::$singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$singular['merged']['irregular'])) . ')';
+ }
+
+ if (preg_match('/(.*)\\b(' . self::$singular['cacheIrregular'] . ')$/i', $word, $regs)) {
+ self::$cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$singular['merged']['irregular'][strtolower($regs[2])], 1);
+
+ return self::$cache['singularize'][$word];
+ }
+
+ if (preg_match('/^(' . self::$singular['cacheUninflected'] . ')$/i', $word, $regs)) {
+ self::$cache['singularize'][$word] = $word;
+
+ return $word;
+ }
+
+ foreach (self::$singular['rules'] as $rule => $replacement) {
+ if (preg_match($rule, $word)) {
+ self::$cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
+
+ return self::$cache['singularize'][$word];
+ }
+ }
+
+ self::$cache['singularize'][$word] = $word;
+
+ return $word;
+ }
+}
diff --git a/vendor/illuminate/container/BoundMethod.php b/vendor/illuminate/container/BoundMethod.php
new file mode 100644
index 0000000..0dfd6fd
--- /dev/null
+++ b/vendor/illuminate/container/BoundMethod.php
@@ -0,0 +1,172 @@
+make($segments[0]), $method], $parameters
+ );
+ }
+
+ /**
+ * Call a method that has been bound to the container.
+ *
+ * @param \Illuminate\Container\Container $container
+ * @param callable $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ protected static function callBoundMethod($container, $callback, $default)
+ {
+ if (! is_array($callback)) {
+ return $default instanceof Closure ? $default() : $default;
+ }
+
+ // Here we need to turn the array callable into a Class@method string we can use to
+ // examine the container and see if there are any method bindings for this given
+ // method. If there are, we can call this method binding callback immediately.
+ $method = static::normalizeMethod($callback);
+
+ if ($container->hasMethodBinding($method)) {
+ return $container->callMethodBinding($method, $callback[0]);
+ }
+
+ return $default instanceof Closure ? $default() : $default;
+ }
+
+ /**
+ * Normalize the given callback into a Class@method string.
+ *
+ * @param callable $callback
+ * @return string
+ */
+ protected static function normalizeMethod($callback)
+ {
+ $class = is_string($callback[0]) ? $callback[0] : get_class($callback[0]);
+
+ return "{$class}@{$callback[1]}";
+ }
+
+ /**
+ * Get all dependencies for a given method.
+ *
+ * @param \Illuminate\Container\Container $container
+ * @param callable|string $callback
+ * @param array $parameters
+ * @return array
+ */
+ protected static function getMethodDependencies($container, $callback, array $parameters = [])
+ {
+ $dependencies = [];
+
+ foreach (static::getCallReflector($callback)->getParameters() as $parameter) {
+ static::addDependencyForCallParameter($container, $parameter, $parameters, $dependencies);
+ }
+
+ return array_merge($dependencies, $parameters);
+ }
+
+ /**
+ * Get the proper reflection instance for the given callback.
+ *
+ * @param callable|string $callback
+ * @return \ReflectionFunctionAbstract
+ */
+ protected static function getCallReflector($callback)
+ {
+ if (is_string($callback) && strpos($callback, '::') !== false) {
+ $callback = explode('::', $callback);
+ }
+
+ return is_array($callback)
+ ? new ReflectionMethod($callback[0], $callback[1])
+ : new ReflectionFunction($callback);
+ }
+
+ /**
+ * Get the dependency for the given call parameter.
+ *
+ * @param \Illuminate\Container\Container $container
+ * @param \ReflectionParameter $parameter
+ * @param array $parameters
+ * @param array $dependencies
+ * @return mixed
+ */
+ protected static function addDependencyForCallParameter($container, $parameter,
+ array &$parameters, &$dependencies)
+ {
+ if (array_key_exists($parameter->name, $parameters)) {
+ $dependencies[] = $parameters[$parameter->name];
+
+ unset($parameters[$parameter->name]);
+ } elseif ($parameter->getClass()) {
+ $dependencies[] = $container->make($parameter->getClass()->name);
+ } elseif ($parameter->isDefaultValueAvailable()) {
+ $dependencies[] = $parameter->getDefaultValue();
+ }
+ }
+
+ /**
+ * Determine if the given string is in Class@method syntax.
+ *
+ * @param mixed $callback
+ * @return bool
+ */
+ protected static function isCallableWithAtSign($callback)
+ {
+ return is_string($callback) && strpos($callback, '@') !== false;
+ }
+}
diff --git a/vendor/illuminate/container/Container.php b/vendor/illuminate/container/Container.php
new file mode 100644
index 0000000..61c2b5e
--- /dev/null
+++ b/vendor/illuminate/container/Container.php
@@ -0,0 +1,1245 @@
+getAlias($concrete));
+ }
+
+ /**
+ * Determine if the given abstract type has been bound.
+ *
+ * @param string $abstract
+ * @return bool
+ */
+ public function bound($abstract)
+ {
+ return isset($this->bindings[$abstract]) ||
+ isset($this->instances[$abstract]) ||
+ $this->isAlias($abstract);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($id)
+ {
+ return $this->bound($id);
+ }
+
+ /**
+ * Determine if the given abstract type has been resolved.
+ *
+ * @param string $abstract
+ * @return bool
+ */
+ public function resolved($abstract)
+ {
+ if ($this->isAlias($abstract)) {
+ $abstract = $this->getAlias($abstract);
+ }
+
+ return isset($this->resolved[$abstract]) ||
+ isset($this->instances[$abstract]);
+ }
+
+ /**
+ * Determine if a given type is shared.
+ *
+ * @param string $abstract
+ * @return bool
+ */
+ public function isShared($abstract)
+ {
+ return isset($this->instances[$abstract]) ||
+ (isset($this->bindings[$abstract]['shared']) &&
+ $this->bindings[$abstract]['shared'] === true);
+ }
+
+ /**
+ * Determine if a given string is an alias.
+ *
+ * @param string $name
+ * @return bool
+ */
+ public function isAlias($name)
+ {
+ return isset($this->aliases[$name]);
+ }
+
+ /**
+ * Register a binding with the container.
+ *
+ * @param string $abstract
+ * @param \Closure|string|null $concrete
+ * @param bool $shared
+ * @return void
+ */
+ public function bind($abstract, $concrete = null, $shared = false)
+ {
+ // If no concrete type was given, we will simply set the concrete type to the
+ // abstract type. After that, the concrete type to be registered as shared
+ // without being forced to state their classes in both of the parameters.
+ $this->dropStaleInstances($abstract);
+
+ if (is_null($concrete)) {
+ $concrete = $abstract;
+ }
+
+ // If the factory is not a Closure, it means it is just a class name which is
+ // bound into this container to the abstract type and we will just wrap it
+ // up inside its own Closure to give us more convenience when extending.
+ if (! $concrete instanceof Closure) {
+ $concrete = $this->getClosure($abstract, $concrete);
+ }
+
+ $this->bindings[$abstract] = compact('concrete', 'shared');
+
+ // If the abstract type was already resolved in this container we'll fire the
+ // rebound listener so that any objects which have already gotten resolved
+ // can have their copy of the object updated via the listener callbacks.
+ if ($this->resolved($abstract)) {
+ $this->rebound($abstract);
+ }
+ }
+
+ /**
+ * Get the Closure to be used when building a type.
+ *
+ * @param string $abstract
+ * @param string $concrete
+ * @return \Closure
+ */
+ protected function getClosure($abstract, $concrete)
+ {
+ return function ($container, $parameters = []) use ($abstract, $concrete) {
+ if ($abstract == $concrete) {
+ return $container->build($concrete);
+ }
+
+ return $container->make($concrete, $parameters);
+ };
+ }
+
+ /**
+ * Determine if the container has a method binding.
+ *
+ * @param string $method
+ * @return bool
+ */
+ public function hasMethodBinding($method)
+ {
+ return isset($this->methodBindings[$method]);
+ }
+
+ /**
+ * Bind a callback to resolve with Container::call.
+ *
+ * @param string $method
+ * @param \Closure $callback
+ * @return void
+ */
+ public function bindMethod($method, $callback)
+ {
+ $this->methodBindings[$method] = $callback;
+ }
+
+ /**
+ * Get the method binding for the given method.
+ *
+ * @param string $method
+ * @param mixed $instance
+ * @return mixed
+ */
+ public function callMethodBinding($method, $instance)
+ {
+ return call_user_func($this->methodBindings[$method], $instance, $this);
+ }
+
+ /**
+ * Add a contextual binding to the container.
+ *
+ * @param string $concrete
+ * @param string $abstract
+ * @param \Closure|string $implementation
+ * @return void
+ */
+ public function addContextualBinding($concrete, $abstract, $implementation)
+ {
+ $this->contextual[$concrete][$this->getAlias($abstract)] = $implementation;
+ }
+
+ /**
+ * Register a binding if it hasn't already been registered.
+ *
+ * @param string $abstract
+ * @param \Closure|string|null $concrete
+ * @param bool $shared
+ * @return void
+ */
+ public function bindIf($abstract, $concrete = null, $shared = false)
+ {
+ if (! $this->bound($abstract)) {
+ $this->bind($abstract, $concrete, $shared);
+ }
+ }
+
+ /**
+ * Register a shared binding in the container.
+ *
+ * @param string $abstract
+ * @param \Closure|string|null $concrete
+ * @return void
+ */
+ public function singleton($abstract, $concrete = null)
+ {
+ $this->bind($abstract, $concrete, true);
+ }
+
+ /**
+ * "Extend" an abstract type in the container.
+ *
+ * @param string $abstract
+ * @param \Closure $closure
+ * @return void
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function extend($abstract, Closure $closure)
+ {
+ $abstract = $this->getAlias($abstract);
+
+ if (isset($this->instances[$abstract])) {
+ $this->instances[$abstract] = $closure($this->instances[$abstract], $this);
+
+ $this->rebound($abstract);
+ } else {
+ $this->extenders[$abstract][] = $closure;
+
+ if ($this->resolved($abstract)) {
+ $this->rebound($abstract);
+ }
+ }
+ }
+
+ /**
+ * Register an existing instance as shared in the container.
+ *
+ * @param string $abstract
+ * @param mixed $instance
+ * @return mixed
+ */
+ public function instance($abstract, $instance)
+ {
+ $this->removeAbstractAlias($abstract);
+
+ $isBound = $this->bound($abstract);
+
+ unset($this->aliases[$abstract]);
+
+ // We'll check to determine if this type has been bound before, and if it has
+ // we will fire the rebound callbacks registered with the container and it
+ // can be updated with consuming classes that have gotten resolved here.
+ $this->instances[$abstract] = $instance;
+
+ if ($isBound) {
+ $this->rebound($abstract);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Remove an alias from the contextual binding alias cache.
+ *
+ * @param string $searched
+ * @return void
+ */
+ protected function removeAbstractAlias($searched)
+ {
+ if (! isset($this->aliases[$searched])) {
+ return;
+ }
+
+ foreach ($this->abstractAliases as $abstract => $aliases) {
+ foreach ($aliases as $index => $alias) {
+ if ($alias == $searched) {
+ unset($this->abstractAliases[$abstract][$index]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Assign a set of tags to a given binding.
+ *
+ * @param array|string $abstracts
+ * @param array|mixed ...$tags
+ * @return void
+ */
+ public function tag($abstracts, $tags)
+ {
+ $tags = is_array($tags) ? $tags : array_slice(func_get_args(), 1);
+
+ foreach ($tags as $tag) {
+ if (! isset($this->tags[$tag])) {
+ $this->tags[$tag] = [];
+ }
+
+ foreach ((array) $abstracts as $abstract) {
+ $this->tags[$tag][] = $abstract;
+ }
+ }
+ }
+
+ /**
+ * Resolve all of the bindings for a given tag.
+ *
+ * @param string $tag
+ * @return array
+ */
+ public function tagged($tag)
+ {
+ $results = [];
+
+ if (isset($this->tags[$tag])) {
+ foreach ($this->tags[$tag] as $abstract) {
+ $results[] = $this->make($abstract);
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Alias a type to a different name.
+ *
+ * @param string $abstract
+ * @param string $alias
+ * @return void
+ */
+ public function alias($abstract, $alias)
+ {
+ $this->aliases[$alias] = $abstract;
+
+ $this->abstractAliases[$abstract][] = $alias;
+ }
+
+ /**
+ * Bind a new callback to an abstract's rebind event.
+ *
+ * @param string $abstract
+ * @param \Closure $callback
+ * @return mixed
+ */
+ public function rebinding($abstract, Closure $callback)
+ {
+ $this->reboundCallbacks[$abstract = $this->getAlias($abstract)][] = $callback;
+
+ if ($this->bound($abstract)) {
+ return $this->make($abstract);
+ }
+ }
+
+ /**
+ * Refresh an instance on the given target and method.
+ *
+ * @param string $abstract
+ * @param mixed $target
+ * @param string $method
+ * @return mixed
+ */
+ public function refresh($abstract, $target, $method)
+ {
+ return $this->rebinding($abstract, function ($app, $instance) use ($target, $method) {
+ $target->{$method}($instance);
+ });
+ }
+
+ /**
+ * Fire the "rebound" callbacks for the given abstract type.
+ *
+ * @param string $abstract
+ * @return void
+ */
+ protected function rebound($abstract)
+ {
+ $instance = $this->make($abstract);
+
+ foreach ($this->getReboundCallbacks($abstract) as $callback) {
+ call_user_func($callback, $this, $instance);
+ }
+ }
+
+ /**
+ * Get the rebound callbacks for a given type.
+ *
+ * @param string $abstract
+ * @return array
+ */
+ protected function getReboundCallbacks($abstract)
+ {
+ if (isset($this->reboundCallbacks[$abstract])) {
+ return $this->reboundCallbacks[$abstract];
+ }
+
+ return [];
+ }
+
+ /**
+ * Wrap the given closure such that its dependencies will be injected when executed.
+ *
+ * @param \Closure $callback
+ * @param array $parameters
+ * @return \Closure
+ */
+ public function wrap(Closure $callback, array $parameters = [])
+ {
+ return function () use ($callback, $parameters) {
+ return $this->call($callback, $parameters);
+ };
+ }
+
+ /**
+ * Call the given Closure / class@method and inject its dependencies.
+ *
+ * @param callable|string $callback
+ * @param array $parameters
+ * @param string|null $defaultMethod
+ * @return mixed
+ */
+ public function call($callback, array $parameters = [], $defaultMethod = null)
+ {
+ return BoundMethod::call($this, $callback, $parameters, $defaultMethod);
+ }
+
+ /**
+ * Get a closure to resolve the given type from the container.
+ *
+ * @param string $abstract
+ * @return \Closure
+ */
+ public function factory($abstract)
+ {
+ return function () use ($abstract) {
+ return $this->make($abstract);
+ };
+ }
+
+ /**
+ * An alias function name for make().
+ *
+ * @param string $abstract
+ * @param array $parameters
+ * @return mixed
+ */
+ public function makeWith($abstract, array $parameters = [])
+ {
+ return $this->make($abstract, $parameters);
+ }
+
+ /**
+ * Resolve the given type from the container.
+ *
+ * @param string $abstract
+ * @param array $parameters
+ * @return mixed
+ */
+ public function make($abstract, array $parameters = [])
+ {
+ return $this->resolve($abstract, $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($id)
+ {
+ if ($this->has($id)) {
+ return $this->resolve($id);
+ }
+
+ throw new EntryNotFoundException;
+ }
+
+ /**
+ * Resolve the given type from the container.
+ *
+ * @param string $abstract
+ * @param array $parameters
+ * @return mixed
+ */
+ protected function resolve($abstract, $parameters = [])
+ {
+ $abstract = $this->getAlias($abstract);
+
+ $needsContextualBuild = ! empty($parameters) || ! is_null(
+ $this->getContextualConcrete($abstract)
+ );
+
+ // If an instance of the type is currently being managed as a singleton we'll
+ // just return an existing instance instead of instantiating new instances
+ // so the developer can keep using the same objects instance every time.
+ if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
+ return $this->instances[$abstract];
+ }
+
+ $this->with[] = $parameters;
+
+ $concrete = $this->getConcrete($abstract);
+
+ // We're ready to instantiate an instance of the concrete type registered for
+ // the binding. This will instantiate the types, as well as resolve any of
+ // its "nested" dependencies recursively until all have gotten resolved.
+ if ($this->isBuildable($concrete, $abstract)) {
+ $object = $this->build($concrete);
+ } else {
+ $object = $this->make($concrete);
+ }
+
+ // If we defined any extenders for this type, we'll need to spin through them
+ // and apply them to the object being built. This allows for the extension
+ // of services, such as changing configuration or decorating the object.
+ foreach ($this->getExtenders($abstract) as $extender) {
+ $object = $extender($object, $this);
+ }
+
+ // If the requested type is registered as a singleton we'll want to cache off
+ // the instances in "memory" so we can return it later without creating an
+ // entirely new instance of an object on each subsequent request for it.
+ if ($this->isShared($abstract) && ! $needsContextualBuild) {
+ $this->instances[$abstract] = $object;
+ }
+
+ $this->fireResolvingCallbacks($abstract, $object);
+
+ // Before returning, we will also set the resolved flag to "true" and pop off
+ // the parameter overrides for this build. After those two things are done
+ // we will be ready to return back the fully constructed class instance.
+ $this->resolved[$abstract] = true;
+
+ array_pop($this->with);
+
+ return $object;
+ }
+
+ /**
+ * Get the concrete type for a given abstract.
+ *
+ * @param string $abstract
+ * @return mixed $concrete
+ */
+ protected function getConcrete($abstract)
+ {
+ if (! is_null($concrete = $this->getContextualConcrete($abstract))) {
+ return $concrete;
+ }
+
+ // If we don't have a registered resolver or concrete for the type, we'll just
+ // assume each type is a concrete name and will attempt to resolve it as is
+ // since the container should be able to resolve concretes automatically.
+ if (isset($this->bindings[$abstract])) {
+ return $this->bindings[$abstract]['concrete'];
+ }
+
+ return $abstract;
+ }
+
+ /**
+ * Get the contextual concrete binding for the given abstract.
+ *
+ * @param string $abstract
+ * @return string|null
+ */
+ protected function getContextualConcrete($abstract)
+ {
+ if (! is_null($binding = $this->findInContextualBindings($abstract))) {
+ return $binding;
+ }
+
+ // Next we need to see if a contextual binding might be bound under an alias of the
+ // given abstract type. So, we will need to check if any aliases exist with this
+ // type and then spin through them and check for contextual bindings on these.
+ if (empty($this->abstractAliases[$abstract])) {
+ return;
+ }
+
+ foreach ($this->abstractAliases[$abstract] as $alias) {
+ if (! is_null($binding = $this->findInContextualBindings($alias))) {
+ return $binding;
+ }
+ }
+ }
+
+ /**
+ * Find the concrete binding for the given abstract in the contextual binding array.
+ *
+ * @param string $abstract
+ * @return string|null
+ */
+ protected function findInContextualBindings($abstract)
+ {
+ if (isset($this->contextual[end($this->buildStack)][$abstract])) {
+ return $this->contextual[end($this->buildStack)][$abstract];
+ }
+ }
+
+ /**
+ * Determine if the given concrete is buildable.
+ *
+ * @param mixed $concrete
+ * @param string $abstract
+ * @return bool
+ */
+ protected function isBuildable($concrete, $abstract)
+ {
+ return $concrete === $abstract || $concrete instanceof Closure;
+ }
+
+ /**
+ * Instantiate a concrete instance of the given type.
+ *
+ * @param string $concrete
+ * @return mixed
+ *
+ * @throws \Illuminate\Contracts\Container\BindingResolutionException
+ */
+ public function build($concrete)
+ {
+ // If the concrete type is actually a Closure, we will just execute it and
+ // hand back the results of the functions, which allows functions to be
+ // used as resolvers for more fine-tuned resolution of these objects.
+ if ($concrete instanceof Closure) {
+ return $concrete($this, $this->getLastParameterOverride());
+ }
+
+ $reflector = new ReflectionClass($concrete);
+
+ // If the type is not instantiable, the developer is attempting to resolve
+ // an abstract type such as an Interface of Abstract Class and there is
+ // no binding registered for the abstractions so we need to bail out.
+ if (! $reflector->isInstantiable()) {
+ return $this->notInstantiable($concrete);
+ }
+
+ $this->buildStack[] = $concrete;
+
+ $constructor = $reflector->getConstructor();
+
+ // If there are no constructors, that means there are no dependencies then
+ // we can just resolve the instances of the objects right away, without
+ // resolving any other types or dependencies out of these containers.
+ if (is_null($constructor)) {
+ array_pop($this->buildStack);
+
+ return new $concrete;
+ }
+
+ $dependencies = $constructor->getParameters();
+
+ // Once we have all the constructor's parameters we can create each of the
+ // dependency instances and then use the reflection instances to make a
+ // new instance of this class, injecting the created dependencies in.
+ $instances = $this->resolveDependencies(
+ $dependencies
+ );
+
+ array_pop($this->buildStack);
+
+ return $reflector->newInstanceArgs($instances);
+ }
+
+ /**
+ * Resolve all of the dependencies from the ReflectionParameters.
+ *
+ * @param array $dependencies
+ * @return array
+ */
+ protected function resolveDependencies(array $dependencies)
+ {
+ $results = [];
+
+ foreach ($dependencies as $dependency) {
+ // If this dependency has a override for this particular build we will use
+ // that instead as the value. Otherwise, we will continue with this run
+ // of resolutions and let reflection attempt to determine the result.
+ if ($this->hasParameterOverride($dependency)) {
+ $results[] = $this->getParameterOverride($dependency);
+
+ continue;
+ }
+
+ // If the class is null, it means the dependency is a string or some other
+ // primitive type which we can not resolve since it is not a class and
+ // we will just bomb out with an error since we have no-where to go.
+ $results[] = is_null($dependency->getClass())
+ ? $this->resolvePrimitive($dependency)
+ : $this->resolveClass($dependency);
+ }
+
+ return $results;
+ }
+
+ /**
+ * Determine if the given dependency has a parameter override.
+ *
+ * @param \ReflectionParameter $dependency
+ * @return bool
+ */
+ protected function hasParameterOverride($dependency)
+ {
+ return array_key_exists(
+ $dependency->name, $this->getLastParameterOverride()
+ );
+ }
+
+ /**
+ * Get a parameter override for a dependency.
+ *
+ * @param \ReflectionParameter $dependency
+ * @return mixed
+ */
+ protected function getParameterOverride($dependency)
+ {
+ return $this->getLastParameterOverride()[$dependency->name];
+ }
+
+ /**
+ * Get the last parameter override.
+ *
+ * @return array
+ */
+ protected function getLastParameterOverride()
+ {
+ return count($this->with) ? end($this->with) : [];
+ }
+
+ /**
+ * Resolve a non-class hinted primitive dependency.
+ *
+ * @param \ReflectionParameter $parameter
+ * @return mixed
+ *
+ * @throws \Illuminate\Contracts\Container\BindingResolutionException
+ */
+ protected function resolvePrimitive(ReflectionParameter $parameter)
+ {
+ if (! is_null($concrete = $this->getContextualConcrete('$'.$parameter->name))) {
+ return $concrete instanceof Closure ? $concrete($this) : $concrete;
+ }
+
+ if ($parameter->isDefaultValueAvailable()) {
+ return $parameter->getDefaultValue();
+ }
+
+ $this->unresolvablePrimitive($parameter);
+ }
+
+ /**
+ * Resolve a class based dependency from the container.
+ *
+ * @param \ReflectionParameter $parameter
+ * @return mixed
+ *
+ * @throws \Illuminate\Contracts\Container\BindingResolutionException
+ */
+ protected function resolveClass(ReflectionParameter $parameter)
+ {
+ try {
+ return $this->make($parameter->getClass()->name);
+ }
+
+ // If we can not resolve the class instance, we will check to see if the value
+ // is optional, and if it is we will return the optional parameter value as
+ // the value of the dependency, similarly to how we do this with scalars.
+ catch (BindingResolutionException $e) {
+ if ($parameter->isOptional()) {
+ return $parameter->getDefaultValue();
+ }
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Throw an exception that the concrete is not instantiable.
+ *
+ * @param string $concrete
+ * @return void
+ *
+ * @throws \Illuminate\Contracts\Container\BindingResolutionException
+ */
+ protected function notInstantiable($concrete)
+ {
+ if (! empty($this->buildStack)) {
+ $previous = implode(', ', $this->buildStack);
+
+ $message = "Target [$concrete] is not instantiable while building [$previous].";
+ } else {
+ $message = "Target [$concrete] is not instantiable.";
+ }
+
+ throw new BindingResolutionException($message);
+ }
+
+ /**
+ * Throw an exception for an unresolvable primitive.
+ *
+ * @param \ReflectionParameter $parameter
+ * @return void
+ *
+ * @throws \Illuminate\Contracts\Container\BindingResolutionException
+ */
+ protected function unresolvablePrimitive(ReflectionParameter $parameter)
+ {
+ $message = "Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}";
+
+ throw new BindingResolutionException($message);
+ }
+
+ /**
+ * Register a new resolving callback.
+ *
+ * @param \Closure|string $abstract
+ * @param \Closure|null $callback
+ * @return void
+ */
+ public function resolving($abstract, Closure $callback = null)
+ {
+ if (is_string($abstract)) {
+ $abstract = $this->getAlias($abstract);
+ }
+
+ if (is_null($callback) && $abstract instanceof Closure) {
+ $this->globalResolvingCallbacks[] = $abstract;
+ } else {
+ $this->resolvingCallbacks[$abstract][] = $callback;
+ }
+ }
+
+ /**
+ * Register a new after resolving callback for all types.
+ *
+ * @param \Closure|string $abstract
+ * @param \Closure|null $callback
+ * @return void
+ */
+ public function afterResolving($abstract, Closure $callback = null)
+ {
+ if (is_string($abstract)) {
+ $abstract = $this->getAlias($abstract);
+ }
+
+ if ($abstract instanceof Closure && is_null($callback)) {
+ $this->globalAfterResolvingCallbacks[] = $abstract;
+ } else {
+ $this->afterResolvingCallbacks[$abstract][] = $callback;
+ }
+ }
+
+ /**
+ * Fire all of the resolving callbacks.
+ *
+ * @param string $abstract
+ * @param mixed $object
+ * @return void
+ */
+ protected function fireResolvingCallbacks($abstract, $object)
+ {
+ $this->fireCallbackArray($object, $this->globalResolvingCallbacks);
+
+ $this->fireCallbackArray(
+ $object, $this->getCallbacksForType($abstract, $object, $this->resolvingCallbacks)
+ );
+
+ $this->fireAfterResolvingCallbacks($abstract, $object);
+ }
+
+ /**
+ * Fire all of the after resolving callbacks.
+ *
+ * @param string $abstract
+ * @param mixed $object
+ * @return void
+ */
+ protected function fireAfterResolvingCallbacks($abstract, $object)
+ {
+ $this->fireCallbackArray($object, $this->globalAfterResolvingCallbacks);
+
+ $this->fireCallbackArray(
+ $object, $this->getCallbacksForType($abstract, $object, $this->afterResolvingCallbacks)
+ );
+ }
+
+ /**
+ * Get all callbacks for a given type.
+ *
+ * @param string $abstract
+ * @param object $object
+ * @param array $callbacksPerType
+ *
+ * @return array
+ */
+ protected function getCallbacksForType($abstract, $object, array $callbacksPerType)
+ {
+ $results = [];
+
+ foreach ($callbacksPerType as $type => $callbacks) {
+ if ($type === $abstract || $object instanceof $type) {
+ $results = array_merge($results, $callbacks);
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Fire an array of callbacks with an object.
+ *
+ * @param mixed $object
+ * @param array $callbacks
+ * @return void
+ */
+ protected function fireCallbackArray($object, array $callbacks)
+ {
+ foreach ($callbacks as $callback) {
+ $callback($object, $this);
+ }
+ }
+
+ /**
+ * Get the container's bindings.
+ *
+ * @return array
+ */
+ public function getBindings()
+ {
+ return $this->bindings;
+ }
+
+ /**
+ * Get the alias for an abstract if available.
+ *
+ * @param string $abstract
+ * @return string
+ *
+ * @throws \LogicException
+ */
+ public function getAlias($abstract)
+ {
+ if (! isset($this->aliases[$abstract])) {
+ return $abstract;
+ }
+
+ if ($this->aliases[$abstract] === $abstract) {
+ throw new LogicException("[{$abstract}] is aliased to itself.");
+ }
+
+ return $this->getAlias($this->aliases[$abstract]);
+ }
+
+ /**
+ * Get the extender callbacks for a given type.
+ *
+ * @param string $abstract
+ * @return array
+ */
+ protected function getExtenders($abstract)
+ {
+ $abstract = $this->getAlias($abstract);
+
+ if (isset($this->extenders[$abstract])) {
+ return $this->extenders[$abstract];
+ }
+
+ return [];
+ }
+
+ /**
+ * Remove all of the extender callbacks for a given type.
+ *
+ * @param string $abstract
+ * @return void
+ */
+ public function forgetExtenders($abstract)
+ {
+ unset($this->extenders[$this->getAlias($abstract)]);
+ }
+
+ /**
+ * Drop all of the stale instances and aliases.
+ *
+ * @param string $abstract
+ * @return void
+ */
+ protected function dropStaleInstances($abstract)
+ {
+ unset($this->instances[$abstract], $this->aliases[$abstract]);
+ }
+
+ /**
+ * Remove a resolved instance from the instance cache.
+ *
+ * @param string $abstract
+ * @return void
+ */
+ public function forgetInstance($abstract)
+ {
+ unset($this->instances[$abstract]);
+ }
+
+ /**
+ * Clear all of the instances from the container.
+ *
+ * @return void
+ */
+ public function forgetInstances()
+ {
+ $this->instances = [];
+ }
+
+ /**
+ * Flush the container of all bindings and resolved instances.
+ *
+ * @return void
+ */
+ public function flush()
+ {
+ $this->aliases = [];
+ $this->resolved = [];
+ $this->bindings = [];
+ $this->instances = [];
+ $this->abstractAliases = [];
+ }
+
+ /**
+ * Set the globally available instance of the container.
+ *
+ * @return static
+ */
+ public static function getInstance()
+ {
+ if (is_null(static::$instance)) {
+ static::$instance = new static;
+ }
+
+ return static::$instance;
+ }
+
+ /**
+ * Set the shared instance of the container.
+ *
+ * @param \Illuminate\Contracts\Container\Container|null $container
+ * @return static
+ */
+ public static function setInstance(ContainerContract $container = null)
+ {
+ return static::$instance = $container;
+ }
+
+ /**
+ * Determine if a given offset exists.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function offsetExists($key)
+ {
+ return $this->bound($key);
+ }
+
+ /**
+ * Get the value at a given offset.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function offsetGet($key)
+ {
+ return $this->make($key);
+ }
+
+ /**
+ * Set the value at a given offset.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($key, $value)
+ {
+ $this->bind($key, $value instanceof Closure ? $value : function () use ($value) {
+ return $value;
+ });
+ }
+
+ /**
+ * Unset the value at a given offset.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function offsetUnset($key)
+ {
+ unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]);
+ }
+
+ /**
+ * Dynamically access container services.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ return $this[$key];
+ }
+
+ /**
+ * Dynamically set container services.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this[$key] = $value;
+ }
+}
diff --git a/vendor/illuminate/container/ContextualBindingBuilder.php b/vendor/illuminate/container/ContextualBindingBuilder.php
new file mode 100644
index 0000000..58b70ce
--- /dev/null
+++ b/vendor/illuminate/container/ContextualBindingBuilder.php
@@ -0,0 +1,68 @@
+concrete = $concrete;
+ $this->container = $container;
+ }
+
+ /**
+ * Define the abstract target that depends on the context.
+ *
+ * @param string $abstract
+ * @return $this
+ */
+ public function needs($abstract)
+ {
+ $this->needs = $abstract;
+
+ return $this;
+ }
+
+ /**
+ * Define the implementation for the contextual binding.
+ *
+ * @param \Closure|string $implementation
+ * @return void
+ */
+ public function give($implementation)
+ {
+ $this->container->addContextualBinding(
+ $this->concrete, $this->needs, $implementation
+ );
+ }
+}
diff --git a/vendor/illuminate/container/EntryNotFoundException.php b/vendor/illuminate/container/EntryNotFoundException.php
new file mode 100644
index 0000000..4266921
--- /dev/null
+++ b/vendor/illuminate/container/EntryNotFoundException.php
@@ -0,0 +1,11 @@
+=7.0",
+ "illuminate/contracts": "5.5.*",
+ "psr/container": "~1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Container\\": ""
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.5-dev"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/contracts/Auth/Access/Authorizable.php b/vendor/illuminate/contracts/Auth/Access/Authorizable.php
new file mode 100644
index 0000000..2f9657c
--- /dev/null
+++ b/vendor/illuminate/contracts/Auth/Access/Authorizable.php
@@ -0,0 +1,15 @@
+id = $id;
+ $this->class = $class;
+ $this->connection = $connection;
+ }
+}
diff --git a/vendor/illuminate/contracts/Debug/ExceptionHandler.php b/vendor/illuminate/contracts/Debug/ExceptionHandler.php
new file mode 100644
index 0000000..e3f18a5
--- /dev/null
+++ b/vendor/illuminate/contracts/Debug/ExceptionHandler.php
@@ -0,0 +1,34 @@
+=7.0",
+ "psr/container": "~1.0",
+ "psr/simple-cache": "~1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Contracts\\": ""
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.5-dev"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/events/CallQueuedListener.php b/vendor/illuminate/events/CallQueuedListener.php
new file mode 100644
index 0000000..a66b4f9
--- /dev/null
+++ b/vendor/illuminate/events/CallQueuedListener.php
@@ -0,0 +1,160 @@
+data = $data;
+ $this->class = $class;
+ $this->method = $method;
+ }
+
+ /**
+ * Handle the queued job.
+ *
+ * @param \Illuminate\Container\Container $container
+ * @return void
+ */
+ public function handle(Container $container)
+ {
+ $this->prepareData();
+
+ $handler = $this->setJobInstanceIfNecessary(
+ $this->job, $container->make($this->class)
+ );
+
+ call_user_func_array(
+ [$handler, $this->method], $this->data
+ );
+ }
+
+ /**
+ * Set the job instance of the given class if necessary.
+ *
+ * @param \Illuminate\Contracts\Queue\Job $job
+ * @param mixed $instance
+ * @return mixed
+ */
+ protected function setJobInstanceIfNecessary(Job $job, $instance)
+ {
+ if (in_array(InteractsWithQueue::class, class_uses_recursive(get_class($instance)))) {
+ $instance->setJob($job);
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Call the failed method on the job instance.
+ *
+ * The event instance and the exception will be passed.
+ *
+ * @param \Exception $e
+ * @return void
+ */
+ public function failed($e)
+ {
+ $this->prepareData();
+
+ $handler = Container::getInstance()->make($this->class);
+
+ $parameters = array_merge($this->data, [$e]);
+
+ if (method_exists($handler, 'failed')) {
+ call_user_func_array([$handler, 'failed'], $parameters);
+ }
+ }
+
+ /**
+ * Unserialize the data if needed.
+ *
+ * @return void
+ */
+ protected function prepareData()
+ {
+ if (is_string($this->data)) {
+ $this->data = unserialize($this->data);
+ }
+ }
+
+ /**
+ * Get the display name for the queued job.
+ *
+ * @return string
+ */
+ public function displayName()
+ {
+ return $this->class;
+ }
+
+ /**
+ * Prepare the instance for cloning.
+ *
+ * @return void
+ */
+ public function __clone()
+ {
+ $this->data = array_map(function ($data) {
+ return is_object($data) ? clone $data : $data;
+ }, $this->data);
+ }
+}
diff --git a/vendor/illuminate/events/Dispatcher.php b/vendor/illuminate/events/Dispatcher.php
new file mode 100644
index 0000000..d99031c
--- /dev/null
+++ b/vendor/illuminate/events/Dispatcher.php
@@ -0,0 +1,563 @@
+container = $container ?: new Container;
+ }
+
+ /**
+ * Register an event listener with the dispatcher.
+ *
+ * @param string|array $events
+ * @param mixed $listener
+ * @return void
+ */
+ public function listen($events, $listener)
+ {
+ foreach ((array) $events as $event) {
+ if (Str::contains($event, '*')) {
+ $this->setupWildcardListen($event, $listener);
+ } else {
+ $this->listeners[$event][] = $this->makeListener($listener);
+ }
+ }
+ }
+
+ /**
+ * Setup a wildcard listener callback.
+ *
+ * @param string $event
+ * @param mixed $listener
+ * @return void
+ */
+ protected function setupWildcardListen($event, $listener)
+ {
+ $this->wildcards[$event][] = $this->makeListener($listener, true);
+ }
+
+ /**
+ * Determine if a given event has listeners.
+ *
+ * @param string $eventName
+ * @return bool
+ */
+ public function hasListeners($eventName)
+ {
+ return isset($this->listeners[$eventName]) || isset($this->wildcards[$eventName]);
+ }
+
+ /**
+ * Register an event and payload to be fired later.
+ *
+ * @param string $event
+ * @param array $payload
+ * @return void
+ */
+ public function push($event, $payload = [])
+ {
+ $this->listen($event.'_pushed', function () use ($event, $payload) {
+ $this->dispatch($event, $payload);
+ });
+ }
+
+ /**
+ * Flush a set of pushed events.
+ *
+ * @param string $event
+ * @return void
+ */
+ public function flush($event)
+ {
+ $this->dispatch($event.'_pushed');
+ }
+
+ /**
+ * Register an event subscriber with the dispatcher.
+ *
+ * @param object|string $subscriber
+ * @return void
+ */
+ public function subscribe($subscriber)
+ {
+ $subscriber = $this->resolveSubscriber($subscriber);
+
+ $subscriber->subscribe($this);
+ }
+
+ /**
+ * Resolve the subscriber instance.
+ *
+ * @param object|string $subscriber
+ * @return mixed
+ */
+ protected function resolveSubscriber($subscriber)
+ {
+ if (is_string($subscriber)) {
+ return $this->container->make($subscriber);
+ }
+
+ return $subscriber;
+ }
+
+ /**
+ * Fire an event until the first non-null response is returned.
+ *
+ * @param string|object $event
+ * @param mixed $payload
+ * @return array|null
+ */
+ public function until($event, $payload = [])
+ {
+ return $this->dispatch($event, $payload, true);
+ }
+
+ /**
+ * Fire an event and call the listeners.
+ *
+ * @param string|object $event
+ * @param mixed $payload
+ * @param bool $halt
+ * @return array|null
+ */
+ public function fire($event, $payload = [], $halt = false)
+ {
+ return $this->dispatch($event, $payload, $halt);
+ }
+
+ /**
+ * Fire an event and call the listeners.
+ *
+ * @param string|object $event
+ * @param mixed $payload
+ * @param bool $halt
+ * @return array|null
+ */
+ public function dispatch($event, $payload = [], $halt = false)
+ {
+ // When the given "event" is actually an object we will assume it is an event
+ // object and use the class as the event name and this event itself as the
+ // payload to the handler, which makes object based events quite simple.
+ list($event, $payload) = $this->parseEventAndPayload(
+ $event, $payload
+ );
+
+ if ($this->shouldBroadcast($payload)) {
+ $this->broadcastEvent($payload[0]);
+ }
+
+ $responses = [];
+
+ foreach ($this->getListeners($event) as $listener) {
+ $response = $listener($event, $payload);
+
+ // If a response is returned from the listener and event halting is enabled
+ // we will just return this response, and not call the rest of the event
+ // listeners. Otherwise we will add the response on the response list.
+ if ($halt && ! is_null($response)) {
+ return $response;
+ }
+
+ // If a boolean false is returned from a listener, we will stop propagating
+ // the event to any further listeners down in the chain, else we keep on
+ // looping through the listeners and firing every one in our sequence.
+ if ($response === false) {
+ break;
+ }
+
+ $responses[] = $response;
+ }
+
+ return $halt ? null : $responses;
+ }
+
+ /**
+ * Parse the given event and payload and prepare them for dispatching.
+ *
+ * @param mixed $event
+ * @param mixed $payload
+ * @return array
+ */
+ protected function parseEventAndPayload($event, $payload)
+ {
+ if (is_object($event)) {
+ list($payload, $event) = [[$event], get_class($event)];
+ }
+
+ return [$event, Arr::wrap($payload)];
+ }
+
+ /**
+ * Determine if the payload has a broadcastable event.
+ *
+ * @param array $payload
+ * @return bool
+ */
+ protected function shouldBroadcast(array $payload)
+ {
+ return isset($payload[0]) &&
+ $payload[0] instanceof ShouldBroadcast &&
+ $this->broadcastWhen($payload[0]);
+ }
+
+ /**
+ * Check if event should be broadcasted by condition.
+ *
+ * @param mixed $event
+ * @return bool
+ */
+ protected function broadcastWhen($event)
+ {
+ return method_exists($event, 'broadcastWhen')
+ ? $event->broadcastWhen() : true;
+ }
+
+ /**
+ * Broadcast the given event class.
+ *
+ * @param \Illuminate\Contracts\Broadcasting\ShouldBroadcast $event
+ * @return void
+ */
+ protected function broadcastEvent($event)
+ {
+ $this->container->make(BroadcastFactory::class)->queue($event);
+ }
+
+ /**
+ * Get all of the listeners for a given event name.
+ *
+ * @param string $eventName
+ * @return array
+ */
+ public function getListeners($eventName)
+ {
+ $listeners = $this->listeners[$eventName] ?? [];
+
+ $listeners = array_merge(
+ $listeners, $this->getWildcardListeners($eventName)
+ );
+
+ return class_exists($eventName, false)
+ ? $this->addInterfaceListeners($eventName, $listeners)
+ : $listeners;
+ }
+
+ /**
+ * Get the wildcard listeners for the event.
+ *
+ * @param string $eventName
+ * @return array
+ */
+ protected function getWildcardListeners($eventName)
+ {
+ $wildcards = [];
+
+ foreach ($this->wildcards as $key => $listeners) {
+ if (Str::is($key, $eventName)) {
+ $wildcards = array_merge($wildcards, $listeners);
+ }
+ }
+
+ return $wildcards;
+ }
+
+ /**
+ * Add the listeners for the event's interfaces to the given array.
+ *
+ * @param string $eventName
+ * @param array $listeners
+ * @return array
+ */
+ protected function addInterfaceListeners($eventName, array $listeners = [])
+ {
+ foreach (class_implements($eventName) as $interface) {
+ if (isset($this->listeners[$interface])) {
+ foreach ($this->listeners[$interface] as $names) {
+ $listeners = array_merge($listeners, (array) $names);
+ }
+ }
+ }
+
+ return $listeners;
+ }
+
+ /**
+ * Register an event listener with the dispatcher.
+ *
+ * @param \Closure|string $listener
+ * @param bool $wildcard
+ * @return \Closure
+ */
+ public function makeListener($listener, $wildcard = false)
+ {
+ if (is_string($listener)) {
+ return $this->createClassListener($listener, $wildcard);
+ }
+
+ return function ($event, $payload) use ($listener, $wildcard) {
+ if ($wildcard) {
+ return $listener($event, $payload);
+ }
+
+ return $listener(...array_values($payload));
+ };
+ }
+
+ /**
+ * Create a class based listener using the IoC container.
+ *
+ * @param string $listener
+ * @param bool $wildcard
+ * @return \Closure
+ */
+ public function createClassListener($listener, $wildcard = false)
+ {
+ return function ($event, $payload) use ($listener, $wildcard) {
+ if ($wildcard) {
+ return call_user_func($this->createClassCallable($listener), $event, $payload);
+ }
+
+ return call_user_func_array(
+ $this->createClassCallable($listener), $payload
+ );
+ };
+ }
+
+ /**
+ * Create the class based event callable.
+ *
+ * @param string $listener
+ * @return callable
+ */
+ protected function createClassCallable($listener)
+ {
+ list($class, $method) = $this->parseClassCallable($listener);
+
+ if ($this->handlerShouldBeQueued($class)) {
+ return $this->createQueuedHandlerCallable($class, $method);
+ }
+
+ return [$this->container->make($class), $method];
+ }
+
+ /**
+ * Parse the class listener into class and method.
+ *
+ * @param string $listener
+ * @return array
+ */
+ protected function parseClassCallable($listener)
+ {
+ return Str::parseCallback($listener, 'handle');
+ }
+
+ /**
+ * Determine if the event handler class should be queued.
+ *
+ * @param string $class
+ * @return bool
+ */
+ protected function handlerShouldBeQueued($class)
+ {
+ try {
+ return (new ReflectionClass($class))->implementsInterface(
+ ShouldQueue::class
+ );
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Create a callable for putting an event handler on the queue.
+ *
+ * @param string $class
+ * @param string $method
+ * @return \Closure
+ */
+ protected function createQueuedHandlerCallable($class, $method)
+ {
+ return function () use ($class, $method) {
+ $arguments = array_map(function ($a) {
+ return is_object($a) ? clone $a : $a;
+ }, func_get_args());
+
+ if ($this->handlerWantsToBeQueued($class, $arguments)) {
+ $this->queueHandler($class, $method, $arguments);
+ }
+ };
+ }
+
+ /**
+ * Determine if the event handler wants to be queued.
+ *
+ * @param string $class
+ * @param array $arguments
+ * @return bool
+ */
+ protected function handlerWantsToBeQueued($class, $arguments)
+ {
+ if (method_exists($class, 'shouldQueue')) {
+ return $this->container->make($class)->shouldQueue($arguments[0]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Queue the handler class.
+ *
+ * @param string $class
+ * @param string $method
+ * @param array $arguments
+ * @return void
+ */
+ protected function queueHandler($class, $method, $arguments)
+ {
+ list($listener, $job) = $this->createListenerAndJob($class, $method, $arguments);
+
+ $connection = $this->resolveQueue()->connection(
+ $listener->connection ?? null
+ );
+
+ $queue = $listener->queue ?? null;
+
+ isset($listener->delay)
+ ? $connection->laterOn($queue, $listener->delay, $job)
+ : $connection->pushOn($queue, $job);
+ }
+
+ /**
+ * Create the listener and job for a queued listener.
+ *
+ * @param string $class
+ * @param string $method
+ * @param array $arguments
+ * @return array
+ */
+ protected function createListenerAndJob($class, $method, $arguments)
+ {
+ $listener = (new ReflectionClass($class))->newInstanceWithoutConstructor();
+
+ return [$listener, $this->propagateListenerOptions(
+ $listener, new CallQueuedListener($class, $method, $arguments)
+ )];
+ }
+
+ /**
+ * Propagate listener options to the job.
+ *
+ * @param mixed $listener
+ * @param mixed $job
+ * @return mixed
+ */
+ protected function propagateListenerOptions($listener, $job)
+ {
+ return tap($job, function ($job) use ($listener) {
+ $job->tries = $listener->tries ?? null;
+ $job->timeout = $listener->timeout ?? null;
+ $job->timeoutAt = method_exists($listener, 'retryUntil')
+ ? $listener->retryUntil() : null;
+ });
+ }
+
+ /**
+ * Remove a set of listeners from the dispatcher.
+ *
+ * @param string $event
+ * @return void
+ */
+ public function forget($event)
+ {
+ if (Str::contains($event, '*')) {
+ unset($this->wildcards[$event]);
+ } else {
+ unset($this->listeners[$event]);
+ }
+ }
+
+ /**
+ * Forget all of the pushed listeners.
+ *
+ * @return void
+ */
+ public function forgetPushed()
+ {
+ foreach ($this->listeners as $key => $value) {
+ if (Str::endsWith($key, '_pushed')) {
+ $this->forget($key);
+ }
+ }
+ }
+
+ /**
+ * Get the queue implementation from the resolver.
+ *
+ * @return \Illuminate\Contracts\Queue\Queue
+ */
+ protected function resolveQueue()
+ {
+ return call_user_func($this->queueResolver);
+ }
+
+ /**
+ * Set the queue resolver implementation.
+ *
+ * @param callable $resolver
+ * @return $this
+ */
+ public function setQueueResolver(callable $resolver)
+ {
+ $this->queueResolver = $resolver;
+
+ return $this;
+ }
+}
diff --git a/vendor/illuminate/events/EventServiceProvider.php b/vendor/illuminate/events/EventServiceProvider.php
new file mode 100644
index 0000000..fa3ed6f
--- /dev/null
+++ b/vendor/illuminate/events/EventServiceProvider.php
@@ -0,0 +1,23 @@
+app->singleton('events', function ($app) {
+ return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
+ return $app->make(QueueFactoryContract::class);
+ });
+ });
+ }
+}
diff --git a/vendor/illuminate/events/composer.json b/vendor/illuminate/events/composer.json
new file mode 100644
index 0000000..772cab0
--- /dev/null
+++ b/vendor/illuminate/events/composer.json
@@ -0,0 +1,36 @@
+{
+ "name": "illuminate/events",
+ "description": "The Illuminate Events package.",
+ "license": "MIT",
+ "homepage": "https://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.0",
+ "illuminate/container": "5.5.*",
+ "illuminate/contracts": "5.5.*",
+ "illuminate/support": "5.5.*"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Events\\": ""
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.5-dev"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/filesystem/Cache.php b/vendor/illuminate/filesystem/Cache.php
new file mode 100644
index 0000000..deb5fe5
--- /dev/null
+++ b/vendor/illuminate/filesystem/Cache.php
@@ -0,0 +1,77 @@
+key = $key;
+ $this->repository = $repository;
+
+ if (! is_null($expire)) {
+ $this->expire = (int) ceil($expire / 60);
+ }
+ }
+
+ /**
+ * Load the cache.
+ *
+ * @return void
+ */
+ public function load()
+ {
+ $contents = $this->repository->get($this->key);
+
+ if (! is_null($contents)) {
+ $this->setFromStorage($contents);
+ }
+ }
+
+ /**
+ * Persist the cache.
+ *
+ * @return void
+ */
+ public function save()
+ {
+ $contents = $this->getForStorage();
+
+ if (! is_null($this->expire)) {
+ $this->repository->put($this->key, $contents, $this->expire);
+ } else {
+ $this->repository->forever($this->key, $contents);
+ }
+ }
+}
diff --git a/vendor/illuminate/filesystem/Filesystem.php b/vendor/illuminate/filesystem/Filesystem.php
new file mode 100644
index 0000000..75ce9d0
--- /dev/null
+++ b/vendor/illuminate/filesystem/Filesystem.php
@@ -0,0 +1,566 @@
+isFile($path)) {
+ return $lock ? $this->sharedGet($path) : file_get_contents($path);
+ }
+
+ throw new FileNotFoundException("File does not exist at path {$path}");
+ }
+
+ /**
+ * Get contents of a file with shared access.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function sharedGet($path)
+ {
+ $contents = '';
+
+ $handle = fopen($path, 'rb');
+
+ if ($handle) {
+ try {
+ if (flock($handle, LOCK_SH)) {
+ clearstatcache(true, $path);
+
+ $contents = fread($handle, $this->size($path) ?: 1);
+
+ flock($handle, LOCK_UN);
+ }
+ } finally {
+ fclose($handle);
+ }
+ }
+
+ return $contents;
+ }
+
+ /**
+ * Get the returned value of a file.
+ *
+ * @param string $path
+ * @return mixed
+ *
+ * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+ */
+ public function getRequire($path)
+ {
+ if ($this->isFile($path)) {
+ return require $path;
+ }
+
+ throw new FileNotFoundException("File does not exist at path {$path}");
+ }
+
+ /**
+ * Require the given file once.
+ *
+ * @param string $file
+ * @return mixed
+ */
+ public function requireOnce($file)
+ {
+ require_once $file;
+ }
+
+ /**
+ * Get the MD5 hash of the file at the given path.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function hash($path)
+ {
+ return md5_file($path);
+ }
+
+ /**
+ * Write the contents of a file.
+ *
+ * @param string $path
+ * @param string $contents
+ * @param bool $lock
+ * @return int
+ */
+ public function put($path, $contents, $lock = false)
+ {
+ return file_put_contents($path, $contents, $lock ? LOCK_EX : 0);
+ }
+
+ /**
+ * Prepend to a file.
+ *
+ * @param string $path
+ * @param string $data
+ * @return int
+ */
+ public function prepend($path, $data)
+ {
+ if ($this->exists($path)) {
+ return $this->put($path, $data.$this->get($path));
+ }
+
+ return $this->put($path, $data);
+ }
+
+ /**
+ * Append to a file.
+ *
+ * @param string $path
+ * @param string $data
+ * @return int
+ */
+ public function append($path, $data)
+ {
+ return file_put_contents($path, $data, FILE_APPEND);
+ }
+
+ /**
+ * Get or set UNIX mode of a file or directory.
+ *
+ * @param string $path
+ * @param int $mode
+ * @return mixed
+ */
+ public function chmod($path, $mode = null)
+ {
+ if ($mode) {
+ return chmod($path, $mode);
+ }
+
+ return substr(sprintf('%o', fileperms($path)), -4);
+ }
+
+ /**
+ * Delete the file at a given path.
+ *
+ * @param string|array $paths
+ * @return bool
+ */
+ public function delete($paths)
+ {
+ $paths = is_array($paths) ? $paths : func_get_args();
+
+ $success = true;
+
+ foreach ($paths as $path) {
+ try {
+ if (! @unlink($path)) {
+ $success = false;
+ }
+ } catch (ErrorException $e) {
+ $success = false;
+ }
+ }
+
+ return $success;
+ }
+
+ /**
+ * Move a file to a new location.
+ *
+ * @param string $path
+ * @param string $target
+ * @return bool
+ */
+ public function move($path, $target)
+ {
+ return rename($path, $target);
+ }
+
+ /**
+ * Copy a file to a new location.
+ *
+ * @param string $path
+ * @param string $target
+ * @return bool
+ */
+ public function copy($path, $target)
+ {
+ return copy($path, $target);
+ }
+
+ /**
+ * Create a hard link to the target file or directory.
+ *
+ * @param string $target
+ * @param string $link
+ * @return void
+ */
+ public function link($target, $link)
+ {
+ if (! windows_os()) {
+ return symlink($target, $link);
+ }
+
+ $mode = $this->isDirectory($target) ? 'J' : 'H';
+
+ exec("mklink /{$mode} \"{$link}\" \"{$target}\"");
+ }
+
+ /**
+ * Extract the file name from a file path.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function name($path)
+ {
+ return pathinfo($path, PATHINFO_FILENAME);
+ }
+
+ /**
+ * Extract the trailing name component from a file path.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function basename($path)
+ {
+ return pathinfo($path, PATHINFO_BASENAME);
+ }
+
+ /**
+ * Extract the parent directory from a file path.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function dirname($path)
+ {
+ return pathinfo($path, PATHINFO_DIRNAME);
+ }
+
+ /**
+ * Extract the file extension from a file path.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function extension($path)
+ {
+ return pathinfo($path, PATHINFO_EXTENSION);
+ }
+
+ /**
+ * Get the file type of a given file.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function type($path)
+ {
+ return filetype($path);
+ }
+
+ /**
+ * Get the mime-type of a given file.
+ *
+ * @param string $path
+ * @return string|false
+ */
+ public function mimeType($path)
+ {
+ return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
+ }
+
+ /**
+ * Get the file size of a given file.
+ *
+ * @param string $path
+ * @return int
+ */
+ public function size($path)
+ {
+ return filesize($path);
+ }
+
+ /**
+ * Get the file's last modification time.
+ *
+ * @param string $path
+ * @return int
+ */
+ public function lastModified($path)
+ {
+ return filemtime($path);
+ }
+
+ /**
+ * Determine if the given path is a directory.
+ *
+ * @param string $directory
+ * @return bool
+ */
+ public function isDirectory($directory)
+ {
+ return is_dir($directory);
+ }
+
+ /**
+ * Determine if the given path is readable.
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isReadable($path)
+ {
+ return is_readable($path);
+ }
+
+ /**
+ * Determine if the given path is writable.
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isWritable($path)
+ {
+ return is_writable($path);
+ }
+
+ /**
+ * Determine if the given path is a file.
+ *
+ * @param string $file
+ * @return bool
+ */
+ public function isFile($file)
+ {
+ return is_file($file);
+ }
+
+ /**
+ * Find path names matching a given pattern.
+ *
+ * @param string $pattern
+ * @param int $flags
+ * @return array
+ */
+ public function glob($pattern, $flags = 0)
+ {
+ return glob($pattern, $flags);
+ }
+
+ /**
+ * Get an array of all files in a directory.
+ *
+ * @param string $directory
+ * @param bool $hidden
+ * @return \Symfony\Component\Finder\SplFileInfo[]
+ */
+ public function files($directory, $hidden = false)
+ {
+ return iterator_to_array(
+ Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory)->depth(0),
+ false
+ );
+ }
+
+ /**
+ * Get all of the files from the given directory (recursive).
+ *
+ * @param string $directory
+ * @param bool $hidden
+ * @return \Symfony\Component\Finder\SplFileInfo[]
+ */
+ public function allFiles($directory, $hidden = false)
+ {
+ return iterator_to_array(
+ Finder::create()->files()->ignoreDotFiles(! $hidden)->in($directory),
+ false
+ );
+ }
+
+ /**
+ * Get all of the directories within a given directory.
+ *
+ * @param string $directory
+ * @return array
+ */
+ public function directories($directory)
+ {
+ $directories = [];
+
+ foreach (Finder::create()->in($directory)->directories()->depth(0) as $dir) {
+ $directories[] = $dir->getPathname();
+ }
+
+ return $directories;
+ }
+
+ /**
+ * Create a directory.
+ *
+ * @param string $path
+ * @param int $mode
+ * @param bool $recursive
+ * @param bool $force
+ * @return bool
+ */
+ public function makeDirectory($path, $mode = 0755, $recursive = false, $force = false)
+ {
+ if ($force) {
+ return @mkdir($path, $mode, $recursive);
+ }
+
+ return mkdir($path, $mode, $recursive);
+ }
+
+ /**
+ * Move a directory.
+ *
+ * @param string $from
+ * @param string $to
+ * @param bool $overwrite
+ * @return bool
+ */
+ public function moveDirectory($from, $to, $overwrite = false)
+ {
+ if ($overwrite && $this->isDirectory($to)) {
+ if (! $this->deleteDirectory($to)) {
+ return false;
+ }
+ }
+
+ return @rename($from, $to) === true;
+ }
+
+ /**
+ * Copy a directory from one location to another.
+ *
+ * @param string $directory
+ * @param string $destination
+ * @param int $options
+ * @return bool
+ */
+ public function copyDirectory($directory, $destination, $options = null)
+ {
+ if (! $this->isDirectory($directory)) {
+ return false;
+ }
+
+ $options = $options ?: FilesystemIterator::SKIP_DOTS;
+
+ // If the destination directory does not actually exist, we will go ahead and
+ // create it recursively, which just gets the destination prepared to copy
+ // the files over. Once we make the directory we'll proceed the copying.
+ if (! $this->isDirectory($destination)) {
+ $this->makeDirectory($destination, 0777, true);
+ }
+
+ $items = new FilesystemIterator($directory, $options);
+
+ foreach ($items as $item) {
+ // As we spin through items, we will check to see if the current file is actually
+ // a directory or a file. When it is actually a directory we will need to call
+ // back into this function recursively to keep copying these nested folders.
+ $target = $destination.'/'.$item->getBasename();
+
+ if ($item->isDir()) {
+ $path = $item->getPathname();
+
+ if (! $this->copyDirectory($path, $target, $options)) {
+ return false;
+ }
+ }
+
+ // If the current items is just a regular file, we will just copy this to the new
+ // location and keep looping. If for some reason the copy fails we'll bail out
+ // and return false, so the developer is aware that the copy process failed.
+ else {
+ if (! $this->copy($item->getPathname(), $target)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Recursively delete a directory.
+ *
+ * The directory itself may be optionally preserved.
+ *
+ * @param string $directory
+ * @param bool $preserve
+ * @return bool
+ */
+ public function deleteDirectory($directory, $preserve = false)
+ {
+ if (! $this->isDirectory($directory)) {
+ return false;
+ }
+
+ $items = new FilesystemIterator($directory);
+
+ foreach ($items as $item) {
+ // If the item is a directory, we can just recurse into the function and
+ // delete that sub-directory otherwise we'll just delete the file and
+ // keep iterating through each file until the directory is cleaned.
+ if ($item->isDir() && ! $item->isLink()) {
+ $this->deleteDirectory($item->getPathname());
+ }
+
+ // If the item is just a file, we can go ahead and delete it since we're
+ // just looping through and waxing all of the files in this directory
+ // and calling directories recursively, so we delete the real path.
+ else {
+ $this->delete($item->getPathname());
+ }
+ }
+
+ if (! $preserve) {
+ @rmdir($directory);
+ }
+
+ return true;
+ }
+
+ /**
+ * Empty the specified directory of all files and folders.
+ *
+ * @param string $directory
+ * @return bool
+ */
+ public function cleanDirectory($directory)
+ {
+ return $this->deleteDirectory($directory, true);
+ }
+}
diff --git a/vendor/illuminate/filesystem/FilesystemAdapter.php b/vendor/illuminate/filesystem/FilesystemAdapter.php
new file mode 100644
index 0000000..8165345
--- /dev/null
+++ b/vendor/illuminate/filesystem/FilesystemAdapter.php
@@ -0,0 +1,684 @@
+driver = $driver;
+ }
+
+ /**
+ * Assert that the given file exists.
+ *
+ * @param string $path
+ * @return void
+ */
+ public function assertExists($path)
+ {
+ PHPUnit::assertTrue(
+ $this->exists($path), "Unable to find a file at path [{$path}]."
+ );
+ }
+
+ /**
+ * Assert that the given file does not exist.
+ *
+ * @param string $path
+ * @return void
+ */
+ public function assertMissing($path)
+ {
+ PHPUnit::assertFalse(
+ $this->exists($path), "Found unexpected file at path [{$path}]."
+ );
+ }
+
+ /**
+ * Determine if a file exists.
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function exists($path)
+ {
+ return $this->driver->has($path);
+ }
+
+ /**
+ * Get the full path for the file at the given "short" path.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function path($path)
+ {
+ return $this->driver->getAdapter()->getPathPrefix().$path;
+ }
+
+ /**
+ * Get the contents of a file.
+ *
+ * @param string $path
+ * @return string
+ *
+ * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+ */
+ public function get($path)
+ {
+ try {
+ return $this->driver->read($path);
+ } catch (FileNotFoundException $e) {
+ throw new ContractFileNotFoundException($path, $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Create a streamed response for a given file.
+ *
+ * @param string $path
+ * @param string|null $name
+ * @param array|null $headers
+ * @param string|null $disposition
+ * @return \Symfony\Component\HttpFoundation\StreamedResponse
+ */
+ public function response($path, $name = null, array $headers = [], $disposition = 'inline')
+ {
+ $response = new StreamedResponse;
+
+ $disposition = $response->headers->makeDisposition($disposition, $name ?? basename($path));
+
+ $response->headers->replace($headers + [
+ 'Content-Type' => $this->mimeType($path),
+ 'Content-Length' => $this->size($path),
+ 'Content-Disposition' => $disposition,
+ ]);
+
+ $response->setCallback(function () use ($path) {
+ $stream = $this->driver->readStream($path);
+ fpassthru($stream);
+ fclose($stream);
+ });
+
+ return $response;
+ }
+
+ /**
+ * Create a streamed download response for a given file.
+ *
+ * @param string $path
+ * @param string|null $name
+ * @param array|null $headers
+ * @return \Symfony\Component\HttpFoundation\StreamedResponse
+ */
+ public function download($path, $name = null, array $headers = [])
+ {
+ return $this->response($path, $name, $headers, 'attachment');
+ }
+
+ /**
+ * Write the contents of a file.
+ *
+ * @param string $path
+ * @param string|resource $contents
+ * @param mixed $options
+ * @return bool
+ */
+ public function put($path, $contents, $options = [])
+ {
+ $options = is_string($options)
+ ? ['visibility' => $options]
+ : (array) $options;
+
+ // If the given contents is actually a file or uploaded file instance than we will
+ // automatically store the file using a stream. This provides a convenient path
+ // for the developer to store streams without managing them manually in code.
+ if ($contents instanceof File ||
+ $contents instanceof UploadedFile) {
+ return $this->putFile($path, $contents, $options);
+ }
+
+ return is_resource($contents)
+ ? $this->driver->putStream($path, $contents, $options)
+ : $this->driver->put($path, $contents, $options);
+ }
+
+ /**
+ * Store the uploaded file on the disk.
+ *
+ * @param string $path
+ * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile $file
+ * @param array $options
+ * @return string|false
+ */
+ public function putFile($path, $file, $options = [])
+ {
+ return $this->putFileAs($path, $file, $file->hashName(), $options);
+ }
+
+ /**
+ * Store the uploaded file on the disk with a given name.
+ *
+ * @param string $path
+ * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile $file
+ * @param string $name
+ * @param array $options
+ * @return string|false
+ */
+ public function putFileAs($path, $file, $name, $options = [])
+ {
+ $stream = fopen($file->getRealPath(), 'r+');
+
+ // Next, we will format the path of the file and store the file using a stream since
+ // they provide better performance than alternatives. Once we write the file this
+ // stream will get closed automatically by us so the developer doesn't have to.
+ $result = $this->put(
+ $path = trim($path.'/'.$name, '/'), $stream, $options
+ );
+
+ if (is_resource($stream)) {
+ fclose($stream);
+ }
+
+ return $result ? $path : false;
+ }
+
+ /**
+ * Get the visibility for the given path.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getVisibility($path)
+ {
+ if ($this->driver->getVisibility($path) == AdapterInterface::VISIBILITY_PUBLIC) {
+ return FilesystemContract::VISIBILITY_PUBLIC;
+ }
+
+ return FilesystemContract::VISIBILITY_PRIVATE;
+ }
+
+ /**
+ * Set the visibility for the given path.
+ *
+ * @param string $path
+ * @param string $visibility
+ * @return void
+ */
+ public function setVisibility($path, $visibility)
+ {
+ return $this->driver->setVisibility($path, $this->parseVisibility($visibility));
+ }
+
+ /**
+ * Prepend to a file.
+ *
+ * @param string $path
+ * @param string $data
+ * @param string $separator
+ * @return int
+ */
+ public function prepend($path, $data, $separator = PHP_EOL)
+ {
+ if ($this->exists($path)) {
+ return $this->put($path, $data.$separator.$this->get($path));
+ }
+
+ return $this->put($path, $data);
+ }
+
+ /**
+ * Append to a file.
+ *
+ * @param string $path
+ * @param string $data
+ * @param string $separator
+ * @return int
+ */
+ public function append($path, $data, $separator = PHP_EOL)
+ {
+ if ($this->exists($path)) {
+ return $this->put($path, $this->get($path).$separator.$data);
+ }
+
+ return $this->put($path, $data);
+ }
+
+ /**
+ * Delete the file at a given path.
+ *
+ * @param string|array $paths
+ * @return bool
+ */
+ public function delete($paths)
+ {
+ $paths = is_array($paths) ? $paths : func_get_args();
+
+ $success = true;
+
+ foreach ($paths as $path) {
+ try {
+ if (! $this->driver->delete($path)) {
+ $success = false;
+ }
+ } catch (FileNotFoundException $e) {
+ $success = false;
+ }
+ }
+
+ return $success;
+ }
+
+ /**
+ * Copy a file to a new location.
+ *
+ * @param string $from
+ * @param string $to
+ * @return bool
+ */
+ public function copy($from, $to)
+ {
+ return $this->driver->copy($from, $to);
+ }
+
+ /**
+ * Move a file to a new location.
+ *
+ * @param string $from
+ * @param string $to
+ * @return bool
+ */
+ public function move($from, $to)
+ {
+ return $this->driver->rename($from, $to);
+ }
+
+ /**
+ * Get the file size of a given file.
+ *
+ * @param string $path
+ * @return int
+ */
+ public function size($path)
+ {
+ return $this->driver->getSize($path);
+ }
+
+ /**
+ * Get the mime-type of a given file.
+ *
+ * @param string $path
+ * @return string|false
+ */
+ public function mimeType($path)
+ {
+ return $this->driver->getMimetype($path);
+ }
+
+ /**
+ * Get the file's last modification time.
+ *
+ * @param string $path
+ * @return int
+ */
+ public function lastModified($path)
+ {
+ return $this->driver->getTimestamp($path);
+ }
+
+ /**
+ * Get the URL for the file at the given path.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function url($path)
+ {
+ $adapter = $this->driver->getAdapter();
+
+ if ($adapter instanceof CachedAdapter) {
+ $adapter = $adapter->getAdapter();
+ }
+
+ if (method_exists($adapter, 'getUrl')) {
+ return $adapter->getUrl($path);
+ } elseif ($adapter instanceof AwsS3Adapter) {
+ return $this->getAwsUrl($adapter, $path);
+ } elseif ($adapter instanceof RackspaceAdapter) {
+ return $this->getRackspaceUrl($adapter, $path);
+ } elseif ($adapter instanceof LocalAdapter) {
+ return $this->getLocalUrl($path);
+ } else {
+ throw new RuntimeException('This driver does not support retrieving URLs.');
+ }
+ }
+
+ /**
+ * Get the URL for the file at the given path.
+ *
+ * @param \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter
+ * @param string $path
+ * @return string
+ */
+ protected function getAwsUrl($adapter, $path)
+ {
+ // If an explicit base URL has been set on the disk configuration then we will use
+ // it as the base URL instead of the default path. This allows the developer to
+ // have full control over the base path for this filesystem's generated URLs.
+ if (! is_null($url = $this->driver->getConfig()->get('url'))) {
+ return $this->concatPathToUrl($url, $adapter->getPathPrefix().$path);
+ }
+
+ return $adapter->getClient()->getObjectUrl(
+ $adapter->getBucket(), $adapter->getPathPrefix().$path
+ );
+ }
+
+ /**
+ * Get the URL for the file at the given path.
+ *
+ * @param \League\Flysystem\Rackspace\RackspaceAdapter $adapter
+ * @param string $path
+ * @return string
+ */
+ protected function getRackspaceUrl($adapter, $path)
+ {
+ return (string) $adapter->getContainer()->getObject($path)->getPublicUrl();
+ }
+
+ /**
+ * Get the URL for the file at the given path.
+ *
+ * @param string $path
+ * @return string
+ */
+ protected function getLocalUrl($path)
+ {
+ $config = $this->driver->getConfig();
+
+ // If an explicit base URL has been set on the disk configuration then we will use
+ // it as the base URL instead of the default path. This allows the developer to
+ // have full control over the base path for this filesystem's generated URLs.
+ if ($config->has('url')) {
+ return $this->concatPathToUrl($config->get('url'), $path);
+ }
+
+ $path = '/storage/'.$path;
+
+ // If the path contains "storage/public", it probably means the developer is using
+ // the default disk to generate the path instead of the "public" disk like they
+ // are really supposed to use. We will remove the public from this path here.
+ if (Str::contains($path, '/storage/public/')) {
+ return Str::replaceFirst('/public/', '/', $path);
+ }
+
+ return $path;
+ }
+
+ /**
+ * Get a temporary URL for the file at the given path.
+ *
+ * @param string $path
+ * @param \DateTimeInterface $expiration
+ * @param array $options
+ * @return string
+ */
+ public function temporaryUrl($path, $expiration, array $options = [])
+ {
+ $adapter = $this->driver->getAdapter();
+
+ if ($adapter instanceof CachedAdapter) {
+ $adapter = $adapter->getAdapter();
+ }
+
+ if (method_exists($adapter, 'getTemporaryUrl')) {
+ return $adapter->getTemporaryUrl($path, $expiration, $options);
+ } elseif ($adapter instanceof AwsS3Adapter) {
+ return $this->getAwsTemporaryUrl($adapter, $path, $expiration, $options);
+ } elseif ($adapter instanceof RackspaceAdapter) {
+ return $this->getRackspaceTemporaryUrl($adapter, $path, $expiration, $options);
+ } else {
+ throw new RuntimeException('This driver does not support creating temporary URLs.');
+ }
+ }
+
+ /**
+ * Get a temporary URL for the file at the given path.
+ *
+ * @param \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter
+ * @param string $path
+ * @param \DateTimeInterface $expiration
+ * @param array $options
+ * @return string
+ */
+ public function getAwsTemporaryUrl($adapter, $path, $expiration, $options)
+ {
+ $client = $adapter->getClient();
+
+ $command = $client->getCommand('GetObject', array_merge([
+ 'Bucket' => $adapter->getBucket(),
+ 'Key' => $adapter->getPathPrefix().$path,
+ ], $options));
+
+ return (string) $client->createPresignedRequest(
+ $command, $expiration
+ )->getUri();
+ }
+
+ /**
+ * Get a temporary URL for the file at the given path.
+ *
+ * @param \League\Flysystem\Rackspace\RackspaceAdapter $adapter
+ * @param string $path
+ * @param \DateTimeInterface $expiration
+ * @param array $options
+ * @return string
+ */
+ public function getRackspaceTemporaryUrl($adapter, $path, $expiration, $options)
+ {
+ return $adapter->getContainer()->getObject($path)->getTemporaryUrl(
+ Carbon::now()->diffInSeconds($expiration),
+ $options['method'] ?? 'GET',
+ $options['forcePublicUrl'] ?? true
+ );
+ }
+
+ /**
+ * Concatenate a path to a URL.
+ *
+ * @param string $url
+ * @param string $path
+ * @return string
+ */
+ protected function concatPathToUrl($url, $path)
+ {
+ return rtrim($url, '/').'/'.ltrim($path, '/');
+ }
+
+ /**
+ * Get an array of all files in a directory.
+ *
+ * @param string|null $directory
+ * @param bool $recursive
+ * @return array
+ */
+ public function files($directory = null, $recursive = false)
+ {
+ $contents = $this->driver->listContents($directory, $recursive);
+
+ return $this->filterContentsByType($contents, 'file');
+ }
+
+ /**
+ * Get all of the files from the given directory (recursive).
+ *
+ * @param string|null $directory
+ * @return array
+ */
+ public function allFiles($directory = null)
+ {
+ return $this->files($directory, true);
+ }
+
+ /**
+ * Get all of the directories within a given directory.
+ *
+ * @param string|null $directory
+ * @param bool $recursive
+ * @return array
+ */
+ public function directories($directory = null, $recursive = false)
+ {
+ $contents = $this->driver->listContents($directory, $recursive);
+
+ return $this->filterContentsByType($contents, 'dir');
+ }
+
+ /**
+ * Get all (recursive) of the directories within a given directory.
+ *
+ * @param string|null $directory
+ * @return array
+ */
+ public function allDirectories($directory = null)
+ {
+ return $this->directories($directory, true);
+ }
+
+ /**
+ * Create a directory.
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function makeDirectory($path)
+ {
+ return $this->driver->createDir($path);
+ }
+
+ /**
+ * Recursively delete a directory.
+ *
+ * @param string $directory
+ * @return bool
+ */
+ public function deleteDirectory($directory)
+ {
+ return $this->driver->deleteDir($directory);
+ }
+
+ /**
+ * Flush the Flysystem cache.
+ *
+ * @return void
+ */
+ public function flushCache()
+ {
+ $adapter = $this->driver->getAdapter();
+
+ if ($adapter instanceof CachedAdapter) {
+ $adapter->getCache()->flush();
+ }
+ }
+
+ /**
+ * Get the Flysystem driver.
+ *
+ * @return \League\Flysystem\FilesystemInterface
+ */
+ public function getDriver()
+ {
+ return $this->driver;
+ }
+
+ /**
+ * Filter directory contents by type.
+ *
+ * @param array $contents
+ * @param string $type
+ * @return array
+ */
+ protected function filterContentsByType($contents, $type)
+ {
+ return Collection::make($contents)
+ ->where('type', $type)
+ ->pluck('path')
+ ->values()
+ ->all();
+ }
+
+ /**
+ * Parse the given visibility value.
+ *
+ * @param string|null $visibility
+ * @return string|null
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function parseVisibility($visibility)
+ {
+ if (is_null($visibility)) {
+ return;
+ }
+
+ switch ($visibility) {
+ case FilesystemContract::VISIBILITY_PUBLIC:
+ return AdapterInterface::VISIBILITY_PUBLIC;
+ case FilesystemContract::VISIBILITY_PRIVATE:
+ return AdapterInterface::VISIBILITY_PRIVATE;
+ }
+
+ throw new InvalidArgumentException('Unknown visibility: '.$visibility);
+ }
+
+ /**
+ * Pass dynamic methods call onto Flysystem.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __call($method, array $parameters)
+ {
+ return call_user_func_array([$this->driver, $method], $parameters);
+ }
+}
diff --git a/vendor/illuminate/filesystem/FilesystemManager.php b/vendor/illuminate/filesystem/FilesystemManager.php
new file mode 100644
index 0000000..04c1bac
--- /dev/null
+++ b/vendor/illuminate/filesystem/FilesystemManager.php
@@ -0,0 +1,370 @@
+app = $app;
+ }
+
+ /**
+ * Get a filesystem instance.
+ *
+ * @param string $name
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ */
+ public function drive($name = null)
+ {
+ return $this->disk($name);
+ }
+
+ /**
+ * Get a filesystem instance.
+ *
+ * @param string $name
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ */
+ public function disk($name = null)
+ {
+ $name = $name ?: $this->getDefaultDriver();
+
+ return $this->disks[$name] = $this->get($name);
+ }
+
+ /**
+ * Get a default cloud filesystem instance.
+ *
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ */
+ public function cloud()
+ {
+ $name = $this->getDefaultCloudDriver();
+
+ return $this->disks[$name] = $this->get($name);
+ }
+
+ /**
+ * Attempt to get the disk from the local cache.
+ *
+ * @param string $name
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ */
+ protected function get($name)
+ {
+ return $this->disks[$name] ?? $this->resolve($name);
+ }
+
+ /**
+ * Resolve the given disk.
+ *
+ * @param string $name
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function resolve($name)
+ {
+ $config = $this->getConfig($name);
+
+ if (isset($this->customCreators[$config['driver']])) {
+ return $this->callCustomCreator($config);
+ }
+
+ $driverMethod = 'create'.ucfirst($config['driver']).'Driver';
+
+ if (method_exists($this, $driverMethod)) {
+ return $this->{$driverMethod}($config);
+ } else {
+ throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
+ }
+ }
+
+ /**
+ * Call a custom driver creator.
+ *
+ * @param array $config
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ */
+ protected function callCustomCreator(array $config)
+ {
+ $driver = $this->customCreators[$config['driver']]($this->app, $config);
+
+ if ($driver instanceof FilesystemInterface) {
+ return $this->adapt($driver);
+ }
+
+ return $driver;
+ }
+
+ /**
+ * Create an instance of the local driver.
+ *
+ * @param array $config
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ */
+ public function createLocalDriver(array $config)
+ {
+ $permissions = $config['permissions'] ?? [];
+
+ $links = ($config['links'] ?? null) === 'skip'
+ ? LocalAdapter::SKIP_LINKS
+ : LocalAdapter::DISALLOW_LINKS;
+
+ return $this->adapt($this->createFlysystem(new LocalAdapter(
+ $config['root'], LOCK_EX, $links, $permissions
+ ), $config));
+ }
+
+ /**
+ * Create an instance of the ftp driver.
+ *
+ * @param array $config
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ */
+ public function createFtpDriver(array $config)
+ {
+ return $this->adapt($this->createFlysystem(
+ new FtpAdapter($config), $config
+ ));
+ }
+
+ /**
+ * Create an instance of the Amazon S3 driver.
+ *
+ * @param array $config
+ * @return \Illuminate\Contracts\Filesystem\Cloud
+ */
+ public function createS3Driver(array $config)
+ {
+ $s3Config = $this->formatS3Config($config);
+
+ $root = $s3Config['root'] ?? null;
+
+ $options = $config['options'] ?? [];
+
+ return $this->adapt($this->createFlysystem(
+ new S3Adapter(new S3Client($s3Config), $s3Config['bucket'], $root, $options), $config
+ ));
+ }
+
+ /**
+ * Format the given S3 configuration with the default options.
+ *
+ * @param array $config
+ * @return array
+ */
+ protected function formatS3Config(array $config)
+ {
+ $config += ['version' => 'latest'];
+
+ if ($config['key'] && $config['secret']) {
+ $config['credentials'] = Arr::only($config, ['key', 'secret']);
+ }
+
+ return $config;
+ }
+
+ /**
+ * Create an instance of the Rackspace driver.
+ *
+ * @param array $config
+ * @return \Illuminate\Contracts\Filesystem\Cloud
+ */
+ public function createRackspaceDriver(array $config)
+ {
+ $client = new Rackspace($config['endpoint'], [
+ 'username' => $config['username'], 'apiKey' => $config['key'],
+ ]);
+
+ $root = $config['root'] ?? null;
+
+ return $this->adapt($this->createFlysystem(
+ new RackspaceAdapter($this->getRackspaceContainer($client, $config), $root), $config
+ ));
+ }
+
+ /**
+ * Get the Rackspace Cloud Files container.
+ *
+ * @param \OpenCloud\Rackspace $client
+ * @param array $config
+ * @return \OpenCloud\ObjectStore\Resource\Container
+ */
+ protected function getRackspaceContainer(Rackspace $client, array $config)
+ {
+ $urlType = $config['url_type'] ?? null;
+
+ $store = $client->objectStoreService('cloudFiles', $config['region'], $urlType);
+
+ return $store->getContainer($config['container']);
+ }
+
+ /**
+ * Create a Flysystem instance with the given adapter.
+ *
+ * @param \League\Flysystem\AdapterInterface $adapter
+ * @param array $config
+ * @return \League\Flysystem\FilesystemInterface
+ */
+ protected function createFlysystem(AdapterInterface $adapter, array $config)
+ {
+ $cache = Arr::pull($config, 'cache');
+
+ $config = Arr::only($config, ['visibility', 'disable_asserts', 'url']);
+
+ if ($cache) {
+ $adapter = new CachedAdapter($adapter, $this->createCacheStore($cache));
+ }
+
+ return new Flysystem($adapter, count($config) > 0 ? $config : null);
+ }
+
+ /**
+ * Create a cache store instance.
+ *
+ * @param mixed $config
+ * @return \League\Flysystem\Cached\CacheInterface
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function createCacheStore($config)
+ {
+ if ($config === true) {
+ return new MemoryStore;
+ }
+
+ return new Cache(
+ $this->app['cache']->store($config['store']),
+ $config['prefix'] ?? 'flysystem',
+ $config['expire'] ?? null
+ );
+ }
+
+ /**
+ * Adapt the filesystem implementation.
+ *
+ * @param \League\Flysystem\FilesystemInterface $filesystem
+ * @return \Illuminate\Contracts\Filesystem\Filesystem
+ */
+ protected function adapt(FilesystemInterface $filesystem)
+ {
+ return new FilesystemAdapter($filesystem);
+ }
+
+ /**
+ * Set the given disk instance.
+ *
+ * @param string $name
+ * @param mixed $disk
+ * @return void
+ */
+ public function set($name, $disk)
+ {
+ $this->disks[$name] = $disk;
+ }
+
+ /**
+ * Get the filesystem connection configuration.
+ *
+ * @param string $name
+ * @return array
+ */
+ protected function getConfig($name)
+ {
+ return $this->app['config']["filesystems.disks.{$name}"];
+ }
+
+ /**
+ * Get the default driver name.
+ *
+ * @return string
+ */
+ public function getDefaultDriver()
+ {
+ return $this->app['config']['filesystems.default'];
+ }
+
+ /**
+ * Get the default cloud driver name.
+ *
+ * @return string
+ */
+ public function getDefaultCloudDriver()
+ {
+ return $this->app['config']['filesystems.cloud'];
+ }
+
+ /**
+ * Register a custom driver creator Closure.
+ *
+ * @param string $driver
+ * @param \Closure $callback
+ * @return $this
+ */
+ public function extend($driver, Closure $callback)
+ {
+ $this->customCreators[$driver] = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Dynamically call the default driver instance.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ return $this->disk()->$method(...$parameters);
+ }
+}
diff --git a/vendor/illuminate/filesystem/FilesystemServiceProvider.php b/vendor/illuminate/filesystem/FilesystemServiceProvider.php
new file mode 100644
index 0000000..6932270
--- /dev/null
+++ b/vendor/illuminate/filesystem/FilesystemServiceProvider.php
@@ -0,0 +1,82 @@
+registerNativeFilesystem();
+
+ $this->registerFlysystem();
+ }
+
+ /**
+ * Register the native filesystem implementation.
+ *
+ * @return void
+ */
+ protected function registerNativeFilesystem()
+ {
+ $this->app->singleton('files', function () {
+ return new Filesystem;
+ });
+ }
+
+ /**
+ * Register the driver based filesystem.
+ *
+ * @return void
+ */
+ protected function registerFlysystem()
+ {
+ $this->registerManager();
+
+ $this->app->singleton('filesystem.disk', function () {
+ return $this->app['filesystem']->disk($this->getDefaultDriver());
+ });
+
+ $this->app->singleton('filesystem.cloud', function () {
+ return $this->app['filesystem']->disk($this->getCloudDriver());
+ });
+ }
+
+ /**
+ * Register the filesystem manager.
+ *
+ * @return void
+ */
+ protected function registerManager()
+ {
+ $this->app->singleton('filesystem', function () {
+ return new FilesystemManager($this->app);
+ });
+ }
+
+ /**
+ * Get the default file driver.
+ *
+ * @return string
+ */
+ protected function getDefaultDriver()
+ {
+ return $this->app['config']['filesystems.default'];
+ }
+
+ /**
+ * Get the default cloud based file driver.
+ *
+ * @return string
+ */
+ protected function getCloudDriver()
+ {
+ return $this->app['config']['filesystems.cloud'];
+ }
+}
diff --git a/vendor/illuminate/filesystem/composer.json b/vendor/illuminate/filesystem/composer.json
new file mode 100644
index 0000000..3f09194
--- /dev/null
+++ b/vendor/illuminate/filesystem/composer.json
@@ -0,0 +1,41 @@
+{
+ "name": "illuminate/filesystem",
+ "description": "The Illuminate Filesystem package.",
+ "license": "MIT",
+ "homepage": "https://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.0",
+ "illuminate/contracts": "5.5.*",
+ "illuminate/support": "5.5.*",
+ "symfony/finder": "~3.3"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Filesystem\\": ""
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.5-dev"
+ }
+ },
+ "suggest": {
+ "league/flysystem": "Required to use the Flysystem local and FTP drivers (~1.0).",
+ "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).",
+ "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0)."
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/support/AggregateServiceProvider.php b/vendor/illuminate/support/AggregateServiceProvider.php
new file mode 100644
index 0000000..d7425c5
--- /dev/null
+++ b/vendor/illuminate/support/AggregateServiceProvider.php
@@ -0,0 +1,52 @@
+instances = [];
+
+ foreach ($this->providers as $provider) {
+ $this->instances[] = $this->app->register($provider);
+ }
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array
+ */
+ public function provides()
+ {
+ $provides = [];
+
+ foreach ($this->providers as $provider) {
+ $instance = $this->app->resolveProvider($provider);
+
+ $provides = array_merge($provides, $instance->provides());
+ }
+
+ return $provides;
+ }
+}
diff --git a/vendor/illuminate/support/Arr.php b/vendor/illuminate/support/Arr.php
new file mode 100644
index 0000000..5cf83eb
--- /dev/null
+++ b/vendor/illuminate/support/Arr.php
@@ -0,0 +1,610 @@
+all();
+ } elseif (! is_array($values)) {
+ continue;
+ }
+
+ $results = array_merge($results, $values);
+ }
+
+ return $results;
+ }
+
+ /**
+ * Cross join the given arrays, returning all possible permutations.
+ *
+ * @param array ...$arrays
+ * @return array
+ */
+ public static function crossJoin(...$arrays)
+ {
+ $results = [[]];
+
+ foreach ($arrays as $index => $array) {
+ $append = [];
+
+ foreach ($results as $product) {
+ foreach ($array as $item) {
+ $product[$index] = $item;
+
+ $append[] = $product;
+ }
+ }
+
+ $results = $append;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Divide an array into two arrays. One with keys and the other with values.
+ *
+ * @param array $array
+ * @return array
+ */
+ public static function divide($array)
+ {
+ return [array_keys($array), array_values($array)];
+ }
+
+ /**
+ * Flatten a multi-dimensional associative array with dots.
+ *
+ * @param array $array
+ * @param string $prepend
+ * @return array
+ */
+ public static function dot($array, $prepend = '')
+ {
+ $results = [];
+
+ foreach ($array as $key => $value) {
+ if (is_array($value) && ! empty($value)) {
+ $results = array_merge($results, static::dot($value, $prepend.$key.'.'));
+ } else {
+ $results[$prepend.$key] = $value;
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Get all of the given array except for a specified array of keys.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ public static function except($array, $keys)
+ {
+ static::forget($array, $keys);
+
+ return $array;
+ }
+
+ /**
+ * Determine if the given key exists in the provided array.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string|int $key
+ * @return bool
+ */
+ public static function exists($array, $key)
+ {
+ if ($array instanceof ArrayAccess) {
+ return $array->offsetExists($key);
+ }
+
+ return array_key_exists($key, $array);
+ }
+
+ /**
+ * Return the first element in an array passing a given truth test.
+ *
+ * @param array $array
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function first($array, callable $callback = null, $default = null)
+ {
+ if (is_null($callback)) {
+ if (empty($array)) {
+ return value($default);
+ }
+
+ foreach ($array as $item) {
+ return $item;
+ }
+ }
+
+ foreach ($array as $key => $value) {
+ if (call_user_func($callback, $value, $key)) {
+ return $value;
+ }
+ }
+
+ return value($default);
+ }
+
+ /**
+ * Return the last element in an array passing a given truth test.
+ *
+ * @param array $array
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function last($array, callable $callback = null, $default = null)
+ {
+ if (is_null($callback)) {
+ return empty($array) ? value($default) : end($array);
+ }
+
+ return static::first(array_reverse($array, true), $callback, $default);
+ }
+
+ /**
+ * Flatten a multi-dimensional array into a single level.
+ *
+ * @param array $array
+ * @param int $depth
+ * @return array
+ */
+ public static function flatten($array, $depth = INF)
+ {
+ $result = [];
+
+ foreach ($array as $item) {
+ $item = $item instanceof Collection ? $item->all() : $item;
+
+ if (! is_array($item)) {
+ $result[] = $item;
+ } elseif ($depth === 1) {
+ $result = array_merge($result, array_values($item));
+ } else {
+ $result = array_merge($result, static::flatten($item, $depth - 1));
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Remove one or many array items from a given array using "dot" notation.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return void
+ */
+ public static function forget(&$array, $keys)
+ {
+ $original = &$array;
+
+ $keys = (array) $keys;
+
+ if (count($keys) === 0) {
+ return;
+ }
+
+ foreach ($keys as $key) {
+ // if the exact key exists in the top-level, remove it
+ if (static::exists($array, $key)) {
+ unset($array[$key]);
+
+ continue;
+ }
+
+ $parts = explode('.', $key);
+
+ // clean up before each pass
+ $array = &$original;
+
+ while (count($parts) > 1) {
+ $part = array_shift($parts);
+
+ if (isset($array[$part]) && is_array($array[$part])) {
+ $array = &$array[$part];
+ } else {
+ continue 2;
+ }
+ }
+
+ unset($array[array_shift($parts)]);
+ }
+ }
+
+ /**
+ * Get an item from an array using "dot" notation.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function get($array, $key, $default = null)
+ {
+ if (! static::accessible($array)) {
+ return value($default);
+ }
+
+ if (is_null($key)) {
+ return $array;
+ }
+
+ if (static::exists($array, $key)) {
+ return $array[$key];
+ }
+
+ if (strpos($key, '.') === false) {
+ return $array[$key] ?? value($default);
+ }
+
+ foreach (explode('.', $key) as $segment) {
+ if (static::accessible($array) && static::exists($array, $segment)) {
+ $array = $array[$segment];
+ } else {
+ return value($default);
+ }
+ }
+
+ return $array;
+ }
+
+ /**
+ * Check if an item or items exist in an array using "dot" notation.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string|array $keys
+ * @return bool
+ */
+ public static function has($array, $keys)
+ {
+ if (is_null($keys)) {
+ return false;
+ }
+
+ $keys = (array) $keys;
+
+ if (! $array) {
+ return false;
+ }
+
+ if ($keys === []) {
+ return false;
+ }
+
+ foreach ($keys as $key) {
+ $subKeyArray = $array;
+
+ if (static::exists($array, $key)) {
+ continue;
+ }
+
+ foreach (explode('.', $key) as $segment) {
+ if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {
+ $subKeyArray = $subKeyArray[$segment];
+ } else {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines if an array is associative.
+ *
+ * An array is "associative" if it doesn't have sequential numerical keys beginning with zero.
+ *
+ * @param array $array
+ * @return bool
+ */
+ public static function isAssoc(array $array)
+ {
+ $keys = array_keys($array);
+
+ return array_keys($keys) !== $keys;
+ }
+
+ /**
+ * Get a subset of the items from the given array.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ public static function only($array, $keys)
+ {
+ return array_intersect_key($array, array_flip((array) $keys));
+ }
+
+ /**
+ * Pluck an array of values from an array.
+ *
+ * @param array $array
+ * @param string|array $value
+ * @param string|array|null $key
+ * @return array
+ */
+ public static function pluck($array, $value, $key = null)
+ {
+ $results = [];
+
+ list($value, $key) = static::explodePluckParameters($value, $key);
+
+ foreach ($array as $item) {
+ $itemValue = data_get($item, $value);
+
+ // If the key is "null", we will just append the value to the array and keep
+ // looping. Otherwise we will key the array using the value of the key we
+ // received from the developer. Then we'll return the final array form.
+ if (is_null($key)) {
+ $results[] = $itemValue;
+ } else {
+ $itemKey = data_get($item, $key);
+
+ if (is_object($itemKey) && method_exists($itemKey, '__toString')) {
+ $itemKey = (string) $itemKey;
+ }
+
+ $results[$itemKey] = $itemValue;
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Explode the "value" and "key" arguments passed to "pluck".
+ *
+ * @param string|array $value
+ * @param string|array|null $key
+ * @return array
+ */
+ protected static function explodePluckParameters($value, $key)
+ {
+ $value = is_string($value) ? explode('.', $value) : $value;
+
+ $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
+
+ return [$value, $key];
+ }
+
+ /**
+ * Push an item onto the beginning of an array.
+ *
+ * @param array $array
+ * @param mixed $value
+ * @param mixed $key
+ * @return array
+ */
+ public static function prepend($array, $value, $key = null)
+ {
+ if (is_null($key)) {
+ array_unshift($array, $value);
+ } else {
+ $array = [$key => $value] + $array;
+ }
+
+ return $array;
+ }
+
+ /**
+ * Get a value from the array, and remove it.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function pull(&$array, $key, $default = null)
+ {
+ $value = static::get($array, $key, $default);
+
+ static::forget($array, $key);
+
+ return $value;
+ }
+
+ /**
+ * Get one or a specified number of random values from an array.
+ *
+ * @param array $array
+ * @param int|null $number
+ * @return mixed
+ *
+ * @throws \InvalidArgumentException
+ */
+ public static function random($array, $number = null)
+ {
+ $requested = is_null($number) ? 1 : $number;
+
+ $count = count($array);
+
+ if ($requested > $count) {
+ throw new InvalidArgumentException(
+ "You requested {$requested} items, but there are only {$count} items available."
+ );
+ }
+
+ if (is_null($number)) {
+ return $array[array_rand($array)];
+ }
+
+ if ((int) $number === 0) {
+ return [];
+ }
+
+ $keys = array_rand($array, $number);
+
+ $results = [];
+
+ foreach ((array) $keys as $key) {
+ $results[] = $array[$key];
+ }
+
+ return $results;
+ }
+
+ /**
+ * Set an array item to a given value using "dot" notation.
+ *
+ * If no key is given to the method, the entire array will be replaced.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $value
+ * @return array
+ */
+ public static function set(&$array, $key, $value)
+ {
+ if (is_null($key)) {
+ return $array = $value;
+ }
+
+ $keys = explode('.', $key);
+
+ while (count($keys) > 1) {
+ $key = array_shift($keys);
+
+ // If the key doesn't exist at this depth, we will just create an empty array
+ // to hold the next value, allowing us to create the arrays to hold final
+ // values at the correct depth. Then we'll keep digging into the array.
+ if (! isset($array[$key]) || ! is_array($array[$key])) {
+ $array[$key] = [];
+ }
+
+ $array = &$array[$key];
+ }
+
+ $array[array_shift($keys)] = $value;
+
+ return $array;
+ }
+
+ /**
+ * Shuffle the given array and return the result.
+ *
+ * @param array $array
+ * @return array
+ */
+ public static function shuffle($array)
+ {
+ shuffle($array);
+
+ return $array;
+ }
+
+ /**
+ * Sort the array using the given callback or "dot" notation.
+ *
+ * @param array $array
+ * @param callable|string|null $callback
+ * @return array
+ */
+ public static function sort($array, $callback = null)
+ {
+ return Collection::make($array)->sortBy($callback)->all();
+ }
+
+ /**
+ * Recursively sort an array by keys and values.
+ *
+ * @param array $array
+ * @return array
+ */
+ public static function sortRecursive($array)
+ {
+ foreach ($array as &$value) {
+ if (is_array($value)) {
+ $value = static::sortRecursive($value);
+ }
+ }
+
+ if (static::isAssoc($array)) {
+ ksort($array);
+ } else {
+ sort($array);
+ }
+
+ return $array;
+ }
+
+ /**
+ * Filter the array using the given callback.
+ *
+ * @param array $array
+ * @param callable $callback
+ * @return array
+ */
+ public static function where($array, callable $callback)
+ {
+ return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);
+ }
+
+ /**
+ * If the given value is not an array, wrap it in one.
+ *
+ * @param mixed $value
+ * @return array
+ */
+ public static function wrap($value)
+ {
+ return ! is_array($value) ? [$value] : $value;
+ }
+}
diff --git a/vendor/illuminate/support/Carbon.php b/vendor/illuminate/support/Carbon.php
new file mode 100644
index 0000000..db1bdbe
--- /dev/null
+++ b/vendor/illuminate/support/Carbon.php
@@ -0,0 +1,48 @@
+items = $this->getArrayableItems($items);
+ }
+
+ /**
+ * Create a new collection instance if the value isn't one already.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public static function make($items = [])
+ {
+ return new static($items);
+ }
+
+ /**
+ * Wrap the given value in a collection if applicable.
+ *
+ * @param mixed $value
+ * @return static
+ */
+ public static function wrap($value)
+ {
+ return $value instanceof self
+ ? new static($value)
+ : new static(Arr::wrap($value));
+ }
+
+ /**
+ * Get the underlying items from the given collection if applicable.
+ *
+ * @param array|static $value
+ * @return array
+ */
+ public static function unwrap($value)
+ {
+ return $value instanceof self ? $value->all() : $value;
+ }
+
+ /**
+ * Create a new collection by invoking the callback a given amount of times.
+ *
+ * @param int $number
+ * @param callable $callback
+ * @return static
+ */
+ public static function times($number, callable $callback = null)
+ {
+ if ($number < 1) {
+ return new static;
+ }
+
+ if (is_null($callback)) {
+ return new static(range(1, $number));
+ }
+
+ return (new static(range(1, $number)))->map($callback);
+ }
+
+ /**
+ * Get all of the items in the collection.
+ *
+ * @return array
+ */
+ public function all()
+ {
+ return $this->items;
+ }
+
+ /**
+ * Get the average value of a given key.
+ *
+ * @param callable|string|null $callback
+ * @return mixed
+ */
+ public function avg($callback = null)
+ {
+ if ($count = $this->count()) {
+ return $this->sum($callback) / $count;
+ }
+ }
+
+ /**
+ * Alias for the "avg" method.
+ *
+ * @param callable|string|null $callback
+ * @return mixed
+ */
+ public function average($callback = null)
+ {
+ return $this->avg($callback);
+ }
+
+ /**
+ * Get the median of a given key.
+ *
+ * @param null $key
+ * @return mixed
+ */
+ public function median($key = null)
+ {
+ $count = $this->count();
+
+ if ($count == 0) {
+ return;
+ }
+
+ $values = (isset($key) ? $this->pluck($key) : $this)
+ ->sort()->values();
+
+ $middle = (int) ($count / 2);
+
+ if ($count % 2) {
+ return $values->get($middle);
+ }
+
+ return (new static([
+ $values->get($middle - 1), $values->get($middle),
+ ]))->average();
+ }
+
+ /**
+ * Get the mode of a given key.
+ *
+ * @param mixed $key
+ * @return array|null
+ */
+ public function mode($key = null)
+ {
+ $count = $this->count();
+
+ if ($count == 0) {
+ return;
+ }
+
+ $collection = isset($key) ? $this->pluck($key) : $this;
+
+ $counts = new self;
+
+ $collection->each(function ($value) use ($counts) {
+ $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1;
+ });
+
+ $sorted = $counts->sort();
+
+ $highestValue = $sorted->last();
+
+ return $sorted->filter(function ($value) use ($highestValue) {
+ return $value == $highestValue;
+ })->sort()->keys()->all();
+ }
+
+ /**
+ * Collapse the collection of items into a single array.
+ *
+ * @return static
+ */
+ public function collapse()
+ {
+ return new static(Arr::collapse($this->items));
+ }
+
+ /**
+ * Determine if an item exists in the collection.
+ *
+ * @param mixed $key
+ * @param mixed $operator
+ * @param mixed $value
+ * @return bool
+ */
+ public function contains($key, $operator = null, $value = null)
+ {
+ if (func_num_args() == 1) {
+ if ($this->useAsCallable($key)) {
+ $placeholder = new stdClass;
+
+ return $this->first($key, $placeholder) !== $placeholder;
+ }
+
+ return in_array($key, $this->items);
+ }
+
+ return $this->contains($this->operatorForWhere(...func_get_args()));
+ }
+
+ /**
+ * Determine if an item exists in the collection using strict comparison.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @return bool
+ */
+ public function containsStrict($key, $value = null)
+ {
+ if (func_num_args() == 2) {
+ return $this->contains(function ($item) use ($key, $value) {
+ return data_get($item, $key) === $value;
+ });
+ }
+
+ if ($this->useAsCallable($key)) {
+ return ! is_null($this->first($key));
+ }
+
+ return in_array($key, $this->items, true);
+ }
+
+ /**
+ * Cross join with the given lists, returning all possible permutations.
+ *
+ * @param mixed ...$lists
+ * @return static
+ */
+ public function crossJoin(...$lists)
+ {
+ return new static(Arr::crossJoin(
+ $this->items, ...array_map([$this, 'getArrayableItems'], $lists)
+ ));
+ }
+
+ /**
+ * Dump the collection and end the script.
+ *
+ * @return void
+ */
+ public function dd(...$args)
+ {
+ http_response_code(500);
+
+ call_user_func_array([$this, 'dump'], $args);
+
+ die(1);
+ }
+
+ /**
+ * Dump the collection.
+ *
+ * @return $this
+ */
+ public function dump()
+ {
+ (new static(func_get_args()))
+ ->push($this)
+ ->each(function ($item) {
+ (new Dumper)->dump($item);
+ });
+
+ return $this;
+ }
+
+ /**
+ * Get the items in the collection that are not present in the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function diff($items)
+ {
+ return new static(array_diff($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Get the items in the collection whose keys and values are not present in the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function diffAssoc($items)
+ {
+ return new static(array_diff_assoc($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Get the items in the collection whose keys are not present in the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function diffKeys($items)
+ {
+ return new static(array_diff_key($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Execute a callback over each item.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function each(callable $callback)
+ {
+ foreach ($this->items as $key => $item) {
+ if ($callback($item, $key) === false) {
+ break;
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Execute a callback over each nested chunk of items.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function eachSpread(callable $callback)
+ {
+ return $this->each(function ($chunk, $key) use ($callback) {
+ $chunk[] = $key;
+
+ return $callback(...$chunk);
+ });
+ }
+
+ /**
+ * Determine if all items in the collection pass the given test.
+ *
+ * @param string|callable $key
+ * @param mixed $operator
+ * @param mixed $value
+ * @return bool
+ */
+ public function every($key, $operator = null, $value = null)
+ {
+ if (func_num_args() == 1) {
+ $callback = $this->valueRetriever($key);
+
+ foreach ($this->items as $k => $v) {
+ if (! $callback($v, $k)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return $this->every($this->operatorForWhere(...func_get_args()));
+ }
+
+ /**
+ * Get all items except for those with the specified keys.
+ *
+ * @param \Illuminate\Support\Collection|mixed $keys
+ * @return static
+ */
+ public function except($keys)
+ {
+ if ($keys instanceof self) {
+ $keys = $keys->all();
+ } elseif (! is_array($keys)) {
+ $keys = func_get_args();
+ }
+
+ return new static(Arr::except($this->items, $keys));
+ }
+
+ /**
+ * Run a filter over each of the items.
+ *
+ * @param callable|null $callback
+ * @return static
+ */
+ public function filter(callable $callback = null)
+ {
+ if ($callback) {
+ return new static(Arr::where($this->items, $callback));
+ }
+
+ return new static(array_filter($this->items));
+ }
+
+ /**
+ * Apply the callback if the value is truthy.
+ *
+ * @param bool $value
+ * @param callable $callback
+ * @param callable $default
+ * @return mixed
+ */
+ public function when($value, callable $callback, callable $default = null)
+ {
+ if ($value) {
+ return $callback($this, $value);
+ } elseif ($default) {
+ return $default($this, $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Apply the callback if the value is falsy.
+ *
+ * @param bool $value
+ * @param callable $callback
+ * @param callable $default
+ * @return mixed
+ */
+ public function unless($value, callable $callback, callable $default = null)
+ {
+ return $this->when(! $value, $callback, $default);
+ }
+
+ /**
+ * Filter items by the given key value pair.
+ *
+ * @param string $key
+ * @param mixed $operator
+ * @param mixed $value
+ * @return static
+ */
+ public function where($key, $operator, $value = null)
+ {
+ return $this->filter($this->operatorForWhere(...func_get_args()));
+ }
+
+ /**
+ * Get an operator checker callback.
+ *
+ * @param string $key
+ * @param string $operator
+ * @param mixed $value
+ * @return \Closure
+ */
+ protected function operatorForWhere($key, $operator, $value = null)
+ {
+ if (func_num_args() == 2) {
+ $value = $operator;
+
+ $operator = '=';
+ }
+
+ return function ($item) use ($key, $operator, $value) {
+ $retrieved = data_get($item, $key);
+
+ $strings = array_filter([$retrieved, $value], function ($value) {
+ return is_string($value) || (is_object($value) && method_exists($value, '__toString'));
+ });
+
+ if (count($strings) < 2 && count(array_filter([$retrieved, $value], 'is_object')) == 1) {
+ return in_array($operator, ['!=', '<>', '!==']);
+ }
+
+ switch ($operator) {
+ default:
+ case '=':
+ case '==': return $retrieved == $value;
+ case '!=':
+ case '<>': return $retrieved != $value;
+ case '<': return $retrieved < $value;
+ case '>': return $retrieved > $value;
+ case '<=': return $retrieved <= $value;
+ case '>=': return $retrieved >= $value;
+ case '===': return $retrieved === $value;
+ case '!==': return $retrieved !== $value;
+ }
+ };
+ }
+
+ /**
+ * Filter items by the given key value pair using strict comparison.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return static
+ */
+ public function whereStrict($key, $value)
+ {
+ return $this->where($key, '===', $value);
+ }
+
+ /**
+ * Filter items by the given key value pair.
+ *
+ * @param string $key
+ * @param mixed $values
+ * @param bool $strict
+ * @return static
+ */
+ public function whereIn($key, $values, $strict = false)
+ {
+ $values = $this->getArrayableItems($values);
+
+ return $this->filter(function ($item) use ($key, $values, $strict) {
+ return in_array(data_get($item, $key), $values, $strict);
+ });
+ }
+
+ /**
+ * Filter items by the given key value pair using strict comparison.
+ *
+ * @param string $key
+ * @param mixed $values
+ * @return static
+ */
+ public function whereInStrict($key, $values)
+ {
+ return $this->whereIn($key, $values, true);
+ }
+
+ /**
+ * Filter items by the given key value pair.
+ *
+ * @param string $key
+ * @param mixed $values
+ * @param bool $strict
+ * @return static
+ */
+ public function whereNotIn($key, $values, $strict = false)
+ {
+ $values = $this->getArrayableItems($values);
+
+ return $this->reject(function ($item) use ($key, $values, $strict) {
+ return in_array(data_get($item, $key), $values, $strict);
+ });
+ }
+
+ /**
+ * Filter items by the given key value pair using strict comparison.
+ *
+ * @param string $key
+ * @param mixed $values
+ * @return static
+ */
+ public function whereNotInStrict($key, $values)
+ {
+ return $this->whereNotIn($key, $values, true);
+ }
+
+ /**
+ * Get the first item from the collection.
+ *
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ public function first(callable $callback = null, $default = null)
+ {
+ return Arr::first($this->items, $callback, $default);
+ }
+
+ /**
+ * Get the first item by the given key value pair.
+ *
+ * @param string $key
+ * @param mixed $operator
+ * @param mixed $value
+ * @return static
+ */
+ public function firstWhere($key, $operator, $value = null)
+ {
+ return $this->first($this->operatorForWhere(...func_get_args()));
+ }
+
+ /**
+ * Get a flattened array of the items in the collection.
+ *
+ * @param int $depth
+ * @return static
+ */
+ public function flatten($depth = INF)
+ {
+ return new static(Arr::flatten($this->items, $depth));
+ }
+
+ /**
+ * Flip the items in the collection.
+ *
+ * @return static
+ */
+ public function flip()
+ {
+ return new static(array_flip($this->items));
+ }
+
+ /**
+ * Remove an item from the collection by key.
+ *
+ * @param string|array $keys
+ * @return $this
+ */
+ public function forget($keys)
+ {
+ foreach ((array) $keys as $key) {
+ $this->offsetUnset($key);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get an item from the collection by key.
+ *
+ * @param mixed $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ if ($this->offsetExists($key)) {
+ return $this->items[$key];
+ }
+
+ return value($default);
+ }
+
+ /**
+ * Group an associative array by a field or using a callback.
+ *
+ * @param callable|string $groupBy
+ * @param bool $preserveKeys
+ * @return static
+ */
+ public function groupBy($groupBy, $preserveKeys = false)
+ {
+ if (is_array($groupBy)) {
+ $nextGroups = $groupBy;
+
+ $groupBy = array_shift($nextGroups);
+ }
+
+ $groupBy = $this->valueRetriever($groupBy);
+
+ $results = [];
+
+ foreach ($this->items as $key => $value) {
+ $groupKeys = $groupBy($value, $key);
+
+ if (! is_array($groupKeys)) {
+ $groupKeys = [$groupKeys];
+ }
+
+ foreach ($groupKeys as $groupKey) {
+ $groupKey = is_bool($groupKey) ? (int) $groupKey : $groupKey;
+
+ if (! array_key_exists($groupKey, $results)) {
+ $results[$groupKey] = new static;
+ }
+
+ $results[$groupKey]->offsetSet($preserveKeys ? $key : null, $value);
+ }
+ }
+
+ $result = new static($results);
+
+ if (! empty($nextGroups)) {
+ return $result->map->groupBy($nextGroups, $preserveKeys);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Key an associative array by a field or using a callback.
+ *
+ * @param callable|string $keyBy
+ * @return static
+ */
+ public function keyBy($keyBy)
+ {
+ $keyBy = $this->valueRetriever($keyBy);
+
+ $results = [];
+
+ foreach ($this->items as $key => $item) {
+ $resolvedKey = $keyBy($item, $key);
+
+ if (is_object($resolvedKey)) {
+ $resolvedKey = (string) $resolvedKey;
+ }
+
+ $results[$resolvedKey] = $item;
+ }
+
+ return new static($results);
+ }
+
+ /**
+ * Determine if an item exists in the collection by key.
+ *
+ * @param mixed $key
+ * @return bool
+ */
+ public function has($key)
+ {
+ $keys = is_array($key) ? $key : func_get_args();
+
+ foreach ($keys as $value) {
+ if (! $this->offsetExists($value)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Concatenate values of a given key as a string.
+ *
+ * @param string $value
+ * @param string $glue
+ * @return string
+ */
+ public function implode($value, $glue = null)
+ {
+ $first = $this->first();
+
+ if (is_array($first) || is_object($first)) {
+ return implode($glue, $this->pluck($value)->all());
+ }
+
+ return implode($value, $this->items);
+ }
+
+ /**
+ * Intersect the collection with the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function intersect($items)
+ {
+ return new static(array_intersect($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Intersect the collection with the given items by key.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function intersectByKeys($items)
+ {
+ return new static(array_intersect_key(
+ $this->items, $this->getArrayableItems($items)
+ ));
+ }
+
+ /**
+ * Determine if the collection is empty or not.
+ *
+ * @return bool
+ */
+ public function isEmpty()
+ {
+ return empty($this->items);
+ }
+
+ /**
+ * Determine if the collection is not empty.
+ *
+ * @return bool
+ */
+ public function isNotEmpty()
+ {
+ return ! $this->isEmpty();
+ }
+
+ /**
+ * Determine if the given value is callable, but not a string.
+ *
+ * @param mixed $value
+ * @return bool
+ */
+ protected function useAsCallable($value)
+ {
+ return ! is_string($value) && is_callable($value);
+ }
+
+ /**
+ * Get the keys of the collection items.
+ *
+ * @return static
+ */
+ public function keys()
+ {
+ return new static(array_keys($this->items));
+ }
+
+ /**
+ * Get the last item from the collection.
+ *
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ public function last(callable $callback = null, $default = null)
+ {
+ return Arr::last($this->items, $callback, $default);
+ }
+
+ /**
+ * Get the values of a given key.
+ *
+ * @param string|array $value
+ * @param string|null $key
+ * @return static
+ */
+ public function pluck($value, $key = null)
+ {
+ return new static(Arr::pluck($this->items, $value, $key));
+ }
+
+ /**
+ * Run a map over each of the items.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function map(callable $callback)
+ {
+ $keys = array_keys($this->items);
+
+ $items = array_map($callback, $this->items, $keys);
+
+ return new static(array_combine($keys, $items));
+ }
+
+ /**
+ * Run a map over each nested chunk of items.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function mapSpread(callable $callback)
+ {
+ return $this->map(function ($chunk, $key) use ($callback) {
+ $chunk[] = $key;
+
+ return $callback(...$chunk);
+ });
+ }
+
+ /**
+ * Run a dictionary map over the items.
+ *
+ * The callback should return an associative array with a single key/value pair.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function mapToDictionary(callable $callback)
+ {
+ $dictionary = $this->map($callback)->reduce(function ($groups, $pair) {
+ $groups[key($pair)][] = reset($pair);
+
+ return $groups;
+ }, []);
+
+ return new static($dictionary);
+ }
+
+ /**
+ * Run a grouping map over the items.
+ *
+ * The callback should return an associative array with a single key/value pair.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function mapToGroups(callable $callback)
+ {
+ $groups = $this->mapToDictionary($callback);
+
+ return $groups->map([$this, 'make']);
+ }
+
+ /**
+ * Run an associative map over each of the items.
+ *
+ * The callback should return an associative array with a single key/value pair.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function mapWithKeys(callable $callback)
+ {
+ $result = [];
+
+ foreach ($this->items as $key => $value) {
+ $assoc = $callback($value, $key);
+
+ foreach ($assoc as $mapKey => $mapValue) {
+ $result[$mapKey] = $mapValue;
+ }
+ }
+
+ return new static($result);
+ }
+
+ /**
+ * Map a collection and flatten the result by a single level.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function flatMap(callable $callback)
+ {
+ return $this->map($callback)->collapse();
+ }
+
+ /**
+ * Map the values into a new class.
+ *
+ * @param string $class
+ * @return static
+ */
+ public function mapInto($class)
+ {
+ return $this->map(function ($value, $key) use ($class) {
+ return new $class($value, $key);
+ });
+ }
+
+ /**
+ * Get the max value of a given key.
+ *
+ * @param callable|string|null $callback
+ * @return mixed
+ */
+ public function max($callback = null)
+ {
+ $callback = $this->valueRetriever($callback);
+
+ return $this->filter(function ($value) {
+ return ! is_null($value);
+ })->reduce(function ($result, $item) use ($callback) {
+ $value = $callback($item);
+
+ return is_null($result) || $value > $result ? $value : $result;
+ });
+ }
+
+ /**
+ * Merge the collection with the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function merge($items)
+ {
+ return new static(array_merge($this->items, $this->getArrayableItems($items)));
+ }
+
+ /**
+ * Create a collection by using this collection for keys and another for its values.
+ *
+ * @param mixed $values
+ * @return static
+ */
+ public function combine($values)
+ {
+ return new static(array_combine($this->all(), $this->getArrayableItems($values)));
+ }
+
+ /**
+ * Union the collection with the given items.
+ *
+ * @param mixed $items
+ * @return static
+ */
+ public function union($items)
+ {
+ return new static($this->items + $this->getArrayableItems($items));
+ }
+
+ /**
+ * Get the min value of a given key.
+ *
+ * @param callable|string|null $callback
+ * @return mixed
+ */
+ public function min($callback = null)
+ {
+ $callback = $this->valueRetriever($callback);
+
+ return $this->filter(function ($value) {
+ return ! is_null($value);
+ })->reduce(function ($result, $item) use ($callback) {
+ $value = $callback($item);
+
+ return is_null($result) || $value < $result ? $value : $result;
+ });
+ }
+
+ /**
+ * Create a new collection consisting of every n-th element.
+ *
+ * @param int $step
+ * @param int $offset
+ * @return static
+ */
+ public function nth($step, $offset = 0)
+ {
+ $new = [];
+
+ $position = 0;
+
+ foreach ($this->items as $item) {
+ if ($position % $step === $offset) {
+ $new[] = $item;
+ }
+
+ $position++;
+ }
+
+ return new static($new);
+ }
+
+ /**
+ * Get the items with the specified keys.
+ *
+ * @param mixed $keys
+ * @return static
+ */
+ public function only($keys)
+ {
+ if (is_null($keys)) {
+ return new static($this->items);
+ }
+
+ if ($keys instanceof self) {
+ $keys = $keys->all();
+ }
+
+ $keys = is_array($keys) ? $keys : func_get_args();
+
+ return new static(Arr::only($this->items, $keys));
+ }
+
+ /**
+ * "Paginate" the collection by slicing it into a smaller collection.
+ *
+ * @param int $page
+ * @param int $perPage
+ * @return static
+ */
+ public function forPage($page, $perPage)
+ {
+ $offset = max(0, ($page - 1) * $perPage);
+
+ return $this->slice($offset, $perPage);
+ }
+
+ /**
+ * Partition the collection into two arrays using the given callback or key.
+ *
+ * @param callable|string $callback
+ * @return static
+ */
+ public function partition($callback)
+ {
+ $partitions = [new static, new static];
+
+ $callback = $this->valueRetriever($callback);
+
+ foreach ($this->items as $key => $item) {
+ $partitions[(int) ! $callback($item, $key)][$key] = $item;
+ }
+
+ return new static($partitions);
+ }
+
+ /**
+ * Pass the collection to the given callback and return the result.
+ *
+ * @param callable $callback
+ * @return mixed
+ */
+ public function pipe(callable $callback)
+ {
+ return $callback($this);
+ }
+
+ /**
+ * Get and remove the last item from the collection.
+ *
+ * @return mixed
+ */
+ public function pop()
+ {
+ return array_pop($this->items);
+ }
+
+ /**
+ * Push an item onto the beginning of the collection.
+ *
+ * @param mixed $value
+ * @param mixed $key
+ * @return $this
+ */
+ public function prepend($value, $key = null)
+ {
+ $this->items = Arr::prepend($this->items, $value, $key);
+
+ return $this;
+ }
+
+ /**
+ * Push an item onto the end of the collection.
+ *
+ * @param mixed $value
+ * @return $this
+ */
+ public function push($value)
+ {
+ $this->offsetSet(null, $value);
+
+ return $this;
+ }
+
+ /**
+ * Push all of the given items onto the collection.
+ *
+ * @param \Traversable $source
+ * @return $this
+ */
+ public function concat($source)
+ {
+ $result = new static($this);
+
+ foreach ($source as $item) {
+ $result->push($item);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get and remove an item from the collection.
+ *
+ * @param mixed $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function pull($key, $default = null)
+ {
+ return Arr::pull($this->items, $key, $default);
+ }
+
+ /**
+ * Put an item in the collection by key.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @return $this
+ */
+ public function put($key, $value)
+ {
+ $this->offsetSet($key, $value);
+
+ return $this;
+ }
+
+ /**
+ * Get one or a specified number of items randomly from the collection.
+ *
+ * @param int|null $number
+ * @return mixed
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function random($number = null)
+ {
+ if (is_null($number)) {
+ return Arr::random($this->items);
+ }
+
+ return new static(Arr::random($this->items, $number));
+ }
+
+ /**
+ * Reduce the collection to a single value.
+ *
+ * @param callable $callback
+ * @param mixed $initial
+ * @return mixed
+ */
+ public function reduce(callable $callback, $initial = null)
+ {
+ return array_reduce($this->items, $callback, $initial);
+ }
+
+ /**
+ * Create a collection of all elements that do not pass a given truth test.
+ *
+ * @param callable|mixed $callback
+ * @return static
+ */
+ public function reject($callback)
+ {
+ if ($this->useAsCallable($callback)) {
+ return $this->filter(function ($value, $key) use ($callback) {
+ return ! $callback($value, $key);
+ });
+ }
+
+ return $this->filter(function ($item) use ($callback) {
+ return $item != $callback;
+ });
+ }
+
+ /**
+ * Reverse items order.
+ *
+ * @return static
+ */
+ public function reverse()
+ {
+ return new static(array_reverse($this->items, true));
+ }
+
+ /**
+ * Search the collection for a given value and return the corresponding key if successful.
+ *
+ * @param mixed $value
+ * @param bool $strict
+ * @return mixed
+ */
+ public function search($value, $strict = false)
+ {
+ if (! $this->useAsCallable($value)) {
+ return array_search($value, $this->items, $strict);
+ }
+
+ foreach ($this->items as $key => $item) {
+ if (call_user_func($value, $item, $key)) {
+ return $key;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get and remove the first item from the collection.
+ *
+ * @return mixed
+ */
+ public function shift()
+ {
+ return array_shift($this->items);
+ }
+
+ /**
+ * Shuffle the items in the collection.
+ *
+ * @param int $seed
+ * @return static
+ */
+ public function shuffle($seed = null)
+ {
+ $items = $this->items;
+
+ if (is_null($seed)) {
+ shuffle($items);
+ } else {
+ srand($seed);
+
+ usort($items, function () {
+ return rand(-1, 1);
+ });
+ }
+
+ return new static($items);
+ }
+
+ /**
+ * Slice the underlying collection array.
+ *
+ * @param int $offset
+ * @param int $length
+ * @return static
+ */
+ public function slice($offset, $length = null)
+ {
+ return new static(array_slice($this->items, $offset, $length, true));
+ }
+
+ /**
+ * Split a collection into a certain number of groups.
+ *
+ * @param int $numberOfGroups
+ * @return static
+ */
+ public function split($numberOfGroups)
+ {
+ if ($this->isEmpty()) {
+ return new static;
+ }
+
+ $groupSize = ceil($this->count() / $numberOfGroups);
+
+ return $this->chunk($groupSize);
+ }
+
+ /**
+ * Chunk the underlying collection array.
+ *
+ * @param int $size
+ * @return static
+ */
+ public function chunk($size)
+ {
+ if ($size <= 0) {
+ return new static;
+ }
+
+ $chunks = [];
+
+ foreach (array_chunk($this->items, $size, true) as $chunk) {
+ $chunks[] = new static($chunk);
+ }
+
+ return new static($chunks);
+ }
+
+ /**
+ * Sort through each item with a callback.
+ *
+ * @param callable|null $callback
+ * @return static
+ */
+ public function sort(callable $callback = null)
+ {
+ $items = $this->items;
+
+ $callback
+ ? uasort($items, $callback)
+ : asort($items);
+
+ return new static($items);
+ }
+
+ /**
+ * Sort the collection using the given callback.
+ *
+ * @param callable|string $callback
+ * @param int $options
+ * @param bool $descending
+ * @return static
+ */
+ public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
+ {
+ $results = [];
+
+ $callback = $this->valueRetriever($callback);
+
+ // First we will loop through the items and get the comparator from a callback
+ // function which we were given. Then, we will sort the returned values and
+ // and grab the corresponding values for the sorted keys from this array.
+ foreach ($this->items as $key => $value) {
+ $results[$key] = $callback($value, $key);
+ }
+
+ $descending ? arsort($results, $options)
+ : asort($results, $options);
+
+ // Once we have sorted all of the keys in the array, we will loop through them
+ // and grab the corresponding model so we can set the underlying items list
+ // to the sorted version. Then we'll just return the collection instance.
+ foreach (array_keys($results) as $key) {
+ $results[$key] = $this->items[$key];
+ }
+
+ return new static($results);
+ }
+
+ /**
+ * Sort the collection in descending order using the given callback.
+ *
+ * @param callable|string $callback
+ * @param int $options
+ * @return static
+ */
+ public function sortByDesc($callback, $options = SORT_REGULAR)
+ {
+ return $this->sortBy($callback, $options, true);
+ }
+
+ /**
+ * Splice a portion of the underlying collection array.
+ *
+ * @param int $offset
+ * @param int|null $length
+ * @param mixed $replacement
+ * @return static
+ */
+ public function splice($offset, $length = null, $replacement = [])
+ {
+ if (func_num_args() == 1) {
+ return new static(array_splice($this->items, $offset));
+ }
+
+ return new static(array_splice($this->items, $offset, $length, $replacement));
+ }
+
+ /**
+ * Get the sum of the given values.
+ *
+ * @param callable|string|null $callback
+ * @return mixed
+ */
+ public function sum($callback = null)
+ {
+ if (is_null($callback)) {
+ return array_sum($this->items);
+ }
+
+ $callback = $this->valueRetriever($callback);
+
+ return $this->reduce(function ($result, $item) use ($callback) {
+ return $result + $callback($item);
+ }, 0);
+ }
+
+ /**
+ * Take the first or last {$limit} items.
+ *
+ * @param int $limit
+ * @return static
+ */
+ public function take($limit)
+ {
+ if ($limit < 0) {
+ return $this->slice($limit, abs($limit));
+ }
+
+ return $this->slice(0, $limit);
+ }
+
+ /**
+ * Pass the collection to the given callback and then return it.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function tap(callable $callback)
+ {
+ $callback(new static($this->items));
+
+ return $this;
+ }
+
+ /**
+ * Transform each item in the collection using a callback.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function transform(callable $callback)
+ {
+ $this->items = $this->map($callback)->all();
+
+ return $this;
+ }
+
+ /**
+ * Return only unique items from the collection array.
+ *
+ * @param string|callable|null $key
+ * @param bool $strict
+ * @return static
+ */
+ public function unique($key = null, $strict = false)
+ {
+ if (is_null($key)) {
+ return new static(array_unique($this->items, SORT_REGULAR));
+ }
+
+ $callback = $this->valueRetriever($key);
+
+ $exists = [];
+
+ return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {
+ if (in_array($id = $callback($item, $key), $exists, $strict)) {
+ return true;
+ }
+
+ $exists[] = $id;
+ });
+ }
+
+ /**
+ * Return only unique items from the collection array using strict comparison.
+ *
+ * @param string|callable|null $key
+ * @return static
+ */
+ public function uniqueStrict($key = null)
+ {
+ return $this->unique($key, true);
+ }
+
+ /**
+ * Reset the keys on the underlying array.
+ *
+ * @return static
+ */
+ public function values()
+ {
+ return new static(array_values($this->items));
+ }
+
+ /**
+ * Get a value retrieving callback.
+ *
+ * @param string $value
+ * @return callable
+ */
+ protected function valueRetriever($value)
+ {
+ if ($this->useAsCallable($value)) {
+ return $value;
+ }
+
+ return function ($item) use ($value) {
+ return data_get($item, $value);
+ };
+ }
+
+ /**
+ * Zip the collection together with one or more arrays.
+ *
+ * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]);
+ * => [[1, 4], [2, 5], [3, 6]]
+ *
+ * @param mixed ...$items
+ * @return static
+ */
+ public function zip($items)
+ {
+ $arrayableItems = array_map(function ($items) {
+ return $this->getArrayableItems($items);
+ }, func_get_args());
+
+ $params = array_merge([function () {
+ return new static(func_get_args());
+ }, $this->items], $arrayableItems);
+
+ return new static(call_user_func_array('array_map', $params));
+ }
+
+ /**
+ * Pad collection to the specified length with a value.
+ *
+ * @param int $size
+ * @param mixed $value
+ * @return static
+ */
+ public function pad($size, $value)
+ {
+ return new static(array_pad($this->items, $size, $value));
+ }
+
+ /**
+ * Get the collection of items as a plain array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return array_map(function ($value) {
+ return $value instanceof Arrayable ? $value->toArray() : $value;
+ }, $this->items);
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize()
+ {
+ return array_map(function ($value) {
+ if ($value instanceof JsonSerializable) {
+ return $value->jsonSerialize();
+ } elseif ($value instanceof Jsonable) {
+ return json_decode($value->toJson(), true);
+ } elseif ($value instanceof Arrayable) {
+ return $value->toArray();
+ }
+
+ return $value;
+ }, $this->items);
+ }
+
+ /**
+ * Get the collection of items as JSON.
+ *
+ * @param int $options
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Get an iterator for the items.
+ *
+ * @return \ArrayIterator
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->items);
+ }
+
+ /**
+ * Get a CachingIterator instance.
+ *
+ * @param int $flags
+ * @return \CachingIterator
+ */
+ public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING)
+ {
+ return new CachingIterator($this->getIterator(), $flags);
+ }
+
+ /**
+ * Count the number of items in the collection.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->items);
+ }
+
+ /**
+ * Get a base Support collection instance from this collection.
+ *
+ * @return \Illuminate\Support\Collection
+ */
+ public function toBase()
+ {
+ return new self($this);
+ }
+
+ /**
+ * Determine if an item exists at an offset.
+ *
+ * @param mixed $key
+ * @return bool
+ */
+ public function offsetExists($key)
+ {
+ return array_key_exists($key, $this->items);
+ }
+
+ /**
+ * Get an item at a given offset.
+ *
+ * @param mixed $key
+ * @return mixed
+ */
+ public function offsetGet($key)
+ {
+ return $this->items[$key];
+ }
+
+ /**
+ * Set the item at a given offset.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($key, $value)
+ {
+ if (is_null($key)) {
+ $this->items[] = $value;
+ } else {
+ $this->items[$key] = $value;
+ }
+ }
+
+ /**
+ * Unset the item at a given offset.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function offsetUnset($key)
+ {
+ unset($this->items[$key]);
+ }
+
+ /**
+ * Convert the collection to its string representation.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->toJson();
+ }
+
+ /**
+ * Results array of items from Collection or Arrayable.
+ *
+ * @param mixed $items
+ * @return array
+ */
+ protected function getArrayableItems($items)
+ {
+ if (is_array($items)) {
+ return $items;
+ } elseif ($items instanceof self) {
+ return $items->all();
+ } elseif ($items instanceof Arrayable) {
+ return $items->toArray();
+ } elseif ($items instanceof Jsonable) {
+ return json_decode($items->toJson(), true);
+ } elseif ($items instanceof JsonSerializable) {
+ return $items->jsonSerialize();
+ } elseif ($items instanceof Traversable) {
+ return iterator_to_array($items);
+ }
+
+ return (array) $items;
+ }
+
+ /**
+ * Add a method to the list of proxied methods.
+ *
+ * @param string $method
+ * @return void
+ */
+ public static function proxy($method)
+ {
+ static::$proxies[] = $method;
+ }
+
+ /**
+ * Dynamically access collection proxies.
+ *
+ * @param string $key
+ * @return mixed
+ *
+ * @throws \Exception
+ */
+ public function __get($key)
+ {
+ if (! in_array($key, static::$proxies)) {
+ throw new Exception("Property [{$key}] does not exist on this collection instance.");
+ }
+
+ return new HigherOrderCollectionProxy($this, $key);
+ }
+}
diff --git a/vendor/illuminate/support/Composer.php b/vendor/illuminate/support/Composer.php
new file mode 100644
index 0000000..bc76aeb
--- /dev/null
+++ b/vendor/illuminate/support/Composer.php
@@ -0,0 +1,99 @@
+files = $files;
+ $this->workingPath = $workingPath;
+ }
+
+ /**
+ * Regenerate the Composer autoloader files.
+ *
+ * @param string $extra
+ * @return void
+ */
+ public function dumpAutoloads($extra = '')
+ {
+ $process = $this->getProcess();
+
+ $process->setCommandLine(trim($this->findComposer().' dump-autoload '.$extra));
+
+ $process->run();
+ }
+
+ /**
+ * Regenerate the optimized Composer autoloader files.
+ *
+ * @return void
+ */
+ public function dumpOptimized()
+ {
+ $this->dumpAutoloads('--optimize');
+ }
+
+ /**
+ * Get the composer command for the environment.
+ *
+ * @return string
+ */
+ protected function findComposer()
+ {
+ if ($this->files->exists($this->workingPath.'/composer.phar')) {
+ return ProcessUtils::escapeArgument((new PhpExecutableFinder)->find(false)).' composer.phar';
+ }
+
+ return 'composer';
+ }
+
+ /**
+ * Get a new Symfony process instance.
+ *
+ * @return \Symfony\Component\Process\Process
+ */
+ protected function getProcess()
+ {
+ return (new Process('', $this->workingPath))->setTimeout(null);
+ }
+
+ /**
+ * Set the working path used by the class.
+ *
+ * @param string $path
+ * @return $this
+ */
+ public function setWorkingPath($path)
+ {
+ $this->workingPath = realpath($path);
+
+ return $this;
+ }
+}
diff --git a/vendor/illuminate/support/Debug/Dumper.php b/vendor/illuminate/support/Debug/Dumper.php
new file mode 100644
index 0000000..7442343
--- /dev/null
+++ b/vendor/illuminate/support/Debug/Dumper.php
@@ -0,0 +1,26 @@
+dump((new VarCloner)->cloneVar($value));
+ } else {
+ var_dump($value);
+ }
+ }
+}
diff --git a/vendor/illuminate/support/Debug/HtmlDumper.php b/vendor/illuminate/support/Debug/HtmlDumper.php
new file mode 100644
index 0000000..5825ac8
--- /dev/null
+++ b/vendor/illuminate/support/Debug/HtmlDumper.php
@@ -0,0 +1,29 @@
+ 'background-color:#fff; color:#222; line-height:1.2em; font-weight:normal; font:12px Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:100000',
+ 'num' => 'color:#a71d5d',
+ 'const' => 'color:#795da3',
+ 'str' => 'color:#df5000',
+ 'cchr' => 'color:#222',
+ 'note' => 'color:#a71d5d',
+ 'ref' => 'color:#a0a0a0',
+ 'public' => 'color:#795da3',
+ 'protected' => 'color:#795da3',
+ 'private' => 'color:#795da3',
+ 'meta' => 'color:#b729d9',
+ 'key' => 'color:#df5000',
+ 'index' => 'color:#a71d5d',
+ ];
+}
diff --git a/vendor/illuminate/support/Facades/App.php b/vendor/illuminate/support/Facades/App.php
new file mode 100644
index 0000000..0e9e637
--- /dev/null
+++ b/vendor/illuminate/support/Facades/App.php
@@ -0,0 +1,31 @@
+make('router')->auth();
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Blade.php b/vendor/illuminate/support/Facades/Blade.php
new file mode 100644
index 0000000..b016a46
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Blade.php
@@ -0,0 +1,19 @@
+getEngineResolver()->resolve('blade')->getCompiler();
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Broadcast.php b/vendor/illuminate/support/Facades/Broadcast.php
new file mode 100644
index 0000000..81af932
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Broadcast.php
@@ -0,0 +1,21 @@
+cookie($key, null));
+ }
+
+ /**
+ * Retrieve a cookie from the request.
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return string
+ */
+ public static function get($key = null, $default = null)
+ {
+ return static::$app['request']->cookie($key, $default);
+ }
+
+ /**
+ * Get the registered name of the component.
+ *
+ * @return string
+ */
+ protected static function getFacadeAccessor()
+ {
+ return 'cookie';
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Crypt.php b/vendor/illuminate/support/Facades/Crypt.php
new file mode 100644
index 0000000..0eef08d
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Crypt.php
@@ -0,0 +1,19 @@
+shouldReceive(...func_get_args());
+ }
+
+ /**
+ * Create a fresh mock instance for the given class.
+ *
+ * @return \Mockery\Expectation
+ */
+ protected static function createFreshMockInstance()
+ {
+ return tap(static::createMock(), function ($mock) {
+ static::swap($mock);
+
+ $mock->shouldAllowMockingProtectedMethods();
+ });
+ }
+
+ /**
+ * Create a fresh mock instance for the given class.
+ *
+ * @return \Mockery\MockInterface
+ */
+ protected static function createMock()
+ {
+ $class = static::getMockableClass();
+
+ return $class ? Mockery::mock($class) : Mockery::mock();
+ }
+
+ /**
+ * Determines whether a mock is set as the instance of the facade.
+ *
+ * @return bool
+ */
+ protected static function isMock()
+ {
+ $name = static::getFacadeAccessor();
+
+ return isset(static::$resolvedInstance[$name]) &&
+ static::$resolvedInstance[$name] instanceof MockInterface;
+ }
+
+ /**
+ * Get the mockable class for the bound instance.
+ *
+ * @return string|null
+ */
+ protected static function getMockableClass()
+ {
+ if ($root = static::getFacadeRoot()) {
+ return get_class($root);
+ }
+ }
+
+ /**
+ * Hotswap the underlying instance behind the facade.
+ *
+ * @param mixed $instance
+ * @return void
+ */
+ public static function swap($instance)
+ {
+ static::$resolvedInstance[static::getFacadeAccessor()] = $instance;
+
+ if (isset(static::$app)) {
+ static::$app->instance(static::getFacadeAccessor(), $instance);
+ }
+ }
+
+ /**
+ * Get the root object behind the facade.
+ *
+ * @return mixed
+ */
+ public static function getFacadeRoot()
+ {
+ return static::resolveFacadeInstance(static::getFacadeAccessor());
+ }
+
+ /**
+ * Get the registered name of the component.
+ *
+ * @return string
+ *
+ * @throws \RuntimeException
+ */
+ protected static function getFacadeAccessor()
+ {
+ throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
+ }
+
+ /**
+ * Resolve the facade root instance from the container.
+ *
+ * @param string|object $name
+ * @return mixed
+ */
+ protected static function resolveFacadeInstance($name)
+ {
+ if (is_object($name)) {
+ return $name;
+ }
+
+ if (isset(static::$resolvedInstance[$name])) {
+ return static::$resolvedInstance[$name];
+ }
+
+ return static::$resolvedInstance[$name] = static::$app[$name];
+ }
+
+ /**
+ * Clear a resolved facade instance.
+ *
+ * @param string $name
+ * @return void
+ */
+ public static function clearResolvedInstance($name)
+ {
+ unset(static::$resolvedInstance[$name]);
+ }
+
+ /**
+ * Clear all of the resolved instances.
+ *
+ * @return void
+ */
+ public static function clearResolvedInstances()
+ {
+ static::$resolvedInstance = [];
+ }
+
+ /**
+ * Get the application instance behind the facade.
+ *
+ * @return \Illuminate\Contracts\Foundation\Application
+ */
+ public static function getFacadeApplication()
+ {
+ return static::$app;
+ }
+
+ /**
+ * Set the application instance.
+ *
+ * @param \Illuminate\Contracts\Foundation\Application $app
+ * @return void
+ */
+ public static function setFacadeApplication($app)
+ {
+ static::$app = $app;
+ }
+
+ /**
+ * Handle dynamic, static calls to the object.
+ *
+ * @param string $method
+ * @param array $args
+ * @return mixed
+ *
+ * @throws \RuntimeException
+ */
+ public static function __callStatic($method, $args)
+ {
+ $instance = static::getFacadeRoot();
+
+ if (! $instance) {
+ throw new RuntimeException('A facade root has not been set.');
+ }
+
+ return $instance->$method(...$args);
+ }
+}
diff --git a/vendor/illuminate/support/Facades/File.php b/vendor/illuminate/support/Facades/File.php
new file mode 100644
index 0000000..0f81bf6
--- /dev/null
+++ b/vendor/illuminate/support/Facades/File.php
@@ -0,0 +1,19 @@
+input($key, $default);
+ }
+
+ /**
+ * Get the registered name of the component.
+ *
+ * @return string
+ */
+ protected static function getFacadeAccessor()
+ {
+ return 'request';
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Lang.php b/vendor/illuminate/support/Facades/Lang.php
new file mode 100644
index 0000000..e5862b9
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Lang.php
@@ -0,0 +1,19 @@
+route($channel, $route);
+ }
+
+ /**
+ * Get the registered name of the component.
+ *
+ * @return string
+ */
+ protected static function getFacadeAccessor()
+ {
+ return ChannelManager::class;
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Password.php b/vendor/illuminate/support/Facades/Password.php
new file mode 100644
index 0000000..6ebea84
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Password.php
@@ -0,0 +1,54 @@
+connection($name)->getSchemaBuilder();
+ }
+
+ /**
+ * Get a schema builder instance for the default connection.
+ *
+ * @return \Illuminate\Database\Schema\Builder
+ */
+ protected static function getFacadeAccessor()
+ {
+ return static::$app['db']->connection()->getSchemaBuilder();
+ }
+}
diff --git a/vendor/illuminate/support/Facades/Session.php b/vendor/illuminate/support/Facades/Session.php
new file mode 100644
index 0000000..bc9b5fd
--- /dev/null
+++ b/vendor/illuminate/support/Facades/Session.php
@@ -0,0 +1,20 @@
+get('filesystems.default');
+
+ (new Filesystem)->cleanDirectory(
+ $root = storage_path('framework/testing/disks/'.$disk)
+ );
+
+ static::set($disk, self::createLocalDriver(['root' => $root]));
+ }
+
+ /**
+ * Replace the given disk with a persistent local testing disk.
+ *
+ * @param string|null $disk
+ * @return void
+ */
+ public static function persistentFake($disk = null)
+ {
+ $disk = $disk ?: self::$app['config']->get('filesystems.default');
+
+ static::set($disk, self::createLocalDriver([
+ 'root' => storage_path('framework/testing/disks/'.$disk),
+ ]));
+ }
+
+ /**
+ * Get the registered name of the component.
+ *
+ * @return string
+ */
+ protected static function getFacadeAccessor()
+ {
+ return 'filesystem';
+ }
+}
diff --git a/vendor/illuminate/support/Facades/URL.php b/vendor/illuminate/support/Facades/URL.php
new file mode 100644
index 0000000..e17414b
--- /dev/null
+++ b/vendor/illuminate/support/Facades/URL.php
@@ -0,0 +1,19 @@
+ $value) {
+ $this->attributes[$key] = $value;
+ }
+ }
+
+ /**
+ * Get an attribute from the container.
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ if (array_key_exists($key, $this->attributes)) {
+ return $this->attributes[$key];
+ }
+
+ return value($default);
+ }
+
+ /**
+ * Get the attributes from the container.
+ *
+ * @return array
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Convert the Fluent instance to an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize()
+ {
+ return $this->toArray();
+ }
+
+ /**
+ * Convert the Fluent instance to JSON.
+ *
+ * @param int $options
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Determine if the given offset exists.
+ *
+ * @param string $offset
+ * @return bool
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->attributes[$offset]);
+ }
+
+ /**
+ * Get the value for a given offset.
+ *
+ * @param string $offset
+ * @return mixed
+ */
+ public function offsetGet($offset)
+ {
+ return $this->get($offset);
+ }
+
+ /**
+ * Set the value at the given offset.
+ *
+ * @param string $offset
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($offset, $value)
+ {
+ $this->attributes[$offset] = $value;
+ }
+
+ /**
+ * Unset the value at the given offset.
+ *
+ * @param string $offset
+ * @return void
+ */
+ public function offsetUnset($offset)
+ {
+ unset($this->attributes[$offset]);
+ }
+
+ /**
+ * Handle dynamic calls to the container to set attributes.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return $this
+ */
+ public function __call($method, $parameters)
+ {
+ $this->attributes[$method] = count($parameters) > 0 ? $parameters[0] : true;
+
+ return $this;
+ }
+
+ /**
+ * Dynamically retrieve the value of an attribute.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ return $this->get($key);
+ }
+
+ /**
+ * Dynamically set the value of an attribute.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->offsetSet($key, $value);
+ }
+
+ /**
+ * Dynamically check if an attribute is set.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function __isset($key)
+ {
+ return $this->offsetExists($key);
+ }
+
+ /**
+ * Dynamically unset an attribute.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function __unset($key)
+ {
+ $this->offsetUnset($key);
+ }
+}
diff --git a/vendor/illuminate/support/HigherOrderCollectionProxy.php b/vendor/illuminate/support/HigherOrderCollectionProxy.php
new file mode 100644
index 0000000..7a781a0
--- /dev/null
+++ b/vendor/illuminate/support/HigherOrderCollectionProxy.php
@@ -0,0 +1,63 @@
+method = $method;
+ $this->collection = $collection;
+ }
+
+ /**
+ * Proxy accessing an attribute onto the collection items.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ return $this->collection->{$this->method}(function ($value) use ($key) {
+ return is_array($value) ? $value[$key] : $value->{$key};
+ });
+ }
+
+ /**
+ * Proxy a method call onto the collection items.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ return $this->collection->{$this->method}(function ($value) use ($method, $parameters) {
+ return $value->{$method}(...$parameters);
+ });
+ }
+}
diff --git a/vendor/illuminate/support/HigherOrderTapProxy.php b/vendor/illuminate/support/HigherOrderTapProxy.php
new file mode 100644
index 0000000..bbf9b2e
--- /dev/null
+++ b/vendor/illuminate/support/HigherOrderTapProxy.php
@@ -0,0 +1,38 @@
+target = $target;
+ }
+
+ /**
+ * Dynamically pass method calls to the target.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ $this->target->{$method}(...$parameters);
+
+ return $this->target;
+ }
+}
diff --git a/vendor/illuminate/support/HtmlString.php b/vendor/illuminate/support/HtmlString.php
new file mode 100644
index 0000000..c13adfd
--- /dev/null
+++ b/vendor/illuminate/support/HtmlString.php
@@ -0,0 +1,46 @@
+html = $html;
+ }
+
+ /**
+ * Get the HTML string.
+ *
+ * @return string
+ */
+ public function toHtml()
+ {
+ return $this->html;
+ }
+
+ /**
+ * Get the HTML string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->toHtml();
+ }
+}
diff --git a/vendor/illuminate/support/InteractsWithTime.php b/vendor/illuminate/support/InteractsWithTime.php
new file mode 100644
index 0000000..19ed3f2
--- /dev/null
+++ b/vendor/illuminate/support/InteractsWithTime.php
@@ -0,0 +1,64 @@
+parseDateInterval($delay);
+
+ return $delay instanceof DateTimeInterface
+ ? max(0, $delay->getTimestamp() - $this->currentTime())
+ : (int) $delay;
+ }
+
+ /**
+ * Get the "available at" UNIX timestamp.
+ *
+ * @param \DateTimeInterface|\DateInterval|int $delay
+ * @return int
+ */
+ protected function availableAt($delay = 0)
+ {
+ $delay = $this->parseDateInterval($delay);
+
+ return $delay instanceof DateTimeInterface
+ ? $delay->getTimestamp()
+ : Carbon::now()->addSeconds($delay)->getTimestamp();
+ }
+
+ /**
+ * If the given value is an interval, convert it to a DateTime instance.
+ *
+ * @param \DateTimeInterface|\DateInterval|int $delay
+ * @return \DateTimeInterface|int
+ */
+ protected function parseDateInterval($delay)
+ {
+ if ($delay instanceof DateInterval) {
+ $delay = Carbon::now()->add($delay);
+ }
+
+ return $delay;
+ }
+
+ /**
+ * Get the current system time as a UNIX timestamp.
+ *
+ * @return int
+ */
+ protected function currentTime()
+ {
+ return Carbon::now()->getTimestamp();
+ }
+}
diff --git a/vendor/illuminate/support/Manager.php b/vendor/illuminate/support/Manager.php
new file mode 100644
index 0000000..592776c
--- /dev/null
+++ b/vendor/illuminate/support/Manager.php
@@ -0,0 +1,140 @@
+app = $app;
+ }
+
+ /**
+ * Get the default driver name.
+ *
+ * @return string
+ */
+ abstract public function getDefaultDriver();
+
+ /**
+ * Get a driver instance.
+ *
+ * @param string $driver
+ * @return mixed
+ */
+ public function driver($driver = null)
+ {
+ $driver = $driver ?: $this->getDefaultDriver();
+
+ // If the given driver has not been created before, we will create the instances
+ // here and cache it so we can return it next time very quickly. If there is
+ // already a driver created by this name, we'll just return that instance.
+ if (! isset($this->drivers[$driver])) {
+ $this->drivers[$driver] = $this->createDriver($driver);
+ }
+
+ return $this->drivers[$driver];
+ }
+
+ /**
+ * Create a new driver instance.
+ *
+ * @param string $driver
+ * @return mixed
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function createDriver($driver)
+ {
+ // We'll check to see if a creator method exists for the given driver. If not we
+ // will check for a custom driver creator, which allows developers to create
+ // drivers using their own customized driver creator Closure to create it.
+ if (isset($this->customCreators[$driver])) {
+ return $this->callCustomCreator($driver);
+ } else {
+ $method = 'create'.Str::studly($driver).'Driver';
+
+ if (method_exists($this, $method)) {
+ return $this->$method();
+ }
+ }
+ throw new InvalidArgumentException("Driver [$driver] not supported.");
+ }
+
+ /**
+ * Call a custom driver creator.
+ *
+ * @param string $driver
+ * @return mixed
+ */
+ protected function callCustomCreator($driver)
+ {
+ return $this->customCreators[$driver]($this->app);
+ }
+
+ /**
+ * Register a custom driver creator Closure.
+ *
+ * @param string $driver
+ * @param \Closure $callback
+ * @return $this
+ */
+ public function extend($driver, Closure $callback)
+ {
+ $this->customCreators[$driver] = $callback;
+
+ return $this;
+ }
+
+ /**
+ * Get all of the created "drivers".
+ *
+ * @return array
+ */
+ public function getDrivers()
+ {
+ return $this->drivers;
+ }
+
+ /**
+ * Dynamically call the default driver instance.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ return $this->driver()->$method(...$parameters);
+ }
+}
diff --git a/vendor/illuminate/support/MessageBag.php b/vendor/illuminate/support/MessageBag.php
new file mode 100644
index 0000000..da2c31e
--- /dev/null
+++ b/vendor/illuminate/support/MessageBag.php
@@ -0,0 +1,395 @@
+ $value) {
+ $this->messages[$key] = $value instanceof Arrayable
+ ? $value->toArray() : (array) $value;
+ }
+ }
+
+ /**
+ * Get the keys present in the message bag.
+ *
+ * @return array
+ */
+ public function keys()
+ {
+ return array_keys($this->messages);
+ }
+
+ /**
+ * Add a message to the bag.
+ *
+ * @param string $key
+ * @param string $message
+ * @return $this
+ */
+ public function add($key, $message)
+ {
+ if ($this->isUnique($key, $message)) {
+ $this->messages[$key][] = $message;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Determine if a key and message combination already exists.
+ *
+ * @param string $key
+ * @param string $message
+ * @return bool
+ */
+ protected function isUnique($key, $message)
+ {
+ $messages = (array) $this->messages;
+
+ return ! isset($messages[$key]) || ! in_array($message, $messages[$key]);
+ }
+
+ /**
+ * Merge a new array of messages into the bag.
+ *
+ * @param \Illuminate\Contracts\Support\MessageProvider|array $messages
+ * @return $this
+ */
+ public function merge($messages)
+ {
+ if ($messages instanceof MessageProvider) {
+ $messages = $messages->getMessageBag()->getMessages();
+ }
+
+ $this->messages = array_merge_recursive($this->messages, $messages);
+
+ return $this;
+ }
+
+ /**
+ * Determine if messages exist for all of the given keys.
+ *
+ * @param array|string $key
+ * @return bool
+ */
+ public function has($key)
+ {
+ if (is_null($key)) {
+ return $this->any();
+ }
+
+ $keys = is_array($key) ? $key : func_get_args();
+
+ foreach ($keys as $key) {
+ if ($this->first($key) === '') {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Determine if messages exist for any of the given keys.
+ *
+ * @param array|string $keys
+ * @return bool
+ */
+ public function hasAny($keys = [])
+ {
+ $keys = is_array($keys) ? $keys : func_get_args();
+
+ foreach ($keys as $key) {
+ if ($this->has($key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the first message from the bag for a given key.
+ *
+ * @param string $key
+ * @param string $format
+ * @return string
+ */
+ public function first($key = null, $format = null)
+ {
+ $messages = is_null($key) ? $this->all($format) : $this->get($key, $format);
+
+ $firstMessage = Arr::first($messages, null, '');
+
+ return is_array($firstMessage) ? Arr::first($firstMessage) : $firstMessage;
+ }
+
+ /**
+ * Get all of the messages from the bag for a given key.
+ *
+ * @param string $key
+ * @param string $format
+ * @return array
+ */
+ public function get($key, $format = null)
+ {
+ // If the message exists in the container, we will transform it and return
+ // the message. Otherwise, we'll check if the key is implicit & collect
+ // all the messages that match a given key and output it as an array.
+ if (array_key_exists($key, $this->messages)) {
+ return $this->transform(
+ $this->messages[$key], $this->checkFormat($format), $key
+ );
+ }
+
+ if (Str::contains($key, '*')) {
+ return $this->getMessagesForWildcardKey($key, $format);
+ }
+
+ return [];
+ }
+
+ /**
+ * Get the messages for a wildcard key.
+ *
+ * @param string $key
+ * @param string|null $format
+ * @return array
+ */
+ protected function getMessagesForWildcardKey($key, $format)
+ {
+ return collect($this->messages)
+ ->filter(function ($messages, $messageKey) use ($key) {
+ return Str::is($key, $messageKey);
+ })
+ ->map(function ($messages, $messageKey) use ($format) {
+ return $this->transform(
+ $messages, $this->checkFormat($format), $messageKey
+ );
+ })->all();
+ }
+
+ /**
+ * Get all of the messages for every key in the bag.
+ *
+ * @param string $format
+ * @return array
+ */
+ public function all($format = null)
+ {
+ $format = $this->checkFormat($format);
+
+ $all = [];
+
+ foreach ($this->messages as $key => $messages) {
+ $all = array_merge($all, $this->transform($messages, $format, $key));
+ }
+
+ return $all;
+ }
+
+ /**
+ * Get all of the unique messages for every key in the bag.
+ *
+ * @param string $format
+ * @return array
+ */
+ public function unique($format = null)
+ {
+ return array_unique($this->all($format));
+ }
+
+ /**
+ * Format an array of messages.
+ *
+ * @param array $messages
+ * @param string $format
+ * @param string $messageKey
+ * @return array
+ */
+ protected function transform($messages, $format, $messageKey)
+ {
+ return collect((array) $messages)
+ ->map(function ($message) use ($format, $messageKey) {
+ // We will simply spin through the given messages and transform each one
+ // replacing the :message place holder with the real message allowing
+ // the messages to be easily formatted to each developer's desires.
+ return str_replace([':message', ':key'], [$message, $messageKey], $format);
+ })->all();
+ }
+
+ /**
+ * Get the appropriate format based on the given format.
+ *
+ * @param string $format
+ * @return string
+ */
+ protected function checkFormat($format)
+ {
+ return $format ?: $this->format;
+ }
+
+ /**
+ * Get the raw messages in the container.
+ *
+ * @return array
+ */
+ public function messages()
+ {
+ return $this->messages;
+ }
+
+ /**
+ * Get the raw messages in the container.
+ *
+ * @return array
+ */
+ public function getMessages()
+ {
+ return $this->messages();
+ }
+
+ /**
+ * Get the messages for the instance.
+ *
+ * @return \Illuminate\Support\MessageBag
+ */
+ public function getMessageBag()
+ {
+ return $this;
+ }
+
+ /**
+ * Get the default message format.
+ *
+ * @return string
+ */
+ public function getFormat()
+ {
+ return $this->format;
+ }
+
+ /**
+ * Set the default message format.
+ *
+ * @param string $format
+ * @return \Illuminate\Support\MessageBag
+ */
+ public function setFormat($format = ':message')
+ {
+ $this->format = $format;
+
+ return $this;
+ }
+
+ /**
+ * Determine if the message bag has any messages.
+ *
+ * @return bool
+ */
+ public function isEmpty()
+ {
+ return ! $this->any();
+ }
+
+ /**
+ * Determine if the message bag has any messages.
+ *
+ * @return bool
+ */
+ public function isNotEmpty()
+ {
+ return $this->any();
+ }
+
+ /**
+ * Determine if the message bag has any messages.
+ *
+ * @return bool
+ */
+ public function any()
+ {
+ return $this->count() > 0;
+ }
+
+ /**
+ * Get the number of messages in the container.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->messages, COUNT_RECURSIVE) - count($this->messages);
+ }
+
+ /**
+ * Get the instance as an array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->getMessages();
+ }
+
+ /**
+ * Convert the object into something JSON serializable.
+ *
+ * @return array
+ */
+ public function jsonSerialize()
+ {
+ return $this->toArray();
+ }
+
+ /**
+ * Convert the object to its JSON representation.
+ *
+ * @param int $options
+ * @return string
+ */
+ public function toJson($options = 0)
+ {
+ return json_encode($this->jsonSerialize(), $options);
+ }
+
+ /**
+ * Convert the message bag to its string representation.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->toJson();
+ }
+}
diff --git a/vendor/illuminate/support/NamespacedItemResolver.php b/vendor/illuminate/support/NamespacedItemResolver.php
new file mode 100644
index 0000000..fea3275
--- /dev/null
+++ b/vendor/illuminate/support/NamespacedItemResolver.php
@@ -0,0 +1,102 @@
+parsed[$key])) {
+ return $this->parsed[$key];
+ }
+
+ // If the key does not contain a double colon, it means the key is not in a
+ // namespace, and is just a regular configuration item. Namespaces are a
+ // tool for organizing configuration items for things such as modules.
+ if (strpos($key, '::') === false) {
+ $segments = explode('.', $key);
+
+ $parsed = $this->parseBasicSegments($segments);
+ } else {
+ $parsed = $this->parseNamespacedSegments($key);
+ }
+
+ // Once we have the parsed array of this key's elements, such as its groups
+ // and namespace, we will cache each array inside a simple list that has
+ // the key and the parsed array for quick look-ups for later requests.
+ return $this->parsed[$key] = $parsed;
+ }
+
+ /**
+ * Parse an array of basic segments.
+ *
+ * @param array $segments
+ * @return array
+ */
+ protected function parseBasicSegments(array $segments)
+ {
+ // The first segment in a basic array will always be the group, so we can go
+ // ahead and grab that segment. If there is only one total segment we are
+ // just pulling an entire group out of the array and not a single item.
+ $group = $segments[0];
+
+ // If there is more than one segment in this group, it means we are pulling
+ // a specific item out of a group and will need to return this item name
+ // as well as the group so we know which item to pull from the arrays.
+ $item = count($segments) === 1
+ ? null
+ : implode('.', array_slice($segments, 1));
+
+ return [null, $group, $item];
+ }
+
+ /**
+ * Parse an array of namespaced segments.
+ *
+ * @param string $key
+ * @return array
+ */
+ protected function parseNamespacedSegments($key)
+ {
+ list($namespace, $item) = explode('::', $key);
+
+ // First we'll just explode the first segment to get the namespace and group
+ // since the item should be in the remaining segments. Once we have these
+ // two pieces of data we can proceed with parsing out the item's value.
+ $itemSegments = explode('.', $item);
+
+ $groupAndItem = array_slice(
+ $this->parseBasicSegments($itemSegments), 1
+ );
+
+ return array_merge([$namespace], $groupAndItem);
+ }
+
+ /**
+ * Set the parsed value of a key.
+ *
+ * @param string $key
+ * @param array $parsed
+ * @return void
+ */
+ public function setParsedKey($key, $parsed)
+ {
+ $this->parsed[$key] = $parsed;
+ }
+}
diff --git a/vendor/illuminate/support/Optional.php b/vendor/illuminate/support/Optional.php
new file mode 100644
index 0000000..8f35221
--- /dev/null
+++ b/vendor/illuminate/support/Optional.php
@@ -0,0 +1,110 @@
+value = $value;
+ }
+
+ /**
+ * Dynamically access a property on the underlying object.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ if (is_object($this->value)) {
+ return $this->value->{$key};
+ }
+ }
+
+ /**
+ * Dynamically pass a method to the underlying object.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ if (static::hasMacro($method)) {
+ return $this->macroCall($method, $parameters);
+ }
+
+ if (is_object($this->value)) {
+ return $this->value->{$method}(...$parameters);
+ }
+ }
+
+ /**
+ * Determine if an item exists at an offset.
+ *
+ * @param mixed $key
+ * @return bool
+ */
+ public function offsetExists($key)
+ {
+ return Arr::accessible($this->value) && Arr::exists($this->value, $key);
+ }
+
+ /**
+ * Get an item at a given offset.
+ *
+ * @param mixed $key
+ * @return mixed
+ */
+ public function offsetGet($key)
+ {
+ return Arr::get($this->value, $key);
+ }
+
+ /**
+ * Set the item at a given offset.
+ *
+ * @param mixed $key
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($key, $value)
+ {
+ if (Arr::accessible($this->value)) {
+ $this->value[$key] = $value;
+ }
+ }
+
+ /**
+ * Unset the item at a given offset.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function offsetUnset($key)
+ {
+ if (Arr::accessible($this->value)) {
+ unset($this->value[$key]);
+ }
+ }
+}
diff --git a/vendor/illuminate/support/Pluralizer.php b/vendor/illuminate/support/Pluralizer.php
new file mode 100644
index 0000000..6cc55ad
--- /dev/null
+++ b/vendor/illuminate/support/Pluralizer.php
@@ -0,0 +1,119 @@
+app = $app;
+ }
+
+ /**
+ * Merge the given configuration with the existing configuration.
+ *
+ * @param string $path
+ * @param string $key
+ * @return void
+ */
+ protected function mergeConfigFrom($path, $key)
+ {
+ $config = $this->app['config']->get($key, []);
+
+ $this->app['config']->set($key, array_merge(require $path, $config));
+ }
+
+ /**
+ * Load the given routes file if routes are not already cached.
+ *
+ * @param string $path
+ * @return void
+ */
+ protected function loadRoutesFrom($path)
+ {
+ if (! $this->app->routesAreCached()) {
+ require $path;
+ }
+ }
+
+ /**
+ * Register a view file namespace.
+ *
+ * @param string|array $path
+ * @param string $namespace
+ * @return void
+ */
+ protected function loadViewsFrom($path, $namespace)
+ {
+ if (is_array($this->app->config['view']['paths'])) {
+ foreach ($this->app->config['view']['paths'] as $viewPath) {
+ if (is_dir($appPath = $viewPath.'/vendor/'.$namespace)) {
+ $this->app['view']->addNamespace($namespace, $appPath);
+ }
+ }
+ }
+
+ $this->app['view']->addNamespace($namespace, $path);
+ }
+
+ /**
+ * Register a translation file namespace.
+ *
+ * @param string $path
+ * @param string $namespace
+ * @return void
+ */
+ protected function loadTranslationsFrom($path, $namespace)
+ {
+ $this->app['translator']->addNamespace($namespace, $path);
+ }
+
+ /**
+ * Register a JSON translation file path.
+ *
+ * @param string $path
+ * @return void
+ */
+ protected function loadJsonTranslationsFrom($path)
+ {
+ $this->app['translator']->addJsonPath($path);
+ }
+
+ /**
+ * Register a database migration path.
+ *
+ * @param array|string $paths
+ * @return void
+ */
+ protected function loadMigrationsFrom($paths)
+ {
+ $this->app->afterResolving('migrator', function ($migrator) use ($paths) {
+ foreach ((array) $paths as $path) {
+ $migrator->path($path);
+ }
+ });
+ }
+
+ /**
+ * Register paths to be published by the publish command.
+ *
+ * @param array $paths
+ * @param string $group
+ * @return void
+ */
+ protected function publishes(array $paths, $group = null)
+ {
+ $this->ensurePublishArrayInitialized($class = static::class);
+
+ static::$publishes[$class] = array_merge(static::$publishes[$class], $paths);
+
+ if ($group) {
+ $this->addPublishGroup($group, $paths);
+ }
+ }
+
+ /**
+ * Ensure the publish array for the service provider is initialized.
+ *
+ * @param string $class
+ * @return void
+ */
+ protected function ensurePublishArrayInitialized($class)
+ {
+ if (! array_key_exists($class, static::$publishes)) {
+ static::$publishes[$class] = [];
+ }
+ }
+
+ /**
+ * Add a publish group / tag to the service provider.
+ *
+ * @param string $group
+ * @param array $paths
+ * @return void
+ */
+ protected function addPublishGroup($group, $paths)
+ {
+ if (! array_key_exists($group, static::$publishGroups)) {
+ static::$publishGroups[$group] = [];
+ }
+
+ static::$publishGroups[$group] = array_merge(
+ static::$publishGroups[$group], $paths
+ );
+ }
+
+ /**
+ * Get the paths to publish.
+ *
+ * @param string $provider
+ * @param string $group
+ * @return array
+ */
+ public static function pathsToPublish($provider = null, $group = null)
+ {
+ if (! is_null($paths = static::pathsForProviderOrGroup($provider, $group))) {
+ return $paths;
+ }
+
+ return collect(static::$publishes)->reduce(function ($paths, $p) {
+ return array_merge($paths, $p);
+ }, []);
+ }
+
+ /**
+ * Get the paths for the provider or group (or both).
+ *
+ * @param string|null $provider
+ * @param string|null $group
+ * @return array
+ */
+ protected static function pathsForProviderOrGroup($provider, $group)
+ {
+ if ($provider && $group) {
+ return static::pathsForProviderAndGroup($provider, $group);
+ } elseif ($group && array_key_exists($group, static::$publishGroups)) {
+ return static::$publishGroups[$group];
+ } elseif ($provider && array_key_exists($provider, static::$publishes)) {
+ return static::$publishes[$provider];
+ } elseif ($group || $provider) {
+ return [];
+ }
+ }
+
+ /**
+ * Get the paths for the provider and group.
+ *
+ * @param string $provider
+ * @param string $group
+ * @return array
+ */
+ protected static function pathsForProviderAndGroup($provider, $group)
+ {
+ if (! empty(static::$publishes[$provider]) && ! empty(static::$publishGroups[$group])) {
+ return array_intersect_key(static::$publishes[$provider], static::$publishGroups[$group]);
+ }
+
+ return [];
+ }
+
+ /**
+ * Get the service providers available for publishing.
+ *
+ * @return array
+ */
+ public static function publishableProviders()
+ {
+ return array_keys(static::$publishes);
+ }
+
+ /**
+ * Get the groups available for publishing.
+ *
+ * @return array
+ */
+ public static function publishableGroups()
+ {
+ return array_keys(static::$publishGroups);
+ }
+
+ /**
+ * Register the package's custom Artisan commands.
+ *
+ * @param array|mixed $commands
+ * @return void
+ */
+ public function commands($commands)
+ {
+ $commands = is_array($commands) ? $commands : func_get_args();
+
+ Artisan::starting(function ($artisan) use ($commands) {
+ $artisan->resolveCommands($commands);
+ });
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array
+ */
+ public function provides()
+ {
+ return [];
+ }
+
+ /**
+ * Get the events that trigger this service provider to register.
+ *
+ * @return array
+ */
+ public function when()
+ {
+ return [];
+ }
+
+ /**
+ * Determine if the provider is deferred.
+ *
+ * @return bool
+ */
+ public function isDeferred()
+ {
+ return $this->defer;
+ }
+}
diff --git a/vendor/illuminate/support/Str.php b/vendor/illuminate/support/Str.php
new file mode 100644
index 0000000..6775f92
--- /dev/null
+++ b/vendor/illuminate/support/Str.php
@@ -0,0 +1,683 @@
+ $val) {
+ $value = str_replace($val, $key, $value);
+ }
+
+ return preg_replace('/[^\x20-\x7E]/u', '', $value);
+ }
+
+ /**
+ * Get the portion of a string before a given value.
+ *
+ * @param string $subject
+ * @param string $search
+ * @return string
+ */
+ public static function before($subject, $search)
+ {
+ return $search === '' ? $subject : explode($search, $subject)[0];
+ }
+
+ /**
+ * Convert a value to camel case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function camel($value)
+ {
+ if (isset(static::$camelCache[$value])) {
+ return static::$camelCache[$value];
+ }
+
+ return static::$camelCache[$value] = lcfirst(static::studly($value));
+ }
+
+ /**
+ * Determine if a given string contains a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function contains($haystack, $needles)
+ {
+ foreach ((array) $needles as $needle) {
+ if ($needle !== '' && mb_strpos($haystack, $needle) !== false) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Determine if a given string ends with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function endsWith($haystack, $needles)
+ {
+ foreach ((array) $needles as $needle) {
+ if (substr($haystack, -strlen($needle)) === (string) $needle) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Cap a string with a single instance of a given value.
+ *
+ * @param string $value
+ * @param string $cap
+ * @return string
+ */
+ public static function finish($value, $cap)
+ {
+ $quoted = preg_quote($cap, '/');
+
+ return preg_replace('/(?:'.$quoted.')+$/u', '', $value).$cap;
+ }
+
+ /**
+ * Determine if a given string matches a given pattern.
+ *
+ * @param string|array $pattern
+ * @param string $value
+ * @return bool
+ */
+ public static function is($pattern, $value)
+ {
+ $patterns = is_array($pattern) ? $pattern : (array) $pattern;
+
+ if (empty($patterns)) {
+ return false;
+ }
+
+ foreach ($patterns as $pattern) {
+ // If the given value is an exact match we can of course return true right
+ // from the beginning. Otherwise, we will translate asterisks and do an
+ // actual pattern match against the two strings to see if they match.
+ if ($pattern == $value) {
+ return true;
+ }
+
+ $pattern = preg_quote($pattern, '#');
+
+ // Asterisks are translated into zero-or-more regular expression wildcards
+ // to make it convenient to check if the strings starts with the given
+ // pattern such as "library/*", making any string check convenient.
+ $pattern = str_replace('\*', '.*', $pattern);
+
+ if (preg_match('#^'.$pattern.'\z#u', $value) === 1) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert a string to kebab case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function kebab($value)
+ {
+ return static::snake($value, '-');
+ }
+
+ /**
+ * Return the length of the given string.
+ *
+ * @param string $value
+ * @param string $encoding
+ * @return int
+ */
+ public static function length($value, $encoding = null)
+ {
+ if ($encoding) {
+ return mb_strlen($value, $encoding);
+ }
+
+ return mb_strlen($value);
+ }
+
+ /**
+ * Limit the number of characters in a string.
+ *
+ * @param string $value
+ * @param int $limit
+ * @param string $end
+ * @return string
+ */
+ public static function limit($value, $limit = 100, $end = '...')
+ {
+ if (mb_strwidth($value, 'UTF-8') <= $limit) {
+ return $value;
+ }
+
+ return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')).$end;
+ }
+
+ /**
+ * Convert the given string to lower-case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function lower($value)
+ {
+ return mb_strtolower($value, 'UTF-8');
+ }
+
+ /**
+ * Limit the number of words in a string.
+ *
+ * @param string $value
+ * @param int $words
+ * @param string $end
+ * @return string
+ */
+ public static function words($value, $words = 100, $end = '...')
+ {
+ preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/u', $value, $matches);
+
+ if (! isset($matches[0]) || static::length($value) === static::length($matches[0])) {
+ return $value;
+ }
+
+ return rtrim($matches[0]).$end;
+ }
+
+ /**
+ * Parse a Class@method style callback into class and method.
+ *
+ * @param string $callback
+ * @param string|null $default
+ * @return array
+ */
+ public static function parseCallback($callback, $default = null)
+ {
+ return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default];
+ }
+
+ /**
+ * Get the plural form of an English word.
+ *
+ * @param string $value
+ * @param int $count
+ * @return string
+ */
+ public static function plural($value, $count = 2)
+ {
+ return Pluralizer::plural($value, $count);
+ }
+
+ /**
+ * Generate a more truly "random" alpha-numeric string.
+ *
+ * @param int $length
+ * @return string
+ */
+ public static function random($length = 16)
+ {
+ $string = '';
+
+ while (($len = strlen($string)) < $length) {
+ $size = $length - $len;
+
+ $bytes = random_bytes($size);
+
+ $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
+ }
+
+ return $string;
+ }
+
+ /**
+ * Replace a given value in the string sequentially with an array.
+ *
+ * @param string $search
+ * @param array $replace
+ * @param string $subject
+ * @return string
+ */
+ public static function replaceArray($search, array $replace, $subject)
+ {
+ foreach ($replace as $value) {
+ $subject = static::replaceFirst($search, $value, $subject);
+ }
+
+ return $subject;
+ }
+
+ /**
+ * Replace the first occurrence of a given value in the string.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @return string
+ */
+ public static function replaceFirst($search, $replace, $subject)
+ {
+ if ($search == '') {
+ return $subject;
+ }
+
+ $position = strpos($subject, $search);
+
+ if ($position !== false) {
+ return substr_replace($subject, $replace, $position, strlen($search));
+ }
+
+ return $subject;
+ }
+
+ /**
+ * Replace the last occurrence of a given value in the string.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @return string
+ */
+ public static function replaceLast($search, $replace, $subject)
+ {
+ $position = strrpos($subject, $search);
+
+ if ($position !== false) {
+ return substr_replace($subject, $replace, $position, strlen($search));
+ }
+
+ return $subject;
+ }
+
+ /**
+ * Begin a string with a single instance of a given value.
+ *
+ * @param string $value
+ * @param string $prefix
+ * @return string
+ */
+ public static function start($value, $prefix)
+ {
+ $quoted = preg_quote($prefix, '/');
+
+ return $prefix.preg_replace('/^(?:'.$quoted.')+/u', '', $value);
+ }
+
+ /**
+ * Convert the given string to upper-case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function upper($value)
+ {
+ return mb_strtoupper($value, 'UTF-8');
+ }
+
+ /**
+ * Convert the given string to title case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function title($value)
+ {
+ return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
+ }
+
+ /**
+ * Get the singular form of an English word.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function singular($value)
+ {
+ return Pluralizer::singular($value);
+ }
+
+ /**
+ * Generate a URL friendly "slug" from a given string.
+ *
+ * @param string $title
+ * @param string $separator
+ * @param string $language
+ * @return string
+ */
+ public static function slug($title, $separator = '-', $language = 'en')
+ {
+ $title = static::ascii($title, $language);
+
+ // Convert all dashes/underscores into separator
+ $flip = $separator == '-' ? '_' : '-';
+
+ $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);
+
+ // Replace @ with the word 'at'
+ $title = str_replace('@', $separator.'at'.$separator, $title);
+
+ // Remove all characters that are not the separator, letters, numbers, or whitespace.
+ $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', mb_strtolower($title));
+
+ // Replace all separator characters and whitespace by a single separator
+ $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
+
+ return trim($title, $separator);
+ }
+
+ /**
+ * Convert a string to snake case.
+ *
+ * @param string $value
+ * @param string $delimiter
+ * @return string
+ */
+ public static function snake($value, $delimiter = '_')
+ {
+ $key = $value;
+
+ if (isset(static::$snakeCache[$key][$delimiter])) {
+ return static::$snakeCache[$key][$delimiter];
+ }
+
+ if (! ctype_lower($value)) {
+ $value = preg_replace('/\s+/u', '', ucwords($value));
+
+ $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
+ }
+
+ return static::$snakeCache[$key][$delimiter] = $value;
+ }
+
+ /**
+ * Determine if a given string starts with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ public static function startsWith($haystack, $needles)
+ {
+ foreach ((array) $needles as $needle) {
+ if ($needle !== '' && substr($haystack, 0, strlen($needle)) === (string) $needle) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Convert a value to studly caps case.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function studly($value)
+ {
+ $key = $value;
+
+ if (isset(static::$studlyCache[$key])) {
+ return static::$studlyCache[$key];
+ }
+
+ $value = ucwords(str_replace(['-', '_'], ' ', $value));
+
+ return static::$studlyCache[$key] = str_replace(' ', '', $value);
+ }
+
+ /**
+ * Returns the portion of string specified by the start and length parameters.
+ *
+ * @param string $string
+ * @param int $start
+ * @param int|null $length
+ * @return string
+ */
+ public static function substr($string, $start, $length = null)
+ {
+ return mb_substr($string, $start, $length, 'UTF-8');
+ }
+
+ /**
+ * Make a string's first character uppercase.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function ucfirst($string)
+ {
+ return static::upper(static::substr($string, 0, 1)).static::substr($string, 1);
+ }
+
+ /**
+ * Returns the replacements for the ascii method.
+ *
+ * Note: Adapted from Stringy\Stringy.
+ *
+ * @see https://github.com/danielstjules/Stringy/blob/3.1.0/LICENSE.txt
+ *
+ * @return array
+ */
+ protected static function charsArray()
+ {
+ static $charsArray;
+
+ if (isset($charsArray)) {
+ return $charsArray;
+ }
+
+ return $charsArray = [
+ '0' => ['°', '₀', '۰', '0'],
+ '1' => ['¹', '₁', '۱', '1'],
+ '2' => ['²', '₂', '۲', '2'],
+ '3' => ['³', '₃', '۳', '3'],
+ '4' => ['⁴', '₄', '۴', '٤', '4'],
+ '5' => ['⁵', '₅', '۵', '٥', '5'],
+ '6' => ['⁶', '₆', '۶', '٦', '6'],
+ '7' => ['⁷', '₇', '۷', '7'],
+ '8' => ['⁸', '₈', '۸', '8'],
+ '9' => ['⁹', '₉', '۹', '9'],
+ 'a' => ['à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ', 'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ā', 'ą', 'å', 'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ', 'ἇ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ', 'ά', 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ', 'အ', 'ာ', 'ါ', 'ǻ', 'ǎ', 'ª', 'ა', 'अ', 'ا', 'a', 'ä'],
+ 'b' => ['б', 'β', 'ب', 'ဗ', 'ბ', 'b'],
+ 'c' => ['ç', 'ć', 'č', 'ĉ', 'ċ', 'c'],
+ 'd' => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', 'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ', 'd'],
+ 'e' => ['é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ', 'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ', 'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э', 'є', 'ə', 'ဧ', 'ေ', 'ဲ', 'ე', 'ए', 'إ', 'ئ', 'e'],
+ 'f' => ['ф', 'φ', 'ف', 'ƒ', 'ფ', 'f'],
+ 'g' => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', 'گ', 'g'],
+ 'h' => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ', 'h'],
+ 'i' => ['í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į', 'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ', 'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'і', 'ї', 'и', 'ဣ', 'ိ', 'ီ', 'ည်', 'ǐ', 'ი', 'इ', 'ی', 'i'],
+ 'j' => ['ĵ', 'ј', 'Ј', 'ჯ', 'ج', 'j'],
+ 'k' => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك', 'က', 'კ', 'ქ', 'ک', 'k'],
+ 'l' => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل', 'လ', 'ლ', 'l'],
+ 'm' => ['м', 'μ', 'م', 'မ', 'მ', 'm'],
+ 'n' => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န', 'ნ', 'n'],
+ 'o' => ['ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ', 'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő', 'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό', 'о', 'و', 'θ', 'ို', 'ǒ', 'ǿ', 'º', 'ო', 'ओ', 'o', 'ö'],
+ 'p' => ['п', 'π', 'ပ', 'პ', 'پ', 'p'],
+ 'q' => ['ყ', 'q'],
+ 'r' => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', 'რ', 'r'],
+ 's' => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ', 'ſ', 'ს', 's'],
+ 't' => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ', 'თ', 'ტ', 't'],
+ 'u' => ['ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ', 'ự', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у', 'ဉ', 'ု', 'ူ', 'ǔ', 'ǖ', 'ǘ', 'ǚ', 'ǜ', 'უ', 'उ', 'u', 'ў', 'ü'],
+ 'v' => ['в', 'ვ', 'ϐ', 'v'],
+ 'w' => ['ŵ', 'ω', 'ώ', 'ဝ', 'ွ', 'w'],
+ 'x' => ['χ', 'ξ', 'x'],
+ 'y' => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', 'ϋ', 'ύ', 'ΰ', 'ي', 'ယ', 'y'],
+ 'z' => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ', 'z'],
+ 'aa' => ['ع', 'आ', 'آ'],
+ 'ae' => ['æ', 'ǽ'],
+ 'ai' => ['ऐ'],
+ 'ch' => ['ч', 'ჩ', 'ჭ', 'چ'],
+ 'dj' => ['ђ', 'đ'],
+ 'dz' => ['џ', 'ძ'],
+ 'ei' => ['ऍ'],
+ 'gh' => ['غ', 'ღ'],
+ 'ii' => ['ई'],
+ 'ij' => ['ij'],
+ 'kh' => ['х', 'خ', 'ხ'],
+ 'lj' => ['љ'],
+ 'nj' => ['њ'],
+ 'oe' => ['ö', 'œ', 'ؤ'],
+ 'oi' => ['ऑ'],
+ 'oii' => ['ऒ'],
+ 'ps' => ['ψ'],
+ 'sh' => ['ш', 'შ', 'ش'],
+ 'shch' => ['щ'],
+ 'ss' => ['ß'],
+ 'sx' => ['ŝ'],
+ 'th' => ['þ', 'ϑ', 'ث', 'ذ', 'ظ'],
+ 'ts' => ['ц', 'ც', 'წ'],
+ 'ue' => ['ü'],
+ 'uu' => ['ऊ'],
+ 'ya' => ['я'],
+ 'yu' => ['ю'],
+ 'zh' => ['ж', 'ჟ', 'ژ'],
+ '(c)' => ['©'],
+ 'A' => ['Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ', 'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Å', 'Ā', 'Ą', 'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ', 'Ἇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ', 'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 'А', 'Ǻ', 'Ǎ', 'A', 'Ä'],
+ 'B' => ['Б', 'Β', 'ब', 'B'],
+ 'C' => ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ', 'C'],
+ 'D' => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ', 'D'],
+ 'E' => ['É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ', 'Ệ', 'Ë', 'Ē', 'Ę', 'Ě', 'Ĕ', 'Ė', 'Ε', 'Έ', 'Ἐ', 'Ἑ', 'Ἒ', 'Ἓ', 'Ἔ', 'Ἕ', 'Έ', 'Ὲ', 'Е', 'Ё', 'Э', 'Є', 'Ə', 'E'],
+ 'F' => ['Ф', 'Φ', 'F'],
+ 'G' => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ', 'G'],
+ 'H' => ['Η', 'Ή', 'Ħ', 'H'],
+ 'I' => ['Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į', 'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ', 'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї', 'Ǐ', 'ϒ', 'I'],
+ 'J' => ['J'],
+ 'K' => ['К', 'Κ', 'K'],
+ 'L' => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल', 'L'],
+ 'M' => ['М', 'Μ', 'M'],
+ 'N' => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν', 'N'],
+ 'O' => ['Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ', 'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ø', 'Ō', 'Ő', 'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ', 'Ὸ', 'Ό', 'О', 'Θ', 'Ө', 'Ǒ', 'Ǿ', 'O', 'Ö'],
+ 'P' => ['П', 'Π', 'P'],
+ 'Q' => ['Q'],
+ 'R' => ['Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ', 'R'],
+ 'S' => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ', 'S'],
+ 'T' => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ', 'T'],
+ 'U' => ['Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ', 'Ự', 'Û', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У', 'Ǔ', 'Ǖ', 'Ǘ', 'Ǚ', 'Ǜ', 'U', 'Ў', 'Ü'],
+ 'V' => ['В', 'V'],
+ 'W' => ['Ω', 'Ώ', 'Ŵ', 'W'],
+ 'X' => ['Χ', 'Ξ', 'X'],
+ 'Y' => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', 'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ', 'Y'],
+ 'Z' => ['Ź', 'Ž', 'Ż', 'З', 'Ζ', 'Z'],
+ 'AE' => ['Æ', 'Ǽ'],
+ 'Ch' => ['Ч'],
+ 'Dj' => ['Ђ'],
+ 'Dz' => ['Џ'],
+ 'Gx' => ['Ĝ'],
+ 'Hx' => ['Ĥ'],
+ 'Ij' => ['IJ'],
+ 'Jx' => ['Ĵ'],
+ 'Kh' => ['Х'],
+ 'Lj' => ['Љ'],
+ 'Nj' => ['Њ'],
+ 'Oe' => ['Œ'],
+ 'Ps' => ['Ψ'],
+ 'Sh' => ['Ш'],
+ 'Shch' => ['Щ'],
+ 'Ss' => ['ẞ'],
+ 'Th' => ['Þ'],
+ 'Ts' => ['Ц'],
+ 'Ya' => ['Я'],
+ 'Yu' => ['Ю'],
+ 'Zh' => ['Ж'],
+ ' ' => ["\xC2\xA0", "\xE2\x80\x80", "\xE2\x80\x81", "\xE2\x80\x82", "\xE2\x80\x83", "\xE2\x80\x84", "\xE2\x80\x85", "\xE2\x80\x86", "\xE2\x80\x87", "\xE2\x80\x88", "\xE2\x80\x89", "\xE2\x80\x8A", "\xE2\x80\xAF", "\xE2\x81\x9F", "\xE3\x80\x80", "\xEF\xBE\xA0"],
+ ];
+ }
+
+ /**
+ * Returns the language specific replacements for the ascii method.
+ *
+ * Note: Adapted from Stringy\Stringy.
+ *
+ * @see https://github.com/danielstjules/Stringy/blob/3.1.0/LICENSE.txt
+ *
+ * @param string $language
+ * @return array|null
+ */
+ protected static function languageSpecificCharsArray($language)
+ {
+ static $languageSpecific;
+
+ if (! isset($languageSpecific)) {
+ $languageSpecific = [
+ 'bg' => [
+ ['х', 'Х', 'щ', 'Щ', 'ъ', 'Ъ', 'ь', 'Ь'],
+ ['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y'],
+ ],
+ 'de' => [
+ ['ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü'],
+ ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'],
+ ],
+ ];
+ }
+
+ return $languageSpecific[$language] ?? null;
+ }
+}
diff --git a/vendor/illuminate/support/Testing/Fakes/BusFake.php b/vendor/illuminate/support/Testing/Fakes/BusFake.php
new file mode 100644
index 0000000..ae1209a
--- /dev/null
+++ b/vendor/illuminate/support/Testing/Fakes/BusFake.php
@@ -0,0 +1,132 @@
+assertDispatchedTimes($command, $callback);
+ }
+
+ PHPUnit::assertTrue(
+ $this->dispatched($command, $callback)->count() > 0,
+ "The expected [{$command}] job was not dispatched."
+ );
+ }
+
+ /**
+ * Assert if a job was pushed a number of times.
+ *
+ * @param string $command
+ * @param int $times
+ * @return void
+ */
+ protected function assertDispatchedTimes($command, $times = 1)
+ {
+ PHPUnit::assertTrue(
+ ($count = $this->dispatched($command)->count()) === $times,
+ "The expected [{$command}] job was pushed {$count} times instead of {$times} times."
+ );
+ }
+
+ /**
+ * Determine if a job was dispatched based on a truth-test callback.
+ *
+ * @param string $command
+ * @param callable|null $callback
+ * @return void
+ */
+ public function assertNotDispatched($command, $callback = null)
+ {
+ PHPUnit::assertTrue(
+ $this->dispatched($command, $callback)->count() === 0,
+ "The unexpected [{$command}] job was dispatched."
+ );
+ }
+
+ /**
+ * Get all of the jobs matching a truth-test callback.
+ *
+ * @param string $command
+ * @param callable|null $callback
+ * @return \Illuminate\Support\Collection
+ */
+ public function dispatched($command, $callback = null)
+ {
+ if (! $this->hasDispatched($command)) {
+ return collect();
+ }
+
+ $callback = $callback ?: function () {
+ return true;
+ };
+
+ return collect($this->commands[$command])->filter(function ($command) use ($callback) {
+ return $callback($command);
+ });
+ }
+
+ /**
+ * Determine if there are any stored commands for a given class.
+ *
+ * @param string $command
+ * @return bool
+ */
+ public function hasDispatched($command)
+ {
+ return isset($this->commands[$command]) && ! empty($this->commands[$command]);
+ }
+
+ /**
+ * Dispatch a command to its appropriate handler.
+ *
+ * @param mixed $command
+ * @return mixed
+ */
+ public function dispatch($command)
+ {
+ return $this->dispatchNow($command);
+ }
+
+ /**
+ * Dispatch a command to its appropriate handler in the current process.
+ *
+ * @param mixed $command
+ * @param mixed $handler
+ * @return mixed
+ */
+ public function dispatchNow($command, $handler = null)
+ {
+ $this->commands[get_class($command)][] = $command;
+ }
+
+ /**
+ * Set the pipes commands should be piped through before dispatching.
+ *
+ * @param array $pipes
+ * @return $this
+ */
+ public function pipeThrough(array $pipes)
+ {
+ //
+ }
+}
diff --git a/vendor/illuminate/support/Testing/Fakes/EventFake.php b/vendor/illuminate/support/Testing/Fakes/EventFake.php
new file mode 100644
index 0000000..edbb90e
--- /dev/null
+++ b/vendor/illuminate/support/Testing/Fakes/EventFake.php
@@ -0,0 +1,260 @@
+dispatcher = $dispatcher;
+
+ $this->eventsToFake = Arr::wrap($eventsToFake);
+ }
+
+ /**
+ * Assert if an event was dispatched based on a truth-test callback.
+ *
+ * @param string $event
+ * @param callable|int|null $callback
+ * @return void
+ */
+ public function assertDispatched($event, $callback = null)
+ {
+ if (is_int($callback)) {
+ return $this->assertDispatchedTimes($event, $callback);
+ }
+
+ PHPUnit::assertTrue(
+ $this->dispatched($event, $callback)->count() > 0,
+ "The expected [{$event}] event was not dispatched."
+ );
+ }
+
+ /**
+ * Assert if a event was dispatched a number of times.
+ *
+ * @param string $event
+ * @param int $times
+ * @return void
+ */
+ public function assertDispatchedTimes($event, $times = 1)
+ {
+ PHPUnit::assertTrue(
+ ($count = $this->dispatched($event)->count()) === $times,
+ "The expected [{$event}] event was dispatched {$count} times instead of {$times} times."
+ );
+ }
+
+ /**
+ * Determine if an event was dispatched based on a truth-test callback.
+ *
+ * @param string $event
+ * @param callable|null $callback
+ * @return void
+ */
+ public function assertNotDispatched($event, $callback = null)
+ {
+ PHPUnit::assertTrue(
+ $this->dispatched($event, $callback)->count() === 0,
+ "The unexpected [{$event}] event was dispatched."
+ );
+ }
+
+ /**
+ * Get all of the events matching a truth-test callback.
+ *
+ * @param string $event
+ * @param callable|null $callback
+ * @return \Illuminate\Support\Collection
+ */
+ public function dispatched($event, $callback = null)
+ {
+ if (! $this->hasDispatched($event)) {
+ return collect();
+ }
+
+ $callback = $callback ?: function () {
+ return true;
+ };
+
+ return collect($this->events[$event])->filter(function ($arguments) use ($callback) {
+ return $callback(...$arguments);
+ });
+ }
+
+ /**
+ * Determine if the given event has been dispatched.
+ *
+ * @param string $event
+ * @return bool
+ */
+ public function hasDispatched($event)
+ {
+ return isset($this->events[$event]) && ! empty($this->events[$event]);
+ }
+
+ /**
+ * Register an event listener with the dispatcher.
+ *
+ * @param string|array $events
+ * @param mixed $listener
+ * @return void
+ */
+ public function listen($events, $listener)
+ {
+ //
+ }
+
+ /**
+ * Determine if a given event has listeners.
+ *
+ * @param string $eventName
+ * @return bool
+ */
+ public function hasListeners($eventName)
+ {
+ //
+ }
+
+ /**
+ * Register an event and payload to be dispatched later.
+ *
+ * @param string $event
+ * @param array $payload
+ * @return void
+ */
+ public function push($event, $payload = [])
+ {
+ //
+ }
+
+ /**
+ * Register an event subscriber with the dispatcher.
+ *
+ * @param object|string $subscriber
+ * @return void
+ */
+ public function subscribe($subscriber)
+ {
+ //
+ }
+
+ /**
+ * Flush a set of pushed events.
+ *
+ * @param string $event
+ * @return void
+ */
+ public function flush($event)
+ {
+ //
+ }
+
+ /**
+ * Fire an event and call the listeners.
+ *
+ * @param string|object $event
+ * @param mixed $payload
+ * @param bool $halt
+ * @return array|null
+ */
+ public function fire($event, $payload = [], $halt = false)
+ {
+ return $this->dispatch($event, $payload, $halt);
+ }
+
+ /**
+ * Fire an event and call the listeners.
+ *
+ * @param string|object $event
+ * @param mixed $payload
+ * @param bool $halt
+ * @return array|null
+ */
+ public function dispatch($event, $payload = [], $halt = false)
+ {
+ $name = is_object($event) ? get_class($event) : (string) $event;
+
+ if ($this->shouldFakeEvent($name)) {
+ $this->events[$name][] = func_get_args();
+ } else {
+ $this->dispatcher->dispatch($event, $payload, $halt);
+ }
+ }
+
+ /**
+ * Determine if an event should be faked or actually dispatched.
+ *
+ * @param string $eventName
+ * @return bool
+ */
+ protected function shouldFakeEvent($eventName)
+ {
+ return empty($this->eventsToFake) || in_array($eventName, $this->eventsToFake);
+ }
+
+ /**
+ * Remove a set of listeners from the dispatcher.
+ *
+ * @param string $event
+ * @return void
+ */
+ public function forget($event)
+ {
+ //
+ }
+
+ /**
+ * Forget all of the queued listeners.
+ *
+ * @return void
+ */
+ public function forgetPushed()
+ {
+ //
+ }
+
+ /**
+ * Dispatch an event and call the listeners.
+ *
+ * @param string|object $event
+ * @param mixed $payload
+ * @return void
+ */
+ public function until($event, $payload = [])
+ {
+ return $this->dispatch($event, $payload, true);
+ }
+}
diff --git a/vendor/illuminate/support/Testing/Fakes/MailFake.php b/vendor/illuminate/support/Testing/Fakes/MailFake.php
new file mode 100644
index 0000000..0d11c08
--- /dev/null
+++ b/vendor/illuminate/support/Testing/Fakes/MailFake.php
@@ -0,0 +1,316 @@
+assertSentTimes($mailable, $callback);
+ }
+
+ PHPUnit::assertTrue(
+ $this->sent($mailable, $callback)->count() > 0,
+ "The expected [{$mailable}] mailable was not sent."
+ );
+ }
+
+ /**
+ * Assert if a mailable was sent a number of times.
+ *
+ * @param string $mailable
+ * @param int $times
+ * @return void
+ */
+ protected function assertSentTimes($mailable, $times = 1)
+ {
+ PHPUnit::assertTrue(
+ ($count = $this->sent($mailable)->count()) === $times,
+ "The expected [{$mailable}] mailable was sent {$count} times instead of {$times} times."
+ );
+ }
+
+ /**
+ * Determine if a mailable was not sent based on a truth-test callback.
+ *
+ * @param string $mailable
+ * @param callable|null $callback
+ * @return void
+ */
+ public function assertNotSent($mailable, $callback = null)
+ {
+ PHPUnit::assertTrue(
+ $this->sent($mailable, $callback)->count() === 0,
+ "The unexpected [{$mailable}] mailable was sent."
+ );
+ }
+
+ /**
+ * Assert that no mailables were sent.
+ *
+ * @return void
+ */
+ public function assertNothingSent()
+ {
+ PHPUnit::assertEmpty($this->mailables, 'Mailables were sent unexpectedly.');
+ }
+
+ /**
+ * Assert if a mailable was queued based on a truth-test callback.
+ *
+ * @param string $mailable
+ * @param callable|int|null $callback
+ * @return void
+ */
+ public function assertQueued($mailable, $callback = null)
+ {
+ if (is_numeric($callback)) {
+ return $this->assertQueuedTimes($mailable, $callback);
+ }
+
+ PHPUnit::assertTrue(
+ $this->queued($mailable, $callback)->count() > 0,
+ "The expected [{$mailable}] mailable was not queued."
+ );
+ }
+
+ /**
+ * Assert if a mailable was queued a number of times.
+ *
+ * @param string $mailable
+ * @param int $times
+ * @return void
+ */
+ protected function assertQueuedTimes($mailable, $times = 1)
+ {
+ PHPUnit::assertTrue(
+ ($count = $this->queued($mailable)->count()) === $times,
+ "The expected [{$mailable}] mailable was queued {$count} times instead of {$times} times."
+ );
+ }
+
+ /**
+ * Determine if a mailable was not queued based on a truth-test callback.
+ *
+ * @param string $mailable
+ * @param callable|null $callback
+ * @return void
+ */
+ public function assertNotQueued($mailable, $callback = null)
+ {
+ PHPUnit::assertTrue(
+ $this->queued($mailable, $callback)->count() === 0,
+ "The unexpected [{$mailable}] mailable was queued."
+ );
+ }
+
+ /**
+ * Assert that no mailables were queued.
+ *
+ * @return void
+ */
+ public function assertNothingQueued()
+ {
+ PHPUnit::assertEmpty($this->queuedMailables, 'Mailables were queued unexpectedly.');
+ }
+
+ /**
+ * Get all of the mailables matching a truth-test callback.
+ *
+ * @param string $mailable
+ * @param callable|null $callback
+ * @return \Illuminate\Support\Collection
+ */
+ public function sent($mailable, $callback = null)
+ {
+ if (! $this->hasSent($mailable)) {
+ return collect();
+ }
+
+ $callback = $callback ?: function () {
+ return true;
+ };
+
+ return $this->mailablesOf($mailable)->filter(function ($mailable) use ($callback) {
+ return $callback($mailable);
+ });
+ }
+
+ /**
+ * Determine if the given mailable has been sent.
+ *
+ * @param string $mailable
+ * @return bool
+ */
+ public function hasSent($mailable)
+ {
+ return $this->mailablesOf($mailable)->count() > 0;
+ }
+
+ /**
+ * Get all of the queued mailables matching a truth-test callback.
+ *
+ * @param string $mailable
+ * @param callable|null $callback
+ * @return \Illuminate\Support\Collection
+ */
+ public function queued($mailable, $callback = null)
+ {
+ if (! $this->hasQueued($mailable)) {
+ return collect();
+ }
+
+ $callback = $callback ?: function () {
+ return true;
+ };
+
+ return $this->queuedMailablesOf($mailable)->filter(function ($mailable) use ($callback) {
+ return $callback($mailable);
+ });
+ }
+
+ /**
+ * Determine if the given mailable has been queued.
+ *
+ * @param string $mailable
+ * @return bool
+ */
+ public function hasQueued($mailable)
+ {
+ return $this->queuedMailablesOf($mailable)->count() > 0;
+ }
+
+ /**
+ * Get all of the mailed mailables for a given type.
+ *
+ * @param string $type
+ * @return \Illuminate\Support\Collection
+ */
+ protected function mailablesOf($type)
+ {
+ return collect($this->mailables)->filter(function ($mailable) use ($type) {
+ return $mailable instanceof $type;
+ });
+ }
+
+ /**
+ * Get all of the mailed mailables for a given type.
+ *
+ * @param string $type
+ * @return \Illuminate\Support\Collection
+ */
+ protected function queuedMailablesOf($type)
+ {
+ return collect($this->queuedMailables)->filter(function ($mailable) use ($type) {
+ return $mailable instanceof $type;
+ });
+ }
+
+ /**
+ * Begin the process of mailing a mailable class instance.
+ *
+ * @param mixed $users
+ * @return \Illuminate\Mail\PendingMail
+ */
+ public function to($users)
+ {
+ return (new PendingMailFake($this))->to($users);
+ }
+
+ /**
+ * Begin the process of mailing a mailable class instance.
+ *
+ * @param mixed $users
+ * @return \Illuminate\Mail\PendingMail
+ */
+ public function bcc($users)
+ {
+ return (new PendingMailFake($this))->bcc($users);
+ }
+
+ /**
+ * Send a new message when only a raw text part.
+ *
+ * @param string $text
+ * @param \Closure|string $callback
+ * @return int
+ */
+ public function raw($text, $callback)
+ {
+ //
+ }
+
+ /**
+ * Send a new message using a view.
+ *
+ * @param string|array $view
+ * @param array $data
+ * @param \Closure|string $callback
+ * @return void
+ */
+ public function send($view, array $data = [], $callback = null)
+ {
+ if (! $view instanceof Mailable) {
+ return;
+ }
+
+ if ($view instanceof ShouldQueue) {
+ return $this->queue($view, $data, $callback);
+ }
+
+ $this->mailables[] = $view;
+ }
+
+ /**
+ * Queue a new e-mail message for sending.
+ *
+ * @param string|array $view
+ * @param string|null $queue
+ * @return mixed
+ */
+ public function queue($view, $queue = null)
+ {
+ if (! $view instanceof Mailable) {
+ return;
+ }
+
+ $this->queuedMailables[] = $view;
+ }
+
+ /**
+ * Get the array of failed recipients.
+ *
+ * @return array
+ */
+ public function failures()
+ {
+ //
+ }
+}
diff --git a/vendor/illuminate/support/Testing/Fakes/NotificationFake.php b/vendor/illuminate/support/Testing/Fakes/NotificationFake.php
new file mode 100644
index 0000000..b610932
--- /dev/null
+++ b/vendor/illuminate/support/Testing/Fakes/NotificationFake.php
@@ -0,0 +1,199 @@
+assertSentTo($singleNotifiable, $notification, $callback);
+ }
+
+ return;
+ }
+
+ if (is_numeric($callback)) {
+ return $this->assertSentToTimes($notifiable, $notification, $callback);
+ }
+
+ PHPUnit::assertTrue(
+ $this->sent($notifiable, $notification, $callback)->count() > 0,
+ "The expected [{$notification}] notification was not sent."
+ );
+ }
+
+ /**
+ * Assert if a notification was sent a number of times.
+ *
+ * @param mixed $notifiable
+ * @param string $notification
+ * @param int $times
+ * @return void
+ */
+ public function assertSentToTimes($notifiable, $notification, $times = 1)
+ {
+ PHPUnit::assertTrue(
+ ($count = $this->sent($notifiable, $notification)->count()) === $times,
+ "The expected [{$notification}] notification was sent {$count} times instead of {$times} times."
+ );
+ }
+
+ /**
+ * Determine if a notification was sent based on a truth-test callback.
+ *
+ * @param mixed $notifiable
+ * @param string $notification
+ * @param callable|null $callback
+ * @return void
+ */
+ public function assertNotSentTo($notifiable, $notification, $callback = null)
+ {
+ if (is_array($notifiable) || $notifiable instanceof Collection) {
+ foreach ($notifiable as $singleNotifiable) {
+ $this->assertNotSentTo($singleNotifiable, $notification, $callback);
+ }
+
+ return;
+ }
+
+ PHPUnit::assertTrue(
+ $this->sent($notifiable, $notification, $callback)->count() === 0,
+ "The unexpected [{$notification}] notification was sent."
+ );
+ }
+
+ /**
+ * Assert that no notifications were sent.
+ *
+ * @return void
+ */
+ public function assertNothingSent()
+ {
+ PHPUnit::assertEmpty($this->notifications, 'Notifications were sent unexpectedly.');
+ }
+
+ /**
+ * Get all of the notifications matching a truth-test callback.
+ *
+ * @param mixed $notifiable
+ * @param string $notification
+ * @param callable|null $callback
+ * @return \Illuminate\Support\Collection
+ */
+ public function sent($notifiable, $notification, $callback = null)
+ {
+ if (! $this->hasSent($notifiable, $notification)) {
+ return collect();
+ }
+
+ $callback = $callback ?: function () {
+ return true;
+ };
+
+ $notifications = collect($this->notificationsFor($notifiable, $notification));
+
+ return $notifications->filter(function ($arguments) use ($callback) {
+ return $callback(...array_values($arguments));
+ })->pluck('notification');
+ }
+
+ /**
+ * Determine if there are more notifications left to inspect.
+ *
+ * @param mixed $notifiable
+ * @param string $notification
+ * @return bool
+ */
+ public function hasSent($notifiable, $notification)
+ {
+ return ! empty($this->notificationsFor($notifiable, $notification));
+ }
+
+ /**
+ * Get all of the notifications for a notifiable entity by type.
+ *
+ * @param mixed $notifiable
+ * @param string $notification
+ * @return array
+ */
+ protected function notificationsFor($notifiable, $notification)
+ {
+ if (isset($this->notifications[get_class($notifiable)][$notifiable->getKey()][$notification])) {
+ return $this->notifications[get_class($notifiable)][$notifiable->getKey()][$notification];
+ }
+
+ return [];
+ }
+
+ /**
+ * Send the given notification to the given notifiable entities.
+ *
+ * @param \Illuminate\Support\Collection|array|mixed $notifiables
+ * @param mixed $notification
+ * @return void
+ */
+ public function send($notifiables, $notification)
+ {
+ return $this->sendNow($notifiables, $notification);
+ }
+
+ /**
+ * Send the given notification immediately.
+ *
+ * @param \Illuminate\Support\Collection|array|mixed $notifiables
+ * @param mixed $notification
+ * @return void
+ */
+ public function sendNow($notifiables, $notification)
+ {
+ if (! $notifiables instanceof Collection && ! is_array($notifiables)) {
+ $notifiables = [$notifiables];
+ }
+
+ foreach ($notifiables as $notifiable) {
+ if (! $notification->id) {
+ $notification->id = Uuid::uuid4()->toString();
+ }
+
+ $this->notifications[get_class($notifiable)][$notifiable->getKey()][get_class($notification)][] = [
+ 'notification' => $notification,
+ 'channels' => $notification->via($notifiable),
+ 'notifiable' => $notifiable,
+ ];
+ }
+ }
+
+ /**
+ * Get a channel instance by name.
+ *
+ * @param string|null $name
+ * @return mixed
+ */
+ public function channel($name = null)
+ {
+ //
+ }
+}
diff --git a/vendor/illuminate/support/Testing/Fakes/PendingMailFake.php b/vendor/illuminate/support/Testing/Fakes/PendingMailFake.php
new file mode 100644
index 0000000..e344fcf
--- /dev/null
+++ b/vendor/illuminate/support/Testing/Fakes/PendingMailFake.php
@@ -0,0 +1,53 @@
+mailer = $mailer;
+ }
+
+ /**
+ * Send a new mailable message instance.
+ *
+ * @param \Illuminate\Mail\Mailable $mailable
+ * @return mixed
+ */
+ public function send(Mailable $mailable)
+ {
+ return $this->sendNow($mailable);
+ }
+
+ /**
+ * Send a mailable message immediately.
+ *
+ * @param \Illuminate\Mail\Mailable $mailable
+ * @return mixed
+ */
+ public function sendNow(Mailable $mailable)
+ {
+ $this->mailer->send($this->fill($mailable));
+ }
+
+ /**
+ * Push the given mailable onto the queue.
+ *
+ * @param \Illuminate\Mail\Mailable $mailable
+ * @return mixed
+ */
+ public function queue(Mailable $mailable)
+ {
+ return $this->mailer->queue($this->fill($mailable));
+ }
+}
diff --git a/vendor/illuminate/support/Testing/Fakes/QueueFake.php b/vendor/illuminate/support/Testing/Fakes/QueueFake.php
new file mode 100644
index 0000000..66d191e
--- /dev/null
+++ b/vendor/illuminate/support/Testing/Fakes/QueueFake.php
@@ -0,0 +1,267 @@
+assertPushedTimes($job, $callback);
+ }
+
+ PHPUnit::assertTrue(
+ $this->pushed($job, $callback)->count() > 0,
+ "The expected [{$job}] job was not pushed."
+ );
+ }
+
+ /**
+ * Assert if a job was pushed a number of times.
+ *
+ * @param string $job
+ * @param int $times
+ * @return void
+ */
+ protected function assertPushedTimes($job, $times = 1)
+ {
+ PHPUnit::assertTrue(
+ ($count = $this->pushed($job)->count()) === $times,
+ "The expected [{$job}] job was pushed {$count} times instead of {$times} times."
+ );
+ }
+
+ /**
+ * Assert if a job was pushed based on a truth-test callback.
+ *
+ * @param string $queue
+ * @param string $job
+ * @param callable|null $callback
+ * @return void
+ */
+ public function assertPushedOn($queue, $job, $callback = null)
+ {
+ return $this->assertPushed($job, function ($job, $pushedQueue) use ($callback, $queue) {
+ if ($pushedQueue !== $queue) {
+ return false;
+ }
+
+ return $callback ? $callback(...func_get_args()) : true;
+ });
+ }
+
+ /**
+ * Determine if a job was pushed based on a truth-test callback.
+ *
+ * @param string $job
+ * @param callable|null $callback
+ * @return void
+ */
+ public function assertNotPushed($job, $callback = null)
+ {
+ PHPUnit::assertTrue(
+ $this->pushed($job, $callback)->count() === 0,
+ "The unexpected [{$job}] job was pushed."
+ );
+ }
+
+ /**
+ * Assert that no jobs were pushed.
+ *
+ * @return void
+ */
+ public function assertNothingPushed()
+ {
+ PHPUnit::assertEmpty($this->jobs, 'Jobs were pushed unexpectedly.');
+ }
+
+ /**
+ * Get all of the jobs matching a truth-test callback.
+ *
+ * @param string $job
+ * @param callable|null $callback
+ * @return \Illuminate\Support\Collection
+ */
+ public function pushed($job, $callback = null)
+ {
+ if (! $this->hasPushed($job)) {
+ return collect();
+ }
+
+ $callback = $callback ?: function () {
+ return true;
+ };
+
+ return collect($this->jobs[$job])->filter(function ($data) use ($callback) {
+ return $callback($data['job'], $data['queue']);
+ })->pluck('job');
+ }
+
+ /**
+ * Determine if there are any stored jobs for a given class.
+ *
+ * @param string $job
+ * @return bool
+ */
+ public function hasPushed($job)
+ {
+ return isset($this->jobs[$job]) && ! empty($this->jobs[$job]);
+ }
+
+ /**
+ * Resolve a queue connection instance.
+ *
+ * @param mixed $value
+ * @return \Illuminate\Contracts\Queue\Queue
+ */
+ public function connection($value = null)
+ {
+ return $this;
+ }
+
+ /**
+ * Get the size of the queue.
+ *
+ * @param string $queue
+ * @return int
+ */
+ public function size($queue = null)
+ {
+ return 0;
+ }
+
+ /**
+ * Push a new job onto the queue.
+ *
+ * @param string $job
+ * @param mixed $data
+ * @param string $queue
+ * @return mixed
+ */
+ public function push($job, $data = '', $queue = null)
+ {
+ $this->jobs[is_object($job) ? get_class($job) : $job][] = [
+ 'job' => $job,
+ 'queue' => $queue,
+ ];
+ }
+
+ /**
+ * Push a raw payload onto the queue.
+ *
+ * @param string $payload
+ * @param string $queue
+ * @param array $options
+ * @return mixed
+ */
+ public function pushRaw($payload, $queue = null, array $options = [])
+ {
+ //
+ }
+
+ /**
+ * Push a new job onto the queue after a delay.
+ *
+ * @param \DateTime|int $delay
+ * @param string $job
+ * @param mixed $data
+ * @param string $queue
+ * @return mixed
+ */
+ public function later($delay, $job, $data = '', $queue = null)
+ {
+ return $this->push($job, $data, $queue);
+ }
+
+ /**
+ * Push a new job onto the queue.
+ *
+ * @param string $queue
+ * @param string $job
+ * @param mixed $data
+ * @return mixed
+ */
+ public function pushOn($queue, $job, $data = '')
+ {
+ return $this->push($job, $data, $queue);
+ }
+
+ /**
+ * Push a new job onto the queue after a delay.
+ *
+ * @param string $queue
+ * @param \DateTime|int $delay
+ * @param string $job
+ * @param mixed $data
+ * @return mixed
+ */
+ public function laterOn($queue, $delay, $job, $data = '')
+ {
+ return $this->push($job, $data, $queue);
+ }
+
+ /**
+ * Pop the next job off of the queue.
+ *
+ * @param string $queue
+ * @return \Illuminate\Contracts\Queue\Job|null
+ */
+ public function pop($queue = null)
+ {
+ //
+ }
+
+ /**
+ * Push an array of jobs onto the queue.
+ *
+ * @param array $jobs
+ * @param mixed $data
+ * @param string $queue
+ * @return mixed
+ */
+ public function bulk($jobs, $data = '', $queue = null)
+ {
+ foreach ($jobs as $job) {
+ $this->push($job, $data, $queue);
+ }
+ }
+
+ /**
+ * Get the connection name for the queue.
+ *
+ * @return string
+ */
+ public function getConnectionName()
+ {
+ //
+ }
+
+ /**
+ * Set the connection name for the queue.
+ *
+ * @param string $name
+ * @return $this
+ */
+ public function setConnectionName($name)
+ {
+ return $this;
+ }
+}
diff --git a/vendor/illuminate/support/Traits/CapsuleManagerTrait.php b/vendor/illuminate/support/Traits/CapsuleManagerTrait.php
new file mode 100644
index 0000000..08089ef
--- /dev/null
+++ b/vendor/illuminate/support/Traits/CapsuleManagerTrait.php
@@ -0,0 +1,69 @@
+container = $container;
+
+ if (! $this->container->bound('config')) {
+ $this->container->instance('config', new Fluent);
+ }
+ }
+
+ /**
+ * Make this capsule instance available globally.
+ *
+ * @return void
+ */
+ public function setAsGlobal()
+ {
+ static::$instance = $this;
+ }
+
+ /**
+ * Get the IoC container instance.
+ *
+ * @return \Illuminate\Contracts\Container\Container
+ */
+ public function getContainer()
+ {
+ return $this->container;
+ }
+
+ /**
+ * Set the IoC container instance.
+ *
+ * @param \Illuminate\Contracts\Container\Container $container
+ * @return void
+ */
+ public function setContainer(Container $container)
+ {
+ $this->container = $container;
+ }
+}
diff --git a/vendor/illuminate/support/Traits/Macroable.php b/vendor/illuminate/support/Traits/Macroable.php
new file mode 100644
index 0000000..a7703b1
--- /dev/null
+++ b/vendor/illuminate/support/Traits/Macroable.php
@@ -0,0 +1,107 @@
+getMethods(
+ ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
+ );
+
+ foreach ($methods as $method) {
+ $method->setAccessible(true);
+
+ static::macro($method->name, $method->invoke($mixin));
+ }
+ }
+
+ /**
+ * Checks if macro is registered.
+ *
+ * @param string $name
+ * @return bool
+ */
+ public static function hasMacro($name)
+ {
+ return isset(static::$macros[$name]);
+ }
+
+ /**
+ * Dynamically handle calls to the class.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ *
+ * @throws \BadMethodCallException
+ */
+ public static function __callStatic($method, $parameters)
+ {
+ if (! static::hasMacro($method)) {
+ throw new BadMethodCallException("Method {$method} does not exist.");
+ }
+
+ if (static::$macros[$method] instanceof Closure) {
+ return call_user_func_array(Closure::bind(static::$macros[$method], null, static::class), $parameters);
+ }
+
+ return call_user_func_array(static::$macros[$method], $parameters);
+ }
+
+ /**
+ * Dynamically handle calls to the class.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __call($method, $parameters)
+ {
+ if (! static::hasMacro($method)) {
+ throw new BadMethodCallException("Method {$method} does not exist.");
+ }
+
+ $macro = static::$macros[$method];
+
+ if ($macro instanceof Closure) {
+ return call_user_func_array($macro->bindTo($this, static::class), $parameters);
+ }
+
+ return call_user_func_array($macro, $parameters);
+ }
+}
diff --git a/vendor/illuminate/support/ViewErrorBag.php b/vendor/illuminate/support/ViewErrorBag.php
new file mode 100644
index 0000000..0f273b5
--- /dev/null
+++ b/vendor/illuminate/support/ViewErrorBag.php
@@ -0,0 +1,130 @@
+bags[$key]);
+ }
+
+ /**
+ * Get a MessageBag instance from the bags.
+ *
+ * @param string $key
+ * @return \Illuminate\Contracts\Support\MessageBag
+ */
+ public function getBag($key)
+ {
+ return Arr::get($this->bags, $key) ?: new MessageBag;
+ }
+
+ /**
+ * Get all the bags.
+ *
+ * @return array
+ */
+ public function getBags()
+ {
+ return $this->bags;
+ }
+
+ /**
+ * Add a new MessageBag instance to the bags.
+ *
+ * @param string $key
+ * @param \Illuminate\Contracts\Support\MessageBag $bag
+ * @return $this
+ */
+ public function put($key, MessageBagContract $bag)
+ {
+ $this->bags[$key] = $bag;
+
+ return $this;
+ }
+
+ /**
+ * Determine if the default message bag has any messages.
+ *
+ * @return bool
+ */
+ public function any()
+ {
+ return $this->count() > 0;
+ }
+
+ /**
+ * Get the number of messages in the default bag.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return $this->getBag('default')->count();
+ }
+
+ /**
+ * Dynamically call methods on the default bag.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function __call($method, $parameters)
+ {
+ return $this->getBag('default')->$method(...$parameters);
+ }
+
+ /**
+ * Dynamically access a view error bag.
+ *
+ * @param string $key
+ * @return \Illuminate\Contracts\Support\MessageBag
+ */
+ public function __get($key)
+ {
+ return $this->getBag($key);
+ }
+
+ /**
+ * Dynamically set a view error bag.
+ *
+ * @param string $key
+ * @param \Illuminate\Contracts\Support\MessageBag $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->put($key, $value);
+ }
+
+ /**
+ * Convert the default bag to its string representation.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return (string) $this->getBag('default');
+ }
+}
diff --git a/vendor/illuminate/support/composer.json b/vendor/illuminate/support/composer.json
new file mode 100644
index 0000000..35f3ebd
--- /dev/null
+++ b/vendor/illuminate/support/composer.json
@@ -0,0 +1,48 @@
+{
+ "name": "illuminate/support",
+ "description": "The Illuminate Support package.",
+ "license": "MIT",
+ "homepage": "https://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.0",
+ "ext-mbstring": "*",
+ "doctrine/inflector": "~1.1",
+ "illuminate/contracts": "5.5.*",
+ "nesbot/carbon": "^1.24.1"
+ },
+ "replace": {
+ "tightenco/collect": "<5.5.33"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\Support\\": ""
+ },
+ "files": [
+ "helpers.php"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.5-dev"
+ }
+ },
+ "suggest": {
+ "illuminate/filesystem": "Required to use the composer class (5.5.*).",
+ "symfony/process": "Required to use the composer class (~3.3).",
+ "symfony/var-dumper": "Required to use the dd function (~3.3)."
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/illuminate/support/helpers.php b/vendor/illuminate/support/helpers.php
new file mode 100644
index 0000000..c52fd66
--- /dev/null
+++ b/vendor/illuminate/support/helpers.php
@@ -0,0 +1,1176 @@
+ $value) {
+ if (is_numeric($key)) {
+ $start++;
+
+ $array[$start] = Arr::pull($array, $key);
+ }
+ }
+
+ return $array;
+ }
+}
+
+if (! function_exists('array_add')) {
+ /**
+ * Add an element to an array using "dot" notation if it doesn't exist.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $value
+ * @return array
+ */
+ function array_add($array, $key, $value)
+ {
+ return Arr::add($array, $key, $value);
+ }
+}
+
+if (! function_exists('array_collapse')) {
+ /**
+ * Collapse an array of arrays into a single array.
+ *
+ * @param array $array
+ * @return array
+ */
+ function array_collapse($array)
+ {
+ return Arr::collapse($array);
+ }
+}
+
+if (! function_exists('array_divide')) {
+ /**
+ * Divide an array into two arrays. One with keys and the other with values.
+ *
+ * @param array $array
+ * @return array
+ */
+ function array_divide($array)
+ {
+ return Arr::divide($array);
+ }
+}
+
+if (! function_exists('array_dot')) {
+ /**
+ * Flatten a multi-dimensional associative array with dots.
+ *
+ * @param array $array
+ * @param string $prepend
+ * @return array
+ */
+ function array_dot($array, $prepend = '')
+ {
+ return Arr::dot($array, $prepend);
+ }
+}
+
+if (! function_exists('array_except')) {
+ /**
+ * Get all of the given array except for a specified array of keys.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ function array_except($array, $keys)
+ {
+ return Arr::except($array, $keys);
+ }
+}
+
+if (! function_exists('array_first')) {
+ /**
+ * Return the first element in an array passing a given truth test.
+ *
+ * @param array $array
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ function array_first($array, callable $callback = null, $default = null)
+ {
+ return Arr::first($array, $callback, $default);
+ }
+}
+
+if (! function_exists('array_flatten')) {
+ /**
+ * Flatten a multi-dimensional array into a single level.
+ *
+ * @param array $array
+ * @param int $depth
+ * @return array
+ */
+ function array_flatten($array, $depth = INF)
+ {
+ return Arr::flatten($array, $depth);
+ }
+}
+
+if (! function_exists('array_forget')) {
+ /**
+ * Remove one or many array items from a given array using "dot" notation.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return void
+ */
+ function array_forget(&$array, $keys)
+ {
+ return Arr::forget($array, $keys);
+ }
+}
+
+if (! function_exists('array_get')) {
+ /**
+ * Get an item from an array using "dot" notation.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function array_get($array, $key, $default = null)
+ {
+ return Arr::get($array, $key, $default);
+ }
+}
+
+if (! function_exists('array_has')) {
+ /**
+ * Check if an item or items exist in an array using "dot" notation.
+ *
+ * @param \ArrayAccess|array $array
+ * @param string|array $keys
+ * @return bool
+ */
+ function array_has($array, $keys)
+ {
+ return Arr::has($array, $keys);
+ }
+}
+
+if (! function_exists('array_last')) {
+ /**
+ * Return the last element in an array passing a given truth test.
+ *
+ * @param array $array
+ * @param callable|null $callback
+ * @param mixed $default
+ * @return mixed
+ */
+ function array_last($array, callable $callback = null, $default = null)
+ {
+ return Arr::last($array, $callback, $default);
+ }
+}
+
+if (! function_exists('array_only')) {
+ /**
+ * Get a subset of the items from the given array.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ function array_only($array, $keys)
+ {
+ return Arr::only($array, $keys);
+ }
+}
+
+if (! function_exists('array_pluck')) {
+ /**
+ * Pluck an array of values from an array.
+ *
+ * @param array $array
+ * @param string|array $value
+ * @param string|array|null $key
+ * @return array
+ */
+ function array_pluck($array, $value, $key = null)
+ {
+ return Arr::pluck($array, $value, $key);
+ }
+}
+
+if (! function_exists('array_prepend')) {
+ /**
+ * Push an item onto the beginning of an array.
+ *
+ * @param array $array
+ * @param mixed $value
+ * @param mixed $key
+ * @return array
+ */
+ function array_prepend($array, $value, $key = null)
+ {
+ return Arr::prepend($array, $value, $key);
+ }
+}
+
+if (! function_exists('array_pull')) {
+ /**
+ * Get a value from the array, and remove it.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function array_pull(&$array, $key, $default = null)
+ {
+ return Arr::pull($array, $key, $default);
+ }
+}
+
+if (! function_exists('array_random')) {
+ /**
+ * Get a random value from an array.
+ *
+ * @param array $array
+ * @param int|null $num
+ * @return mixed
+ */
+ function array_random($array, $num = null)
+ {
+ return Arr::random($array, $num);
+ }
+}
+
+if (! function_exists('array_set')) {
+ /**
+ * Set an array item to a given value using "dot" notation.
+ *
+ * If no key is given to the method, the entire array will be replaced.
+ *
+ * @param array $array
+ * @param string $key
+ * @param mixed $value
+ * @return array
+ */
+ function array_set(&$array, $key, $value)
+ {
+ return Arr::set($array, $key, $value);
+ }
+}
+
+if (! function_exists('array_sort')) {
+ /**
+ * Sort the array by the given callback or attribute name.
+ *
+ * @param array $array
+ * @param callable|string|null $callback
+ * @return array
+ */
+ function array_sort($array, $callback = null)
+ {
+ return Arr::sort($array, $callback);
+ }
+}
+
+if (! function_exists('array_sort_recursive')) {
+ /**
+ * Recursively sort an array by keys and values.
+ *
+ * @param array $array
+ * @return array
+ */
+ function array_sort_recursive($array)
+ {
+ return Arr::sortRecursive($array);
+ }
+}
+
+if (! function_exists('array_where')) {
+ /**
+ * Filter the array using the given callback.
+ *
+ * @param array $array
+ * @param callable $callback
+ * @return array
+ */
+ function array_where($array, callable $callback)
+ {
+ return Arr::where($array, $callback);
+ }
+}
+
+if (! function_exists('array_wrap')) {
+ /**
+ * If the given value is not an array, wrap it in one.
+ *
+ * @param mixed $value
+ * @return array
+ */
+ function array_wrap($value)
+ {
+ return Arr::wrap($value);
+ }
+}
+
+if (! function_exists('blank')) {
+ /**
+ * Determine if the given value is "blank".
+ *
+ * @param mixed $value
+ * @return bool
+ */
+ function blank($value)
+ {
+ if (is_null($value)) {
+ return true;
+ }
+
+ if (is_string($value)) {
+ return trim($value) === '';
+ }
+
+ if (is_numeric($value) || is_bool($value)) {
+ return false;
+ }
+
+ if ($value instanceof Countable) {
+ return count($value) === 0;
+ }
+
+ return empty($value);
+ }
+}
+
+if (! function_exists('camel_case')) {
+ /**
+ * Convert a value to camel case.
+ *
+ * @param string $value
+ * @return string
+ */
+ function camel_case($value)
+ {
+ return Str::camel($value);
+ }
+}
+
+if (! function_exists('class_basename')) {
+ /**
+ * Get the class "basename" of the given object / class.
+ *
+ * @param string|object $class
+ * @return string
+ */
+ function class_basename($class)
+ {
+ $class = is_object($class) ? get_class($class) : $class;
+
+ return basename(str_replace('\\', '/', $class));
+ }
+}
+
+if (! function_exists('class_uses_recursive')) {
+ /**
+ * Returns all traits used by a class, its subclasses and trait of their traits.
+ *
+ * @param object|string $class
+ * @return array
+ */
+ function class_uses_recursive($class)
+ {
+ if (is_object($class)) {
+ $class = get_class($class);
+ }
+
+ $results = [];
+
+ foreach (array_merge([$class => $class], class_parents($class)) as $class) {
+ $results += trait_uses_recursive($class);
+ }
+
+ return array_unique($results);
+ }
+}
+
+if (! function_exists('collect')) {
+ /**
+ * Create a collection from the given value.
+ *
+ * @param mixed $value
+ * @return \Illuminate\Support\Collection
+ */
+ function collect($value = null)
+ {
+ return new Collection($value);
+ }
+}
+
+if (! function_exists('data_fill')) {
+ /**
+ * Fill in data where it's missing.
+ *
+ * @param mixed $target
+ * @param string|array $key
+ * @param mixed $value
+ * @return mixed
+ */
+ function data_fill(&$target, $key, $value)
+ {
+ return data_set($target, $key, $value, false);
+ }
+}
+
+if (! function_exists('data_get')) {
+ /**
+ * Get an item from an array or object using "dot" notation.
+ *
+ * @param mixed $target
+ * @param string|array $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function data_get($target, $key, $default = null)
+ {
+ if (is_null($key)) {
+ return $target;
+ }
+
+ $key = is_array($key) ? $key : explode('.', $key);
+
+ while (! is_null($segment = array_shift($key))) {
+ if ($segment === '*') {
+ if ($target instanceof Collection) {
+ $target = $target->all();
+ } elseif (! is_array($target)) {
+ return value($default);
+ }
+
+ $result = Arr::pluck($target, $key);
+
+ return in_array('*', $key) ? Arr::collapse($result) : $result;
+ }
+
+ if (Arr::accessible($target) && Arr::exists($target, $segment)) {
+ $target = $target[$segment];
+ } elseif (is_object($target) && isset($target->{$segment})) {
+ $target = $target->{$segment};
+ } else {
+ return value($default);
+ }
+ }
+
+ return $target;
+ }
+}
+
+if (! function_exists('data_set')) {
+ /**
+ * Set an item on an array or object using dot notation.
+ *
+ * @param mixed $target
+ * @param string|array $key
+ * @param mixed $value
+ * @param bool $overwrite
+ * @return mixed
+ */
+ function data_set(&$target, $key, $value, $overwrite = true)
+ {
+ $segments = is_array($key) ? $key : explode('.', $key);
+
+ if (($segment = array_shift($segments)) === '*') {
+ if (! Arr::accessible($target)) {
+ $target = [];
+ }
+
+ if ($segments) {
+ foreach ($target as &$inner) {
+ data_set($inner, $segments, $value, $overwrite);
+ }
+ } elseif ($overwrite) {
+ foreach ($target as &$inner) {
+ $inner = $value;
+ }
+ }
+ } elseif (Arr::accessible($target)) {
+ if ($segments) {
+ if (! Arr::exists($target, $segment)) {
+ $target[$segment] = [];
+ }
+
+ data_set($target[$segment], $segments, $value, $overwrite);
+ } elseif ($overwrite || ! Arr::exists($target, $segment)) {
+ $target[$segment] = $value;
+ }
+ } elseif (is_object($target)) {
+ if ($segments) {
+ if (! isset($target->{$segment})) {
+ $target->{$segment} = [];
+ }
+
+ data_set($target->{$segment}, $segments, $value, $overwrite);
+ } elseif ($overwrite || ! isset($target->{$segment})) {
+ $target->{$segment} = $value;
+ }
+ } else {
+ $target = [];
+
+ if ($segments) {
+ data_set($target[$segment], $segments, $value, $overwrite);
+ } elseif ($overwrite) {
+ $target[$segment] = $value;
+ }
+ }
+
+ return $target;
+ }
+}
+
+if (! function_exists('dd')) {
+ /**
+ * Dump the passed variables and end the script.
+ *
+ * @param mixed $args
+ * @return void
+ */
+ function dd(...$args)
+ {
+ http_response_code(500);
+
+ foreach ($args as $x) {
+ (new Dumper)->dump($x);
+ }
+
+ die(1);
+ }
+}
+
+if (! function_exists('e')) {
+ /**
+ * Escape HTML special characters in a string.
+ *
+ * @param \Illuminate\Contracts\Support\Htmlable|string $value
+ * @param bool $doubleEncode
+ * @return string
+ */
+ function e($value, $doubleEncode = false)
+ {
+ if ($value instanceof Htmlable) {
+ return $value->toHtml();
+ }
+
+ return htmlspecialchars($value, ENT_QUOTES, 'UTF-8', $doubleEncode);
+ }
+}
+
+if (! function_exists('ends_with')) {
+ /**
+ * Determine if a given string ends with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ function ends_with($haystack, $needles)
+ {
+ return Str::endsWith($haystack, $needles);
+ }
+}
+
+if (! function_exists('env')) {
+ /**
+ * Gets the value of an environment variable.
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function env($key, $default = null)
+ {
+ $value = getenv($key);
+
+ if ($value === false) {
+ return value($default);
+ }
+
+ switch (strtolower($value)) {
+ case 'true':
+ case '(true)':
+ return true;
+ case 'false':
+ case '(false)':
+ return false;
+ case 'empty':
+ case '(empty)':
+ return '';
+ case 'null':
+ case '(null)':
+ return;
+ }
+
+ if (strlen($value) > 1 && Str::startsWith($value, '"') && Str::endsWith($value, '"')) {
+ return substr($value, 1, -1);
+ }
+
+ return $value;
+ }
+}
+
+if (! function_exists('filled')) {
+ /**
+ * Determine if a value is "filled".
+ *
+ * @param mixed $value
+ * @return bool
+ */
+ function filled($value)
+ {
+ return ! blank($value);
+ }
+}
+
+if (! function_exists('head')) {
+ /**
+ * Get the first element of an array. Useful for method chaining.
+ *
+ * @param array $array
+ * @return mixed
+ */
+ function head($array)
+ {
+ return reset($array);
+ }
+}
+
+if (! function_exists('kebab_case')) {
+ /**
+ * Convert a string to kebab case.
+ *
+ * @param string $value
+ * @return string
+ */
+ function kebab_case($value)
+ {
+ return Str::kebab($value);
+ }
+}
+
+if (! function_exists('last')) {
+ /**
+ * Get the last element from an array.
+ *
+ * @param array $array
+ * @return mixed
+ */
+ function last($array)
+ {
+ return end($array);
+ }
+}
+
+if (! function_exists('object_get')) {
+ /**
+ * Get an item from an object using "dot" notation.
+ *
+ * @param object $object
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ function object_get($object, $key, $default = null)
+ {
+ if (is_null($key) || trim($key) == '') {
+ return $object;
+ }
+
+ foreach (explode('.', $key) as $segment) {
+ if (! is_object($object) || ! isset($object->{$segment})) {
+ return value($default);
+ }
+
+ $object = $object->{$segment};
+ }
+
+ return $object;
+ }
+}
+
+if (! function_exists('optional')) {
+ /**
+ * Provide access to optional objects.
+ *
+ * @param mixed $value
+ * @return mixed
+ */
+ function optional($value = null)
+ {
+ return new Optional($value);
+ }
+}
+
+if (! function_exists('preg_replace_array')) {
+ /**
+ * Replace a given pattern with each value in the array in sequentially.
+ *
+ * @param string $pattern
+ * @param array $replacements
+ * @param string $subject
+ * @return string
+ */
+ function preg_replace_array($pattern, array $replacements, $subject)
+ {
+ return preg_replace_callback($pattern, function () use (&$replacements) {
+ foreach ($replacements as $key => $value) {
+ return array_shift($replacements);
+ }
+ }, $subject);
+ }
+}
+
+if (! function_exists('retry')) {
+ /**
+ * Retry an operation a given number of times.
+ *
+ * @param int $times
+ * @param callable $callback
+ * @param int $sleep
+ * @return mixed
+ *
+ * @throws \Exception
+ */
+ function retry($times, callable $callback, $sleep = 0)
+ {
+ $times--;
+
+ beginning:
+ try {
+ return $callback();
+ } catch (Exception $e) {
+ if (! $times) {
+ throw $e;
+ }
+
+ $times--;
+
+ if ($sleep) {
+ usleep($sleep * 1000);
+ }
+
+ goto beginning;
+ }
+ }
+}
+
+if (! function_exists('snake_case')) {
+ /**
+ * Convert a string to snake case.
+ *
+ * @param string $value
+ * @param string $delimiter
+ * @return string
+ */
+ function snake_case($value, $delimiter = '_')
+ {
+ return Str::snake($value, $delimiter);
+ }
+}
+
+if (! function_exists('starts_with')) {
+ /**
+ * Determine if a given string starts with a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ function starts_with($haystack, $needles)
+ {
+ return Str::startsWith($haystack, $needles);
+ }
+}
+
+if (! function_exists('str_after')) {
+ /**
+ * Return the remainder of a string after a given value.
+ *
+ * @param string $subject
+ * @param string $search
+ * @return string
+ */
+ function str_after($subject, $search)
+ {
+ return Str::after($subject, $search);
+ }
+}
+
+if (! function_exists('str_before')) {
+ /**
+ * Get the portion of a string before a given value.
+ *
+ * @param string $subject
+ * @param string $search
+ * @return string
+ */
+ function str_before($subject, $search)
+ {
+ return Str::before($subject, $search);
+ }
+}
+
+if (! function_exists('str_contains')) {
+ /**
+ * Determine if a given string contains a given substring.
+ *
+ * @param string $haystack
+ * @param string|array $needles
+ * @return bool
+ */
+ function str_contains($haystack, $needles)
+ {
+ return Str::contains($haystack, $needles);
+ }
+}
+
+if (! function_exists('str_finish')) {
+ /**
+ * Cap a string with a single instance of a given value.
+ *
+ * @param string $value
+ * @param string $cap
+ * @return string
+ */
+ function str_finish($value, $cap)
+ {
+ return Str::finish($value, $cap);
+ }
+}
+
+if (! function_exists('str_is')) {
+ /**
+ * Determine if a given string matches a given pattern.
+ *
+ * @param string|array $pattern
+ * @param string $value
+ * @return bool
+ */
+ function str_is($pattern, $value)
+ {
+ return Str::is($pattern, $value);
+ }
+}
+
+if (! function_exists('str_limit')) {
+ /**
+ * Limit the number of characters in a string.
+ *
+ * @param string $value
+ * @param int $limit
+ * @param string $end
+ * @return string
+ */
+ function str_limit($value, $limit = 100, $end = '...')
+ {
+ return Str::limit($value, $limit, $end);
+ }
+}
+
+if (! function_exists('str_plural')) {
+ /**
+ * Get the plural form of an English word.
+ *
+ * @param string $value
+ * @param int $count
+ * @return string
+ */
+ function str_plural($value, $count = 2)
+ {
+ return Str::plural($value, $count);
+ }
+}
+
+if (! function_exists('str_random')) {
+ /**
+ * Generate a more truly "random" alpha-numeric string.
+ *
+ * @param int $length
+ * @return string
+ *
+ * @throws \RuntimeException
+ */
+ function str_random($length = 16)
+ {
+ return Str::random($length);
+ }
+}
+
+if (! function_exists('str_replace_array')) {
+ /**
+ * Replace a given value in the string sequentially with an array.
+ *
+ * @param string $search
+ * @param array $replace
+ * @param string $subject
+ * @return string
+ */
+ function str_replace_array($search, array $replace, $subject)
+ {
+ return Str::replaceArray($search, $replace, $subject);
+ }
+}
+
+if (! function_exists('str_replace_first')) {
+ /**
+ * Replace the first occurrence of a given value in the string.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @return string
+ */
+ function str_replace_first($search, $replace, $subject)
+ {
+ return Str::replaceFirst($search, $replace, $subject);
+ }
+}
+
+if (! function_exists('str_replace_last')) {
+ /**
+ * Replace the last occurrence of a given value in the string.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @return string
+ */
+ function str_replace_last($search, $replace, $subject)
+ {
+ return Str::replaceLast($search, $replace, $subject);
+ }
+}
+
+if (! function_exists('str_singular')) {
+ /**
+ * Get the singular form of an English word.
+ *
+ * @param string $value
+ * @return string
+ */
+ function str_singular($value)
+ {
+ return Str::singular($value);
+ }
+}
+
+if (! function_exists('str_slug')) {
+ /**
+ * Generate a URL friendly "slug" from a given string.
+ *
+ * @param string $title
+ * @param string $separator
+ * @param string $language
+ * @return string
+ */
+ function str_slug($title, $separator = '-', $language = 'en')
+ {
+ return Str::slug($title, $separator, $language);
+ }
+}
+
+if (! function_exists('str_start')) {
+ /**
+ * Begin a string with a single instance of a given value.
+ *
+ * @param string $value
+ * @param string $prefix
+ * @return string
+ */
+ function str_start($value, $prefix)
+ {
+ return Str::start($value, $prefix);
+ }
+}
+
+if (! function_exists('studly_case')) {
+ /**
+ * Convert a value to studly caps case.
+ *
+ * @param string $value
+ * @return string
+ */
+ function studly_case($value)
+ {
+ return Str::studly($value);
+ }
+}
+
+if (! function_exists('tap')) {
+ /**
+ * Call the given Closure with the given value then return the value.
+ *
+ * @param mixed $value
+ * @param callable|null $callback
+ * @return mixed
+ */
+ function tap($value, $callback = null)
+ {
+ if (is_null($callback)) {
+ return new HigherOrderTapProxy($value);
+ }
+
+ $callback($value);
+
+ return $value;
+ }
+}
+
+if (! function_exists('throw_if')) {
+ /**
+ * Throw the given exception if the given condition is true.
+ *
+ * @param mixed $condition
+ * @param \Throwable|string $exception
+ * @param array ...$parameters
+ * @return mixed
+ * @throws \Throwable
+ */
+ function throw_if($condition, $exception, ...$parameters)
+ {
+ if ($condition) {
+ throw (is_string($exception) ? new $exception(...$parameters) : $exception);
+ }
+
+ return $condition;
+ }
+}
+
+if (! function_exists('throw_unless')) {
+ /**
+ * Throw the given exception unless the given condition is true.
+ *
+ * @param mixed $condition
+ * @param \Throwable|string $exception
+ * @param array ...$parameters
+ * @return mixed
+ * @throws \Throwable
+ */
+ function throw_unless($condition, $exception, ...$parameters)
+ {
+ if (! $condition) {
+ throw (is_string($exception) ? new $exception(...$parameters) : $exception);
+ }
+
+ return $condition;
+ }
+}
+
+if (! function_exists('title_case')) {
+ /**
+ * Convert a value to title case.
+ *
+ * @param string $value
+ * @return string
+ */
+ function title_case($value)
+ {
+ return Str::title($value);
+ }
+}
+
+if (! function_exists('trait_uses_recursive')) {
+ /**
+ * Returns all traits used by a trait and its traits.
+ *
+ * @param string $trait
+ * @return array
+ */
+ function trait_uses_recursive($trait)
+ {
+ $traits = class_uses($trait);
+
+ foreach ($traits as $trait) {
+ $traits += trait_uses_recursive($trait);
+ }
+
+ return $traits;
+ }
+}
+
+if (! function_exists('transform')) {
+ /**
+ * Transform the given value if it is present.
+ *
+ * @param mixed $value
+ * @param callable $callback
+ * @param mixed $default
+ * @return mixed|null
+ */
+ function transform($value, callable $callback, $default = null)
+ {
+ if (filled($value)) {
+ return $callback($value);
+ }
+
+ if (is_callable($default)) {
+ return $default($value);
+ }
+
+ return $default;
+ }
+}
+
+if (! function_exists('value')) {
+ /**
+ * Return the default value of the given value.
+ *
+ * @param mixed $value
+ * @return mixed
+ */
+ function value($value)
+ {
+ return $value instanceof Closure ? $value() : $value;
+ }
+}
+
+if (! function_exists('windows_os')) {
+ /**
+ * Determine whether the current environment is Windows based.
+ *
+ * @return bool
+ */
+ function windows_os()
+ {
+ return strtolower(substr(PHP_OS, 0, 3)) === 'win';
+ }
+}
+
+if (! function_exists('with')) {
+ /**
+ * Return the given value, optionally passed through the given callback.
+ *
+ * @param mixed $value
+ * @param callable|null $callback
+ * @return mixed
+ */
+ function with($value, callable $callback = null)
+ {
+ return is_null($callback) ? $value : $callback($value);
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/BladeCompiler.php b/vendor/illuminate/view/Compilers/BladeCompiler.php
new file mode 100644
index 0000000..6a999c9
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/BladeCompiler.php
@@ -0,0 +1,468 @@
+setPath($path);
+ }
+
+ if (! is_null($this->cachePath)) {
+ $contents = $this->compileString($this->files->get($this->getPath()));
+
+ $this->files->put($this->getCompiledPath($this->getPath()), $contents);
+ }
+ }
+
+ /**
+ * Get the path currently being compiled.
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Set the path currently being compiled.
+ *
+ * @param string $path
+ * @return void
+ */
+ public function setPath($path)
+ {
+ $this->path = $path;
+ }
+
+ /**
+ * Compile the given Blade template contents.
+ *
+ * @param string $value
+ * @return string
+ */
+ public function compileString($value)
+ {
+ if (strpos($value, '@verbatim') !== false) {
+ $value = $this->storeVerbatimBlocks($value);
+ }
+
+ $this->footer = [];
+
+ if (strpos($value, '@php') !== false) {
+ $value = $this->storePhpBlocks($value);
+ }
+
+ $result = '';
+
+ // Here we will loop through all of the tokens returned by the Zend lexer and
+ // parse each one into the corresponding valid PHP. We will then have this
+ // template as the correctly rendered PHP that can be rendered natively.
+ foreach (token_get_all($value) as $token) {
+ $result .= is_array($token) ? $this->parseToken($token) : $token;
+ }
+
+ if (! empty($this->rawBlocks)) {
+ $result = $this->restoreRawContent($result);
+ }
+
+ // If there are any footer lines that need to get added to a template we will
+ // add them here at the end of the template. This gets used mainly for the
+ // template inheritance via the extends keyword that should be appended.
+ if (count($this->footer) > 0) {
+ $result = $this->addFooters($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Store the verbatim blocks and replace them with a temporary placeholder.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function storeVerbatimBlocks($value)
+ {
+ return preg_replace_callback('/(?storeRawBlock($matches[1]);
+ }, $value);
+ }
+
+ /**
+ * Store the PHP blocks and replace them with a temporary placeholder.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function storePhpBlocks($value)
+ {
+ return preg_replace_callback('/(?storeRawBlock("");
+ }, $value);
+ }
+
+ /**
+ * Store a raw block and return a unique raw placeholder.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function storeRawBlock($value)
+ {
+ return $this->getRawPlaceholder(
+ array_push($this->rawBlocks, $value) - 1
+ );
+ }
+
+ /**
+ * Replace the raw placeholders with the original code stored in the raw blocks.
+ *
+ * @param string $result
+ * @return string
+ */
+ protected function restoreRawContent($result)
+ {
+ $result = preg_replace_callback('/'.$this->getRawPlaceholder('(\d+)').'/', function ($matches) {
+ return $this->rawBlocks[$matches[1]];
+ }, $result);
+
+ $this->rawBlocks = [];
+
+ return $result;
+ }
+
+ /**
+ * Get a placeholder to temporary mark the position of raw blocks.
+ *
+ * @param int|string $replace
+ * @return string
+ */
+ protected function getRawPlaceholder($replace)
+ {
+ return str_replace('#', $replace, '@__raw_block_#__@');
+ }
+
+ /**
+ * Add the stored footers onto the given content.
+ *
+ * @param string $result
+ * @return string
+ */
+ protected function addFooters($result)
+ {
+ return ltrim($result, PHP_EOL)
+ .PHP_EOL.implode(PHP_EOL, array_reverse($this->footer));
+ }
+
+ /**
+ * Parse the tokens from the template.
+ *
+ * @param array $token
+ * @return string
+ */
+ protected function parseToken($token)
+ {
+ list($id, $content) = $token;
+
+ if ($id == T_INLINE_HTML) {
+ foreach ($this->compilers as $type) {
+ $content = $this->{"compile{$type}"}($content);
+ }
+ }
+
+ return $content;
+ }
+
+ /**
+ * Execute the user defined extensions.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileExtensions($value)
+ {
+ foreach ($this->extensions as $compiler) {
+ $value = call_user_func($compiler, $value, $this);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Compile Blade statements that start with "@".
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileStatements($value)
+ {
+ return preg_replace_callback(
+ '/\B@(@?\w+(?:::\w+)?)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x', function ($match) {
+ return $this->compileStatement($match);
+ }, $value
+ );
+ }
+
+ /**
+ * Compile a single Blade @ statement.
+ *
+ * @param array $match
+ * @return string
+ */
+ protected function compileStatement($match)
+ {
+ if (Str::contains($match[1], '@')) {
+ $match[0] = isset($match[3]) ? $match[1].$match[3] : $match[1];
+ } elseif (isset($this->customDirectives[$match[1]])) {
+ $match[0] = $this->callCustomDirective($match[1], Arr::get($match, 3));
+ } elseif (method_exists($this, $method = 'compile'.ucfirst($match[1]))) {
+ $match[0] = $this->$method(Arr::get($match, 3));
+ }
+
+ return isset($match[3]) ? $match[0] : $match[0].$match[2];
+ }
+
+ /**
+ * Call the given directive with the given value.
+ *
+ * @param string $name
+ * @param string|null $value
+ * @return string
+ */
+ protected function callCustomDirective($name, $value)
+ {
+ if (Str::startsWith($value, '(') && Str::endsWith($value, ')')) {
+ $value = Str::substr($value, 1, -1);
+ }
+
+ return call_user_func($this->customDirectives[$name], trim($value));
+ }
+
+ /**
+ * Strip the parentheses from the given expression.
+ *
+ * @param string $expression
+ * @return string
+ */
+ public function stripParentheses($expression)
+ {
+ if (Str::startsWith($expression, '(')) {
+ $expression = substr($expression, 1, -1);
+ }
+
+ return $expression;
+ }
+
+ /**
+ * Register a custom Blade compiler.
+ *
+ * @param callable $compiler
+ * @return void
+ */
+ public function extend(callable $compiler)
+ {
+ $this->extensions[] = $compiler;
+ }
+
+ /**
+ * Get the extensions used by the compiler.
+ *
+ * @return array
+ */
+ public function getExtensions()
+ {
+ return $this->extensions;
+ }
+
+ /**
+ * Register an "if" statement directive.
+ *
+ * @param string $name
+ * @param callable $callback
+ * @return void
+ */
+ public function if($name, callable $callback)
+ {
+ $this->conditions[$name] = $callback;
+
+ $this->directive($name, function ($expression) use ($name) {
+ return $expression
+ ? ""
+ : "";
+ });
+
+ $this->directive('else'.$name, function ($expression) use ($name) {
+ return $expression
+ ? ""
+ : "";
+ });
+
+ $this->directive('end'.$name, function () {
+ return '';
+ });
+ }
+
+ /**
+ * Check the result of a condition.
+ *
+ * @param string $name
+ * @param array $parameters
+ * @return bool
+ */
+ public function check($name, ...$parameters)
+ {
+ return call_user_func($this->conditions[$name], ...$parameters);
+ }
+
+ /**
+ * Register a handler for custom directives.
+ *
+ * @param string $name
+ * @param callable $handler
+ * @return void
+ */
+ public function directive($name, callable $handler)
+ {
+ $this->customDirectives[$name] = $handler;
+ }
+
+ /**
+ * Get the list of custom directives.
+ *
+ * @return array
+ */
+ public function getCustomDirectives()
+ {
+ return $this->customDirectives;
+ }
+
+ /**
+ * Set the echo format to be used by the compiler.
+ *
+ * @param string $format
+ * @return void
+ */
+ public function setEchoFormat($format)
+ {
+ $this->echoFormat = $format;
+ }
+
+ /**
+ * Set the echo format to double encode entities.
+ *
+ * @return void
+ */
+ public function doubleEncode()
+ {
+ $this->setEchoFormat('e(%s, true)');
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Compiler.php b/vendor/illuminate/view/Compilers/Compiler.php
new file mode 100644
index 0000000..9407419
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Compiler.php
@@ -0,0 +1,74 @@
+files = $files;
+ $this->cachePath = $cachePath;
+ }
+
+ /**
+ * Get the path to the compiled version of a view.
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getCompiledPath($path)
+ {
+ return $this->cachePath.'/'.sha1($path).'.php';
+ }
+
+ /**
+ * Determine if the view at the given path is expired.
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isExpired($path)
+ {
+ $compiled = $this->getCompiledPath($path);
+
+ // If the compiled file doesn't exist we will indicate that the view is expired
+ // so that it can be re-compiled. Else, we will verify the last modification
+ // of the views is less than the modification times of the compiled views.
+ if (! $this->files->exists($compiled)) {
+ return true;
+ }
+
+ return $this->files->lastModified($path) >=
+ $this->files->lastModified($compiled);
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/CompilerInterface.php b/vendor/illuminate/view/Compilers/CompilerInterface.php
new file mode 100644
index 0000000..dfcb023
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/CompilerInterface.php
@@ -0,0 +1,30 @@
+check{$expression}): ?>";
+ }
+
+ /**
+ * Compile the cannot statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileCannot($expression)
+ {
+ return "denies{$expression}): ?>";
+ }
+
+ /**
+ * Compile the else-can statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElsecan($expression)
+ {
+ return "check{$expression}): ?>";
+ }
+
+ /**
+ * Compile the else-cannot statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElsecannot($expression)
+ {
+ return "denies{$expression}): ?>";
+ }
+
+ /**
+ * Compile the end-can statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndcan()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the end-cannot statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndcannot()
+ {
+ return '';
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesComments.php b/vendor/illuminate/view/Compilers/Concerns/CompilesComments.php
new file mode 100644
index 0000000..104a9c8
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesComments.php
@@ -0,0 +1,19 @@
+contentTags[0], $this->contentTags[1]);
+
+ return preg_replace($pattern, '', $value);
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesComponents.php b/vendor/illuminate/view/Compilers/Concerns/CompilesComponents.php
new file mode 100644
index 0000000..af0eee7
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesComponents.php
@@ -0,0 +1,48 @@
+startComponent{$expression}; ?>";
+ }
+
+ /**
+ * Compile the end-component statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndComponent()
+ {
+ return 'renderComponent(); ?>';
+ }
+
+ /**
+ * Compile the slot statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileSlot($expression)
+ {
+ return "slot{$expression}; ?>";
+ }
+
+ /**
+ * Compile the end-slot statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndSlot()
+ {
+ return 'endSlot(); ?>';
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesConditionals.php b/vendor/illuminate/view/Compilers/Concerns/CompilesConditionals.php
new file mode 100644
index 0000000..bf72134
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesConditionals.php
@@ -0,0 +1,204 @@
+guard{$guard}->check()): ?>";
+ }
+
+ /**
+ * Compile the end-auth statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndAuth()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the if-guest statements into valid PHP.
+ *
+ * @param string|null $guard
+ * @return string
+ */
+ protected function compileGuest($guard = null)
+ {
+ $guard = is_null($guard) ? '()' : $guard;
+
+ return "guard{$guard}->guest()): ?>";
+ }
+
+ /**
+ * Compile the end-guest statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndGuest()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the has-section statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileHasSection($expression)
+ {
+ return "yieldContent{$expression}))): ?>";
+ }
+
+ /**
+ * Compile the if statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileIf($expression)
+ {
+ return "";
+ }
+
+ /**
+ * Compile the unless statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileUnless($expression)
+ {
+ return "";
+ }
+
+ /**
+ * Compile the else-if statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileElseif($expression)
+ {
+ return "";
+ }
+
+ /**
+ * Compile the else statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileElse()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the end-if statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndif()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the end-unless statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndunless()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the if-isset statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileIsset($expression)
+ {
+ return "";
+ }
+
+ /**
+ * Compile the end-isset statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndIsset()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the switch statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileSwitch($expression)
+ {
+ $this->firstCaseInSwitch = true;
+
+ return "firstCaseInSwitch) {
+ $this->firstCaseInSwitch = false;
+
+ return "case {$expression}: ?>";
+ }
+
+ return "";
+ }
+
+ /**
+ * Compile the default statements in switch case into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileDefault()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the end switch statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndSwitch()
+ {
+ return '';
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesEchos.php b/vendor/illuminate/view/Compilers/Concerns/CompilesEchos.php
new file mode 100644
index 0000000..018f90b
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesEchos.php
@@ -0,0 +1,105 @@
+getEchoMethods() as $method) {
+ $value = $this->$method($value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Get the echo methods in the proper order for compilation.
+ *
+ * @return array
+ */
+ protected function getEchoMethods()
+ {
+ return [
+ 'compileRawEchos',
+ 'compileEscapedEchos',
+ 'compileRegularEchos',
+ ];
+ }
+
+ /**
+ * Compile the "raw" echo statements.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRawEchos($value)
+ {
+ $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->rawTags[0], $this->rawTags[1]);
+
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
+
+ return $matches[1] ? substr($matches[0], 1) : "compileEchoDefaults($matches[2])}; ?>{$whitespace}";
+ };
+
+ return preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the "regular" echo statements.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileRegularEchos($value)
+ {
+ $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->contentTags[0], $this->contentTags[1]);
+
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
+
+ $wrapped = sprintf($this->echoFormat, $this->compileEchoDefaults($matches[2]));
+
+ return $matches[1] ? substr($matches[0], 1) : "{$whitespace}";
+ };
+
+ return preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the escaped echo statements.
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function compileEscapedEchos($value)
+ {
+ $pattern = sprintf('/(@)?%s\s*(.+?)\s*%s(\r?\n)?/s', $this->escapedTags[0], $this->escapedTags[1]);
+
+ $callback = function ($matches) {
+ $whitespace = empty($matches[3]) ? '' : $matches[3].$matches[3];
+
+ return $matches[1] ? $matches[0] : "compileEchoDefaults($matches[2])}); ?>{$whitespace}";
+ };
+
+ return preg_replace_callback($pattern, $callback, $value);
+ }
+
+ /**
+ * Compile the default values for the echo statement.
+ *
+ * @param string $value
+ * @return string
+ */
+ public function compileEchoDefaults($value)
+ {
+ return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/si', 'isset($1) ? $1 : $2', $value);
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesIncludes.php b/vendor/illuminate/view/Compilers/Concerns/CompilesIncludes.php
new file mode 100644
index 0000000..417d4ef
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesIncludes.php
@@ -0,0 +1,69 @@
+renderEach{$expression}; ?>";
+ }
+
+ /**
+ * Compile the include statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileInclude($expression)
+ {
+ $expression = $this->stripParentheses($expression);
+
+ return "make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
+ }
+
+ /**
+ * Compile the include-if statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileIncludeIf($expression)
+ {
+ $expression = $this->stripParentheses($expression);
+
+ return "exists({$expression})) echo \$__env->make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
+ }
+
+ /**
+ * Compile the include-when statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileIncludeWhen($expression)
+ {
+ $expression = $this->stripParentheses($expression);
+
+ return "renderWhen($expression, array_except(get_defined_vars(), array('__data', '__path'))); ?>";
+ }
+
+ /**
+ * Compile the include-first statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileIncludeFirst($expression)
+ {
+ $expression = $this->stripParentheses($expression);
+
+ return "first({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesInjections.php b/vendor/illuminate/view/Compilers/Concerns/CompilesInjections.php
new file mode 100644
index 0000000..c295bcd
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesInjections.php
@@ -0,0 +1,23 @@
+";
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesJson.php b/vendor/illuminate/view/Compilers/Concerns/CompilesJson.php
new file mode 100644
index 0000000..cf343e9
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesJson.php
@@ -0,0 +1,30 @@
+stripParentheses($expression));
+
+ $options = isset($parts[1]) ? trim($parts[1]) : $this->encodingOptions;
+
+ $depth = isset($parts[2]) ? trim($parts[2]) : 512;
+
+ return "";
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesLayouts.php b/vendor/illuminate/view/Compilers/Concerns/CompilesLayouts.php
new file mode 100644
index 0000000..329a705
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesLayouts.php
@@ -0,0 +1,116 @@
+stripParentheses($expression);
+
+ $echo = "make({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
+
+ $this->footer[] = $echo;
+
+ return '';
+ }
+
+ /**
+ * Compile the section statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileSection($expression)
+ {
+ $this->lastSection = trim($expression, "()'\" ");
+
+ return "startSection{$expression}; ?>";
+ }
+
+ /**
+ * Replace the @parent directive to a placeholder.
+ *
+ * @return string
+ */
+ protected function compileParent()
+ {
+ return ViewFactory::parentPlaceholder($this->lastSection ?: '');
+ }
+
+ /**
+ * Compile the yield statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileYield($expression)
+ {
+ return "yieldContent{$expression}; ?>";
+ }
+
+ /**
+ * Compile the show statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileShow()
+ {
+ return 'yieldSection(); ?>';
+ }
+
+ /**
+ * Compile the append statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileAppend()
+ {
+ return 'appendSection(); ?>';
+ }
+
+ /**
+ * Compile the overwrite statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileOverwrite()
+ {
+ return 'stopSection(true); ?>';
+ }
+
+ /**
+ * Compile the stop statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileStop()
+ {
+ return 'stopSection(); ?>';
+ }
+
+ /**
+ * Compile the end-section statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndsection()
+ {
+ return 'stopSection(); ?>';
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesLoops.php b/vendor/illuminate/view/Compilers/Concerns/CompilesLoops.php
new file mode 100644
index 0000000..9f64c4f
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesLoops.php
@@ -0,0 +1,180 @@
+forElseCounter;
+
+ preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
+
+ $iteratee = trim($matches[1]);
+
+ $iteration = trim($matches[2]);
+
+ $initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
+
+ $iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';
+
+ return "";
+ }
+
+ /**
+ * Compile the for-else-empty and empty statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileEmpty($expression)
+ {
+ if ($expression) {
+ return "";
+ }
+
+ $empty = '$__empty_'.$this->forElseCounter--;
+
+ return "popLoop(); \$loop = \$__env->getLastLoop(); if ({$empty}): ?>";
+ }
+
+ /**
+ * Compile the end-for-else statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndforelse()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the end-empty statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndEmpty()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the for statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileFor($expression)
+ {
+ return "";
+ }
+
+ /**
+ * Compile the for-each statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileForeach($expression)
+ {
+ preg_match('/\( *(.*) +as *(.*)\)$/is', $expression, $matches);
+
+ $iteratee = trim($matches[1]);
+
+ $iteration = trim($matches[2]);
+
+ $initLoop = "\$__currentLoopData = {$iteratee}; \$__env->addLoop(\$__currentLoopData);";
+
+ $iterateLoop = '$__env->incrementLoopIndices(); $loop = $__env->getLastLoop();';
+
+ return "";
+ }
+
+ /**
+ * Compile the break statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileBreak($expression)
+ {
+ if ($expression) {
+ preg_match('/\(\s*(-?\d+)\s*\)$/', $expression, $matches);
+
+ return $matches ? '' : "";
+ }
+
+ return '';
+ }
+
+ /**
+ * Compile the continue statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileContinue($expression)
+ {
+ if ($expression) {
+ preg_match('/\(\s*(-?\d+)\s*\)$/', $expression, $matches);
+
+ return $matches ? '' : "";
+ }
+
+ return '';
+ }
+
+ /**
+ * Compile the end-for statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndfor()
+ {
+ return '';
+ }
+
+ /**
+ * Compile the end-for-each statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndforeach()
+ {
+ return 'popLoop(); $loop = $__env->getLastLoop(); ?>';
+ }
+
+ /**
+ * Compile the while statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileWhile($expression)
+ {
+ return "";
+ }
+
+ /**
+ * Compile the end-while statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndwhile()
+ {
+ return '';
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesRawPhp.php b/vendor/illuminate/view/Compilers/Concerns/CompilesRawPhp.php
new file mode 100644
index 0000000..41c7edf
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesRawPhp.php
@@ -0,0 +1,32 @@
+";
+ }
+
+ return '@php';
+ }
+
+ /**
+ * Compile the unset statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileUnset($expression)
+ {
+ return "";
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesStacks.php b/vendor/illuminate/view/Compilers/Concerns/CompilesStacks.php
new file mode 100644
index 0000000..79a380e
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesStacks.php
@@ -0,0 +1,59 @@
+yieldPushContent{$expression}; ?>";
+ }
+
+ /**
+ * Compile the push statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compilePush($expression)
+ {
+ return "startPush{$expression}; ?>";
+ }
+
+ /**
+ * Compile the end-push statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndpush()
+ {
+ return 'stopPush(); ?>';
+ }
+
+ /**
+ * Compile the prepend statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compilePrepend($expression)
+ {
+ return "startPrepend{$expression}; ?>";
+ }
+
+ /**
+ * Compile the end-prepend statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndprepend()
+ {
+ return 'stopPrepend(); ?>';
+ }
+}
diff --git a/vendor/illuminate/view/Compilers/Concerns/CompilesTranslations.php b/vendor/illuminate/view/Compilers/Concerns/CompilesTranslations.php
new file mode 100644
index 0000000..feb7e65
--- /dev/null
+++ b/vendor/illuminate/view/Compilers/Concerns/CompilesTranslations.php
@@ -0,0 +1,44 @@
+startTranslation(); ?>';
+ } elseif ($expression[1] === '[') {
+ return "startTranslation{$expression}; ?>";
+ }
+
+ return "getFromJson{$expression}; ?>";
+ }
+
+ /**
+ * Compile the end-lang statements into valid PHP.
+ *
+ * @return string
+ */
+ protected function compileEndlang()
+ {
+ return 'renderTranslation(); ?>';
+ }
+
+ /**
+ * Compile the choice statements into valid PHP.
+ *
+ * @param string $expression
+ * @return string
+ */
+ protected function compileChoice($expression)
+ {
+ return "choice{$expression}; ?>";
+ }
+}
diff --git a/vendor/illuminate/view/Concerns/ManagesComponents.php b/vendor/illuminate/view/Concerns/ManagesComponents.php
new file mode 100644
index 0000000..d523f7e
--- /dev/null
+++ b/vendor/illuminate/view/Concerns/ManagesComponents.php
@@ -0,0 +1,128 @@
+componentStack[] = $name;
+
+ $this->componentData[$this->currentComponent()] = $data;
+
+ $this->slots[$this->currentComponent()] = [];
+ }
+ }
+
+ /**
+ * Render the current component.
+ *
+ * @return string
+ */
+ public function renderComponent()
+ {
+ $name = array_pop($this->componentStack);
+
+ return $this->make($name, $this->componentData($name))->render();
+ }
+
+ /**
+ * Get the data for the given component.
+ *
+ * @param string $name
+ * @return array
+ */
+ protected function componentData($name)
+ {
+ return array_merge(
+ $this->componentData[count($this->componentStack)],
+ ['slot' => new HtmlString(trim(ob_get_clean()))],
+ $this->slots[count($this->componentStack)]
+ );
+ }
+
+ /**
+ * Start the slot rendering process.
+ *
+ * @param string $name
+ * @param string|null $content
+ * @return void
+ */
+ public function slot($name, $content = null)
+ {
+ if (count(func_get_args()) == 2) {
+ $this->slots[$this->currentComponent()][$name] = $content;
+ } else {
+ if (ob_start()) {
+ $this->slots[$this->currentComponent()][$name] = '';
+
+ $this->slotStack[$this->currentComponent()][] = $name;
+ }
+ }
+ }
+
+ /**
+ * Save the slot content for rendering.
+ *
+ * @return void
+ */
+ public function endSlot()
+ {
+ last($this->componentStack);
+
+ $currentSlot = array_pop(
+ $this->slotStack[$this->currentComponent()]
+ );
+
+ $this->slots[$this->currentComponent()]
+ [$currentSlot] = new HtmlString(trim(ob_get_clean()));
+ }
+
+ /**
+ * Get the index for the current component.
+ *
+ * @return int
+ */
+ protected function currentComponent()
+ {
+ return count($this->componentStack) - 1;
+ }
+}
diff --git a/vendor/illuminate/view/Concerns/ManagesEvents.php b/vendor/illuminate/view/Concerns/ManagesEvents.php
new file mode 100644
index 0000000..f3d7717
--- /dev/null
+++ b/vendor/illuminate/view/Concerns/ManagesEvents.php
@@ -0,0 +1,192 @@
+addViewEvent($view, $callback, 'creating: ');
+ }
+
+ return $creators;
+ }
+
+ /**
+ * Register multiple view composers via an array.
+ *
+ * @param array $composers
+ * @return array
+ */
+ public function composers(array $composers)
+ {
+ $registered = [];
+
+ foreach ($composers as $callback => $views) {
+ $registered = array_merge($registered, $this->composer($views, $callback));
+ }
+
+ return $registered;
+ }
+
+ /**
+ * Register a view composer event.
+ *
+ * @param array|string $views
+ * @param \Closure|string $callback
+ * @return array
+ */
+ public function composer($views, $callback)
+ {
+ $composers = [];
+
+ foreach ((array) $views as $view) {
+ $composers[] = $this->addViewEvent($view, $callback, 'composing: ');
+ }
+
+ return $composers;
+ }
+
+ /**
+ * Add an event for a given view.
+ *
+ * @param string $view
+ * @param \Closure|string $callback
+ * @param string $prefix
+ * @return \Closure|null
+ */
+ protected function addViewEvent($view, $callback, $prefix = 'composing: ')
+ {
+ $view = $this->normalizeName($view);
+
+ if ($callback instanceof Closure) {
+ $this->addEventListener($prefix.$view, $callback);
+
+ return $callback;
+ } elseif (is_string($callback)) {
+ return $this->addClassEvent($view, $callback, $prefix);
+ }
+ }
+
+ /**
+ * Register a class based view composer.
+ *
+ * @param string $view
+ * @param string $class
+ * @param string $prefix
+ * @return \Closure
+ */
+ protected function addClassEvent($view, $class, $prefix)
+ {
+ $name = $prefix.$view;
+
+ // When registering a class based view "composer", we will simply resolve the
+ // classes from the application IoC container then call the compose method
+ // on the instance. This allows for convenient, testable view composers.
+ $callback = $this->buildClassEventCallback(
+ $class, $prefix
+ );
+
+ $this->addEventListener($name, $callback);
+
+ return $callback;
+ }
+
+ /**
+ * Build a class based container callback Closure.
+ *
+ * @param string $class
+ * @param string $prefix
+ * @return \Closure
+ */
+ protected function buildClassEventCallback($class, $prefix)
+ {
+ list($class, $method) = $this->parseClassEvent($class, $prefix);
+
+ // Once we have the class and method name, we can build the Closure to resolve
+ // the instance out of the IoC container and call the method on it with the
+ // given arguments that are passed to the Closure as the composer's data.
+ return function () use ($class, $method) {
+ return call_user_func_array(
+ [$this->container->make($class), $method], func_get_args()
+ );
+ };
+ }
+
+ /**
+ * Parse a class based composer name.
+ *
+ * @param string $class
+ * @param string $prefix
+ * @return array
+ */
+ protected function parseClassEvent($class, $prefix)
+ {
+ return Str::parseCallback($class, $this->classEventMethodForPrefix($prefix));
+ }
+
+ /**
+ * Determine the class event method based on the given prefix.
+ *
+ * @param string $prefix
+ * @return string
+ */
+ protected function classEventMethodForPrefix($prefix)
+ {
+ return Str::contains($prefix, 'composing') ? 'compose' : 'create';
+ }
+
+ /**
+ * Add a listener to the event dispatcher.
+ *
+ * @param string $name
+ * @param \Closure $callback
+ * @return void
+ */
+ protected function addEventListener($name, $callback)
+ {
+ if (Str::contains($name, '*')) {
+ $callback = function ($name, array $data) use ($callback) {
+ return $callback($data[0]);
+ };
+ }
+
+ $this->events->listen($name, $callback);
+ }
+
+ /**
+ * Call the composer for a given view.
+ *
+ * @param \Illuminate\Contracts\View\View $view
+ * @return void
+ */
+ public function callComposer(ViewContract $view)
+ {
+ $this->events->dispatch('composing: '.$view->name(), [$view]);
+ }
+
+ /**
+ * Call the creator for a given view.
+ *
+ * @param \Illuminate\Contracts\View\View $view
+ * @return void
+ */
+ public function callCreator(ViewContract $view)
+ {
+ $this->events->dispatch('creating: '.$view->name(), [$view]);
+ }
+}
diff --git a/vendor/illuminate/view/Concerns/ManagesLayouts.php b/vendor/illuminate/view/Concerns/ManagesLayouts.php
new file mode 100644
index 0000000..6f492d1
--- /dev/null
+++ b/vendor/illuminate/view/Concerns/ManagesLayouts.php
@@ -0,0 +1,218 @@
+sectionStack[] = $section;
+ }
+ } else {
+ $this->extendSection($section, $content instanceof View ? $content : e($content));
+ }
+ }
+
+ /**
+ * Inject inline content into a section.
+ *
+ * @param string $section
+ * @param string $content
+ * @return void
+ */
+ public function inject($section, $content)
+ {
+ $this->startSection($section, $content);
+ }
+
+ /**
+ * Stop injecting content into a section and return its contents.
+ *
+ * @return string
+ */
+ public function yieldSection()
+ {
+ if (empty($this->sectionStack)) {
+ return '';
+ }
+
+ return $this->yieldContent($this->stopSection());
+ }
+
+ /**
+ * Stop injecting content into a section.
+ *
+ * @param bool $overwrite
+ * @return string
+ * @throws \InvalidArgumentException
+ */
+ public function stopSection($overwrite = false)
+ {
+ if (empty($this->sectionStack)) {
+ throw new InvalidArgumentException('Cannot end a section without first starting one.');
+ }
+
+ $last = array_pop($this->sectionStack);
+
+ if ($overwrite) {
+ $this->sections[$last] = ob_get_clean();
+ } else {
+ $this->extendSection($last, ob_get_clean());
+ }
+
+ return $last;
+ }
+
+ /**
+ * Stop injecting content into a section and append it.
+ *
+ * @return string
+ * @throws \InvalidArgumentException
+ */
+ public function appendSection()
+ {
+ if (empty($this->sectionStack)) {
+ throw new InvalidArgumentException('Cannot end a section without first starting one.');
+ }
+
+ $last = array_pop($this->sectionStack);
+
+ if (isset($this->sections[$last])) {
+ $this->sections[$last] .= ob_get_clean();
+ } else {
+ $this->sections[$last] = ob_get_clean();
+ }
+
+ return $last;
+ }
+
+ /**
+ * Append content to a given section.
+ *
+ * @param string $section
+ * @param string $content
+ * @return void
+ */
+ protected function extendSection($section, $content)
+ {
+ if (isset($this->sections[$section])) {
+ $content = str_replace(static::parentPlaceholder($section), $content, $this->sections[$section]);
+ }
+
+ $this->sections[$section] = $content;
+ }
+
+ /**
+ * Get the string contents of a section.
+ *
+ * @param string $section
+ * @param string $default
+ * @return string
+ */
+ public function yieldContent($section, $default = '')
+ {
+ $sectionContent = $default instanceof View ? $default : e($default);
+
+ if (isset($this->sections[$section])) {
+ $sectionContent = $this->sections[$section];
+ }
+
+ $sectionContent = str_replace('@@parent', '--parent--holder--', $sectionContent);
+
+ return str_replace(
+ '--parent--holder--', '@parent', str_replace(static::parentPlaceholder($section), '', $sectionContent)
+ );
+ }
+
+ /**
+ * Get the parent placeholder for the current request.
+ *
+ * @param string $section
+ * @return string
+ */
+ public static function parentPlaceholder($section = '')
+ {
+ if (! isset(static::$parentPlaceholder[$section])) {
+ static::$parentPlaceholder[$section] = '##parent-placeholder-'.sha1($section).'##';
+ }
+
+ return static::$parentPlaceholder[$section];
+ }
+
+ /**
+ * Check if section exists.
+ *
+ * @param string $name
+ * @return bool
+ */
+ public function hasSection($name)
+ {
+ return array_key_exists($name, $this->sections);
+ }
+
+ /**
+ * Get the contents of a section.
+ *
+ * @param string $name
+ * @param string $default
+ * @return mixed
+ */
+ public function getSection($name, $default = null)
+ {
+ return $this->getSections()[$name] ?? $default;
+ }
+
+ /**
+ * Get the entire array of sections.
+ *
+ * @return array
+ */
+ public function getSections()
+ {
+ return $this->sections;
+ }
+
+ /**
+ * Flush all of the sections.
+ *
+ * @return void
+ */
+ public function flushSections()
+ {
+ $this->sections = [];
+ $this->sectionStack = [];
+ }
+}
diff --git a/vendor/illuminate/view/Concerns/ManagesLoops.php b/vendor/illuminate/view/Concerns/ManagesLoops.php
new file mode 100644
index 0000000..5f50b24
--- /dev/null
+++ b/vendor/illuminate/view/Concerns/ManagesLoops.php
@@ -0,0 +1,90 @@
+loopsStack);
+
+ $this->loopsStack[] = [
+ 'iteration' => 0,
+ 'index' => 0,
+ 'remaining' => $length ?? null,
+ 'count' => $length,
+ 'first' => true,
+ 'last' => isset($length) ? $length == 1 : null,
+ 'depth' => count($this->loopsStack) + 1,
+ 'parent' => $parent ? (object) $parent : null,
+ ];
+ }
+
+ /**
+ * Increment the top loop's indices.
+ *
+ * @return void
+ */
+ public function incrementLoopIndices()
+ {
+ $loop = $this->loopsStack[$index = count($this->loopsStack) - 1];
+
+ $this->loopsStack[$index] = array_merge($this->loopsStack[$index], [
+ 'iteration' => $loop['iteration'] + 1,
+ 'index' => $loop['iteration'],
+ 'first' => $loop['iteration'] == 0,
+ 'remaining' => isset($loop['count']) ? $loop['remaining'] - 1 : null,
+ 'last' => isset($loop['count']) ? $loop['iteration'] == $loop['count'] - 1 : null,
+ ]);
+ }
+
+ /**
+ * Pop a loop from the top of the loop stack.
+ *
+ * @return void
+ */
+ public function popLoop()
+ {
+ array_pop($this->loopsStack);
+ }
+
+ /**
+ * Get an instance of the last loop in the stack.
+ *
+ * @return \stdClass|null
+ */
+ public function getLastLoop()
+ {
+ if ($last = Arr::last($this->loopsStack)) {
+ return (object) $last;
+ }
+ }
+
+ /**
+ * Get the entire loop stack.
+ *
+ * @return array
+ */
+ public function getLoopStack()
+ {
+ return $this->loopsStack;
+ }
+}
diff --git a/vendor/illuminate/view/Concerns/ManagesStacks.php b/vendor/illuminate/view/Concerns/ManagesStacks.php
new file mode 100644
index 0000000..53af024
--- /dev/null
+++ b/vendor/illuminate/view/Concerns/ManagesStacks.php
@@ -0,0 +1,177 @@
+pushStack[] = $section;
+ }
+ } else {
+ $this->extendPush($section, $content);
+ }
+ }
+
+ /**
+ * Stop injecting content into a push section.
+ *
+ * @return string
+ * @throws \InvalidArgumentException
+ */
+ public function stopPush()
+ {
+ if (empty($this->pushStack)) {
+ throw new InvalidArgumentException('Cannot end a push stack without first starting one.');
+ }
+
+ return tap(array_pop($this->pushStack), function ($last) {
+ $this->extendPush($last, ob_get_clean());
+ });
+ }
+
+ /**
+ * Append content to a given push section.
+ *
+ * @param string $section
+ * @param string $content
+ * @return void
+ */
+ protected function extendPush($section, $content)
+ {
+ if (! isset($this->pushes[$section])) {
+ $this->pushes[$section] = [];
+ }
+
+ if (! isset($this->pushes[$section][$this->renderCount])) {
+ $this->pushes[$section][$this->renderCount] = $content;
+ } else {
+ $this->pushes[$section][$this->renderCount] .= $content;
+ }
+ }
+
+ /**
+ * Start prepending content into a push section.
+ *
+ * @param string $section
+ * @param string $content
+ * @return void
+ */
+ public function startPrepend($section, $content = '')
+ {
+ if ($content === '') {
+ if (ob_start()) {
+ $this->pushStack[] = $section;
+ }
+ } else {
+ $this->extendPrepend($section, $content);
+ }
+ }
+
+ /**
+ * Stop prepending content into a push section.
+ *
+ * @return string
+ * @throws \InvalidArgumentException
+ */
+ public function stopPrepend()
+ {
+ if (empty($this->pushStack)) {
+ throw new InvalidArgumentException('Cannot end a prepend operation without first starting one.');
+ }
+
+ return tap(array_pop($this->pushStack), function ($last) {
+ $this->extendPrepend($last, ob_get_clean());
+ });
+ }
+
+ /**
+ * Prepend content to a given stack.
+ *
+ * @param string $section
+ * @param string $content
+ * @return void
+ */
+ protected function extendPrepend($section, $content)
+ {
+ if (! isset($this->prepends[$section])) {
+ $this->prepends[$section] = [];
+ }
+
+ if (! isset($this->prepends[$section][$this->renderCount])) {
+ $this->prepends[$section][$this->renderCount] = $content;
+ } else {
+ $this->prepends[$section][$this->renderCount] = $content.$this->prepends[$section][$this->renderCount];
+ }
+ }
+
+ /**
+ * Get the string contents of a push section.
+ *
+ * @param string $section
+ * @param string $default
+ * @return string
+ */
+ public function yieldPushContent($section, $default = '')
+ {
+ if (! isset($this->pushes[$section]) && ! isset($this->prepends[$section])) {
+ return $default;
+ }
+
+ $output = '';
+
+ if (isset($this->prepends[$section])) {
+ $output .= implode(array_reverse($this->prepends[$section]));
+ }
+
+ if (isset($this->pushes[$section])) {
+ $output .= implode($this->pushes[$section]);
+ }
+
+ return $output;
+ }
+
+ /**
+ * Flush all of the stacks.
+ *
+ * @return void
+ */
+ public function flushStacks()
+ {
+ $this->pushes = [];
+ $this->prepends = [];
+ $this->pushStack = [];
+ }
+}
diff --git a/vendor/illuminate/view/Concerns/ManagesTranslations.php b/vendor/illuminate/view/Concerns/ManagesTranslations.php
new file mode 100644
index 0000000..841c3fe
--- /dev/null
+++ b/vendor/illuminate/view/Concerns/ManagesTranslations.php
@@ -0,0 +1,38 @@
+translationReplacements = $replacements;
+ }
+
+ /**
+ * Render the current translation.
+ *
+ * @return string
+ */
+ public function renderTranslation()
+ {
+ return $this->container->make('translator')->getFromJson(
+ trim(ob_get_clean()), $this->translationReplacements
+ );
+ }
+}
diff --git a/vendor/illuminate/view/Engines/CompilerEngine.php b/vendor/illuminate/view/Engines/CompilerEngine.php
new file mode 100644
index 0000000..2f7f84b
--- /dev/null
+++ b/vendor/illuminate/view/Engines/CompilerEngine.php
@@ -0,0 +1,102 @@
+compiler = $compiler;
+ }
+
+ /**
+ * Get the evaluated contents of the view.
+ *
+ * @param string $path
+ * @param array $data
+ * @return string
+ */
+ public function get($path, array $data = [])
+ {
+ $this->lastCompiled[] = $path;
+
+ // If this given view has expired, which means it has simply been edited since
+ // it was last compiled, we will re-compile the views so we can evaluate a
+ // fresh copy of the view. We'll pass the compiler the path of the view.
+ if ($this->compiler->isExpired($path)) {
+ $this->compiler->compile($path);
+ }
+
+ $compiled = $this->compiler->getCompiledPath($path);
+
+ // Once we have the path to the compiled file, we will evaluate the paths with
+ // typical PHP just like any other templates. We also keep a stack of views
+ // which have been rendered for right exception messages to be generated.
+ $results = $this->evaluatePath($compiled, $data);
+
+ array_pop($this->lastCompiled);
+
+ return $results;
+ }
+
+ /**
+ * Handle a view exception.
+ *
+ * @param \Exception $e
+ * @param int $obLevel
+ * @return void
+ *
+ * @throws \Exception
+ */
+ protected function handleViewException(Exception $e, $obLevel)
+ {
+ $e = new ErrorException($this->getMessage($e), 0, 1, $e->getFile(), $e->getLine(), $e);
+
+ parent::handleViewException($e, $obLevel);
+ }
+
+ /**
+ * Get the exception message for an exception.
+ *
+ * @param \Exception $e
+ * @return string
+ */
+ protected function getMessage(Exception $e)
+ {
+ return $e->getMessage().' (View: '.realpath(last($this->lastCompiled)).')';
+ }
+
+ /**
+ * Get the compiler implementation.
+ *
+ * @return \Illuminate\View\Compilers\CompilerInterface
+ */
+ public function getCompiler()
+ {
+ return $this->compiler;
+ }
+}
diff --git a/vendor/illuminate/view/Engines/Engine.php b/vendor/illuminate/view/Engines/Engine.php
new file mode 100644
index 0000000..bf5c748
--- /dev/null
+++ b/vendor/illuminate/view/Engines/Engine.php
@@ -0,0 +1,23 @@
+lastRendered;
+ }
+}
diff --git a/vendor/illuminate/view/Engines/EngineResolver.php b/vendor/illuminate/view/Engines/EngineResolver.php
new file mode 100644
index 0000000..b6abb68
--- /dev/null
+++ b/vendor/illuminate/view/Engines/EngineResolver.php
@@ -0,0 +1,59 @@
+resolved[$engine]);
+
+ $this->resolvers[$engine] = $resolver;
+ }
+
+ /**
+ * Resolve an engine instance by name.
+ *
+ * @param string $engine
+ * @return \Illuminate\Contracts\View\Engine
+ * @throws \InvalidArgumentException
+ */
+ public function resolve($engine)
+ {
+ if (isset($this->resolved[$engine])) {
+ return $this->resolved[$engine];
+ }
+
+ if (isset($this->resolvers[$engine])) {
+ return $this->resolved[$engine] = call_user_func($this->resolvers[$engine]);
+ }
+
+ throw new InvalidArgumentException("Engine $engine not found.");
+ }
+}
diff --git a/vendor/illuminate/view/Engines/FileEngine.php b/vendor/illuminate/view/Engines/FileEngine.php
new file mode 100644
index 0000000..360b543
--- /dev/null
+++ b/vendor/illuminate/view/Engines/FileEngine.php
@@ -0,0 +1,20 @@
+evaluatePath($path, $data);
+ }
+
+ /**
+ * Get the evaluated contents of the view at the given path.
+ *
+ * @param string $__path
+ * @param array $__data
+ * @return string
+ */
+ protected function evaluatePath($__path, $__data)
+ {
+ $obLevel = ob_get_level();
+
+ ob_start();
+
+ extract($__data, EXTR_SKIP);
+
+ // We'll evaluate the contents of the view inside a try/catch block so we can
+ // flush out any stray output that might get out before an error occurs or
+ // an exception is thrown. This prevents any partial views from leaking.
+ try {
+ include $__path;
+ } catch (Exception $e) {
+ $this->handleViewException($e, $obLevel);
+ } catch (Throwable $e) {
+ $this->handleViewException(new FatalThrowableError($e), $obLevel);
+ }
+
+ return ltrim(ob_get_clean());
+ }
+
+ /**
+ * Handle a view exception.
+ *
+ * @param \Exception $e
+ * @param int $obLevel
+ * @return void
+ *
+ * @throws \Exception
+ */
+ protected function handleViewException(Exception $e, $obLevel)
+ {
+ while (ob_get_level() > $obLevel) {
+ ob_end_clean();
+ }
+
+ throw $e;
+ }
+}
diff --git a/vendor/illuminate/view/Factory.php b/vendor/illuminate/view/Factory.php
new file mode 100644
index 0000000..2b11ec5
--- /dev/null
+++ b/vendor/illuminate/view/Factory.php
@@ -0,0 +1,563 @@
+ 'blade',
+ 'php' => 'php',
+ 'css' => 'file',
+ ];
+
+ /**
+ * The view composer events.
+ *
+ * @var array
+ */
+ protected $composers = [];
+
+ /**
+ * The number of active rendering operations.
+ *
+ * @var int
+ */
+ protected $renderCount = 0;
+
+ /**
+ * Create a new view factory instance.
+ *
+ * @param \Illuminate\View\Engines\EngineResolver $engines
+ * @param \Illuminate\View\ViewFinderInterface $finder
+ * @param \Illuminate\Contracts\Events\Dispatcher $events
+ * @return void
+ */
+ public function __construct(EngineResolver $engines, ViewFinderInterface $finder, Dispatcher $events)
+ {
+ $this->finder = $finder;
+ $this->events = $events;
+ $this->engines = $engines;
+
+ $this->share('__env', $this);
+ }
+
+ /**
+ * Get the evaluated view contents for the given view.
+ *
+ * @param string $path
+ * @param array $data
+ * @param array $mergeData
+ * @return \Illuminate\Contracts\View\View
+ */
+ public function file($path, $data = [], $mergeData = [])
+ {
+ $data = array_merge($mergeData, $this->parseData($data));
+
+ return tap($this->viewInstance($path, $path, $data), function ($view) {
+ $this->callCreator($view);
+ });
+ }
+
+ /**
+ * Get the evaluated view contents for the given view.
+ *
+ * @param string $view
+ * @param array $data
+ * @param array $mergeData
+ * @return \Illuminate\Contracts\View\View
+ */
+ public function make($view, $data = [], $mergeData = [])
+ {
+ $path = $this->finder->find(
+ $view = $this->normalizeName($view)
+ );
+
+ // Next, we will create the view instance and call the view creator for the view
+ // which can set any data, etc. Then we will return the view instance back to
+ // the caller for rendering or performing other view manipulations on this.
+ $data = array_merge($mergeData, $this->parseData($data));
+
+ return tap($this->viewInstance($view, $path, $data), function ($view) {
+ $this->callCreator($view);
+ });
+ }
+
+ /**
+ * Get the first view that actually exists from the given list.
+ *
+ * @param array $views
+ * @param array $data
+ * @param array $mergeData
+ * @return \Illuminate\Contracts\View\View
+ */
+ public function first(array $views, $data = [], $mergeData = [])
+ {
+ $view = collect($views)->first(function ($view) {
+ return $this->exists($view);
+ });
+
+ if (! $view) {
+ throw new InvalidArgumentException('None of the views in the given array exist.');
+ }
+
+ return $this->make($view, $data, $mergeData);
+ }
+
+ /**
+ * Get the rendered content of the view based on a given condition.
+ *
+ * @param bool $condition
+ * @param string $view
+ * @param array $data
+ * @param array $mergeData
+ * @return string
+ */
+ public function renderWhen($condition, $view, $data = [], $mergeData = [])
+ {
+ if (! $condition) {
+ return '';
+ }
+
+ return $this->make($view, $this->parseData($data), $mergeData)->render();
+ }
+
+ /**
+ * Get the rendered contents of a partial from a loop.
+ *
+ * @param string $view
+ * @param array $data
+ * @param string $iterator
+ * @param string $empty
+ * @return string
+ */
+ public function renderEach($view, $data, $iterator, $empty = 'raw|')
+ {
+ $result = '';
+
+ // If is actually data in the array, we will loop through the data and append
+ // an instance of the partial view to the final result HTML passing in the
+ // iterated value of this data array, allowing the views to access them.
+ if (count($data) > 0) {
+ foreach ($data as $key => $value) {
+ $result .= $this->make(
+ $view, ['key' => $key, $iterator => $value]
+ )->render();
+ }
+ }
+
+ // If there is no data in the array, we will render the contents of the empty
+ // view. Alternatively, the "empty view" could be a raw string that begins
+ // with "raw|" for convenience and to let this know that it is a string.
+ else {
+ $result = Str::startsWith($empty, 'raw|')
+ ? substr($empty, 4)
+ : $this->make($empty)->render();
+ }
+
+ return $result;
+ }
+
+ /**
+ * Normalize a view name.
+ *
+ * @param string $name
+ * @return string
+ */
+ protected function normalizeName($name)
+ {
+ return ViewName::normalize($name);
+ }
+
+ /**
+ * Parse the given data into a raw array.
+ *
+ * @param mixed $data
+ * @return array
+ */
+ protected function parseData($data)
+ {
+ return $data instanceof Arrayable ? $data->toArray() : $data;
+ }
+
+ /**
+ * Create a new view instance from the given arguments.
+ *
+ * @param string $view
+ * @param string $path
+ * @param array $data
+ * @return \Illuminate\Contracts\View\View
+ */
+ protected function viewInstance($view, $path, $data)
+ {
+ return new View($this, $this->getEngineFromPath($path), $view, $path, $data);
+ }
+
+ /**
+ * Determine if a given view exists.
+ *
+ * @param string $view
+ * @return bool
+ */
+ public function exists($view)
+ {
+ try {
+ $this->finder->find($view);
+ } catch (InvalidArgumentException $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the appropriate view engine for the given path.
+ *
+ * @param string $path
+ * @return \Illuminate\Contracts\View\Engine
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function getEngineFromPath($path)
+ {
+ if (! $extension = $this->getExtension($path)) {
+ throw new InvalidArgumentException("Unrecognized extension in file: $path");
+ }
+
+ $engine = $this->extensions[$extension];
+
+ return $this->engines->resolve($engine);
+ }
+
+ /**
+ * Get the extension used by the view file.
+ *
+ * @param string $path
+ * @return string
+ */
+ protected function getExtension($path)
+ {
+ $extensions = array_keys($this->extensions);
+
+ return Arr::first($extensions, function ($value) use ($path) {
+ return Str::endsWith($path, '.'.$value);
+ });
+ }
+
+ /**
+ * Add a piece of shared data to the environment.
+ *
+ * @param array|string $key
+ * @param mixed $value
+ * @return mixed
+ */
+ public function share($key, $value = null)
+ {
+ $keys = is_array($key) ? $key : [$key => $value];
+
+ foreach ($keys as $key => $value) {
+ $this->shared[$key] = $value;
+ }
+
+ return $value;
+ }
+
+ /**
+ * Increment the rendering counter.
+ *
+ * @return void
+ */
+ public function incrementRender()
+ {
+ $this->renderCount++;
+ }
+
+ /**
+ * Decrement the rendering counter.
+ *
+ * @return void
+ */
+ public function decrementRender()
+ {
+ $this->renderCount--;
+ }
+
+ /**
+ * Check if there are no active render operations.
+ *
+ * @return bool
+ */
+ public function doneRendering()
+ {
+ return $this->renderCount == 0;
+ }
+
+ /**
+ * Add a location to the array of view locations.
+ *
+ * @param string $location
+ * @return void
+ */
+ public function addLocation($location)
+ {
+ $this->finder->addLocation($location);
+ }
+
+ /**
+ * Add a new namespace to the loader.
+ *
+ * @param string $namespace
+ * @param string|array $hints
+ * @return $this
+ */
+ public function addNamespace($namespace, $hints)
+ {
+ $this->finder->addNamespace($namespace, $hints);
+
+ return $this;
+ }
+
+ /**
+ * Prepend a new namespace to the loader.
+ *
+ * @param string $namespace
+ * @param string|array $hints
+ * @return $this
+ */
+ public function prependNamespace($namespace, $hints)
+ {
+ $this->finder->prependNamespace($namespace, $hints);
+
+ return $this;
+ }
+
+ /**
+ * Replace the namespace hints for the given namespace.
+ *
+ * @param string $namespace
+ * @param string|array $hints
+ * @return $this
+ */
+ public function replaceNamespace($namespace, $hints)
+ {
+ $this->finder->replaceNamespace($namespace, $hints);
+
+ return $this;
+ }
+
+ /**
+ * Register a valid view extension and its engine.
+ *
+ * @param string $extension
+ * @param string $engine
+ * @param \Closure $resolver
+ * @return void
+ */
+ public function addExtension($extension, $engine, $resolver = null)
+ {
+ $this->finder->addExtension($extension);
+
+ if (isset($resolver)) {
+ $this->engines->register($engine, $resolver);
+ }
+
+ unset($this->extensions[$extension]);
+
+ $this->extensions = array_merge([$extension => $engine], $this->extensions);
+ }
+
+ /**
+ * Flush all of the factory state like sections and stacks.
+ *
+ * @return void
+ */
+ public function flushState()
+ {
+ $this->renderCount = 0;
+
+ $this->flushSections();
+ $this->flushStacks();
+ }
+
+ /**
+ * Flush all of the section contents if done rendering.
+ *
+ * @return void
+ */
+ public function flushStateIfDoneRendering()
+ {
+ if ($this->doneRendering()) {
+ $this->flushState();
+ }
+ }
+
+ /**
+ * Get the extension to engine bindings.
+ *
+ * @return array
+ */
+ public function getExtensions()
+ {
+ return $this->extensions;
+ }
+
+ /**
+ * Get the engine resolver instance.
+ *
+ * @return \Illuminate\View\Engines\EngineResolver
+ */
+ public function getEngineResolver()
+ {
+ return $this->engines;
+ }
+
+ /**
+ * Get the view finder instance.
+ *
+ * @return \Illuminate\View\ViewFinderInterface
+ */
+ public function getFinder()
+ {
+ return $this->finder;
+ }
+
+ /**
+ * Set the view finder instance.
+ *
+ * @param \Illuminate\View\ViewFinderInterface $finder
+ * @return void
+ */
+ public function setFinder(ViewFinderInterface $finder)
+ {
+ $this->finder = $finder;
+ }
+
+ /**
+ * Flush the cache of views located by the finder.
+ *
+ * @return void
+ */
+ public function flushFinderCache()
+ {
+ $this->getFinder()->flush();
+ }
+
+ /**
+ * Get the event dispatcher instance.
+ *
+ * @return \Illuminate\Contracts\Events\Dispatcher
+ */
+ public function getDispatcher()
+ {
+ return $this->events;
+ }
+
+ /**
+ * Set the event dispatcher instance.
+ *
+ * @param \Illuminate\Contracts\Events\Dispatcher $events
+ * @return void
+ */
+ public function setDispatcher(Dispatcher $events)
+ {
+ $this->events = $events;
+ }
+
+ /**
+ * Get the IoC container instance.
+ *
+ * @return \Illuminate\Contracts\Container\Container
+ */
+ public function getContainer()
+ {
+ return $this->container;
+ }
+
+ /**
+ * Set the IoC container instance.
+ *
+ * @param \Illuminate\Contracts\Container\Container $container
+ * @return void
+ */
+ public function setContainer(Container $container)
+ {
+ $this->container = $container;
+ }
+
+ /**
+ * Get an item from the shared data.
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function shared($key, $default = null)
+ {
+ return Arr::get($this->shared, $key, $default);
+ }
+
+ /**
+ * Get all of the shared data for the environment.
+ *
+ * @return array
+ */
+ public function getShared()
+ {
+ return $this->shared;
+ }
+}
diff --git a/vendor/illuminate/view/FileViewFinder.php b/vendor/illuminate/view/FileViewFinder.php
new file mode 100644
index 0000000..cf6bb8e
--- /dev/null
+++ b/vendor/illuminate/view/FileViewFinder.php
@@ -0,0 +1,298 @@
+files = $files;
+ $this->paths = $paths;
+
+ if (isset($extensions)) {
+ $this->extensions = $extensions;
+ }
+ }
+
+ /**
+ * Get the fully qualified location of the view.
+ *
+ * @param string $name
+ * @return string
+ */
+ public function find($name)
+ {
+ if (isset($this->views[$name])) {
+ return $this->views[$name];
+ }
+
+ if ($this->hasHintInformation($name = trim($name))) {
+ return $this->views[$name] = $this->findNamespacedView($name);
+ }
+
+ return $this->views[$name] = $this->findInPaths($name, $this->paths);
+ }
+
+ /**
+ * Get the path to a template with a named path.
+ *
+ * @param string $name
+ * @return string
+ */
+ protected function findNamespacedView($name)
+ {
+ list($namespace, $view) = $this->parseNamespaceSegments($name);
+
+ return $this->findInPaths($view, $this->hints[$namespace]);
+ }
+
+ /**
+ * Get the segments of a template with a named path.
+ *
+ * @param string $name
+ * @return array
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function parseNamespaceSegments($name)
+ {
+ $segments = explode(static::HINT_PATH_DELIMITER, $name);
+
+ if (count($segments) != 2) {
+ throw new InvalidArgumentException("View [$name] has an invalid name.");
+ }
+
+ if (! isset($this->hints[$segments[0]])) {
+ throw new InvalidArgumentException("No hint path defined for [{$segments[0]}].");
+ }
+
+ return $segments;
+ }
+
+ /**
+ * Find the given view in the list of paths.
+ *
+ * @param string $name
+ * @param array $paths
+ * @return string
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function findInPaths($name, $paths)
+ {
+ foreach ((array) $paths as $path) {
+ foreach ($this->getPossibleViewFiles($name) as $file) {
+ if ($this->files->exists($viewPath = $path.'/'.$file)) {
+ return $viewPath;
+ }
+ }
+ }
+
+ throw new InvalidArgumentException("View [$name] not found.");
+ }
+
+ /**
+ * Get an array of possible view files.
+ *
+ * @param string $name
+ * @return array
+ */
+ protected function getPossibleViewFiles($name)
+ {
+ return array_map(function ($extension) use ($name) {
+ return str_replace('.', '/', $name).'.'.$extension;
+ }, $this->extensions);
+ }
+
+ /**
+ * Add a location to the finder.
+ *
+ * @param string $location
+ * @return void
+ */
+ public function addLocation($location)
+ {
+ $this->paths[] = $location;
+ }
+
+ /**
+ * Prepend a location to the finder.
+ *
+ * @param string $location
+ * @return void
+ */
+ public function prependLocation($location)
+ {
+ array_unshift($this->paths, $location);
+ }
+
+ /**
+ * Add a namespace hint to the finder.
+ *
+ * @param string $namespace
+ * @param string|array $hints
+ * @return void
+ */
+ public function addNamespace($namespace, $hints)
+ {
+ $hints = (array) $hints;
+
+ if (isset($this->hints[$namespace])) {
+ $hints = array_merge($this->hints[$namespace], $hints);
+ }
+
+ $this->hints[$namespace] = $hints;
+ }
+
+ /**
+ * Prepend a namespace hint to the finder.
+ *
+ * @param string $namespace
+ * @param string|array $hints
+ * @return void
+ */
+ public function prependNamespace($namespace, $hints)
+ {
+ $hints = (array) $hints;
+
+ if (isset($this->hints[$namespace])) {
+ $hints = array_merge($hints, $this->hints[$namespace]);
+ }
+
+ $this->hints[$namespace] = $hints;
+ }
+
+ /**
+ * Replace the namespace hints for the given namespace.
+ *
+ * @param string $namespace
+ * @param string|array $hints
+ * @return void
+ */
+ public function replaceNamespace($namespace, $hints)
+ {
+ $this->hints[$namespace] = (array) $hints;
+ }
+
+ /**
+ * Register an extension with the view finder.
+ *
+ * @param string $extension
+ * @return void
+ */
+ public function addExtension($extension)
+ {
+ if (($index = array_search($extension, $this->extensions)) !== false) {
+ unset($this->extensions[$index]);
+ }
+
+ array_unshift($this->extensions, $extension);
+ }
+
+ /**
+ * Returns whether or not the view name has any hint information.
+ *
+ * @param string $name
+ * @return bool
+ */
+ public function hasHintInformation($name)
+ {
+ return strpos($name, static::HINT_PATH_DELIMITER) > 0;
+ }
+
+ /**
+ * Flush the cache of located views.
+ *
+ * @return void
+ */
+ public function flush()
+ {
+ $this->views = [];
+ }
+
+ /**
+ * Get the filesystem instance.
+ *
+ * @return \Illuminate\Filesystem\Filesystem
+ */
+ public function getFilesystem()
+ {
+ return $this->files;
+ }
+
+ /**
+ * Get the active view paths.
+ *
+ * @return array
+ */
+ public function getPaths()
+ {
+ return $this->paths;
+ }
+
+ /**
+ * Get the namespace to file path hints.
+ *
+ * @return array
+ */
+ public function getHints()
+ {
+ return $this->hints;
+ }
+
+ /**
+ * Get registered extensions.
+ *
+ * @return array
+ */
+ public function getExtensions()
+ {
+ return $this->extensions;
+ }
+}
diff --git a/vendor/illuminate/view/Middleware/ShareErrorsFromSession.php b/vendor/illuminate/view/Middleware/ShareErrorsFromSession.php
new file mode 100644
index 0000000..618b7dd
--- /dev/null
+++ b/vendor/illuminate/view/Middleware/ShareErrorsFromSession.php
@@ -0,0 +1,51 @@
+view = $view;
+ }
+
+ /**
+ * Handle an incoming request.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param \Closure $next
+ * @return mixed
+ */
+ public function handle($request, Closure $next)
+ {
+ // If the current session has an "errors" variable bound to it, we will share
+ // its value with all view instances so the views can easily access errors
+ // without having to bind. An empty bag is set when there aren't errors.
+ $this->view->share(
+ 'errors', $request->session()->get('errors') ?: new ViewErrorBag
+ );
+
+ // Putting the errors in the view for every view allows the developer to just
+ // assume that some errors are always available, which is convenient since
+ // they don't have to continually run checks for the presence of errors.
+
+ return $next($request);
+ }
+}
diff --git a/vendor/illuminate/view/View.php b/vendor/illuminate/view/View.php
new file mode 100644
index 0000000..496eb6c
--- /dev/null
+++ b/vendor/illuminate/view/View.php
@@ -0,0 +1,414 @@
+view = $view;
+ $this->path = $path;
+ $this->engine = $engine;
+ $this->factory = $factory;
+
+ $this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data;
+ }
+
+ /**
+ * Get the string contents of the view.
+ *
+ * @param callable|null $callback
+ * @return string
+ *
+ * @throws \Throwable
+ */
+ public function render(callable $callback = null)
+ {
+ try {
+ $contents = $this->renderContents();
+
+ $response = isset($callback) ? call_user_func($callback, $this, $contents) : null;
+
+ // Once we have the contents of the view, we will flush the sections if we are
+ // done rendering all views so that there is nothing left hanging over when
+ // another view gets rendered in the future by the application developer.
+ $this->factory->flushStateIfDoneRendering();
+
+ return ! is_null($response) ? $response : $contents;
+ } catch (Exception $e) {
+ $this->factory->flushState();
+
+ throw $e;
+ } catch (Throwable $e) {
+ $this->factory->flushState();
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Get the contents of the view instance.
+ *
+ * @return string
+ */
+ protected function renderContents()
+ {
+ // We will keep track of the amount of views being rendered so we can flush
+ // the section after the complete rendering operation is done. This will
+ // clear out the sections for any separate views that may be rendered.
+ $this->factory->incrementRender();
+
+ $this->factory->callComposer($this);
+
+ $contents = $this->getContents();
+
+ // Once we've finished rendering the view, we'll decrement the render count
+ // so that each sections get flushed out next time a view is created and
+ // no old sections are staying around in the memory of an environment.
+ $this->factory->decrementRender();
+
+ return $contents;
+ }
+
+ /**
+ * Get the evaluated contents of the view.
+ *
+ * @return string
+ */
+ protected function getContents()
+ {
+ return $this->engine->get($this->path, $this->gatherData());
+ }
+
+ /**
+ * Get the data bound to the view instance.
+ *
+ * @return array
+ */
+ protected function gatherData()
+ {
+ $data = array_merge($this->factory->getShared(), $this->data);
+
+ foreach ($data as $key => $value) {
+ if ($value instanceof Renderable) {
+ $data[$key] = $value->render();
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Get the sections of the rendered view.
+ *
+ * @return string
+ */
+ public function renderSections()
+ {
+ return $this->render(function () {
+ return $this->factory->getSections();
+ });
+ }
+
+ /**
+ * Add a piece of data to the view.
+ *
+ * @param string|array $key
+ * @param mixed $value
+ * @return $this
+ */
+ public function with($key, $value = null)
+ {
+ if (is_array($key)) {
+ $this->data = array_merge($this->data, $key);
+ } else {
+ $this->data[$key] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Add a view instance to the view data.
+ *
+ * @param string $key
+ * @param string $view
+ * @param array $data
+ * @return $this
+ */
+ public function nest($key, $view, array $data = [])
+ {
+ return $this->with($key, $this->factory->make($view, $data));
+ }
+
+ /**
+ * Add validation errors to the view.
+ *
+ * @param \Illuminate\Contracts\Support\MessageProvider|array $provider
+ * @return $this
+ */
+ public function withErrors($provider)
+ {
+ $this->with('errors', $this->formatErrors($provider));
+
+ return $this;
+ }
+
+ /**
+ * Format the given message provider into a MessageBag.
+ *
+ * @param \Illuminate\Contracts\Support\MessageProvider|array $provider
+ * @return \Illuminate\Support\MessageBag
+ */
+ protected function formatErrors($provider)
+ {
+ return $provider instanceof MessageProvider
+ ? $provider->getMessageBag() : new MessageBag((array) $provider);
+ }
+
+ /**
+ * Get the name of the view.
+ *
+ * @return string
+ */
+ public function name()
+ {
+ return $this->getName();
+ }
+
+ /**
+ * Get the name of the view.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->view;
+ }
+
+ /**
+ * Get the array of view data.
+ *
+ * @return array
+ */
+ public function getData()
+ {
+ return $this->data;
+ }
+
+ /**
+ * Get the path to the view file.
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Set the path to the view.
+ *
+ * @param string $path
+ * @return void
+ */
+ public function setPath($path)
+ {
+ $this->path = $path;
+ }
+
+ /**
+ * Get the view factory instance.
+ *
+ * @return \Illuminate\View\Factory
+ */
+ public function getFactory()
+ {
+ return $this->factory;
+ }
+
+ /**
+ * Get the view's rendering engine.
+ *
+ * @return \Illuminate\Contracts\View\Engine
+ */
+ public function getEngine()
+ {
+ return $this->engine;
+ }
+
+ /**
+ * Determine if a piece of data is bound.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function offsetExists($key)
+ {
+ return array_key_exists($key, $this->data);
+ }
+
+ /**
+ * Get a piece of bound data to the view.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function offsetGet($key)
+ {
+ return $this->data[$key];
+ }
+
+ /**
+ * Set a piece of data on the view.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function offsetSet($key, $value)
+ {
+ $this->with($key, $value);
+ }
+
+ /**
+ * Unset a piece of data from the view.
+ *
+ * @param string $key
+ * @return void
+ */
+ public function offsetUnset($key)
+ {
+ unset($this->data[$key]);
+ }
+
+ /**
+ * Get a piece of data from the view.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function &__get($key)
+ {
+ return $this->data[$key];
+ }
+
+ /**
+ * Set a piece of data on the view.
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->with($key, $value);
+ }
+
+ /**
+ * Check if a piece of data is bound to the view.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function __isset($key)
+ {
+ return isset($this->data[$key]);
+ }
+
+ /**
+ * Remove a piece of bound data from the view.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function __unset($key)
+ {
+ unset($this->data[$key]);
+ }
+
+ /**
+ * Dynamically bind parameters to the view.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return \Illuminate\View\View
+ *
+ * @throws \BadMethodCallException
+ */
+ public function __call($method, $parameters)
+ {
+ if (! Str::startsWith($method, 'with')) {
+ throw new BadMethodCallException("Method [$method] does not exist on view.");
+ }
+
+ return $this->with(Str::camel(substr($method, 4)), $parameters[0]);
+ }
+
+ /**
+ * Get the string contents of the view.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render();
+ }
+}
diff --git a/vendor/illuminate/view/ViewFinderInterface.php b/vendor/illuminate/view/ViewFinderInterface.php
new file mode 100644
index 0000000..49d609e
--- /dev/null
+++ b/vendor/illuminate/view/ViewFinderInterface.php
@@ -0,0 +1,71 @@
+registerFactory();
+
+ $this->registerViewFinder();
+
+ $this->registerEngineResolver();
+ }
+
+ /**
+ * Register the view environment.
+ *
+ * @return void
+ */
+ public function registerFactory()
+ {
+ $this->app->singleton('view', function ($app) {
+ // Next we need to grab the engine resolver instance that will be used by the
+ // environment. The resolver will be used by an environment to get each of
+ // the various engine implementations such as plain PHP or Blade engine.
+ $resolver = $app['view.engine.resolver'];
+
+ $finder = $app['view.finder'];
+
+ $factory = $this->createFactory($resolver, $finder, $app['events']);
+
+ // We will also set the container instance on this view environment since the
+ // view composers may be classes registered in the container, which allows
+ // for great testable, flexible composers for the application developer.
+ $factory->setContainer($app);
+
+ $factory->share('app', $app);
+
+ return $factory;
+ });
+ }
+
+ /**
+ * Create a new Factory Instance.
+ *
+ * @param \Illuminate\View\Engines\EngineResolver $resolver
+ * @param \Illuminate\View\ViewFinderInterface $finder
+ * @param \Illuminate\Contracts\Events\Dispatcher $events
+ * @return \Illuminate\View\Factory
+ */
+ protected function createFactory($resolver, $finder, $events)
+ {
+ return new Factory($resolver, $finder, $events);
+ }
+
+ /**
+ * Register the view finder implementation.
+ *
+ * @return void
+ */
+ public function registerViewFinder()
+ {
+ $this->app->bind('view.finder', function ($app) {
+ return new FileViewFinder($app['files'], $app['config']['view.paths']);
+ });
+ }
+
+ /**
+ * Register the engine resolver instance.
+ *
+ * @return void
+ */
+ public function registerEngineResolver()
+ {
+ $this->app->singleton('view.engine.resolver', function () {
+ $resolver = new EngineResolver;
+
+ // Next, we will register the various view engines with the resolver so that the
+ // environment will resolve the engines needed for various views based on the
+ // extension of view file. We call a method for each of the view's engines.
+ foreach (['file', 'php', 'blade'] as $engine) {
+ $this->{'register'.ucfirst($engine).'Engine'}($resolver);
+ }
+
+ return $resolver;
+ });
+ }
+
+ /**
+ * Register the file engine implementation.
+ *
+ * @param \Illuminate\View\Engines\EngineResolver $resolver
+ * @return void
+ */
+ public function registerFileEngine($resolver)
+ {
+ $resolver->register('file', function () {
+ return new FileEngine;
+ });
+ }
+
+ /**
+ * Register the PHP engine implementation.
+ *
+ * @param \Illuminate\View\Engines\EngineResolver $resolver
+ * @return void
+ */
+ public function registerPhpEngine($resolver)
+ {
+ $resolver->register('php', function () {
+ return new PhpEngine;
+ });
+ }
+
+ /**
+ * Register the Blade engine implementation.
+ *
+ * @param \Illuminate\View\Engines\EngineResolver $resolver
+ * @return void
+ */
+ public function registerBladeEngine($resolver)
+ {
+ // The Compiler engine requires an instance of the CompilerInterface, which in
+ // this case will be the Blade compiler, so we'll first create the compiler
+ // instance to pass into the engine so it can compile the views properly.
+ $this->app->singleton('blade.compiler', function () {
+ return new BladeCompiler(
+ $this->app['files'], $this->app['config']['view.compiled']
+ );
+ });
+
+ $resolver->register('blade', function () {
+ return new CompilerEngine($this->app['blade.compiler']);
+ });
+ }
+}
diff --git a/vendor/illuminate/view/composer.json b/vendor/illuminate/view/composer.json
new file mode 100644
index 0000000..142c755
--- /dev/null
+++ b/vendor/illuminate/view/composer.json
@@ -0,0 +1,39 @@
+{
+ "name": "illuminate/view",
+ "description": "The Illuminate View package.",
+ "license": "MIT",
+ "homepage": "https://laravel.com",
+ "support": {
+ "issues": "https://github.com/laravel/framework/issues",
+ "source": "https://github.com/laravel/framework"
+ },
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "require": {
+ "php": ">=7.0",
+ "illuminate/container": "5.5.*",
+ "illuminate/contracts": "5.5.*",
+ "illuminate/events": "5.5.*",
+ "illuminate/filesystem": "5.5.*",
+ "illuminate/support": "5.5.*",
+ "symfony/debug": "~3.3"
+ },
+ "autoload": {
+ "psr-4": {
+ "Illuminate\\View\\": ""
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.5-dev"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "minimum-stability": "dev"
+}
diff --git a/vendor/jenssegers/blade/.github/FUNDING.yml b/vendor/jenssegers/blade/.github/FUNDING.yml
new file mode 100644
index 0000000..7cbfb65
--- /dev/null
+++ b/vendor/jenssegers/blade/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+github: [jenssegers]
+open_collective: jenssegers-blade
diff --git a/vendor/jenssegers/blade/README.md b/vendor/jenssegers/blade/README.md
new file mode 100644
index 0000000..2aab4c9
--- /dev/null
+++ b/vendor/jenssegers/blade/README.md
@@ -0,0 +1,55 @@
+# Blade
+
+[](https://packagist.org/packages/jenssegers/blade) [](https://travis-ci.org/jenssegers/blade) [](https://coveralls.io/r/jenssegers/blade)
+
+The standalone version of [Laravel's Blade templating engine](https://laravel.com/docs/5.8/blade) for use outside of Laravel.
+
+
+
+
+ */
+class BufferingLogger extends AbstractLogger
+{
+ private $logs = [];
+
+ public function log($level, $message, array $context = [])
+ {
+ $this->logs[] = [$level, $message, $context];
+ }
+
+ public function cleanLogs()
+ {
+ $logs = $this->logs;
+ $this->logs = [];
+
+ return $logs;
+ }
+}
diff --git a/vendor/symfony/debug/CHANGELOG.md b/vendor/symfony/debug/CHANGELOG.md
new file mode 100644
index 0000000..31c67eb
--- /dev/null
+++ b/vendor/symfony/debug/CHANGELOG.md
@@ -0,0 +1,64 @@
+CHANGELOG
+=========
+
+3.4.0
+-----
+
+* deprecated `ErrorHandler::stackErrors()` and `ErrorHandler::unstackErrors()`
+
+3.3.0
+-----
+
+* deprecated the `ContextErrorException` class: use \ErrorException directly now
+
+3.2.0
+-----
+
+* `FlattenException::getTrace()` now returns additional type descriptions
+ `integer` and `float`.
+
+
+3.0.0
+-----
+
+* removed classes, methods and interfaces deprecated in 2.x
+
+2.8.0
+-----
+
+* added BufferingLogger for errors that happen before a proper logger is configured
+* allow throwing from `__toString()` with `return trigger_error($e, E_USER_ERROR);`
+* deprecate ExceptionHandler::createResponse
+
+2.7.0
+-----
+
+* added deprecations checking for parent interfaces/classes to DebugClassLoader
+* added ZTS support to symfony_debug extension
+* added symfony_debug_backtrace() to symfony_debug extension
+ to track the backtrace of fatal errors
+
+2.6.0
+-----
+
+* generalized ErrorHandler and ExceptionHandler,
+ with some new methods and others deprecated
+* enhanced error messages for uncaught exceptions
+
+2.5.0
+-----
+
+* added ExceptionHandler::setHandler()
+* added UndefinedMethodFatalErrorHandler
+* deprecated DummyException
+
+2.4.0
+-----
+
+ * added a DebugClassLoader able to wrap any autoloader providing a findFile method
+ * improved error messages for not found classes and functions
+
+2.3.0
+-----
+
+ * added the component
diff --git a/vendor/symfony/debug/Debug.php b/vendor/symfony/debug/Debug.php
new file mode 100644
index 0000000..746f329
--- /dev/null
+++ b/vendor/symfony/debug/Debug.php
@@ -0,0 +1,60 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Debug;
+
+/**
+ * Registers all the debug tools.
+ *
+ * @author Fabien Potencier
+ */
+class DebugClassLoader
+{
+ private $classLoader;
+ private $isFinder;
+ private $loaded = [];
+ private static $caseCheck;
+ private static $checkedClasses = [];
+ private static $final = [];
+ private static $finalMethods = [];
+ private static $deprecated = [];
+ private static $internal = [];
+ private static $internalMethods = [];
+ private static $php7Reserved = ['int' => 1, 'float' => 1, 'bool' => 1, 'string' => 1, 'true' => 1, 'false' => 1, 'null' => 1];
+ private static $darwinCache = ['/' => ['/', []]];
+
+ public function __construct(callable $classLoader)
+ {
+ $this->classLoader = $classLoader;
+ $this->isFinder = \is_array($classLoader) && method_exists($classLoader[0], 'findFile');
+
+ if (!isset(self::$caseCheck)) {
+ $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), \DIRECTORY_SEPARATOR);
+ $i = strrpos($file, \DIRECTORY_SEPARATOR);
+ $dir = substr($file, 0, 1 + $i);
+ $file = substr($file, 1 + $i);
+ $test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file);
+ $test = realpath($dir.$test);
+
+ if (false === $test || false === $i) {
+ // filesystem is case sensitive
+ self::$caseCheck = 0;
+ } elseif (substr($test, -\strlen($file)) === $file) {
+ // filesystem is case insensitive and realpath() normalizes the case of characters
+ self::$caseCheck = 1;
+ } elseif (false !== stripos(\PHP_OS, 'darwin')) {
+ // on MacOSX, HFS+ is case insensitive but realpath() doesn't normalize the case of characters
+ self::$caseCheck = 2;
+ } else {
+ // filesystem case checks failed, fallback to disabling them
+ self::$caseCheck = 0;
+ }
+ }
+ }
+
+ /**
+ * Gets the wrapped class loader.
+ *
+ * @return callable The wrapped class loader
+ */
+ public function getClassLoader()
+ {
+ return $this->classLoader;
+ }
+
+ /**
+ * Wraps all autoloaders.
+ */
+ public static function enable()
+ {
+ // Ensures we don't hit https://bugs.php.net/42098
+ class_exists('Symfony\Component\Debug\ErrorHandler');
+ class_exists('Psr\Log\LogLevel');
+
+ if (!\is_array($functions = spl_autoload_functions())) {
+ return;
+ }
+
+ foreach ($functions as $function) {
+ spl_autoload_unregister($function);
+ }
+
+ foreach ($functions as $function) {
+ if (!\is_array($function) || !$function[0] instanceof self) {
+ $function = [new static($function), 'loadClass'];
+ }
+
+ spl_autoload_register($function);
+ }
+ }
+
+ /**
+ * Disables the wrapping.
+ */
+ public static function disable()
+ {
+ if (!\is_array($functions = spl_autoload_functions())) {
+ return;
+ }
+
+ foreach ($functions as $function) {
+ spl_autoload_unregister($function);
+ }
+
+ foreach ($functions as $function) {
+ if (\is_array($function) && $function[0] instanceof self) {
+ $function = $function[0]->getClassLoader();
+ }
+
+ spl_autoload_register($function);
+ }
+ }
+
+ /**
+ * @return string|null
+ */
+ public function findFile($class)
+ {
+ return $this->isFinder ? $this->classLoader[0]->findFile($class) ?: null : null;
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ *
+ * @throws \RuntimeException
+ */
+ public function loadClass($class)
+ {
+ $e = error_reporting(error_reporting() | \E_PARSE | \E_ERROR | \E_CORE_ERROR | \E_COMPILE_ERROR);
+
+ try {
+ if ($this->isFinder && !isset($this->loaded[$class])) {
+ $this->loaded[$class] = true;
+ if (!$file = $this->classLoader[0]->findFile($class) ?: false) {
+ // no-op
+ } elseif (\function_exists('opcache_is_script_cached') && @opcache_is_script_cached($file)) {
+ include $file;
+
+ return;
+ } elseif (false === include $file) {
+ return;
+ }
+ } else {
+ \call_user_func($this->classLoader, $class);
+ $file = false;
+ }
+ } finally {
+ error_reporting($e);
+ }
+
+ $this->checkClass($class, $file);
+ }
+
+ private function checkClass($class, $file = null)
+ {
+ $exists = null === $file || class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false);
+
+ if (null !== $file && $class && '\\' === $class[0]) {
+ $class = substr($class, 1);
+ }
+
+ if ($exists) {
+ if (isset(self::$checkedClasses[$class])) {
+ return;
+ }
+ self::$checkedClasses[$class] = true;
+
+ $refl = new \ReflectionClass($class);
+ if (null === $file && $refl->isInternal()) {
+ return;
+ }
+ $name = $refl->getName();
+
+ if ($name !== $class && 0 === strcasecmp($name, $class)) {
+ throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name));
+ }
+
+ $deprecations = $this->checkAnnotations($refl, $name);
+
+ if (isset(self::$php7Reserved[strtolower($refl->getShortName())])) {
+ $deprecations[] = sprintf('The "%s" class uses the reserved name "%s", it will break on PHP 7 and higher', $name, $refl->getShortName());
+ }
+
+ foreach ($deprecations as $message) {
+ @trigger_error($message, \E_USER_DEPRECATED);
+ }
+ }
+
+ if (!$file) {
+ return;
+ }
+
+ if (!$exists) {
+ if (false !== strpos($class, '/')) {
+ throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
+ }
+
+ throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
+ }
+
+ if (self::$caseCheck && $message = $this->checkCase($refl, $file, $class)) {
+ throw new \RuntimeException(sprintf('Case mismatch between class and real file names: "%s" vs "%s" in "%s".', $message[0], $message[1], $message[2]));
+ }
+ }
+
+ public function checkAnnotations(\ReflectionClass $refl, $class)
+ {
+ $deprecations = [];
+
+ // Don't trigger deprecations for classes in the same vendor
+ if (2 > $len = 1 + (strpos($class, '\\') ?: strpos($class, '_'))) {
+ $len = 0;
+ $ns = '';
+ } else {
+ $ns = str_replace('_', '\\', substr($class, 0, $len));
+ }
+
+ // Detect annotations on the class
+ if (false !== $doc = $refl->getDocComment()) {
+ foreach (['final', 'deprecated', 'internal'] as $annotation) {
+ if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) {
+ self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : '';
+ }
+ }
+ }
+
+ $parent = get_parent_class($class);
+ $parentAndOwnInterfaces = $this->getOwnInterfaces($class, $parent);
+ if ($parent) {
+ $parentAndOwnInterfaces[$parent] = $parent;
+
+ if (!isset(self::$checkedClasses[$parent])) {
+ $this->checkClass($parent);
+ }
+
+ if (isset(self::$final[$parent])) {
+ $deprecations[] = sprintf('The "%s" class is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $class);
+ }
+ }
+
+ // Detect if the parent is annotated
+ foreach ($parentAndOwnInterfaces + class_uses($class, false) as $use) {
+ if (!isset(self::$checkedClasses[$use])) {
+ $this->checkClass($use);
+ }
+ if (isset(self::$deprecated[$use]) && strncmp($ns, str_replace('_', '\\', $use), $len) && !isset(self::$deprecated[$class])) {
+ $type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
+ $verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
+
+ $deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]);
+ }
+ if (isset(self::$internal[$use]) && strncmp($ns, str_replace('_', '\\', $use), $len)) {
+ $deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class);
+ }
+ }
+
+ if (trait_exists($class)) {
+ return $deprecations;
+ }
+
+ // Inherit @final and @internal annotations for methods
+ self::$finalMethods[$class] = [];
+ self::$internalMethods[$class] = [];
+ foreach ($parentAndOwnInterfaces as $use) {
+ foreach (['finalMethods', 'internalMethods'] as $property) {
+ if (isset(self::${$property}[$use])) {
+ self::${$property}[$class] = self::${$property}[$class] ? self::${$property}[$use] + self::${$property}[$class] : self::${$property}[$use];
+ }
+ }
+ }
+
+ foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $method) {
+ if ($method->class !== $class) {
+ continue;
+ }
+
+ if ($parent && isset(self::$finalMethods[$parent][$method->name])) {
+ list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
+ $deprecations[] = sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class);
+ }
+
+ if (isset(self::$internalMethods[$class][$method->name])) {
+ list($declaringClass, $message) = self::$internalMethods[$class][$method->name];
+ if (strncmp($ns, $declaringClass, $len)) {
+ $deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class);
+ }
+ }
+
+ // Detect method annotations
+ if (false === $doc = $method->getDocComment()) {
+ continue;
+ }
+
+ foreach (['final', 'internal'] as $annotation) {
+ if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) {
+ $message = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : '';
+ self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message];
+ }
+ }
+ }
+
+ return $deprecations;
+ }
+
+ /**
+ * @param string $file
+ * @param string $class
+ *
+ * @return array|null
+ */
+ public function checkCase(\ReflectionClass $refl, $file, $class)
+ {
+ $real = explode('\\', $class.strrchr($file, '.'));
+ $tail = explode(\DIRECTORY_SEPARATOR, str_replace('/', \DIRECTORY_SEPARATOR, $file));
+
+ $i = \count($tail) - 1;
+ $j = \count($real) - 1;
+
+ while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
+ --$i;
+ --$j;
+ }
+
+ array_splice($tail, 0, $i + 1);
+
+ if (!$tail) {
+ return null;
+ }
+
+ $tail = \DIRECTORY_SEPARATOR.implode(\DIRECTORY_SEPARATOR, $tail);
+ $tailLen = \strlen($tail);
+ $real = $refl->getFileName();
+
+ if (2 === self::$caseCheck) {
+ $real = $this->darwinRealpath($real);
+ }
+
+ if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
+ && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
+ ) {
+ return [substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)];
+ }
+
+ return null;
+ }
+
+ /**
+ * `realpath` on MacOSX doesn't normalize the case of characters.
+ */
+ private function darwinRealpath($real)
+ {
+ $i = 1 + strrpos($real, '/');
+ $file = substr($real, $i);
+ $real = substr($real, 0, $i);
+
+ if (isset(self::$darwinCache[$real])) {
+ $kDir = $real;
+ } else {
+ $kDir = strtolower($real);
+
+ if (isset(self::$darwinCache[$kDir])) {
+ $real = self::$darwinCache[$kDir][0];
+ } else {
+ $dir = getcwd();
+ chdir($real);
+ $real = getcwd().'/';
+ chdir($dir);
+
+ $dir = $real;
+ $k = $kDir;
+ $i = \strlen($dir) - 1;
+ while (!isset(self::$darwinCache[$k])) {
+ self::$darwinCache[$k] = [$dir, []];
+ self::$darwinCache[$dir] = &self::$darwinCache[$k];
+
+ while ('/' !== $dir[--$i]) {
+ }
+ $k = substr($k, 0, ++$i);
+ $dir = substr($dir, 0, $i--);
+ }
+ }
+ }
+
+ $dirFiles = self::$darwinCache[$kDir][1];
+
+ if (!isset($dirFiles[$file]) && ') : eval()\'d code' === substr($file, -17)) {
+ // Get the file name from "file_name.php(123) : eval()'d code"
+ $file = substr($file, 0, strrpos($file, '(', -17));
+ }
+
+ if (isset($dirFiles[$file])) {
+ return $real.$dirFiles[$file];
+ }
+
+ $kFile = strtolower($file);
+
+ if (!isset($dirFiles[$kFile])) {
+ foreach (scandir($real, 2) as $f) {
+ if ('.' !== $f[0]) {
+ $dirFiles[$f] = $f;
+ if ($f === $file) {
+ $kFile = $k = $file;
+ } elseif ($f !== $k = strtolower($f)) {
+ $dirFiles[$k] = $f;
+ }
+ }
+ }
+ self::$darwinCache[$kDir][1] = $dirFiles;
+ }
+
+ return $real.$dirFiles[$kFile];
+ }
+
+ /**
+ * `class_implements` includes interfaces from the parents so we have to manually exclude them.
+ *
+ * @param string $class
+ * @param string|false $parent
+ *
+ * @return string[]
+ */
+ private function getOwnInterfaces($class, $parent)
+ {
+ $ownInterfaces = class_implements($class, false);
+
+ if ($parent) {
+ foreach (class_implements($parent, false) as $interface) {
+ unset($ownInterfaces[$interface]);
+ }
+ }
+
+ foreach ($ownInterfaces as $interface) {
+ foreach (class_implements($interface) as $interface) {
+ unset($ownInterfaces[$interface]);
+ }
+ }
+
+ return $ownInterfaces;
+ }
+}
diff --git a/vendor/symfony/debug/ErrorHandler.php b/vendor/symfony/debug/ErrorHandler.php
new file mode 100644
index 0000000..b8ec09e
--- /dev/null
+++ b/vendor/symfony/debug/ErrorHandler.php
@@ -0,0 +1,787 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Debug;
+
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use Symfony\Component\Debug\Exception\ContextErrorException;
+use Symfony\Component\Debug\Exception\FatalErrorException;
+use Symfony\Component\Debug\Exception\FatalThrowableError;
+use Symfony\Component\Debug\Exception\OutOfMemoryException;
+use Symfony\Component\Debug\Exception\SilencedErrorContext;
+use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
+use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface;
+use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
+use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
+
+/**
+ * A generic ErrorHandler for the PHP engine.
+ *
+ * Provides five bit fields that control how errors are handled:
+ * - thrownErrors: errors thrown as \ErrorException
+ * - loggedErrors: logged errors, when not @-silenced
+ * - scopedErrors: errors thrown or logged with their local context
+ * - tracedErrors: errors logged with their stack trace
+ * - screamedErrors: never @-silenced errors
+ *
+ * Each error level can be logged by a dedicated PSR-3 logger object.
+ * Screaming only applies to logging.
+ * Throwing takes precedence over logging.
+ * Uncaught exceptions are logged as E_ERROR.
+ * E_DEPRECATED and E_USER_DEPRECATED levels never throw.
+ * E_RECOVERABLE_ERROR and E_USER_ERROR levels always throw.
+ * Non catchable errors that can be detected at shutdown time are logged when the scream bit field allows so.
+ * As errors have a performance cost, repeated errors are all logged, so that the developer
+ * can see them and weight them as more important to fix than others of the same level.
+ *
+ * @author Nicolas Grekas
+ * @author Grégoire Pineau
+ */
+class FatalThrowableError extends FatalErrorException
+{
+ public function __construct(\Throwable $e)
+ {
+ if ($e instanceof \ParseError) {
+ $message = 'Parse error: '.$e->getMessage();
+ $severity = \E_PARSE;
+ } elseif ($e instanceof \TypeError) {
+ $message = 'Type error: '.$e->getMessage();
+ $severity = \E_RECOVERABLE_ERROR;
+ } else {
+ $message = $e->getMessage();
+ $severity = \E_ERROR;
+ }
+
+ \ErrorException::__construct(
+ $message,
+ $e->getCode(),
+ $severity,
+ $e->getFile(),
+ $e->getLine(),
+ $e->getPrevious()
+ );
+
+ $this->setTrace($e->getTrace());
+ }
+}
diff --git a/vendor/symfony/debug/Exception/FlattenException.php b/vendor/symfony/debug/Exception/FlattenException.php
new file mode 100644
index 0000000..9514bdc
--- /dev/null
+++ b/vendor/symfony/debug/Exception/FlattenException.php
@@ -0,0 +1,263 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Debug\Exception;
+
+use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
+
+/**
+ * FlattenException wraps a PHP Exception to be able to serialize it.
+ *
+ * Basically, this class removes all objects from the trace.
+ *
+ * @author Fabien Potencier
+ */
+class OutOfMemoryException extends FatalErrorException
+{
+}
diff --git a/vendor/symfony/debug/Exception/SilencedErrorContext.php b/vendor/symfony/debug/Exception/SilencedErrorContext.php
new file mode 100644
index 0000000..2bacfd5
--- /dev/null
+++ b/vendor/symfony/debug/Exception/SilencedErrorContext.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\Debug\Exception;
+
+/**
+ * Data Object that represents a Silenced Error.
+ *
+ * @author Grégoire Pineau
+ */
+class ExceptionHandler
+{
+ private $debug;
+ private $charset;
+ private $handler;
+ private $caughtBuffer;
+ private $caughtLength;
+ private $fileLinkFormat;
+
+ public function __construct($debug = true, $charset = null, $fileLinkFormat = null)
+ {
+ $this->debug = $debug;
+ $this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
+ $this->fileLinkFormat = $fileLinkFormat;
+ }
+
+ /**
+ * Registers the exception handler.
+ *
+ * @param bool $debug Enable/disable debug mode, where the stack trace is displayed
+ * @param string|null $charset The charset used by exception messages
+ * @param string|null $fileLinkFormat The IDE link template
+ *
+ * @return static
+ */
+ public static function register($debug = true, $charset = null, $fileLinkFormat = null)
+ {
+ $handler = new static($debug, $charset, $fileLinkFormat);
+
+ $prev = set_exception_handler([$handler, 'handle']);
+ if (\is_array($prev) && $prev[0] instanceof ErrorHandler) {
+ restore_exception_handler();
+ $prev[0]->setExceptionHandler([$handler, 'handle']);
+ }
+
+ return $handler;
+ }
+
+ /**
+ * Sets a user exception handler.
+ *
+ * @param callable $handler An handler that will be called on Exception
+ *
+ * @return callable|null The previous exception handler if any
+ */
+ public function setHandler(callable $handler = null)
+ {
+ $old = $this->handler;
+ $this->handler = $handler;
+
+ return $old;
+ }
+
+ /**
+ * Sets the format for links to source files.
+ *
+ * @param string|FileLinkFormatter $fileLinkFormat The format for links to source files
+ *
+ * @return string The previous file link format
+ */
+ public function setFileLinkFormat($fileLinkFormat)
+ {
+ $old = $this->fileLinkFormat;
+ $this->fileLinkFormat = $fileLinkFormat;
+
+ return $old;
+ }
+
+ /**
+ * Sends a response for the given Exception.
+ *
+ * To be as fail-safe as possible, the exception is first handled
+ * by our simple exception handler, then by the user exception handler.
+ * The latter takes precedence and any output from the former is cancelled,
+ * if and only if nothing bad happens in this handling path.
+ */
+ public function handle(\Exception $exception)
+ {
+ if (null === $this->handler || $exception instanceof OutOfMemoryException) {
+ $this->sendPhpResponse($exception);
+
+ return;
+ }
+
+ $caughtLength = $this->caughtLength = 0;
+
+ ob_start(function ($buffer) {
+ $this->caughtBuffer = $buffer;
+
+ return '';
+ });
+
+ $this->sendPhpResponse($exception);
+ while (null === $this->caughtBuffer && ob_end_flush()) {
+ // Empty loop, everything is in the condition
+ }
+ if (isset($this->caughtBuffer[0])) {
+ ob_start(function ($buffer) {
+ if ($this->caughtLength) {
+ // use substr_replace() instead of substr() for mbstring overloading resistance
+ $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength);
+ if (isset($cleanBuffer[0])) {
+ $buffer = $cleanBuffer;
+ }
+ }
+
+ return $buffer;
+ });
+
+ echo $this->caughtBuffer;
+ $caughtLength = ob_get_length();
+ }
+ $this->caughtBuffer = null;
+
+ try {
+ \call_user_func($this->handler, $exception);
+ $this->caughtLength = $caughtLength;
+ } catch (\Exception $e) {
+ if (!$caughtLength) {
+ // All handlers failed. Let PHP handle that now.
+ throw $exception;
+ }
+ }
+ }
+
+ /**
+ * Sends the error associated with the given Exception as a plain PHP response.
+ *
+ * This method uses plain PHP functions like header() and echo to output
+ * the response.
+ *
+ * @param \Exception|FlattenException $exception An \Exception or FlattenException instance
+ */
+ public function sendPhpResponse($exception)
+ {
+ if (!$exception instanceof FlattenException) {
+ $exception = FlattenException::create($exception);
+ }
+
+ if (!headers_sent()) {
+ header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
+ foreach ($exception->getHeaders() as $name => $value) {
+ header($name.': '.$value, false);
+ }
+ header('Content-Type: text/html; charset='.$this->charset);
+ }
+
+ echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
+ }
+
+ /**
+ * Gets the full HTML content associated with the given exception.
+ *
+ * @param \Exception|FlattenException $exception An \Exception or FlattenException instance
+ *
+ * @return string The HTML content as a string
+ */
+ public function getHtml($exception)
+ {
+ if (!$exception instanceof FlattenException) {
+ $exception = FlattenException::create($exception);
+ }
+
+ return $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
+ }
+
+ /**
+ * Gets the HTML content associated with the given exception.
+ *
+ * @return string The content as a string
+ */
+ public function getContent(FlattenException $exception)
+ {
+ switch ($exception->getStatusCode()) {
+ case 404:
+ $title = 'Sorry, the page you are looking for could not be found.';
+ break;
+ default:
+ $title = 'Whoops, looks like something went wrong.';
+ }
+
+ if (!$this->debug) {
+ return <<$title
+
+ + (%d/%d) + %s ++ + |
---|
'; + if ($trace['function']) { + $content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args'])); + } + if (isset($trace['file']) && isset($trace['line'])) { + $content .= $this->formatPath($trace['file'], $trace['line']); + } + $content .= " |
+ */ +class ErrorHandlerTest extends TestCase +{ + public function testRegister() + { + $handler = ErrorHandler::register(); + + try { + $this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler); + $this->assertSame($handler, ErrorHandler::register()); + + $newHandler = new ErrorHandler(); + + $this->assertSame($handler, ErrorHandler::register($newHandler, false)); + $h = set_error_handler('var_dump'); + restore_error_handler(); + $this->assertSame([$handler, 'handleError'], $h); + + try { + $this->assertSame($newHandler, ErrorHandler::register($newHandler, true)); + $h = set_error_handler('var_dump'); + restore_error_handler(); + $this->assertSame([$newHandler, 'handleError'], $h); + } catch (\Exception $e) { + } + + restore_error_handler(); + restore_exception_handler(); + + if (isset($e)) { + throw $e; + } + } catch (\Exception $e) { + } + + restore_error_handler(); + restore_exception_handler(); + + if (isset($e)) { + throw $e; + } + } + + public function testErrorGetLast() + { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $handler = ErrorHandler::register(); + $handler->setDefaultLogger($logger); + $handler->screamAt(\E_ALL); + + try { + @trigger_error('Hello', \E_USER_WARNING); + $expected = [ + 'type' => \E_USER_WARNING, + 'message' => 'Hello', + 'file' => __FILE__, + 'line' => __LINE__ - 5, + ]; + $this->assertSame($expected, error_get_last()); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + public function testNotice() + { + ErrorHandler::register(); + + try { + self::triggerNotice($this); + $this->fail('ErrorException expected'); + } catch (\ErrorException $exception) { + // if an exception is thrown, the test passed + if (\PHP_VERSION_ID < 80000) { + $this->assertEquals(\E_NOTICE, $exception->getSeverity()); + $this->assertMatchesRegularExpression('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage()); + } else { + $this->assertEquals(\E_WARNING, $exception->getSeverity()); + $this->assertMatchesRegularExpression('/^Warning: Undefined variable \$(foo|bar)/', $exception->getMessage()); + } + $this->assertEquals(__FILE__, $exception->getFile()); + + $trace = $exception->getTrace(); + + $this->assertEquals(__FILE__, $trace[0]['file']); + $this->assertEquals(__CLASS__, $trace[0]['class']); + $this->assertEquals('triggerNotice', $trace[0]['function']); + $this->assertEquals('::', $trace[0]['type']); + + $this->assertEquals(__FILE__, $trace[0]['file']); + $this->assertEquals(__CLASS__, $trace[1]['class']); + $this->assertEquals(__FUNCTION__, $trace[1]['function']); + $this->assertEquals('->', $trace[1]['type']); + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + // dummy function to test trace in error handler. + private static function triggerNotice($that) + { + $that->assertSame('', $foo.$foo.$bar); + } + + public function testConstruct() + { + try { + $handler = ErrorHandler::register(); + $handler->throwAt(3, true); + $this->assertEquals(3 | \E_RECOVERABLE_ERROR | \E_USER_ERROR, $handler->throwAt(0)); + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + public function testDefaultLogger() + { + try { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $handler = ErrorHandler::register(); + + $handler->setDefaultLogger($logger, \E_NOTICE); + $handler->setDefaultLogger($logger, [\E_USER_NOTICE => LogLevel::CRITICAL]); + + $loggers = [ + \E_DEPRECATED => [null, LogLevel::INFO], + \E_USER_DEPRECATED => [null, LogLevel::INFO], + \E_NOTICE => [$logger, LogLevel::WARNING], + \E_USER_NOTICE => [$logger, LogLevel::CRITICAL], + \E_STRICT => [null, LogLevel::WARNING], + \E_WARNING => [null, LogLevel::WARNING], + \E_USER_WARNING => [null, LogLevel::WARNING], + \E_COMPILE_WARNING => [null, LogLevel::WARNING], + \E_CORE_WARNING => [null, LogLevel::WARNING], + \E_USER_ERROR => [null, LogLevel::CRITICAL], + \E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL], + \E_COMPILE_ERROR => [null, LogLevel::CRITICAL], + \E_PARSE => [null, LogLevel::CRITICAL], + \E_ERROR => [null, LogLevel::CRITICAL], + \E_CORE_ERROR => [null, LogLevel::CRITICAL], + ]; + $this->assertSame($loggers, $handler->setLoggers([])); + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + public function testHandleError() + { + try { + $handler = ErrorHandler::register(); + $handler->throwAt(0, true); + $this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, [])); + + restore_error_handler(); + restore_exception_handler(); + + $handler = ErrorHandler::register(); + $handler->throwAt(3, true); + $this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, [])); + + restore_error_handler(); + restore_exception_handler(); + + $handler = ErrorHandler::register(); + $handler->throwAt(3, true); + try { + $handler->handleError(4, 'foo', 'foo.php', 12, []); + } catch (\ErrorException $e) { + $this->assertSame('Parse Error: foo', $e->getMessage()); + $this->assertSame(4, $e->getSeverity()); + $this->assertSame('foo.php', $e->getFile()); + $this->assertSame(12, $e->getLine()); + } + + restore_error_handler(); + restore_exception_handler(); + + $handler = ErrorHandler::register(); + $handler->throwAt(\E_USER_DEPRECATED, true); + $this->assertFalse($handler->handleError(\E_USER_DEPRECATED, 'foo', 'foo.php', 12, [])); + + restore_error_handler(); + restore_exception_handler(); + + $handler = ErrorHandler::register(); + $handler->throwAt(\E_DEPRECATED, true); + $this->assertFalse($handler->handleError(\E_DEPRECATED, 'foo', 'foo.php', 12, [])); + + restore_error_handler(); + restore_exception_handler(); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $warnArgCheck = function ($logLevel, $message, $context) { + $this->assertEquals('info', $logLevel); + $this->assertEquals('User Deprecated: foo', $message); + $this->assertArrayHasKey('exception', $context); + $exception = $context['exception']; + $this->assertInstanceOf(\ErrorException::class, $exception); + $this->assertSame('User Deprecated: foo', $exception->getMessage()); + $this->assertSame(\E_USER_DEPRECATED, $exception->getSeverity()); + }; + + $logger + ->expects($this->once()) + ->method('log') + ->willReturnCallback($warnArgCheck) + ; + + $handler = ErrorHandler::register(); + $handler->setDefaultLogger($logger, \E_USER_DEPRECATED); + $this->assertTrue($handler->handleError(\E_USER_DEPRECATED, 'foo', 'foo.php', 12, [])); + + restore_error_handler(); + restore_exception_handler(); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $line = null; + $logArgCheck = function ($level, $message, $context) use (&$line) { + $this->assertArrayHasKey('exception', $context); + $exception = $context['exception']; + + if (\PHP_VERSION_ID < 80000) { + $this->assertEquals('Notice: Undefined variable: undefVar', $message); + $this->assertSame(\E_NOTICE, $exception->getSeverity()); + } else { + $this->assertEquals('Warning: Undefined variable $undefVar', $message); + $this->assertSame(\E_WARNING, $exception->getSeverity()); + } + $this->assertInstanceOf(SilencedErrorContext::class, $exception); + $this->assertSame(__FILE__, $exception->getFile()); + $this->assertSame($line, $exception->getLine()); + $this->assertNotEmpty($exception->getTrace()); + $this->assertSame(1, $exception->count); + }; + + $logger + ->expects($this->once()) + ->method('log') + ->willReturnCallback($logArgCheck) + ; + + $handler = ErrorHandler::register(); + if (\PHP_VERSION_ID < 80000) { + $handler->setDefaultLogger($logger, \E_NOTICE); + $handler->screamAt(\E_NOTICE); + } else { + $handler->setDefaultLogger($logger, \E_WARNING); + $handler->screamAt(\E_WARNING); + } + unset($undefVar); + $line = __LINE__ + 1; + @$undefVar++; + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + public function testHandleUserError() + { + if (\PHP_VERSION_ID >= 70400) { + $this->markTestSkipped('PHP 7.4 allows __toString to throw exceptions'); + } + + try { + $handler = ErrorHandler::register(); + $handler->throwAt(0, true); + + $e = null; + $x = new \Exception('Foo'); + + try { + $f = new Fixtures\ToStringThrower($x); + $f .= ''; // Trigger $f->__toString() + } catch (\Exception $e) { + } + + $this->assertSame($x, $e); + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + public function testHandleDeprecation() + { + $logArgCheck = function ($level, $message, $context) { + $this->assertEquals(LogLevel::INFO, $level); + $this->assertArrayHasKey('exception', $context); + $exception = $context['exception']; + $this->assertInstanceOf(\ErrorException::class, $exception); + $this->assertSame('User Deprecated: Foo deprecation', $exception->getMessage()); + }; + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $logger + ->expects($this->once()) + ->method('log') + ->willReturnCallback($logArgCheck) + ; + + $handler = new ErrorHandler(); + $handler->setDefaultLogger($logger); + @$handler->handleError(\E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []); + } + + /** + * @group no-hhvm + */ + public function testHandleException() + { + try { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $handler = ErrorHandler::register(); + + $exception = new \Exception('foo'); + + $logArgCheck = function ($level, $message, $context) { + $this->assertSame('Uncaught Exception: foo', $message); + $this->assertArrayHasKey('exception', $context); + $this->assertInstanceOf(\Exception::class, $context['exception']); + }; + + $logger + ->expects($this->exactly(2)) + ->method('log') + ->willReturnCallback($logArgCheck) + ; + + $handler->setDefaultLogger($logger, \E_ERROR); + + try { + $handler->handleException($exception); + $this->fail('Exception expected'); + } catch (\Exception $e) { + $this->assertSame($exception, $e); + } + + $handler->setExceptionHandler(function ($e) use ($exception) { + $this->assertSame($exception, $e); + }); + + $handler->handleException($exception); + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + /** + * @group legacy + */ + public function testErrorStacking() + { + try { + $handler = ErrorHandler::register(); + $handler->screamAt(\E_USER_WARNING); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + + $logger + ->expects($this->exactly(2)) + ->method('log') + ->withConsecutive( + [$this->equalTo(LogLevel::WARNING), $this->equalTo('Dummy log')], + [$this->equalTo(LogLevel::DEBUG), $this->equalTo('User Warning: Silenced warning')] + ) + ; + + $handler->setDefaultLogger($logger, [\E_USER_WARNING => LogLevel::WARNING]); + + ErrorHandler::stackErrors(); + @trigger_error('Silenced warning', \E_USER_WARNING); + $logger->log(LogLevel::WARNING, 'Dummy log'); + ErrorHandler::unstackErrors(); + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + public function testBootstrappingLogger() + { + $bootLogger = new BufferingLogger(); + $handler = new ErrorHandler($bootLogger); + + $loggers = [ + \E_DEPRECATED => [$bootLogger, LogLevel::INFO], + \E_USER_DEPRECATED => [$bootLogger, LogLevel::INFO], + \E_NOTICE => [$bootLogger, LogLevel::WARNING], + \E_USER_NOTICE => [$bootLogger, LogLevel::WARNING], + \E_STRICT => [$bootLogger, LogLevel::WARNING], + \E_WARNING => [$bootLogger, LogLevel::WARNING], + \E_USER_WARNING => [$bootLogger, LogLevel::WARNING], + \E_COMPILE_WARNING => [$bootLogger, LogLevel::WARNING], + \E_CORE_WARNING => [$bootLogger, LogLevel::WARNING], + \E_USER_ERROR => [$bootLogger, LogLevel::CRITICAL], + \E_RECOVERABLE_ERROR => [$bootLogger, LogLevel::CRITICAL], + \E_COMPILE_ERROR => [$bootLogger, LogLevel::CRITICAL], + \E_PARSE => [$bootLogger, LogLevel::CRITICAL], + \E_ERROR => [$bootLogger, LogLevel::CRITICAL], + \E_CORE_ERROR => [$bootLogger, LogLevel::CRITICAL], + ]; + + $this->assertSame($loggers, $handler->setLoggers([])); + + $handler->handleError(\E_DEPRECATED, 'Foo message', __FILE__, 123, []); + + $logs = $bootLogger->cleanLogs(); + + $this->assertCount(1, $logs); + $log = $logs[0]; + $this->assertSame('info', $log[0]); + $this->assertSame('Deprecated: Foo message', $log[1]); + $this->assertArrayHasKey('exception', $log[2]); + $exception = $log[2]['exception']; + $this->assertInstanceOf(\ErrorException::class, $exception); + $this->assertSame('Deprecated: Foo message', $exception->getMessage()); + $this->assertSame(__FILE__, $exception->getFile()); + $this->assertSame(123, $exception->getLine()); + $this->assertSame(\E_DEPRECATED, $exception->getSeverity()); + + $bootLogger->log(LogLevel::WARNING, 'Foo message', ['exception' => $exception]); + + $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $mockLogger->expects($this->once()) + ->method('log') + ->with(LogLevel::WARNING, 'Foo message', ['exception' => $exception]); + + $handler->setLoggers([\E_DEPRECATED => [$mockLogger, LogLevel::WARNING]]); + } + + /** + * @group no-hhvm + */ + public function testSettingLoggerWhenExceptionIsBuffered() + { + $bootLogger = new BufferingLogger(); + $handler = new ErrorHandler($bootLogger); + + $exception = new \Exception('Foo message'); + + $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $mockLogger->expects($this->once()) + ->method('log') + ->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', ['exception' => $exception]); + + $handler->setExceptionHandler(function () use ($handler, $mockLogger) { + $handler->setDefaultLogger($mockLogger); + }); + + $handler->handleException($exception); + } + + /** + * @group no-hhvm + */ + public function testHandleFatalError() + { + try { + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $handler = ErrorHandler::register(); + + $error = [ + 'type' => \E_PARSE, + 'message' => 'foo', + 'file' => 'bar', + 'line' => 123, + ]; + + $logArgCheck = function ($level, $message, $context) { + $this->assertEquals('Fatal Parse Error: foo', $message); + $this->assertArrayHasKey('exception', $context); + $this->assertInstanceOf(\Exception::class, $context['exception']); + }; + + $logger + ->expects($this->once()) + ->method('log') + ->willReturnCallback($logArgCheck) + ; + + $handler->setDefaultLogger($logger, \E_PARSE); + + $handler->handleFatalError($error); + + restore_error_handler(); + restore_exception_handler(); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + + /** + * @requires PHP 7 + */ + public function testHandleErrorException() + { + $exception = new \Error("Class 'IReallyReallyDoNotExistAnywhereInTheRepositoryISwear' not found"); + + $handler = new ErrorHandler(); + $handler->setExceptionHandler(function () use (&$args) { + $args = \func_get_args(); + }); + + $handler->handleException($exception); + + $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]); + $this->assertStringStartsWith("Attempted to load class \"IReallyReallyDoNotExistAnywhereInTheRepositoryISwear\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage()); + } + + /** + * @group no-hhvm + */ + public function testHandleFatalErrorOnHHVM() + { + if (!\defined('HHVM_VERSION')) { + $this->markTestSkipped('This test requires HHVM.'); + } + + try { + $handler = ErrorHandler::register(); + + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $logger + ->expects($this->once()) + ->method('log') + ->with( + $this->equalTo(LogLevel::CRITICAL), + $this->equalTo('Fatal Error: foo') + ) + ; + + $handler->setDefaultLogger($logger, \E_ERROR); + + $error = [ + 'type' => \E_ERROR + 0x1000000, // This error level is used by HHVM for fatal errors + 'message' => 'foo', + 'file' => 'bar', + 'line' => 123, + 'context' => [123], + 'backtrace' => [456], + ]; + + \call_user_func_array([$handler, 'handleError'], $error); + $handler->handleFatalError($error); + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + /** + * @group no-hhvm + */ + public function testCustomExceptionHandler() + { + $this->expectException('Exception'); + $handler = new ErrorHandler(); + $handler->setExceptionHandler(function ($e) use ($handler) { + $handler->handleException($e); + }); + + $handler->handleException(new \Exception()); + } + + /** + * @dataProvider errorHandlerWhenLoggingProvider + */ + public function testErrorHandlerWhenLogging($previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined) + { + try { + if ($previousHandlerWasDefined) { + set_error_handler('count'); + } + + $logger = $loggerSetsAnotherHandler ? new LoggerThatSetAnErrorHandler() : new NullLogger(); + + $handler = ErrorHandler::register(); + $handler->setDefaultLogger($logger); + + if ($nextHandlerIsDefined) { + $handler = ErrorHandlerThatUsesThePreviousOne::register(); + } + + @trigger_error('foo', \E_USER_DEPRECATED); + @trigger_error('bar', \E_USER_DEPRECATED); + + $this->assertSame([$handler, 'handleError'], set_error_handler('var_dump')); + + if ($logger instanceof LoggerThatSetAnErrorHandler) { + $this->assertCount(2, $logger->cleanLogs()); + } + + restore_error_handler(); + + if ($previousHandlerWasDefined) { + restore_error_handler(); + } + + if ($nextHandlerIsDefined) { + restore_error_handler(); + } + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + public function errorHandlerWhenLoggingProvider() + { + foreach ([false, true] as $previousHandlerWasDefined) { + foreach ([false, true] as $loggerSetsAnotherHandler) { + foreach ([false, true] as $nextHandlerIsDefined) { + yield [$previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined]; + } + } + } + } +} diff --git a/vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php b/vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php new file mode 100644 index 0000000..7143e5d --- /dev/null +++ b/vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php @@ -0,0 +1,314 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests\Exception; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Debug\Exception\FlattenException; +use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\ConflictHttpException; +use Symfony\Component\HttpKernel\Exception\GoneHttpException; +use Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException; +use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; +use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException; +use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException; +use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; +use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; +use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; +use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException; + +class FlattenExceptionTest extends TestCase +{ + public function testStatusCode() + { + $flattened = FlattenException::create(new \RuntimeException(), 403); + $this->assertEquals('403', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new \RuntimeException()); + $this->assertEquals('500', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new NotFoundHttpException()); + $this->assertEquals('404', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"')); + $this->assertEquals('401', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new BadRequestHttpException()); + $this->assertEquals('400', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new NotAcceptableHttpException()); + $this->assertEquals('406', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new ConflictHttpException()); + $this->assertEquals('409', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST'])); + $this->assertEquals('405', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new AccessDeniedHttpException()); + $this->assertEquals('403', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new GoneHttpException()); + $this->assertEquals('410', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new LengthRequiredHttpException()); + $this->assertEquals('411', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new PreconditionFailedHttpException()); + $this->assertEquals('412', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new PreconditionRequiredHttpException()); + $this->assertEquals('428', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new ServiceUnavailableHttpException()); + $this->assertEquals('503', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new TooManyRequestsHttpException()); + $this->assertEquals('429', $flattened->getStatusCode()); + + $flattened = FlattenException::create(new UnsupportedMediaTypeHttpException()); + $this->assertEquals('415', $flattened->getStatusCode()); + + if (class_exists(SuspiciousOperationException::class)) { + $flattened = FlattenException::create(new SuspiciousOperationException()); + $this->assertEquals('400', $flattened->getStatusCode()); + } + } + + public function testHeadersForHttpException() + { + $flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST'])); + $this->assertEquals(['Allow' => 'POST'], $flattened->getHeaders()); + + $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"')); + $this->assertEquals(['WWW-Authenticate' => 'Basic realm="My Realm"'], $flattened->getHeaders()); + + $flattened = FlattenException::create(new ServiceUnavailableHttpException('Fri, 31 Dec 1999 23:59:59 GMT')); + $this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders()); + + $flattened = FlattenException::create(new ServiceUnavailableHttpException(120)); + $this->assertEquals(['Retry-After' => 120], $flattened->getHeaders()); + + $flattened = FlattenException::create(new TooManyRequestsHttpException('Fri, 31 Dec 1999 23:59:59 GMT')); + $this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders()); + + $flattened = FlattenException::create(new TooManyRequestsHttpException(120)); + $this->assertEquals(['Retry-After' => 120], $flattened->getHeaders()); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testFlattenHttpException(\Exception $exception) + { + $flattened = FlattenException::create($exception); + $flattened2 = FlattenException::create($exception); + + $flattened->setPrevious($flattened2); + + $this->assertEquals($exception->getMessage(), $flattened->getMessage(), 'The message is copied from the original exception.'); + $this->assertEquals($exception->getCode(), $flattened->getCode(), 'The code is copied from the original exception.'); + $this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception'); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testPrevious(\Exception $exception) + { + $flattened = FlattenException::create($exception); + $flattened2 = FlattenException::create($exception); + + $flattened->setPrevious($flattened2); + + $this->assertSame($flattened2, $flattened->getPrevious()); + + $this->assertSame([$flattened2], $flattened->getAllPrevious()); + } + + /** + * @requires PHP 7.0 + */ + public function testPreviousError() + { + $exception = new \Exception('test', 123, new \ParseError('Oh noes!', 42)); + + $flattened = FlattenException::create($exception)->getPrevious(); + + $this->assertEquals('Parse error: Oh noes!', $flattened->getMessage(), 'The message is copied from the original exception.'); + $this->assertEquals(42, $flattened->getCode(), 'The code is copied from the original exception.'); + $this->assertEquals('Symfony\Component\Debug\Exception\FatalThrowableError', $flattened->getClass(), 'The class is set to the class of the original exception'); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testLine(\Exception $exception) + { + $flattened = FlattenException::create($exception); + $this->assertSame($exception->getLine(), $flattened->getLine()); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testFile(\Exception $exception) + { + $flattened = FlattenException::create($exception); + $this->assertSame($exception->getFile(), $flattened->getFile()); + } + + /** + * @dataProvider flattenDataProvider + */ + public function testToArray(\Exception $exception) + { + $flattened = FlattenException::create($exception); + $flattened->setTrace([], 'foo.php', 123); + + $this->assertEquals([ + [ + 'message' => 'test', + 'class' => 'Exception', + 'trace' => [[ + 'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123, + 'args' => [], + ]], + ], + ], $flattened->toArray()); + } + + public function flattenDataProvider() + { + return [ + [new \Exception('test', 123)], + ]; + } + + public function testArguments() + { + if (\PHP_VERSION_ID >= 70400) { + $this->markTestSkipped('PHP 7.4 removes arguments from exception traces.'); + } + + $dh = opendir(__DIR__); + $fh = tmpfile(); + + $incomplete = unserialize('O:14:"BogusTestClass":0:{}'); + + $exception = $this->createException([ + (object) ['foo' => 1], + new NotFoundHttpException(), + $incomplete, + $dh, + $fh, + function () {}, + [1, 2], + ['foo' => 123], + null, + true, + false, + 0, + 0.0, + '0', + '', + \INF, + \NAN, + ]); + + $flattened = FlattenException::create($exception); + $trace = $flattened->getTrace(); + $args = $trace[1]['args']; + $array = $args[0][1]; + + closedir($dh); + fclose($fh); + + $i = 0; + $this->assertSame(['object', 'stdClass'], $array[$i++]); + $this->assertSame(['object', 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException'], $array[$i++]); + $this->assertSame(['incomplete-object', 'BogusTestClass'], $array[$i++]); + $this->assertSame(['resource', \defined('HHVM_VERSION') ? 'Directory' : 'stream'], $array[$i++]); + $this->assertSame(['resource', 'stream'], $array[$i++]); + + $args = $array[$i++]; + $this->assertSame($args[0], 'object'); + $this->assertTrue('Closure' === $args[1] || is_subclass_of($args[1], '\Closure'), 'Expect object class name to be Closure or a subclass of Closure.'); + + $this->assertSame(['array', [['integer', 1], ['integer', 2]]], $array[$i++]); + $this->assertSame(['array', ['foo' => ['integer', 123]]], $array[$i++]); + $this->assertSame(['null', null], $array[$i++]); + $this->assertSame(['boolean', true], $array[$i++]); + $this->assertSame(['boolean', false], $array[$i++]); + $this->assertSame(['integer', 0], $array[$i++]); + $this->assertSame(['float', 0.0], $array[$i++]); + $this->assertSame(['string', '0'], $array[$i++]); + $this->assertSame(['string', ''], $array[$i++]); + $this->assertSame(['float', \INF], $array[$i++]); + + // assertEquals() does not like NAN values. + $this->assertEquals('float', $array[$i][0]); + $this->assertNan($array[$i][1]); + } + + public function testRecursionInArguments() + { + if (\PHP_VERSION_ID >= 70400) { + $this->markTestSkipped('PHP 7.4 removes arguments from exception traces.'); + } + + $a = null; + $a = ['foo', [2, &$a]]; + $exception = $this->createException($a); + + $flattened = FlattenException::create($exception); + $trace = $flattened->getTrace(); + $this->assertStringContainsString('*DEEP NESTED ARRAY*', serialize($trace)); + } + + public function testTooBigArray() + { + if (\PHP_VERSION_ID >= 70400) { + $this->markTestSkipped('PHP 7.4 removes arguments from exception traces.'); + } + + $a = []; + for ($i = 0; $i < 20; ++$i) { + for ($j = 0; $j < 50; ++$j) { + for ($k = 0; $k < 10; ++$k) { + $a[$i][$j][$k] = 'value'; + } + } + } + $a[20] = 'value'; + $a[21] = 'value1'; + $exception = $this->createException($a); + + $flattened = FlattenException::create($exception); + $trace = $flattened->getTrace(); + + $this->assertSame($trace[1]['args'][0], ['array', ['array', '*SKIPPED over 10000 entries*']]); + + $serializeTrace = serialize($trace); + + $this->assertStringContainsString('*SKIPPED over 10000 entries*', $serializeTrace); + $this->assertStringNotContainsString('*value1*', $serializeTrace); + } + + private function createException($foo) + { + return new \Exception(); + } +} diff --git a/vendor/symfony/debug/Tests/ExceptionHandlerTest.php b/vendor/symfony/debug/Tests/ExceptionHandlerTest.php new file mode 100644 index 0000000..3ed3cfa --- /dev/null +++ b/vendor/symfony/debug/Tests/ExceptionHandlerTest.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Debug\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Debug\Exception\OutOfMemoryException; +use Symfony\Component\Debug\ExceptionHandler; +use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; + +require_once __DIR__.'/HeaderMock.php'; + +class ExceptionHandlerTest extends TestCase +{ + protected function setUp() + { + testHeader(); + } + + protected function tearDown() + { + testHeader(); + } + + public function testDebug() + { + $handler = new ExceptionHandler(false); + + ob_start(); + $handler->sendPhpResponse(new \RuntimeException('Foo')); + $response = ob_get_clean(); + + $this->assertStringContainsString('Whoops, looks like something went wrong.', $response); + $this->assertStringNotContainsString('
+ *
+ * @internal
+ */
+final class Mbstring
+{
+ const MB_CASE_FOLD = PHP_INT_MAX;
+
+ private static $encodingList = array('ASCII', 'UTF-8');
+ private static $language = 'neutral';
+ private static $internalEncoding = 'UTF-8';
+ private static $caseFold = array(
+ array('µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"),
+ array('μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'),
+ );
+
+ public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
+ {
+ if (\is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
+ $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
+ } else {
+ $fromEncoding = self::getEncoding($fromEncoding);
+ }
+
+ $toEncoding = self::getEncoding($toEncoding);
+
+ if ('BASE64' === $fromEncoding) {
+ $s = base64_decode($s);
+ $fromEncoding = $toEncoding;
+ }
+
+ if ('BASE64' === $toEncoding) {
+ return base64_encode($s);
+ }
+
+ if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
+ if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
+ $fromEncoding = 'Windows-1252';
+ }
+ if ('UTF-8' !== $fromEncoding) {
+ $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
+ }
+
+ return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
+ }
+
+ if ('HTML-ENTITIES' === $fromEncoding) {
+ $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
+ $fromEncoding = 'UTF-8';
+ }
+
+ return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
+ }
+
+ public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
+ {
+ $vars = array(&$a, &$b, &$c, &$d, &$e, &$f);
+
+ $ok = true;
+ array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
+ if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
+ $ok = false;
+ }
+ });
+
+ return $ok ? $fromEncoding : false;
+ }
+
+ public static function mb_decode_mimeheader($s)
+ {
+ return iconv_mime_decode($s, 2, self::$internalEncoding);
+ }
+
+ public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
+ {
+ trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
+ }
+
+ public static function mb_decode_numericentity($s, $convmap, $encoding = null)
+ {
+ if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
+ trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);
+
+ return null;
+ }
+
+ if (!\is_array($convmap) || !$convmap) {
+ return false;
+ }
+
+ if (null !== $encoding && !\is_scalar($encoding)) {
+ trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);
+
+ return ''; // Instead of null (cf. mb_encode_numericentity).
+ }
+
+ $s = (string) $s;
+ if ('' === $s) {
+ return '';
+ }
+
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' === $encoding) {
+ $encoding = null;
+ if (!preg_match('//u', $s)) {
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
+ }
+ } else {
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
+ }
+
+ $cnt = floor(\count($convmap) / 4) * 4;
+
+ for ($i = 0; $i < $cnt; $i += 4) {
+ // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
+ $convmap[$i] += $convmap[$i + 2];
+ $convmap[$i + 1] += $convmap[$i + 2];
+ }
+
+ $s = preg_replace_callback('/(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
+ $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
+ for ($i = 0; $i < $cnt; $i += 4) {
+ if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
+ return Mbstring::mb_chr($c - $convmap[$i + 2]);
+ }
+ }
+
+ return $m[0];
+ }, $s);
+
+ if (null === $encoding) {
+ return $s;
+ }
+
+ return iconv('UTF-8', $encoding.'//IGNORE', $s);
+ }
+
+ public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
+ {
+ if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
+ trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);
+
+ return null;
+ }
+
+ if (!\is_array($convmap) || !$convmap) {
+ return false;
+ }
+
+ if (null !== $encoding && !\is_scalar($encoding)) {
+ trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);
+
+ return null; // Instead of '' (cf. mb_decode_numericentity).
+ }
+
+ if (null !== $is_hex && !\is_scalar($is_hex)) {
+ trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', E_USER_WARNING);
+
+ return null;
+ }
+
+ $s = (string) $s;
+ if ('' === $s) {
+ return '';
+ }
+
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' === $encoding) {
+ $encoding = null;
+ if (!preg_match('//u', $s)) {
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
+ }
+ } else {
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
+ }
+
+ static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
+
+ $cnt = floor(\count($convmap) / 4) * 4;
+ $i = 0;
+ $len = \strlen($s);
+ $result = '';
+
+ while ($i < $len) {
+ $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
+ $uchr = substr($s, $i, $ulen);
+ $i += $ulen;
+ $c = self::mb_ord($uchr);
+
+ for ($j = 0; $j < $cnt; $j += 4) {
+ if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
+ $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
+ $result .= $is_hex ? sprintf('%X;', $cOffset) : ''.$cOffset.';';
+ continue 2;
+ }
+ }
+ $result .= $uchr;
+ }
+
+ if (null === $encoding) {
+ return $result;
+ }
+
+ return iconv('UTF-8', $encoding.'//IGNORE', $result);
+ }
+
+ public static function mb_convert_case($s, $mode, $encoding = null)
+ {
+ $s = (string) $s;
+ if ('' === $s) {
+ return '';
+ }
+
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' === $encoding) {
+ $encoding = null;
+ if (!preg_match('//u', $s)) {
+ $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
+ }
+ } else {
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
+ }
+
+ if (MB_CASE_TITLE == $mode) {
+ static $titleRegexp = null;
+ if (null === $titleRegexp) {
+ $titleRegexp = self::getData('titleCaseRegexp');
+ }
+ $s = preg_replace_callback($titleRegexp, array(__CLASS__, 'title_case'), $s);
+ } else {
+ if (MB_CASE_UPPER == $mode) {
+ static $upper = null;
+ if (null === $upper) {
+ $upper = self::getData('upperCase');
+ }
+ $map = $upper;
+ } else {
+ if (self::MB_CASE_FOLD === $mode) {
+ $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
+ }
+
+ static $lower = null;
+ if (null === $lower) {
+ $lower = self::getData('lowerCase');
+ }
+ $map = $lower;
+ }
+
+ static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
+
+ $i = 0;
+ $len = \strlen($s);
+
+ while ($i < $len) {
+ $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
+ $uchr = substr($s, $i, $ulen);
+ $i += $ulen;
+
+ if (isset($map[$uchr])) {
+ $uchr = $map[$uchr];
+ $nlen = \strlen($uchr);
+
+ if ($nlen == $ulen) {
+ $nlen = $i;
+ do {
+ $s[--$nlen] = $uchr[--$ulen];
+ } while ($ulen);
+ } else {
+ $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
+ $len += $nlen - $ulen;
+ $i += $nlen - $ulen;
+ }
+ }
+ }
+ }
+
+ if (null === $encoding) {
+ return $s;
+ }
+
+ return iconv('UTF-8', $encoding.'//IGNORE', $s);
+ }
+
+ public static function mb_internal_encoding($encoding = null)
+ {
+ if (null === $encoding) {
+ return self::$internalEncoding;
+ }
+
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
+ self::$internalEncoding = $encoding;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static function mb_language($lang = null)
+ {
+ if (null === $lang) {
+ return self::$language;
+ }
+
+ switch ($lang = strtolower($lang)) {
+ case 'uni':
+ case 'neutral':
+ self::$language = $lang;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static function mb_list_encodings()
+ {
+ return array('UTF-8');
+ }
+
+ public static function mb_encoding_aliases($encoding)
+ {
+ switch (strtoupper($encoding)) {
+ case 'UTF8':
+ case 'UTF-8':
+ return array('utf8');
+ }
+
+ return false;
+ }
+
+ public static function mb_check_encoding($var = null, $encoding = null)
+ {
+ if (null === $encoding) {
+ if (null === $var) {
+ return false;
+ }
+ $encoding = self::$internalEncoding;
+ }
+
+ return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
+ }
+
+ public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
+ {
+ if (null === $encodingList) {
+ $encodingList = self::$encodingList;
+ } else {
+ if (!\is_array($encodingList)) {
+ $encodingList = array_map('trim', explode(',', $encodingList));
+ }
+ $encodingList = array_map('strtoupper', $encodingList);
+ }
+
+ foreach ($encodingList as $enc) {
+ switch ($enc) {
+ case 'ASCII':
+ if (!preg_match('/[\x80-\xFF]/', $str)) {
+ return $enc;
+ }
+ break;
+
+ case 'UTF8':
+ case 'UTF-8':
+ if (preg_match('//u', $str)) {
+ return 'UTF-8';
+ }
+ break;
+
+ default:
+ if (0 === strncmp($enc, 'ISO-8859-', 9)) {
+ return $enc;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static function mb_detect_order($encodingList = null)
+ {
+ if (null === $encodingList) {
+ return self::$encodingList;
+ }
+
+ if (!\is_array($encodingList)) {
+ $encodingList = array_map('trim', explode(',', $encodingList));
+ }
+ $encodingList = array_map('strtoupper', $encodingList);
+
+ foreach ($encodingList as $enc) {
+ switch ($enc) {
+ default:
+ if (strncmp($enc, 'ISO-8859-', 9)) {
+ return false;
+ }
+ // no break
+ case 'ASCII':
+ case 'UTF8':
+ case 'UTF-8':
+ }
+ }
+
+ self::$encodingList = $encodingList;
+
+ return true;
+ }
+
+ public static function mb_strlen($s, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return \strlen($s);
+ }
+
+ return @iconv_strlen($s, $encoding);
+ }
+
+ public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return strpos($haystack, $needle, $offset);
+ }
+
+ $needle = (string) $needle;
+ if ('' === $needle) {
+ trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);
+
+ return false;
+ }
+
+ return iconv_strpos($haystack, $needle, $offset, $encoding);
+ }
+
+ public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return strrpos($haystack, $needle, $offset);
+ }
+
+ if ($offset != (int) $offset) {
+ $offset = 0;
+ } elseif ($offset = (int) $offset) {
+ if ($offset < 0) {
+ if (0 > $offset += self::mb_strlen($needle)) {
+ $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
+ }
+ $offset = 0;
+ } else {
+ $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
+ }
+ }
+
+ $pos = iconv_strrpos($haystack, $needle, $encoding);
+
+ return false !== $pos ? $offset + $pos : false;
+ }
+
+ public static function mb_str_split($string, $split_length = 1, $encoding = null)
+ {
+ if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) {
+ trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', E_USER_WARNING);
+
+ return null;
+ }
+
+ if (1 > $split_length = (int) $split_length) {
+ trigger_error('The length of each segment must be greater than zero', E_USER_WARNING);
+
+ return false;
+ }
+
+ if (null === $encoding) {
+ $encoding = mb_internal_encoding();
+ }
+
+ if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
+ $rx = '/(';
+ while (65535 < $split_length) {
+ $rx .= '.{65535}';
+ $split_length -= 65535;
+ }
+ $rx .= '.{'.$split_length.'})/us';
+
+ return preg_split($rx, $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+ }
+
+ $result = array();
+ $length = mb_strlen($string, $encoding);
+
+ for ($i = 0; $i < $length; $i += $split_length) {
+ $result[] = mb_substr($string, $i, $split_length, $encoding);
+ }
+
+ return $result;
+ }
+
+ public static function mb_strtolower($s, $encoding = null)
+ {
+ return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
+ }
+
+ public static function mb_strtoupper($s, $encoding = null)
+ {
+ return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
+ }
+
+ public static function mb_substitute_character($c = null)
+ {
+ if (0 === strcasecmp($c, 'none')) {
+ return true;
+ }
+
+ return null !== $c ? false : 'none';
+ }
+
+ public static function mb_substr($s, $start, $length = null, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ return (string) substr($s, $start, null === $length ? 2147483647 : $length);
+ }
+
+ if ($start < 0) {
+ $start = iconv_strlen($s, $encoding) + $start;
+ if ($start < 0) {
+ $start = 0;
+ }
+ }
+
+ if (null === $length) {
+ $length = 2147483647;
+ } elseif ($length < 0) {
+ $length = iconv_strlen($s, $encoding) + $length - $start;
+ if ($length < 0) {
+ return '';
+ }
+ }
+
+ return (string) iconv_substr($s, $start, $length, $encoding);
+ }
+
+ public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
+ {
+ $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
+ $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
+
+ return self::mb_strpos($haystack, $needle, $offset, $encoding);
+ }
+
+ public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
+ {
+ $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
+
+ return self::getSubpart($pos, $part, $haystack, $encoding);
+ }
+
+ public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+ if ('CP850' === $encoding || 'ASCII' === $encoding) {
+ $pos = strrpos($haystack, $needle);
+ } else {
+ $needle = self::mb_substr($needle, 0, 1, $encoding);
+ $pos = iconv_strrpos($haystack, $needle, $encoding);
+ }
+
+ return self::getSubpart($pos, $part, $haystack, $encoding);
+ }
+
+ public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
+ {
+ $needle = self::mb_substr($needle, 0, 1, $encoding);
+ $pos = self::mb_strripos($haystack, $needle, $encoding);
+
+ return self::getSubpart($pos, $part, $haystack, $encoding);
+ }
+
+ public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
+ {
+ $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
+ $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
+
+ return self::mb_strrpos($haystack, $needle, $offset, $encoding);
+ }
+
+ public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
+ {
+ $pos = strpos($haystack, $needle);
+ if (false === $pos) {
+ return false;
+ }
+ if ($part) {
+ return substr($haystack, 0, $pos);
+ }
+
+ return substr($haystack, $pos);
+ }
+
+ public static function mb_get_info($type = 'all')
+ {
+ $info = array(
+ 'internal_encoding' => self::$internalEncoding,
+ 'http_output' => 'pass',
+ 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
+ 'func_overload' => 0,
+ 'func_overload_list' => 'no overload',
+ 'mail_charset' => 'UTF-8',
+ 'mail_header_encoding' => 'BASE64',
+ 'mail_body_encoding' => 'BASE64',
+ 'illegal_chars' => 0,
+ 'encoding_translation' => 'Off',
+ 'language' => self::$language,
+ 'detect_order' => self::$encodingList,
+ 'substitute_character' => 'none',
+ 'strict_detection' => 'Off',
+ );
+
+ if ('all' === $type) {
+ return $info;
+ }
+ if (isset($info[$type])) {
+ return $info[$type];
+ }
+
+ return false;
+ }
+
+ public static function mb_http_input($type = '')
+ {
+ return false;
+ }
+
+ public static function mb_http_output($encoding = null)
+ {
+ return null !== $encoding ? 'pass' === $encoding : 'pass';
+ }
+
+ public static function mb_strwidth($s, $encoding = null)
+ {
+ $encoding = self::getEncoding($encoding);
+
+ if ('UTF-8' !== $encoding) {
+ $s = iconv($encoding, 'UTF-8//IGNORE', $s);
+ }
+
+ $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
+
+ return ($wide << 1) + iconv_strlen($s, 'UTF-8');
+ }
+
+ public static function mb_substr_count($haystack, $needle, $encoding = null)
+ {
+ return substr_count($haystack, $needle);
+ }
+
+ public static function mb_output_handler($contents, $status)
+ {
+ return $contents;
+ }
+
+ public static function mb_chr($code, $encoding = null)
+ {
+ if (0x80 > $code %= 0x200000) {
+ $s = \chr($code);
+ } elseif (0x800 > $code) {
+ $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
+ } elseif (0x10000 > $code) {
+ $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
+ } else {
+ $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
+ }
+
+ if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
+ $s = mb_convert_encoding($s, $encoding, 'UTF-8');
+ }
+
+ return $s;
+ }
+
+ public static function mb_ord($s, $encoding = null)
+ {
+ if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
+ $s = mb_convert_encoding($s, 'UTF-8', $encoding);
+ }
+
+ if (1 === \strlen($s)) {
+ return \ord($s);
+ }
+
+ $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
+ if (0xF0 <= $code) {
+ return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
+ }
+ if (0xE0 <= $code) {
+ return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
+ }
+ if (0xC0 <= $code) {
+ return (($code - 0xC0) << 6) + $s[2] - 0x80;
+ }
+
+ return $code;
+ }
+
+ private static function getSubpart($pos, $part, $haystack, $encoding)
+ {
+ if (false === $pos) {
+ return false;
+ }
+ if ($part) {
+ return self::mb_substr($haystack, 0, $pos, $encoding);
+ }
+
+ return self::mb_substr($haystack, $pos, null, $encoding);
+ }
+
+ private static function html_encoding_callback(array $m)
+ {
+ $i = 1;
+ $entities = '';
+ $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));
+
+ while (isset($m[$i])) {
+ if (0x80 > $m[$i]) {
+ $entities .= \chr($m[$i++]);
+ continue;
+ }
+ if (0xF0 <= $m[$i]) {
+ $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
+ } elseif (0xE0 <= $m[$i]) {
+ $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
+ } else {
+ $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
+ }
+
+ $entities .= ''.$c.';';
+ }
+
+ return $entities;
+ }
+
+ private static function title_case(array $s)
+ {
+ return self::mb_convert_case($s[1], MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], MB_CASE_LOWER, 'UTF-8');
+ }
+
+ private static function getData($file)
+ {
+ if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
+ return require $file;
+ }
+
+ return false;
+ }
+
+ private static function getEncoding($encoding)
+ {
+ if (null === $encoding) {
+ return self::$internalEncoding;
+ }
+
+ if ('UTF-8' === $encoding) {
+ return 'UTF-8';
+ }
+
+ $encoding = strtoupper($encoding);
+
+ if ('8BIT' === $encoding || 'BINARY' === $encoding) {
+ return 'CP850';
+ }
+
+ if ('UTF8' === $encoding) {
+ return 'UTF-8';
+ }
+
+ return $encoding;
+ }
+}
diff --git a/vendor/symfony/polyfill-mbstring/README.md b/vendor/symfony/polyfill-mbstring/README.md
new file mode 100644
index 0000000..4efb599
--- /dev/null
+++ b/vendor/symfony/polyfill-mbstring/README.md
@@ -0,0 +1,13 @@
+Symfony Polyfill / Mbstring
+===========================
+
+This component provides a partial, native PHP implementation for the
+[Mbstring](https://php.net/mbstring) extension.
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/vendor/symfony/polyfill-mbstring/Resources/mb_convert_variables.php8 b/vendor/symfony/polyfill-mbstring/Resources/mb_convert_variables.php8
new file mode 100644
index 0000000..d22d058
--- /dev/null
+++ b/vendor/symfony/polyfill-mbstring/Resources/mb_convert_variables.php8
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Mbstring as p;
+
+if (!function_exists('mb_convert_variables')) {
+ /**
+ * Convert character code in variable(s)
+ */
+ function mb_convert_variables($to_encoding, $from_encoding, &$var, &...$vars)
+ {
+ $vars = [&$var, ...$vars];
+
+ $ok = true;
+ array_walk_recursive($vars, function (&$v) use (&$ok, $to_encoding, $from_encoding) {
+ if (false === $v = p\Mbstring::mb_convert_encoding($v, $to_encoding, $from_encoding)) {
+ $ok = false;
+ }
+ });
+
+ return $ok ? $from_encoding : false;
+ }
+}
diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
new file mode 100644
index 0000000..a22eca5
--- /dev/null
+++ b/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php
@@ -0,0 +1,1397 @@
+ 'a',
+ 'B' => 'b',
+ 'C' => 'c',
+ 'D' => 'd',
+ 'E' => 'e',
+ 'F' => 'f',
+ 'G' => 'g',
+ 'H' => 'h',
+ 'I' => 'i',
+ 'J' => 'j',
+ 'K' => 'k',
+ 'L' => 'l',
+ 'M' => 'm',
+ 'N' => 'n',
+ 'O' => 'o',
+ 'P' => 'p',
+ 'Q' => 'q',
+ 'R' => 'r',
+ 'S' => 's',
+ 'T' => 't',
+ 'U' => 'u',
+ 'V' => 'v',
+ 'W' => 'w',
+ 'X' => 'x',
+ 'Y' => 'y',
+ 'Z' => 'z',
+ 'À' => 'à',
+ 'Á' => 'á',
+ 'Â' => 'â',
+ 'Ã' => 'ã',
+ 'Ä' => 'ä',
+ 'Å' => 'å',
+ 'Æ' => 'æ',
+ 'Ç' => 'ç',
+ 'È' => 'è',
+ 'É' => 'é',
+ 'Ê' => 'ê',
+ 'Ë' => 'ë',
+ 'Ì' => 'ì',
+ 'Í' => 'í',
+ 'Î' => 'î',
+ 'Ï' => 'ï',
+ 'Ð' => 'ð',
+ 'Ñ' => 'ñ',
+ 'Ò' => 'ò',
+ 'Ó' => 'ó',
+ 'Ô' => 'ô',
+ 'Õ' => 'õ',
+ 'Ö' => 'ö',
+ 'Ø' => 'ø',
+ 'Ù' => 'ù',
+ 'Ú' => 'ú',
+ 'Û' => 'û',
+ 'Ü' => 'ü',
+ 'Ý' => 'ý',
+ 'Þ' => 'þ',
+ 'Ā' => 'ā',
+ 'Ă' => 'ă',
+ 'Ą' => 'ą',
+ 'Ć' => 'ć',
+ 'Ĉ' => 'ĉ',
+ 'Ċ' => 'ċ',
+ 'Č' => 'č',
+ 'Ď' => 'ď',
+ 'Đ' => 'đ',
+ 'Ē' => 'ē',
+ 'Ĕ' => 'ĕ',
+ 'Ė' => 'ė',
+ 'Ę' => 'ę',
+ 'Ě' => 'ě',
+ 'Ĝ' => 'ĝ',
+ 'Ğ' => 'ğ',
+ 'Ġ' => 'ġ',
+ 'Ģ' => 'ģ',
+ 'Ĥ' => 'ĥ',
+ 'Ħ' => 'ħ',
+ 'Ĩ' => 'ĩ',
+ 'Ī' => 'ī',
+ 'Ĭ' => 'ĭ',
+ 'Į' => 'į',
+ 'İ' => 'i',
+ 'IJ' => 'ij',
+ 'Ĵ' => 'ĵ',
+ 'Ķ' => 'ķ',
+ 'Ĺ' => 'ĺ',
+ 'Ļ' => 'ļ',
+ 'Ľ' => 'ľ',
+ 'Ŀ' => 'ŀ',
+ 'Ł' => 'ł',
+ 'Ń' => 'ń',
+ 'Ņ' => 'ņ',
+ 'Ň' => 'ň',
+ 'Ŋ' => 'ŋ',
+ 'Ō' => 'ō',
+ 'Ŏ' => 'ŏ',
+ 'Ő' => 'ő',
+ 'Œ' => 'œ',
+ 'Ŕ' => 'ŕ',
+ 'Ŗ' => 'ŗ',
+ 'Ř' => 'ř',
+ 'Ś' => 'ś',
+ 'Ŝ' => 'ŝ',
+ 'Ş' => 'ş',
+ 'Š' => 'š',
+ 'Ţ' => 'ţ',
+ 'Ť' => 'ť',
+ 'Ŧ' => 'ŧ',
+ 'Ũ' => 'ũ',
+ 'Ū' => 'ū',
+ 'Ŭ' => 'ŭ',
+ 'Ů' => 'ů',
+ 'Ű' => 'ű',
+ 'Ų' => 'ų',
+ 'Ŵ' => 'ŵ',
+ 'Ŷ' => 'ŷ',
+ 'Ÿ' => 'ÿ',
+ 'Ź' => 'ź',
+ 'Ż' => 'ż',
+ 'Ž' => 'ž',
+ 'Ɓ' => 'ɓ',
+ 'Ƃ' => 'ƃ',
+ 'Ƅ' => 'ƅ',
+ 'Ɔ' => 'ɔ',
+ 'Ƈ' => 'ƈ',
+ 'Ɖ' => 'ɖ',
+ 'Ɗ' => 'ɗ',
+ 'Ƌ' => 'ƌ',
+ 'Ǝ' => 'ǝ',
+ 'Ə' => 'ə',
+ 'Ɛ' => 'ɛ',
+ 'Ƒ' => 'ƒ',
+ 'Ɠ' => 'ɠ',
+ 'Ɣ' => 'ɣ',
+ 'Ɩ' => 'ɩ',
+ 'Ɨ' => 'ɨ',
+ 'Ƙ' => 'ƙ',
+ 'Ɯ' => 'ɯ',
+ 'Ɲ' => 'ɲ',
+ 'Ɵ' => 'ɵ',
+ 'Ơ' => 'ơ',
+ 'Ƣ' => 'ƣ',
+ 'Ƥ' => 'ƥ',
+ 'Ʀ' => 'ʀ',
+ 'Ƨ' => 'ƨ',
+ 'Ʃ' => 'ʃ',
+ 'Ƭ' => 'ƭ',
+ 'Ʈ' => 'ʈ',
+ 'Ư' => 'ư',
+ 'Ʊ' => 'ʊ',
+ 'Ʋ' => 'ʋ',
+ 'Ƴ' => 'ƴ',
+ 'Ƶ' => 'ƶ',
+ 'Ʒ' => 'ʒ',
+ 'Ƹ' => 'ƹ',
+ 'Ƽ' => 'ƽ',
+ 'DŽ' => 'dž',
+ 'Dž' => 'dž',
+ 'LJ' => 'lj',
+ 'Lj' => 'lj',
+ 'NJ' => 'nj',
+ 'Nj' => 'nj',
+ 'Ǎ' => 'ǎ',
+ 'Ǐ' => 'ǐ',
+ 'Ǒ' => 'ǒ',
+ 'Ǔ' => 'ǔ',
+ 'Ǖ' => 'ǖ',
+ 'Ǘ' => 'ǘ',
+ 'Ǚ' => 'ǚ',
+ 'Ǜ' => 'ǜ',
+ 'Ǟ' => 'ǟ',
+ 'Ǡ' => 'ǡ',
+ 'Ǣ' => 'ǣ',
+ 'Ǥ' => 'ǥ',
+ 'Ǧ' => 'ǧ',
+ 'Ǩ' => 'ǩ',
+ 'Ǫ' => 'ǫ',
+ 'Ǭ' => 'ǭ',
+ 'Ǯ' => 'ǯ',
+ 'DZ' => 'dz',
+ 'Dz' => 'dz',
+ 'Ǵ' => 'ǵ',
+ 'Ƕ' => 'ƕ',
+ 'Ƿ' => 'ƿ',
+ 'Ǹ' => 'ǹ',
+ 'Ǻ' => 'ǻ',
+ 'Ǽ' => 'ǽ',
+ 'Ǿ' => 'ǿ',
+ 'Ȁ' => 'ȁ',
+ 'Ȃ' => 'ȃ',
+ 'Ȅ' => 'ȅ',
+ 'Ȇ' => 'ȇ',
+ 'Ȉ' => 'ȉ',
+ 'Ȋ' => 'ȋ',
+ 'Ȍ' => 'ȍ',
+ 'Ȏ' => 'ȏ',
+ 'Ȑ' => 'ȑ',
+ 'Ȓ' => 'ȓ',
+ 'Ȕ' => 'ȕ',
+ 'Ȗ' => 'ȗ',
+ 'Ș' => 'ș',
+ 'Ț' => 'ț',
+ 'Ȝ' => 'ȝ',
+ 'Ȟ' => 'ȟ',
+ 'Ƞ' => 'ƞ',
+ 'Ȣ' => 'ȣ',
+ 'Ȥ' => 'ȥ',
+ 'Ȧ' => 'ȧ',
+ 'Ȩ' => 'ȩ',
+ 'Ȫ' => 'ȫ',
+ 'Ȭ' => 'ȭ',
+ 'Ȯ' => 'ȯ',
+ 'Ȱ' => 'ȱ',
+ 'Ȳ' => 'ȳ',
+ 'Ⱥ' => 'ⱥ',
+ 'Ȼ' => 'ȼ',
+ 'Ƚ' => 'ƚ',
+ 'Ⱦ' => 'ⱦ',
+ 'Ɂ' => 'ɂ',
+ 'Ƀ' => 'ƀ',
+ 'Ʉ' => 'ʉ',
+ 'Ʌ' => 'ʌ',
+ 'Ɇ' => 'ɇ',
+ 'Ɉ' => 'ɉ',
+ 'Ɋ' => 'ɋ',
+ 'Ɍ' => 'ɍ',
+ 'Ɏ' => 'ɏ',
+ 'Ͱ' => 'ͱ',
+ 'Ͳ' => 'ͳ',
+ 'Ͷ' => 'ͷ',
+ 'Ϳ' => 'ϳ',
+ 'Ά' => 'ά',
+ 'Έ' => 'έ',
+ 'Ή' => 'ή',
+ 'Ί' => 'ί',
+ 'Ό' => 'ό',
+ 'Ύ' => 'ύ',
+ 'Ώ' => 'ώ',
+ 'Α' => 'α',
+ 'Β' => 'β',
+ 'Γ' => 'γ',
+ 'Δ' => 'δ',
+ 'Ε' => 'ε',
+ 'Ζ' => 'ζ',
+ 'Η' => 'η',
+ 'Θ' => 'θ',
+ 'Ι' => 'ι',
+ 'Κ' => 'κ',
+ 'Λ' => 'λ',
+ 'Μ' => 'μ',
+ 'Ν' => 'ν',
+ 'Ξ' => 'ξ',
+ 'Ο' => 'ο',
+ 'Π' => 'π',
+ 'Ρ' => 'ρ',
+ 'Σ' => 'σ',
+ 'Τ' => 'τ',
+ 'Υ' => 'υ',
+ 'Φ' => 'φ',
+ 'Χ' => 'χ',
+ 'Ψ' => 'ψ',
+ 'Ω' => 'ω',
+ 'Ϊ' => 'ϊ',
+ 'Ϋ' => 'ϋ',
+ 'Ϗ' => 'ϗ',
+ 'Ϙ' => 'ϙ',
+ 'Ϛ' => 'ϛ',
+ 'Ϝ' => 'ϝ',
+ 'Ϟ' => 'ϟ',
+ 'Ϡ' => 'ϡ',
+ 'Ϣ' => 'ϣ',
+ 'Ϥ' => 'ϥ',
+ 'Ϧ' => 'ϧ',
+ 'Ϩ' => 'ϩ',
+ 'Ϫ' => 'ϫ',
+ 'Ϭ' => 'ϭ',
+ 'Ϯ' => 'ϯ',
+ 'ϴ' => 'θ',
+ 'Ϸ' => 'ϸ',
+ 'Ϲ' => 'ϲ',
+ 'Ϻ' => 'ϻ',
+ 'Ͻ' => 'ͻ',
+ 'Ͼ' => 'ͼ',
+ 'Ͽ' => 'ͽ',
+ 'Ѐ' => 'ѐ',
+ 'Ё' => 'ё',
+ 'Ђ' => 'ђ',
+ 'Ѓ' => 'ѓ',
+ 'Є' => 'є',
+ 'Ѕ' => 'ѕ',
+ 'І' => 'і',
+ 'Ї' => 'ї',
+ 'Ј' => 'ј',
+ 'Љ' => 'љ',
+ 'Њ' => 'њ',
+ 'Ћ' => 'ћ',
+ 'Ќ' => 'ќ',
+ 'Ѝ' => 'ѝ',
+ 'Ў' => 'ў',
+ 'Џ' => 'џ',
+ 'А' => 'а',
+ 'Б' => 'б',
+ 'В' => 'в',
+ 'Г' => 'г',
+ 'Д' => 'д',
+ 'Е' => 'е',
+ 'Ж' => 'ж',
+ 'З' => 'з',
+ 'И' => 'и',
+ 'Й' => 'й',
+ 'К' => 'к',
+ 'Л' => 'л',
+ 'М' => 'м',
+ 'Н' => 'н',
+ 'О' => 'о',
+ 'П' => 'п',
+ 'Р' => 'р',
+ 'С' => 'с',
+ 'Т' => 'т',
+ 'У' => 'у',
+ 'Ф' => 'ф',
+ 'Х' => 'х',
+ 'Ц' => 'ц',
+ 'Ч' => 'ч',
+ 'Ш' => 'ш',
+ 'Щ' => 'щ',
+ 'Ъ' => 'ъ',
+ 'Ы' => 'ы',
+ 'Ь' => 'ь',
+ 'Э' => 'э',
+ 'Ю' => 'ю',
+ 'Я' => 'я',
+ 'Ѡ' => 'ѡ',
+ 'Ѣ' => 'ѣ',
+ 'Ѥ' => 'ѥ',
+ 'Ѧ' => 'ѧ',
+ 'Ѩ' => 'ѩ',
+ 'Ѫ' => 'ѫ',
+ 'Ѭ' => 'ѭ',
+ 'Ѯ' => 'ѯ',
+ 'Ѱ' => 'ѱ',
+ 'Ѳ' => 'ѳ',
+ 'Ѵ' => 'ѵ',
+ 'Ѷ' => 'ѷ',
+ 'Ѹ' => 'ѹ',
+ 'Ѻ' => 'ѻ',
+ 'Ѽ' => 'ѽ',
+ 'Ѿ' => 'ѿ',
+ 'Ҁ' => 'ҁ',
+ 'Ҋ' => 'ҋ',
+ 'Ҍ' => 'ҍ',
+ 'Ҏ' => 'ҏ',
+ 'Ґ' => 'ґ',
+ 'Ғ' => 'ғ',
+ 'Ҕ' => 'ҕ',
+ 'Җ' => 'җ',
+ 'Ҙ' => 'ҙ',
+ 'Қ' => 'қ',
+ 'Ҝ' => 'ҝ',
+ 'Ҟ' => 'ҟ',
+ 'Ҡ' => 'ҡ',
+ 'Ң' => 'ң',
+ 'Ҥ' => 'ҥ',
+ 'Ҧ' => 'ҧ',
+ 'Ҩ' => 'ҩ',
+ 'Ҫ' => 'ҫ',
+ 'Ҭ' => 'ҭ',
+ 'Ү' => 'ү',
+ 'Ұ' => 'ұ',
+ 'Ҳ' => 'ҳ',
+ 'Ҵ' => 'ҵ',
+ 'Ҷ' => 'ҷ',
+ 'Ҹ' => 'ҹ',
+ 'Һ' => 'һ',
+ 'Ҽ' => 'ҽ',
+ 'Ҿ' => 'ҿ',
+ 'Ӏ' => 'ӏ',
+ 'Ӂ' => 'ӂ',
+ 'Ӄ' => 'ӄ',
+ 'Ӆ' => 'ӆ',
+ 'Ӈ' => 'ӈ',
+ 'Ӊ' => 'ӊ',
+ 'Ӌ' => 'ӌ',
+ 'Ӎ' => 'ӎ',
+ 'Ӑ' => 'ӑ',
+ 'Ӓ' => 'ӓ',
+ 'Ӕ' => 'ӕ',
+ 'Ӗ' => 'ӗ',
+ 'Ә' => 'ә',
+ 'Ӛ' => 'ӛ',
+ 'Ӝ' => 'ӝ',
+ 'Ӟ' => 'ӟ',
+ 'Ӡ' => 'ӡ',
+ 'Ӣ' => 'ӣ',
+ 'Ӥ' => 'ӥ',
+ 'Ӧ' => 'ӧ',
+ 'Ө' => 'ө',
+ 'Ӫ' => 'ӫ',
+ 'Ӭ' => 'ӭ',
+ 'Ӯ' => 'ӯ',
+ 'Ӱ' => 'ӱ',
+ 'Ӳ' => 'ӳ',
+ 'Ӵ' => 'ӵ',
+ 'Ӷ' => 'ӷ',
+ 'Ӹ' => 'ӹ',
+ 'Ӻ' => 'ӻ',
+ 'Ӽ' => 'ӽ',
+ 'Ӿ' => 'ӿ',
+ 'Ԁ' => 'ԁ',
+ 'Ԃ' => 'ԃ',
+ 'Ԅ' => 'ԅ',
+ 'Ԇ' => 'ԇ',
+ 'Ԉ' => 'ԉ',
+ 'Ԋ' => 'ԋ',
+ 'Ԍ' => 'ԍ',
+ 'Ԏ' => 'ԏ',
+ 'Ԑ' => 'ԑ',
+ 'Ԓ' => 'ԓ',
+ 'Ԕ' => 'ԕ',
+ 'Ԗ' => 'ԗ',
+ 'Ԙ' => 'ԙ',
+ 'Ԛ' => 'ԛ',
+ 'Ԝ' => 'ԝ',
+ 'Ԟ' => 'ԟ',
+ 'Ԡ' => 'ԡ',
+ 'Ԣ' => 'ԣ',
+ 'Ԥ' => 'ԥ',
+ 'Ԧ' => 'ԧ',
+ 'Ԩ' => 'ԩ',
+ 'Ԫ' => 'ԫ',
+ 'Ԭ' => 'ԭ',
+ 'Ԯ' => 'ԯ',
+ 'Ա' => 'ա',
+ 'Բ' => 'բ',
+ 'Գ' => 'գ',
+ 'Դ' => 'դ',
+ 'Ե' => 'ե',
+ 'Զ' => 'զ',
+ 'Է' => 'է',
+ 'Ը' => 'ը',
+ 'Թ' => 'թ',
+ 'Ժ' => 'ժ',
+ 'Ի' => 'ի',
+ 'Լ' => 'լ',
+ 'Խ' => 'խ',
+ 'Ծ' => 'ծ',
+ 'Կ' => 'կ',
+ 'Հ' => 'հ',
+ 'Ձ' => 'ձ',
+ 'Ղ' => 'ղ',
+ 'Ճ' => 'ճ',
+ 'Մ' => 'մ',
+ 'Յ' => 'յ',
+ 'Ն' => 'ն',
+ 'Շ' => 'շ',
+ 'Ո' => 'ո',
+ 'Չ' => 'չ',
+ 'Պ' => 'պ',
+ 'Ջ' => 'ջ',
+ 'Ռ' => 'ռ',
+ 'Ս' => 'ս',
+ 'Վ' => 'վ',
+ 'Տ' => 'տ',
+ 'Ր' => 'ր',
+ 'Ց' => 'ց',
+ 'Ւ' => 'ւ',
+ 'Փ' => 'փ',
+ 'Ք' => 'ք',
+ 'Օ' => 'օ',
+ 'Ֆ' => 'ֆ',
+ 'Ⴀ' => 'ⴀ',
+ 'Ⴁ' => 'ⴁ',
+ 'Ⴂ' => 'ⴂ',
+ 'Ⴃ' => 'ⴃ',
+ 'Ⴄ' => 'ⴄ',
+ 'Ⴅ' => 'ⴅ',
+ 'Ⴆ' => 'ⴆ',
+ 'Ⴇ' => 'ⴇ',
+ 'Ⴈ' => 'ⴈ',
+ 'Ⴉ' => 'ⴉ',
+ 'Ⴊ' => 'ⴊ',
+ 'Ⴋ' => 'ⴋ',
+ 'Ⴌ' => 'ⴌ',
+ 'Ⴍ' => 'ⴍ',
+ 'Ⴎ' => 'ⴎ',
+ 'Ⴏ' => 'ⴏ',
+ 'Ⴐ' => 'ⴐ',
+ 'Ⴑ' => 'ⴑ',
+ 'Ⴒ' => 'ⴒ',
+ 'Ⴓ' => 'ⴓ',
+ 'Ⴔ' => 'ⴔ',
+ 'Ⴕ' => 'ⴕ',
+ 'Ⴖ' => 'ⴖ',
+ 'Ⴗ' => 'ⴗ',
+ 'Ⴘ' => 'ⴘ',
+ 'Ⴙ' => 'ⴙ',
+ 'Ⴚ' => 'ⴚ',
+ 'Ⴛ' => 'ⴛ',
+ 'Ⴜ' => 'ⴜ',
+ 'Ⴝ' => 'ⴝ',
+ 'Ⴞ' => 'ⴞ',
+ 'Ⴟ' => 'ⴟ',
+ 'Ⴠ' => 'ⴠ',
+ 'Ⴡ' => 'ⴡ',
+ 'Ⴢ' => 'ⴢ',
+ 'Ⴣ' => 'ⴣ',
+ 'Ⴤ' => 'ⴤ',
+ 'Ⴥ' => 'ⴥ',
+ 'Ⴧ' => 'ⴧ',
+ 'Ⴭ' => 'ⴭ',
+ 'Ꭰ' => 'ꭰ',
+ 'Ꭱ' => 'ꭱ',
+ 'Ꭲ' => 'ꭲ',
+ 'Ꭳ' => 'ꭳ',
+ 'Ꭴ' => 'ꭴ',
+ 'Ꭵ' => 'ꭵ',
+ 'Ꭶ' => 'ꭶ',
+ 'Ꭷ' => 'ꭷ',
+ 'Ꭸ' => 'ꭸ',
+ 'Ꭹ' => 'ꭹ',
+ 'Ꭺ' => 'ꭺ',
+ 'Ꭻ' => 'ꭻ',
+ 'Ꭼ' => 'ꭼ',
+ 'Ꭽ' => 'ꭽ',
+ 'Ꭾ' => 'ꭾ',
+ 'Ꭿ' => 'ꭿ',
+ 'Ꮀ' => 'ꮀ',
+ 'Ꮁ' => 'ꮁ',
+ 'Ꮂ' => 'ꮂ',
+ 'Ꮃ' => 'ꮃ',
+ 'Ꮄ' => 'ꮄ',
+ 'Ꮅ' => 'ꮅ',
+ 'Ꮆ' => 'ꮆ',
+ 'Ꮇ' => 'ꮇ',
+ 'Ꮈ' => 'ꮈ',
+ 'Ꮉ' => 'ꮉ',
+ 'Ꮊ' => 'ꮊ',
+ 'Ꮋ' => 'ꮋ',
+ 'Ꮌ' => 'ꮌ',
+ 'Ꮍ' => 'ꮍ',
+ 'Ꮎ' => 'ꮎ',
+ 'Ꮏ' => 'ꮏ',
+ 'Ꮐ' => 'ꮐ',
+ 'Ꮑ' => 'ꮑ',
+ 'Ꮒ' => 'ꮒ',
+ 'Ꮓ' => 'ꮓ',
+ 'Ꮔ' => 'ꮔ',
+ 'Ꮕ' => 'ꮕ',
+ 'Ꮖ' => 'ꮖ',
+ 'Ꮗ' => 'ꮗ',
+ 'Ꮘ' => 'ꮘ',
+ 'Ꮙ' => 'ꮙ',
+ 'Ꮚ' => 'ꮚ',
+ 'Ꮛ' => 'ꮛ',
+ 'Ꮜ' => 'ꮜ',
+ 'Ꮝ' => 'ꮝ',
+ 'Ꮞ' => 'ꮞ',
+ 'Ꮟ' => 'ꮟ',
+ 'Ꮠ' => 'ꮠ',
+ 'Ꮡ' => 'ꮡ',
+ 'Ꮢ' => 'ꮢ',
+ 'Ꮣ' => 'ꮣ',
+ 'Ꮤ' => 'ꮤ',
+ 'Ꮥ' => 'ꮥ',
+ 'Ꮦ' => 'ꮦ',
+ 'Ꮧ' => 'ꮧ',
+ 'Ꮨ' => 'ꮨ',
+ 'Ꮩ' => 'ꮩ',
+ 'Ꮪ' => 'ꮪ',
+ 'Ꮫ' => 'ꮫ',
+ 'Ꮬ' => 'ꮬ',
+ 'Ꮭ' => 'ꮭ',
+ 'Ꮮ' => 'ꮮ',
+ 'Ꮯ' => 'ꮯ',
+ 'Ꮰ' => 'ꮰ',
+ 'Ꮱ' => 'ꮱ',
+ 'Ꮲ' => 'ꮲ',
+ 'Ꮳ' => 'ꮳ',
+ 'Ꮴ' => 'ꮴ',
+ 'Ꮵ' => 'ꮵ',
+ 'Ꮶ' => 'ꮶ',
+ 'Ꮷ' => 'ꮷ',
+ 'Ꮸ' => 'ꮸ',
+ 'Ꮹ' => 'ꮹ',
+ 'Ꮺ' => 'ꮺ',
+ 'Ꮻ' => 'ꮻ',
+ 'Ꮼ' => 'ꮼ',
+ 'Ꮽ' => 'ꮽ',
+ 'Ꮾ' => 'ꮾ',
+ 'Ꮿ' => 'ꮿ',
+ 'Ᏸ' => 'ᏸ',
+ 'Ᏹ' => 'ᏹ',
+ 'Ᏺ' => 'ᏺ',
+ 'Ᏻ' => 'ᏻ',
+ 'Ᏼ' => 'ᏼ',
+ 'Ᏽ' => 'ᏽ',
+ 'Ა' => 'ა',
+ 'Ბ' => 'ბ',
+ 'Გ' => 'გ',
+ 'Დ' => 'დ',
+ 'Ე' => 'ე',
+ 'Ვ' => 'ვ',
+ 'Ზ' => 'ზ',
+ 'Თ' => 'თ',
+ 'Ი' => 'ი',
+ 'Კ' => 'კ',
+ 'Ლ' => 'ლ',
+ 'Მ' => 'მ',
+ 'Ნ' => 'ნ',
+ 'Ო' => 'ო',
+ 'Პ' => 'პ',
+ 'Ჟ' => 'ჟ',
+ 'Რ' => 'რ',
+ 'Ს' => 'ს',
+ 'Ტ' => 'ტ',
+ 'Უ' => 'უ',
+ 'Ფ' => 'ფ',
+ 'Ქ' => 'ქ',
+ 'Ღ' => 'ღ',
+ 'Ყ' => 'ყ',
+ 'Შ' => 'შ',
+ 'Ჩ' => 'ჩ',
+ 'Ც' => 'ც',
+ 'Ძ' => 'ძ',
+ 'Წ' => 'წ',
+ 'Ჭ' => 'ჭ',
+ 'Ხ' => 'ხ',
+ 'Ჯ' => 'ჯ',
+ 'Ჰ' => 'ჰ',
+ 'Ჱ' => 'ჱ',
+ 'Ჲ' => 'ჲ',
+ 'Ჳ' => 'ჳ',
+ 'Ჴ' => 'ჴ',
+ 'Ჵ' => 'ჵ',
+ 'Ჶ' => 'ჶ',
+ 'Ჷ' => 'ჷ',
+ 'Ჸ' => 'ჸ',
+ 'Ჹ' => 'ჹ',
+ 'Ჺ' => 'ჺ',
+ 'Ჽ' => 'ჽ',
+ 'Ჾ' => 'ჾ',
+ 'Ჿ' => 'ჿ',
+ 'Ḁ' => 'ḁ',
+ 'Ḃ' => 'ḃ',
+ 'Ḅ' => 'ḅ',
+ 'Ḇ' => 'ḇ',
+ 'Ḉ' => 'ḉ',
+ 'Ḋ' => 'ḋ',
+ 'Ḍ' => 'ḍ',
+ 'Ḏ' => 'ḏ',
+ 'Ḑ' => 'ḑ',
+ 'Ḓ' => 'ḓ',
+ 'Ḕ' => 'ḕ',
+ 'Ḗ' => 'ḗ',
+ 'Ḙ' => 'ḙ',
+ 'Ḛ' => 'ḛ',
+ 'Ḝ' => 'ḝ',
+ 'Ḟ' => 'ḟ',
+ 'Ḡ' => 'ḡ',
+ 'Ḣ' => 'ḣ',
+ 'Ḥ' => 'ḥ',
+ 'Ḧ' => 'ḧ',
+ 'Ḩ' => 'ḩ',
+ 'Ḫ' => 'ḫ',
+ 'Ḭ' => 'ḭ',
+ 'Ḯ' => 'ḯ',
+ 'Ḱ' => 'ḱ',
+ 'Ḳ' => 'ḳ',
+ 'Ḵ' => 'ḵ',
+ 'Ḷ' => 'ḷ',
+ 'Ḹ' => 'ḹ',
+ 'Ḻ' => 'ḻ',
+ 'Ḽ' => 'ḽ',
+ 'Ḿ' => 'ḿ',
+ 'Ṁ' => 'ṁ',
+ 'Ṃ' => 'ṃ',
+ 'Ṅ' => 'ṅ',
+ 'Ṇ' => 'ṇ',
+ 'Ṉ' => 'ṉ',
+ 'Ṋ' => 'ṋ',
+ 'Ṍ' => 'ṍ',
+ 'Ṏ' => 'ṏ',
+ 'Ṑ' => 'ṑ',
+ 'Ṓ' => 'ṓ',
+ 'Ṕ' => 'ṕ',
+ 'Ṗ' => 'ṗ',
+ 'Ṙ' => 'ṙ',
+ 'Ṛ' => 'ṛ',
+ 'Ṝ' => 'ṝ',
+ 'Ṟ' => 'ṟ',
+ 'Ṡ' => 'ṡ',
+ 'Ṣ' => 'ṣ',
+ 'Ṥ' => 'ṥ',
+ 'Ṧ' => 'ṧ',
+ 'Ṩ' => 'ṩ',
+ 'Ṫ' => 'ṫ',
+ 'Ṭ' => 'ṭ',
+ 'Ṯ' => 'ṯ',
+ 'Ṱ' => 'ṱ',
+ 'Ṳ' => 'ṳ',
+ 'Ṵ' => 'ṵ',
+ 'Ṷ' => 'ṷ',
+ 'Ṹ' => 'ṹ',
+ 'Ṻ' => 'ṻ',
+ 'Ṽ' => 'ṽ',
+ 'Ṿ' => 'ṿ',
+ 'Ẁ' => 'ẁ',
+ 'Ẃ' => 'ẃ',
+ 'Ẅ' => 'ẅ',
+ 'Ẇ' => 'ẇ',
+ 'Ẉ' => 'ẉ',
+ 'Ẋ' => 'ẋ',
+ 'Ẍ' => 'ẍ',
+ 'Ẏ' => 'ẏ',
+ 'Ẑ' => 'ẑ',
+ 'Ẓ' => 'ẓ',
+ 'Ẕ' => 'ẕ',
+ 'ẞ' => 'ß',
+ 'Ạ' => 'ạ',
+ 'Ả' => 'ả',
+ 'Ấ' => 'ấ',
+ 'Ầ' => 'ầ',
+ 'Ẩ' => 'ẩ',
+ 'Ẫ' => 'ẫ',
+ 'Ậ' => 'ậ',
+ 'Ắ' => 'ắ',
+ 'Ằ' => 'ằ',
+ 'Ẳ' => 'ẳ',
+ 'Ẵ' => 'ẵ',
+ 'Ặ' => 'ặ',
+ 'Ẹ' => 'ẹ',
+ 'Ẻ' => 'ẻ',
+ 'Ẽ' => 'ẽ',
+ 'Ế' => 'ế',
+ 'Ề' => 'ề',
+ 'Ể' => 'ể',
+ 'Ễ' => 'ễ',
+ 'Ệ' => 'ệ',
+ 'Ỉ' => 'ỉ',
+ 'Ị' => 'ị',
+ 'Ọ' => 'ọ',
+ 'Ỏ' => 'ỏ',
+ 'Ố' => 'ố',
+ 'Ồ' => 'ồ',
+ 'Ổ' => 'ổ',
+ 'Ỗ' => 'ỗ',
+ 'Ộ' => 'ộ',
+ 'Ớ' => 'ớ',
+ 'Ờ' => 'ờ',
+ 'Ở' => 'ở',
+ 'Ỡ' => 'ỡ',
+ 'Ợ' => 'ợ',
+ 'Ụ' => 'ụ',
+ 'Ủ' => 'ủ',
+ 'Ứ' => 'ứ',
+ 'Ừ' => 'ừ',
+ 'Ử' => 'ử',
+ 'Ữ' => 'ữ',
+ 'Ự' => 'ự',
+ 'Ỳ' => 'ỳ',
+ 'Ỵ' => 'ỵ',
+ 'Ỷ' => 'ỷ',
+ 'Ỹ' => 'ỹ',
+ 'Ỻ' => 'ỻ',
+ 'Ỽ' => 'ỽ',
+ 'Ỿ' => 'ỿ',
+ 'Ἀ' => 'ἀ',
+ 'Ἁ' => 'ἁ',
+ 'Ἂ' => 'ἂ',
+ 'Ἃ' => 'ἃ',
+ 'Ἄ' => 'ἄ',
+ 'Ἅ' => 'ἅ',
+ 'Ἆ' => 'ἆ',
+ 'Ἇ' => 'ἇ',
+ 'Ἐ' => 'ἐ',
+ 'Ἑ' => 'ἑ',
+ 'Ἒ' => 'ἒ',
+ 'Ἓ' => 'ἓ',
+ 'Ἔ' => 'ἔ',
+ 'Ἕ' => 'ἕ',
+ 'Ἠ' => 'ἠ',
+ 'Ἡ' => 'ἡ',
+ 'Ἢ' => 'ἢ',
+ 'Ἣ' => 'ἣ',
+ 'Ἤ' => 'ἤ',
+ 'Ἥ' => 'ἥ',
+ 'Ἦ' => 'ἦ',
+ 'Ἧ' => 'ἧ',
+ 'Ἰ' => 'ἰ',
+ 'Ἱ' => 'ἱ',
+ 'Ἲ' => 'ἲ',
+ 'Ἳ' => 'ἳ',
+ 'Ἴ' => 'ἴ',
+ 'Ἵ' => 'ἵ',
+ 'Ἶ' => 'ἶ',
+ 'Ἷ' => 'ἷ',
+ 'Ὀ' => 'ὀ',
+ 'Ὁ' => 'ὁ',
+ 'Ὂ' => 'ὂ',
+ 'Ὃ' => 'ὃ',
+ 'Ὄ' => 'ὄ',
+ 'Ὅ' => 'ὅ',
+ 'Ὑ' => 'ὑ',
+ 'Ὓ' => 'ὓ',
+ 'Ὕ' => 'ὕ',
+ 'Ὗ' => 'ὗ',
+ 'Ὠ' => 'ὠ',
+ 'Ὡ' => 'ὡ',
+ 'Ὢ' => 'ὢ',
+ 'Ὣ' => 'ὣ',
+ 'Ὤ' => 'ὤ',
+ 'Ὥ' => 'ὥ',
+ 'Ὦ' => 'ὦ',
+ 'Ὧ' => 'ὧ',
+ 'ᾈ' => 'ᾀ',
+ 'ᾉ' => 'ᾁ',
+ 'ᾊ' => 'ᾂ',
+ 'ᾋ' => 'ᾃ',
+ 'ᾌ' => 'ᾄ',
+ 'ᾍ' => 'ᾅ',
+ 'ᾎ' => 'ᾆ',
+ 'ᾏ' => 'ᾇ',
+ 'ᾘ' => 'ᾐ',
+ 'ᾙ' => 'ᾑ',
+ 'ᾚ' => 'ᾒ',
+ 'ᾛ' => 'ᾓ',
+ 'ᾜ' => 'ᾔ',
+ 'ᾝ' => 'ᾕ',
+ 'ᾞ' => 'ᾖ',
+ 'ᾟ' => 'ᾗ',
+ 'ᾨ' => 'ᾠ',
+ 'ᾩ' => 'ᾡ',
+ 'ᾪ' => 'ᾢ',
+ 'ᾫ' => 'ᾣ',
+ 'ᾬ' => 'ᾤ',
+ 'ᾭ' => 'ᾥ',
+ 'ᾮ' => 'ᾦ',
+ 'ᾯ' => 'ᾧ',
+ 'Ᾰ' => 'ᾰ',
+ 'Ᾱ' => 'ᾱ',
+ 'Ὰ' => 'ὰ',
+ 'Ά' => 'ά',
+ 'ᾼ' => 'ᾳ',
+ 'Ὲ' => 'ὲ',
+ 'Έ' => 'έ',
+ 'Ὴ' => 'ὴ',
+ 'Ή' => 'ή',
+ 'ῌ' => 'ῃ',
+ 'Ῐ' => 'ῐ',
+ 'Ῑ' => 'ῑ',
+ 'Ὶ' => 'ὶ',
+ 'Ί' => 'ί',
+ 'Ῠ' => 'ῠ',
+ 'Ῡ' => 'ῡ',
+ 'Ὺ' => 'ὺ',
+ 'Ύ' => 'ύ',
+ 'Ῥ' => 'ῥ',
+ 'Ὸ' => 'ὸ',
+ 'Ό' => 'ό',
+ 'Ὼ' => 'ὼ',
+ 'Ώ' => 'ώ',
+ 'ῼ' => 'ῳ',
+ 'Ω' => 'ω',
+ 'K' => 'k',
+ 'Å' => 'å',
+ 'Ⅎ' => 'ⅎ',
+ 'Ⅰ' => 'ⅰ',
+ 'Ⅱ' => 'ⅱ',
+ 'Ⅲ' => 'ⅲ',
+ 'Ⅳ' => 'ⅳ',
+ 'Ⅴ' => 'ⅴ',
+ 'Ⅵ' => 'ⅵ',
+ 'Ⅶ' => 'ⅶ',
+ 'Ⅷ' => 'ⅷ',
+ 'Ⅸ' => 'ⅸ',
+ 'Ⅹ' => 'ⅹ',
+ 'Ⅺ' => 'ⅺ',
+ 'Ⅻ' => 'ⅻ',
+ 'Ⅼ' => 'ⅼ',
+ 'Ⅽ' => 'ⅽ',
+ 'Ⅾ' => 'ⅾ',
+ 'Ⅿ' => 'ⅿ',
+ 'Ↄ' => 'ↄ',
+ 'Ⓐ' => 'ⓐ',
+ 'Ⓑ' => 'ⓑ',
+ 'Ⓒ' => 'ⓒ',
+ 'Ⓓ' => 'ⓓ',
+ 'Ⓔ' => 'ⓔ',
+ 'Ⓕ' => 'ⓕ',
+ 'Ⓖ' => 'ⓖ',
+ 'Ⓗ' => 'ⓗ',
+ 'Ⓘ' => 'ⓘ',
+ 'Ⓙ' => 'ⓙ',
+ 'Ⓚ' => 'ⓚ',
+ 'Ⓛ' => 'ⓛ',
+ 'Ⓜ' => 'ⓜ',
+ 'Ⓝ' => 'ⓝ',
+ 'Ⓞ' => 'ⓞ',
+ 'Ⓟ' => 'ⓟ',
+ 'Ⓠ' => 'ⓠ',
+ 'Ⓡ' => 'ⓡ',
+ 'Ⓢ' => 'ⓢ',
+ 'Ⓣ' => 'ⓣ',
+ 'Ⓤ' => 'ⓤ',
+ 'Ⓥ' => 'ⓥ',
+ 'Ⓦ' => 'ⓦ',
+ 'Ⓧ' => 'ⓧ',
+ 'Ⓨ' => 'ⓨ',
+ 'Ⓩ' => 'ⓩ',
+ 'Ⰰ' => 'ⰰ',
+ 'Ⰱ' => 'ⰱ',
+ 'Ⰲ' => 'ⰲ',
+ 'Ⰳ' => 'ⰳ',
+ 'Ⰴ' => 'ⰴ',
+ 'Ⰵ' => 'ⰵ',
+ 'Ⰶ' => 'ⰶ',
+ 'Ⰷ' => 'ⰷ',
+ 'Ⰸ' => 'ⰸ',
+ 'Ⰹ' => 'ⰹ',
+ 'Ⰺ' => 'ⰺ',
+ 'Ⰻ' => 'ⰻ',
+ 'Ⰼ' => 'ⰼ',
+ 'Ⰽ' => 'ⰽ',
+ 'Ⰾ' => 'ⰾ',
+ 'Ⰿ' => 'ⰿ',
+ 'Ⱀ' => 'ⱀ',
+ 'Ⱁ' => 'ⱁ',
+ 'Ⱂ' => 'ⱂ',
+ 'Ⱃ' => 'ⱃ',
+ 'Ⱄ' => 'ⱄ',
+ 'Ⱅ' => 'ⱅ',
+ 'Ⱆ' => 'ⱆ',
+ 'Ⱇ' => 'ⱇ',
+ 'Ⱈ' => 'ⱈ',
+ 'Ⱉ' => 'ⱉ',
+ 'Ⱊ' => 'ⱊ',
+ 'Ⱋ' => 'ⱋ',
+ 'Ⱌ' => 'ⱌ',
+ 'Ⱍ' => 'ⱍ',
+ 'Ⱎ' => 'ⱎ',
+ 'Ⱏ' => 'ⱏ',
+ 'Ⱐ' => 'ⱐ',
+ 'Ⱑ' => 'ⱑ',
+ 'Ⱒ' => 'ⱒ',
+ 'Ⱓ' => 'ⱓ',
+ 'Ⱔ' => 'ⱔ',
+ 'Ⱕ' => 'ⱕ',
+ 'Ⱖ' => 'ⱖ',
+ 'Ⱗ' => 'ⱗ',
+ 'Ⱘ' => 'ⱘ',
+ 'Ⱙ' => 'ⱙ',
+ 'Ⱚ' => 'ⱚ',
+ 'Ⱛ' => 'ⱛ',
+ 'Ⱜ' => 'ⱜ',
+ 'Ⱝ' => 'ⱝ',
+ 'Ⱞ' => 'ⱞ',
+ 'Ⱡ' => 'ⱡ',
+ 'Ɫ' => 'ɫ',
+ 'Ᵽ' => 'ᵽ',
+ 'Ɽ' => 'ɽ',
+ 'Ⱨ' => 'ⱨ',
+ 'Ⱪ' => 'ⱪ',
+ 'Ⱬ' => 'ⱬ',
+ 'Ɑ' => 'ɑ',
+ 'Ɱ' => 'ɱ',
+ 'Ɐ' => 'ɐ',
+ 'Ɒ' => 'ɒ',
+ 'Ⱳ' => 'ⱳ',
+ 'Ⱶ' => 'ⱶ',
+ 'Ȿ' => 'ȿ',
+ 'Ɀ' => 'ɀ',
+ 'Ⲁ' => 'ⲁ',
+ 'Ⲃ' => 'ⲃ',
+ 'Ⲅ' => 'ⲅ',
+ 'Ⲇ' => 'ⲇ',
+ 'Ⲉ' => 'ⲉ',
+ 'Ⲋ' => 'ⲋ',
+ 'Ⲍ' => 'ⲍ',
+ 'Ⲏ' => 'ⲏ',
+ 'Ⲑ' => 'ⲑ',
+ 'Ⲓ' => 'ⲓ',
+ 'Ⲕ' => 'ⲕ',
+ 'Ⲗ' => 'ⲗ',
+ 'Ⲙ' => 'ⲙ',
+ 'Ⲛ' => 'ⲛ',
+ 'Ⲝ' => 'ⲝ',
+ 'Ⲟ' => 'ⲟ',
+ 'Ⲡ' => 'ⲡ',
+ 'Ⲣ' => 'ⲣ',
+ 'Ⲥ' => 'ⲥ',
+ 'Ⲧ' => 'ⲧ',
+ 'Ⲩ' => 'ⲩ',
+ 'Ⲫ' => 'ⲫ',
+ 'Ⲭ' => 'ⲭ',
+ 'Ⲯ' => 'ⲯ',
+ 'Ⲱ' => 'ⲱ',
+ 'Ⲳ' => 'ⲳ',
+ 'Ⲵ' => 'ⲵ',
+ 'Ⲷ' => 'ⲷ',
+ 'Ⲹ' => 'ⲹ',
+ 'Ⲻ' => 'ⲻ',
+ 'Ⲽ' => 'ⲽ',
+ 'Ⲿ' => 'ⲿ',
+ 'Ⳁ' => 'ⳁ',
+ 'Ⳃ' => 'ⳃ',
+ 'Ⳅ' => 'ⳅ',
+ 'Ⳇ' => 'ⳇ',
+ 'Ⳉ' => 'ⳉ',
+ 'Ⳋ' => 'ⳋ',
+ 'Ⳍ' => 'ⳍ',
+ 'Ⳏ' => 'ⳏ',
+ 'Ⳑ' => 'ⳑ',
+ 'Ⳓ' => 'ⳓ',
+ 'Ⳕ' => 'ⳕ',
+ 'Ⳗ' => 'ⳗ',
+ 'Ⳙ' => 'ⳙ',
+ 'Ⳛ' => 'ⳛ',
+ 'Ⳝ' => 'ⳝ',
+ 'Ⳟ' => 'ⳟ',
+ 'Ⳡ' => 'ⳡ',
+ 'Ⳣ' => 'ⳣ',
+ 'Ⳬ' => 'ⳬ',
+ 'Ⳮ' => 'ⳮ',
+ 'Ⳳ' => 'ⳳ',
+ 'Ꙁ' => 'ꙁ',
+ 'Ꙃ' => 'ꙃ',
+ 'Ꙅ' => 'ꙅ',
+ 'Ꙇ' => 'ꙇ',
+ 'Ꙉ' => 'ꙉ',
+ 'Ꙋ' => 'ꙋ',
+ 'Ꙍ' => 'ꙍ',
+ 'Ꙏ' => 'ꙏ',
+ 'Ꙑ' => 'ꙑ',
+ 'Ꙓ' => 'ꙓ',
+ 'Ꙕ' => 'ꙕ',
+ 'Ꙗ' => 'ꙗ',
+ 'Ꙙ' => 'ꙙ',
+ 'Ꙛ' => 'ꙛ',
+ 'Ꙝ' => 'ꙝ',
+ 'Ꙟ' => 'ꙟ',
+ 'Ꙡ' => 'ꙡ',
+ 'Ꙣ' => 'ꙣ',
+ 'Ꙥ' => 'ꙥ',
+ 'Ꙧ' => 'ꙧ',
+ 'Ꙩ' => 'ꙩ',
+ 'Ꙫ' => 'ꙫ',
+ 'Ꙭ' => 'ꙭ',
+ 'Ꚁ' => 'ꚁ',
+ 'Ꚃ' => 'ꚃ',
+ 'Ꚅ' => 'ꚅ',
+ 'Ꚇ' => 'ꚇ',
+ 'Ꚉ' => 'ꚉ',
+ 'Ꚋ' => 'ꚋ',
+ 'Ꚍ' => 'ꚍ',
+ 'Ꚏ' => 'ꚏ',
+ 'Ꚑ' => 'ꚑ',
+ 'Ꚓ' => 'ꚓ',
+ 'Ꚕ' => 'ꚕ',
+ 'Ꚗ' => 'ꚗ',
+ 'Ꚙ' => 'ꚙ',
+ 'Ꚛ' => 'ꚛ',
+ 'Ꜣ' => 'ꜣ',
+ 'Ꜥ' => 'ꜥ',
+ 'Ꜧ' => 'ꜧ',
+ 'Ꜩ' => 'ꜩ',
+ 'Ꜫ' => 'ꜫ',
+ 'Ꜭ' => 'ꜭ',
+ 'Ꜯ' => 'ꜯ',
+ 'Ꜳ' => 'ꜳ',
+ 'Ꜵ' => 'ꜵ',
+ 'Ꜷ' => 'ꜷ',
+ 'Ꜹ' => 'ꜹ',
+ 'Ꜻ' => 'ꜻ',
+ 'Ꜽ' => 'ꜽ',
+ 'Ꜿ' => 'ꜿ',
+ 'Ꝁ' => 'ꝁ',
+ 'Ꝃ' => 'ꝃ',
+ 'Ꝅ' => 'ꝅ',
+ 'Ꝇ' => 'ꝇ',
+ 'Ꝉ' => 'ꝉ',
+ 'Ꝋ' => 'ꝋ',
+ 'Ꝍ' => 'ꝍ',
+ 'Ꝏ' => 'ꝏ',
+ 'Ꝑ' => 'ꝑ',
+ 'Ꝓ' => 'ꝓ',
+ 'Ꝕ' => 'ꝕ',
+ 'Ꝗ' => 'ꝗ',
+ 'Ꝙ' => 'ꝙ',
+ 'Ꝛ' => 'ꝛ',
+ 'Ꝝ' => 'ꝝ',
+ 'Ꝟ' => 'ꝟ',
+ 'Ꝡ' => 'ꝡ',
+ 'Ꝣ' => 'ꝣ',
+ 'Ꝥ' => 'ꝥ',
+ 'Ꝧ' => 'ꝧ',
+ 'Ꝩ' => 'ꝩ',
+ 'Ꝫ' => 'ꝫ',
+ 'Ꝭ' => 'ꝭ',
+ 'Ꝯ' => 'ꝯ',
+ 'Ꝺ' => 'ꝺ',
+ 'Ꝼ' => 'ꝼ',
+ 'Ᵹ' => 'ᵹ',
+ 'Ꝿ' => 'ꝿ',
+ 'Ꞁ' => 'ꞁ',
+ 'Ꞃ' => 'ꞃ',
+ 'Ꞅ' => 'ꞅ',
+ 'Ꞇ' => 'ꞇ',
+ 'Ꞌ' => 'ꞌ',
+ 'Ɥ' => 'ɥ',
+ 'Ꞑ' => 'ꞑ',
+ 'Ꞓ' => 'ꞓ',
+ 'Ꞗ' => 'ꞗ',
+ 'Ꞙ' => 'ꞙ',
+ 'Ꞛ' => 'ꞛ',
+ 'Ꞝ' => 'ꞝ',
+ 'Ꞟ' => 'ꞟ',
+ 'Ꞡ' => 'ꞡ',
+ 'Ꞣ' => 'ꞣ',
+ 'Ꞥ' => 'ꞥ',
+ 'Ꞧ' => 'ꞧ',
+ 'Ꞩ' => 'ꞩ',
+ 'Ɦ' => 'ɦ',
+ 'Ɜ' => 'ɜ',
+ 'Ɡ' => 'ɡ',
+ 'Ɬ' => 'ɬ',
+ 'Ɪ' => 'ɪ',
+ 'Ʞ' => 'ʞ',
+ 'Ʇ' => 'ʇ',
+ 'Ʝ' => 'ʝ',
+ 'Ꭓ' => 'ꭓ',
+ 'Ꞵ' => 'ꞵ',
+ 'Ꞷ' => 'ꞷ',
+ 'Ꞹ' => 'ꞹ',
+ 'Ꞻ' => 'ꞻ',
+ 'Ꞽ' => 'ꞽ',
+ 'Ꞿ' => 'ꞿ',
+ 'Ꟃ' => 'ꟃ',
+ 'Ꞔ' => 'ꞔ',
+ 'Ʂ' => 'ʂ',
+ 'Ᶎ' => 'ᶎ',
+ 'Ꟈ' => 'ꟈ',
+ 'Ꟊ' => 'ꟊ',
+ 'Ꟶ' => 'ꟶ',
+ 'A' => 'a',
+ 'B' => 'b',
+ 'C' => 'c',
+ 'D' => 'd',
+ 'E' => 'e',
+ 'F' => 'f',
+ 'G' => 'g',
+ 'H' => 'h',
+ 'I' => 'i',
+ 'J' => 'j',
+ 'K' => 'k',
+ 'L' => 'l',
+ 'M' => 'm',
+ 'N' => 'n',
+ 'O' => 'o',
+ 'P' => 'p',
+ 'Q' => 'q',
+ 'R' => 'r',
+ 'S' => 's',
+ 'T' => 't',
+ 'U' => 'u',
+ 'V' => 'v',
+ 'W' => 'w',
+ 'X' => 'x',
+ 'Y' => 'y',
+ 'Z' => 'z',
+ '𐐀' => '𐐨',
+ '𐐁' => '𐐩',
+ '𐐂' => '𐐪',
+ '𐐃' => '𐐫',
+ '𐐄' => '𐐬',
+ '𐐅' => '𐐭',
+ '𐐆' => '𐐮',
+ '𐐇' => '𐐯',
+ '𐐈' => '𐐰',
+ '𐐉' => '𐐱',
+ '𐐊' => '𐐲',
+ '𐐋' => '𐐳',
+ '𐐌' => '𐐴',
+ '𐐍' => '𐐵',
+ '𐐎' => '𐐶',
+ '𐐏' => '𐐷',
+ '𐐐' => '𐐸',
+ '𐐑' => '𐐹',
+ '𐐒' => '𐐺',
+ '𐐓' => '𐐻',
+ '𐐔' => '𐐼',
+ '𐐕' => '𐐽',
+ '𐐖' => '𐐾',
+ '𐐗' => '𐐿',
+ '𐐘' => '𐑀',
+ '𐐙' => '𐑁',
+ '𐐚' => '𐑂',
+ '𐐛' => '𐑃',
+ '𐐜' => '𐑄',
+ '𐐝' => '𐑅',
+ '𐐞' => '𐑆',
+ '𐐟' => '𐑇',
+ '𐐠' => '𐑈',
+ '𐐡' => '𐑉',
+ '𐐢' => '𐑊',
+ '𐐣' => '𐑋',
+ '𐐤' => '𐑌',
+ '𐐥' => '𐑍',
+ '𐐦' => '𐑎',
+ '𐐧' => '𐑏',
+ '𐒰' => '𐓘',
+ '𐒱' => '𐓙',
+ '𐒲' => '𐓚',
+ '𐒳' => '𐓛',
+ '𐒴' => '𐓜',
+ '𐒵' => '𐓝',
+ '𐒶' => '𐓞',
+ '𐒷' => '𐓟',
+ '𐒸' => '𐓠',
+ '𐒹' => '𐓡',
+ '𐒺' => '𐓢',
+ '𐒻' => '𐓣',
+ '𐒼' => '𐓤',
+ '𐒽' => '𐓥',
+ '𐒾' => '𐓦',
+ '𐒿' => '𐓧',
+ '𐓀' => '𐓨',
+ '𐓁' => '𐓩',
+ '𐓂' => '𐓪',
+ '𐓃' => '𐓫',
+ '𐓄' => '𐓬',
+ '𐓅' => '𐓭',
+ '𐓆' => '𐓮',
+ '𐓇' => '𐓯',
+ '𐓈' => '𐓰',
+ '𐓉' => '𐓱',
+ '𐓊' => '𐓲',
+ '𐓋' => '𐓳',
+ '𐓌' => '𐓴',
+ '𐓍' => '𐓵',
+ '𐓎' => '𐓶',
+ '𐓏' => '𐓷',
+ '𐓐' => '𐓸',
+ '𐓑' => '𐓹',
+ '𐓒' => '𐓺',
+ '𐓓' => '𐓻',
+ '𐲀' => '𐳀',
+ '𐲁' => '𐳁',
+ '𐲂' => '𐳂',
+ '𐲃' => '𐳃',
+ '𐲄' => '𐳄',
+ '𐲅' => '𐳅',
+ '𐲆' => '𐳆',
+ '𐲇' => '𐳇',
+ '𐲈' => '𐳈',
+ '𐲉' => '𐳉',
+ '𐲊' => '𐳊',
+ '𐲋' => '𐳋',
+ '𐲌' => '𐳌',
+ '𐲍' => '𐳍',
+ '𐲎' => '𐳎',
+ '𐲏' => '𐳏',
+ '𐲐' => '𐳐',
+ '𐲑' => '𐳑',
+ '𐲒' => '𐳒',
+ '𐲓' => '𐳓',
+ '𐲔' => '𐳔',
+ '𐲕' => '𐳕',
+ '𐲖' => '𐳖',
+ '𐲗' => '𐳗',
+ '𐲘' => '𐳘',
+ '𐲙' => '𐳙',
+ '𐲚' => '𐳚',
+ '𐲛' => '𐳛',
+ '𐲜' => '𐳜',
+ '𐲝' => '𐳝',
+ '𐲞' => '𐳞',
+ '𐲟' => '𐳟',
+ '𐲠' => '𐳠',
+ '𐲡' => '𐳡',
+ '𐲢' => '𐳢',
+ '𐲣' => '𐳣',
+ '𐲤' => '𐳤',
+ '𐲥' => '𐳥',
+ '𐲦' => '𐳦',
+ '𐲧' => '𐳧',
+ '𐲨' => '𐳨',
+ '𐲩' => '𐳩',
+ '𐲪' => '𐳪',
+ '𐲫' => '𐳫',
+ '𐲬' => '𐳬',
+ '𐲭' => '𐳭',
+ '𐲮' => '𐳮',
+ '𐲯' => '𐳯',
+ '𐲰' => '𐳰',
+ '𐲱' => '𐳱',
+ '𐲲' => '𐳲',
+ '𑢠' => '𑣀',
+ '𑢡' => '𑣁',
+ '𑢢' => '𑣂',
+ '𑢣' => '𑣃',
+ '𑢤' => '𑣄',
+ '𑢥' => '𑣅',
+ '𑢦' => '𑣆',
+ '𑢧' => '𑣇',
+ '𑢨' => '𑣈',
+ '𑢩' => '𑣉',
+ '𑢪' => '𑣊',
+ '𑢫' => '𑣋',
+ '𑢬' => '𑣌',
+ '𑢭' => '𑣍',
+ '𑢮' => '𑣎',
+ '𑢯' => '𑣏',
+ '𑢰' => '𑣐',
+ '𑢱' => '𑣑',
+ '𑢲' => '𑣒',
+ '𑢳' => '𑣓',
+ '𑢴' => '𑣔',
+ '𑢵' => '𑣕',
+ '𑢶' => '𑣖',
+ '𑢷' => '𑣗',
+ '𑢸' => '𑣘',
+ '𑢹' => '𑣙',
+ '𑢺' => '𑣚',
+ '𑢻' => '𑣛',
+ '𑢼' => '𑣜',
+ '𑢽' => '𑣝',
+ '𑢾' => '𑣞',
+ '𑢿' => '𑣟',
+ '𖹀' => '𖹠',
+ '𖹁' => '𖹡',
+ '𖹂' => '𖹢',
+ '𖹃' => '𖹣',
+ '𖹄' => '𖹤',
+ '𖹅' => '𖹥',
+ '𖹆' => '𖹦',
+ '𖹇' => '𖹧',
+ '𖹈' => '𖹨',
+ '𖹉' => '𖹩',
+ '𖹊' => '𖹪',
+ '𖹋' => '𖹫',
+ '𖹌' => '𖹬',
+ '𖹍' => '𖹭',
+ '𖹎' => '𖹮',
+ '𖹏' => '𖹯',
+ '𖹐' => '𖹰',
+ '𖹑' => '𖹱',
+ '𖹒' => '𖹲',
+ '𖹓' => '𖹳',
+ '𖹔' => '𖹴',
+ '𖹕' => '𖹵',
+ '𖹖' => '𖹶',
+ '𖹗' => '𖹷',
+ '𖹘' => '𖹸',
+ '𖹙' => '𖹹',
+ '𖹚' => '𖹺',
+ '𖹛' => '𖹻',
+ '𖹜' => '𖹼',
+ '𖹝' => '𖹽',
+ '𖹞' => '𖹾',
+ '𖹟' => '𖹿',
+ '𞤀' => '𞤢',
+ '𞤁' => '𞤣',
+ '𞤂' => '𞤤',
+ '𞤃' => '𞤥',
+ '𞤄' => '𞤦',
+ '𞤅' => '𞤧',
+ '𞤆' => '𞤨',
+ '𞤇' => '𞤩',
+ '𞤈' => '𞤪',
+ '𞤉' => '𞤫',
+ '𞤊' => '𞤬',
+ '𞤋' => '𞤭',
+ '𞤌' => '𞤮',
+ '𞤍' => '𞤯',
+ '𞤎' => '𞤰',
+ '𞤏' => '𞤱',
+ '𞤐' => '𞤲',
+ '𞤑' => '𞤳',
+ '𞤒' => '𞤴',
+ '𞤓' => '𞤵',
+ '𞤔' => '𞤶',
+ '𞤕' => '𞤷',
+ '𞤖' => '𞤸',
+ '𞤗' => '𞤹',
+ '𞤘' => '𞤺',
+ '𞤙' => '𞤻',
+ '𞤚' => '𞤼',
+ '𞤛' => '𞤽',
+ '𞤜' => '𞤾',
+ '𞤝' => '𞤿',
+ '𞤞' => '𞥀',
+ '𞤟' => '𞥁',
+ '𞤠' => '𞥂',
+ '𞤡' => '𞥃',
+);
diff --git a/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
new file mode 100644
index 0000000..2a8f6e7
--- /dev/null
+++ b/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php
@@ -0,0 +1,5 @@
+ 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ 'e' => 'E',
+ 'f' => 'F',
+ 'g' => 'G',
+ 'h' => 'H',
+ 'i' => 'I',
+ 'j' => 'J',
+ 'k' => 'K',
+ 'l' => 'L',
+ 'm' => 'M',
+ 'n' => 'N',
+ 'o' => 'O',
+ 'p' => 'P',
+ 'q' => 'Q',
+ 'r' => 'R',
+ 's' => 'S',
+ 't' => 'T',
+ 'u' => 'U',
+ 'v' => 'V',
+ 'w' => 'W',
+ 'x' => 'X',
+ 'y' => 'Y',
+ 'z' => 'Z',
+ 'µ' => 'Μ',
+ 'à' => 'À',
+ 'á' => 'Á',
+ 'â' => 'Â',
+ 'ã' => 'Ã',
+ 'ä' => 'Ä',
+ 'å' => 'Å',
+ 'æ' => 'Æ',
+ 'ç' => 'Ç',
+ 'è' => 'È',
+ 'é' => 'É',
+ 'ê' => 'Ê',
+ 'ë' => 'Ë',
+ 'ì' => 'Ì',
+ 'í' => 'Í',
+ 'î' => 'Î',
+ 'ï' => 'Ï',
+ 'ð' => 'Ð',
+ 'ñ' => 'Ñ',
+ 'ò' => 'Ò',
+ 'ó' => 'Ó',
+ 'ô' => 'Ô',
+ 'õ' => 'Õ',
+ 'ö' => 'Ö',
+ 'ø' => 'Ø',
+ 'ù' => 'Ù',
+ 'ú' => 'Ú',
+ 'û' => 'Û',
+ 'ü' => 'Ü',
+ 'ý' => 'Ý',
+ 'þ' => 'Þ',
+ 'ÿ' => 'Ÿ',
+ 'ā' => 'Ā',
+ 'ă' => 'Ă',
+ 'ą' => 'Ą',
+ 'ć' => 'Ć',
+ 'ĉ' => 'Ĉ',
+ 'ċ' => 'Ċ',
+ 'č' => 'Č',
+ 'ď' => 'Ď',
+ 'đ' => 'Đ',
+ 'ē' => 'Ē',
+ 'ĕ' => 'Ĕ',
+ 'ė' => 'Ė',
+ 'ę' => 'Ę',
+ 'ě' => 'Ě',
+ 'ĝ' => 'Ĝ',
+ 'ğ' => 'Ğ',
+ 'ġ' => 'Ġ',
+ 'ģ' => 'Ģ',
+ 'ĥ' => 'Ĥ',
+ 'ħ' => 'Ħ',
+ 'ĩ' => 'Ĩ',
+ 'ī' => 'Ī',
+ 'ĭ' => 'Ĭ',
+ 'į' => 'Į',
+ 'ı' => 'I',
+ 'ij' => 'IJ',
+ 'ĵ' => 'Ĵ',
+ 'ķ' => 'Ķ',
+ 'ĺ' => 'Ĺ',
+ 'ļ' => 'Ļ',
+ 'ľ' => 'Ľ',
+ 'ŀ' => 'Ŀ',
+ 'ł' => 'Ł',
+ 'ń' => 'Ń',
+ 'ņ' => 'Ņ',
+ 'ň' => 'Ň',
+ 'ŋ' => 'Ŋ',
+ 'ō' => 'Ō',
+ 'ŏ' => 'Ŏ',
+ 'ő' => 'Ő',
+ 'œ' => 'Œ',
+ 'ŕ' => 'Ŕ',
+ 'ŗ' => 'Ŗ',
+ 'ř' => 'Ř',
+ 'ś' => 'Ś',
+ 'ŝ' => 'Ŝ',
+ 'ş' => 'Ş',
+ 'š' => 'Š',
+ 'ţ' => 'Ţ',
+ 'ť' => 'Ť',
+ 'ŧ' => 'Ŧ',
+ 'ũ' => 'Ũ',
+ 'ū' => 'Ū',
+ 'ŭ' => 'Ŭ',
+ 'ů' => 'Ů',
+ 'ű' => 'Ű',
+ 'ų' => 'Ų',
+ 'ŵ' => 'Ŵ',
+ 'ŷ' => 'Ŷ',
+ 'ź' => 'Ź',
+ 'ż' => 'Ż',
+ 'ž' => 'Ž',
+ 'ſ' => 'S',
+ 'ƀ' => 'Ƀ',
+ 'ƃ' => 'Ƃ',
+ 'ƅ' => 'Ƅ',
+ 'ƈ' => 'Ƈ',
+ 'ƌ' => 'Ƌ',
+ 'ƒ' => 'Ƒ',
+ 'ƕ' => 'Ƕ',
+ 'ƙ' => 'Ƙ',
+ 'ƚ' => 'Ƚ',
+ 'ƞ' => 'Ƞ',
+ 'ơ' => 'Ơ',
+ 'ƣ' => 'Ƣ',
+ 'ƥ' => 'Ƥ',
+ 'ƨ' => 'Ƨ',
+ 'ƭ' => 'Ƭ',
+ 'ư' => 'Ư',
+ 'ƴ' => 'Ƴ',
+ 'ƶ' => 'Ƶ',
+ 'ƹ' => 'Ƹ',
+ 'ƽ' => 'Ƽ',
+ 'ƿ' => 'Ƿ',
+ 'Dž' => 'DŽ',
+ 'dž' => 'DŽ',
+ 'Lj' => 'LJ',
+ 'lj' => 'LJ',
+ 'Nj' => 'NJ',
+ 'nj' => 'NJ',
+ 'ǎ' => 'Ǎ',
+ 'ǐ' => 'Ǐ',
+ 'ǒ' => 'Ǒ',
+ 'ǔ' => 'Ǔ',
+ 'ǖ' => 'Ǖ',
+ 'ǘ' => 'Ǘ',
+ 'ǚ' => 'Ǚ',
+ 'ǜ' => 'Ǜ',
+ 'ǝ' => 'Ǝ',
+ 'ǟ' => 'Ǟ',
+ 'ǡ' => 'Ǡ',
+ 'ǣ' => 'Ǣ',
+ 'ǥ' => 'Ǥ',
+ 'ǧ' => 'Ǧ',
+ 'ǩ' => 'Ǩ',
+ 'ǫ' => 'Ǫ',
+ 'ǭ' => 'Ǭ',
+ 'ǯ' => 'Ǯ',
+ 'Dz' => 'DZ',
+ 'dz' => 'DZ',
+ 'ǵ' => 'Ǵ',
+ 'ǹ' => 'Ǹ',
+ 'ǻ' => 'Ǻ',
+ 'ǽ' => 'Ǽ',
+ 'ǿ' => 'Ǿ',
+ 'ȁ' => 'Ȁ',
+ 'ȃ' => 'Ȃ',
+ 'ȅ' => 'Ȅ',
+ 'ȇ' => 'Ȇ',
+ 'ȉ' => 'Ȉ',
+ 'ȋ' => 'Ȋ',
+ 'ȍ' => 'Ȍ',
+ 'ȏ' => 'Ȏ',
+ 'ȑ' => 'Ȑ',
+ 'ȓ' => 'Ȓ',
+ 'ȕ' => 'Ȕ',
+ 'ȗ' => 'Ȗ',
+ 'ș' => 'Ș',
+ 'ț' => 'Ț',
+ 'ȝ' => 'Ȝ',
+ 'ȟ' => 'Ȟ',
+ 'ȣ' => 'Ȣ',
+ 'ȥ' => 'Ȥ',
+ 'ȧ' => 'Ȧ',
+ 'ȩ' => 'Ȩ',
+ 'ȫ' => 'Ȫ',
+ 'ȭ' => 'Ȭ',
+ 'ȯ' => 'Ȯ',
+ 'ȱ' => 'Ȱ',
+ 'ȳ' => 'Ȳ',
+ 'ȼ' => 'Ȼ',
+ 'ȿ' => 'Ȿ',
+ 'ɀ' => 'Ɀ',
+ 'ɂ' => 'Ɂ',
+ 'ɇ' => 'Ɇ',
+ 'ɉ' => 'Ɉ',
+ 'ɋ' => 'Ɋ',
+ 'ɍ' => 'Ɍ',
+ 'ɏ' => 'Ɏ',
+ 'ɐ' => 'Ɐ',
+ 'ɑ' => 'Ɑ',
+ 'ɒ' => 'Ɒ',
+ 'ɓ' => 'Ɓ',
+ 'ɔ' => 'Ɔ',
+ 'ɖ' => 'Ɖ',
+ 'ɗ' => 'Ɗ',
+ 'ə' => 'Ə',
+ 'ɛ' => 'Ɛ',
+ 'ɜ' => 'Ɜ',
+ 'ɠ' => 'Ɠ',
+ 'ɡ' => 'Ɡ',
+ 'ɣ' => 'Ɣ',
+ 'ɥ' => 'Ɥ',
+ 'ɦ' => 'Ɦ',
+ 'ɨ' => 'Ɨ',
+ 'ɩ' => 'Ɩ',
+ 'ɪ' => 'Ɪ',
+ 'ɫ' => 'Ɫ',
+ 'ɬ' => 'Ɬ',
+ 'ɯ' => 'Ɯ',
+ 'ɱ' => 'Ɱ',
+ 'ɲ' => 'Ɲ',
+ 'ɵ' => 'Ɵ',
+ 'ɽ' => 'Ɽ',
+ 'ʀ' => 'Ʀ',
+ 'ʂ' => 'Ʂ',
+ 'ʃ' => 'Ʃ',
+ 'ʇ' => 'Ʇ',
+ 'ʈ' => 'Ʈ',
+ 'ʉ' => 'Ʉ',
+ 'ʊ' => 'Ʊ',
+ 'ʋ' => 'Ʋ',
+ 'ʌ' => 'Ʌ',
+ 'ʒ' => 'Ʒ',
+ 'ʝ' => 'Ʝ',
+ 'ʞ' => 'Ʞ',
+ 'ͅ' => 'Ι',
+ 'ͱ' => 'Ͱ',
+ 'ͳ' => 'Ͳ',
+ 'ͷ' => 'Ͷ',
+ 'ͻ' => 'Ͻ',
+ 'ͼ' => 'Ͼ',
+ 'ͽ' => 'Ͽ',
+ 'ά' => 'Ά',
+ 'έ' => 'Έ',
+ 'ή' => 'Ή',
+ 'ί' => 'Ί',
+ 'α' => 'Α',
+ 'β' => 'Β',
+ 'γ' => 'Γ',
+ 'δ' => 'Δ',
+ 'ε' => 'Ε',
+ 'ζ' => 'Ζ',
+ 'η' => 'Η',
+ 'θ' => 'Θ',
+ 'ι' => 'Ι',
+ 'κ' => 'Κ',
+ 'λ' => 'Λ',
+ 'μ' => 'Μ',
+ 'ν' => 'Ν',
+ 'ξ' => 'Ξ',
+ 'ο' => 'Ο',
+ 'π' => 'Π',
+ 'ρ' => 'Ρ',
+ 'ς' => 'Σ',
+ 'σ' => 'Σ',
+ 'τ' => 'Τ',
+ 'υ' => 'Υ',
+ 'φ' => 'Φ',
+ 'χ' => 'Χ',
+ 'ψ' => 'Ψ',
+ 'ω' => 'Ω',
+ 'ϊ' => 'Ϊ',
+ 'ϋ' => 'Ϋ',
+ 'ό' => 'Ό',
+ 'ύ' => 'Ύ',
+ 'ώ' => 'Ώ',
+ 'ϐ' => 'Β',
+ 'ϑ' => 'Θ',
+ 'ϕ' => 'Φ',
+ 'ϖ' => 'Π',
+ 'ϗ' => 'Ϗ',
+ 'ϙ' => 'Ϙ',
+ 'ϛ' => 'Ϛ',
+ 'ϝ' => 'Ϝ',
+ 'ϟ' => 'Ϟ',
+ 'ϡ' => 'Ϡ',
+ 'ϣ' => 'Ϣ',
+ 'ϥ' => 'Ϥ',
+ 'ϧ' => 'Ϧ',
+ 'ϩ' => 'Ϩ',
+ 'ϫ' => 'Ϫ',
+ 'ϭ' => 'Ϭ',
+ 'ϯ' => 'Ϯ',
+ 'ϰ' => 'Κ',
+ 'ϱ' => 'Ρ',
+ 'ϲ' => 'Ϲ',
+ 'ϳ' => 'Ϳ',
+ 'ϵ' => 'Ε',
+ 'ϸ' => 'Ϸ',
+ 'ϻ' => 'Ϻ',
+ 'а' => 'А',
+ 'б' => 'Б',
+ 'в' => 'В',
+ 'г' => 'Г',
+ 'д' => 'Д',
+ 'е' => 'Е',
+ 'ж' => 'Ж',
+ 'з' => 'З',
+ 'и' => 'И',
+ 'й' => 'Й',
+ 'к' => 'К',
+ 'л' => 'Л',
+ 'м' => 'М',
+ 'н' => 'Н',
+ 'о' => 'О',
+ 'п' => 'П',
+ 'р' => 'Р',
+ 'с' => 'С',
+ 'т' => 'Т',
+ 'у' => 'У',
+ 'ф' => 'Ф',
+ 'х' => 'Х',
+ 'ц' => 'Ц',
+ 'ч' => 'Ч',
+ 'ш' => 'Ш',
+ 'щ' => 'Щ',
+ 'ъ' => 'Ъ',
+ 'ы' => 'Ы',
+ 'ь' => 'Ь',
+ 'э' => 'Э',
+ 'ю' => 'Ю',
+ 'я' => 'Я',
+ 'ѐ' => 'Ѐ',
+ 'ё' => 'Ё',
+ 'ђ' => 'Ђ',
+ 'ѓ' => 'Ѓ',
+ 'є' => 'Є',
+ 'ѕ' => 'Ѕ',
+ 'і' => 'І',
+ 'ї' => 'Ї',
+ 'ј' => 'Ј',
+ 'љ' => 'Љ',
+ 'њ' => 'Њ',
+ 'ћ' => 'Ћ',
+ 'ќ' => 'Ќ',
+ 'ѝ' => 'Ѝ',
+ 'ў' => 'Ў',
+ 'џ' => 'Џ',
+ 'ѡ' => 'Ѡ',
+ 'ѣ' => 'Ѣ',
+ 'ѥ' => 'Ѥ',
+ 'ѧ' => 'Ѧ',
+ 'ѩ' => 'Ѩ',
+ 'ѫ' => 'Ѫ',
+ 'ѭ' => 'Ѭ',
+ 'ѯ' => 'Ѯ',
+ 'ѱ' => 'Ѱ',
+ 'ѳ' => 'Ѳ',
+ 'ѵ' => 'Ѵ',
+ 'ѷ' => 'Ѷ',
+ 'ѹ' => 'Ѹ',
+ 'ѻ' => 'Ѻ',
+ 'ѽ' => 'Ѽ',
+ 'ѿ' => 'Ѿ',
+ 'ҁ' => 'Ҁ',
+ 'ҋ' => 'Ҋ',
+ 'ҍ' => 'Ҍ',
+ 'ҏ' => 'Ҏ',
+ 'ґ' => 'Ґ',
+ 'ғ' => 'Ғ',
+ 'ҕ' => 'Ҕ',
+ 'җ' => 'Җ',
+ 'ҙ' => 'Ҙ',
+ 'қ' => 'Қ',
+ 'ҝ' => 'Ҝ',
+ 'ҟ' => 'Ҟ',
+ 'ҡ' => 'Ҡ',
+ 'ң' => 'Ң',
+ 'ҥ' => 'Ҥ',
+ 'ҧ' => 'Ҧ',
+ 'ҩ' => 'Ҩ',
+ 'ҫ' => 'Ҫ',
+ 'ҭ' => 'Ҭ',
+ 'ү' => 'Ү',
+ 'ұ' => 'Ұ',
+ 'ҳ' => 'Ҳ',
+ 'ҵ' => 'Ҵ',
+ 'ҷ' => 'Ҷ',
+ 'ҹ' => 'Ҹ',
+ 'һ' => 'Һ',
+ 'ҽ' => 'Ҽ',
+ 'ҿ' => 'Ҿ',
+ 'ӂ' => 'Ӂ',
+ 'ӄ' => 'Ӄ',
+ 'ӆ' => 'Ӆ',
+ 'ӈ' => 'Ӈ',
+ 'ӊ' => 'Ӊ',
+ 'ӌ' => 'Ӌ',
+ 'ӎ' => 'Ӎ',
+ 'ӏ' => 'Ӏ',
+ 'ӑ' => 'Ӑ',
+ 'ӓ' => 'Ӓ',
+ 'ӕ' => 'Ӕ',
+ 'ӗ' => 'Ӗ',
+ 'ә' => 'Ә',
+ 'ӛ' => 'Ӛ',
+ 'ӝ' => 'Ӝ',
+ 'ӟ' => 'Ӟ',
+ 'ӡ' => 'Ӡ',
+ 'ӣ' => 'Ӣ',
+ 'ӥ' => 'Ӥ',
+ 'ӧ' => 'Ӧ',
+ 'ө' => 'Ө',
+ 'ӫ' => 'Ӫ',
+ 'ӭ' => 'Ӭ',
+ 'ӯ' => 'Ӯ',
+ 'ӱ' => 'Ӱ',
+ 'ӳ' => 'Ӳ',
+ 'ӵ' => 'Ӵ',
+ 'ӷ' => 'Ӷ',
+ 'ӹ' => 'Ӹ',
+ 'ӻ' => 'Ӻ',
+ 'ӽ' => 'Ӽ',
+ 'ӿ' => 'Ӿ',
+ 'ԁ' => 'Ԁ',
+ 'ԃ' => 'Ԃ',
+ 'ԅ' => 'Ԅ',
+ 'ԇ' => 'Ԇ',
+ 'ԉ' => 'Ԉ',
+ 'ԋ' => 'Ԋ',
+ 'ԍ' => 'Ԍ',
+ 'ԏ' => 'Ԏ',
+ 'ԑ' => 'Ԑ',
+ 'ԓ' => 'Ԓ',
+ 'ԕ' => 'Ԕ',
+ 'ԗ' => 'Ԗ',
+ 'ԙ' => 'Ԙ',
+ 'ԛ' => 'Ԛ',
+ 'ԝ' => 'Ԝ',
+ 'ԟ' => 'Ԟ',
+ 'ԡ' => 'Ԡ',
+ 'ԣ' => 'Ԣ',
+ 'ԥ' => 'Ԥ',
+ 'ԧ' => 'Ԧ',
+ 'ԩ' => 'Ԩ',
+ 'ԫ' => 'Ԫ',
+ 'ԭ' => 'Ԭ',
+ 'ԯ' => 'Ԯ',
+ 'ա' => 'Ա',
+ 'բ' => 'Բ',
+ 'գ' => 'Գ',
+ 'դ' => 'Դ',
+ 'ե' => 'Ե',
+ 'զ' => 'Զ',
+ 'է' => 'Է',
+ 'ը' => 'Ը',
+ 'թ' => 'Թ',
+ 'ժ' => 'Ժ',
+ 'ի' => 'Ի',
+ 'լ' => 'Լ',
+ 'խ' => 'Խ',
+ 'ծ' => 'Ծ',
+ 'կ' => 'Կ',
+ 'հ' => 'Հ',
+ 'ձ' => 'Ձ',
+ 'ղ' => 'Ղ',
+ 'ճ' => 'Ճ',
+ 'մ' => 'Մ',
+ 'յ' => 'Յ',
+ 'ն' => 'Ն',
+ 'շ' => 'Շ',
+ 'ո' => 'Ո',
+ 'չ' => 'Չ',
+ 'պ' => 'Պ',
+ 'ջ' => 'Ջ',
+ 'ռ' => 'Ռ',
+ 'ս' => 'Ս',
+ 'վ' => 'Վ',
+ 'տ' => 'Տ',
+ 'ր' => 'Ր',
+ 'ց' => 'Ց',
+ 'ւ' => 'Ւ',
+ 'փ' => 'Փ',
+ 'ք' => 'Ք',
+ 'օ' => 'Օ',
+ 'ֆ' => 'Ֆ',
+ 'ა' => 'Ა',
+ 'ბ' => 'Ბ',
+ 'გ' => 'Გ',
+ 'დ' => 'Დ',
+ 'ე' => 'Ე',
+ 'ვ' => 'Ვ',
+ 'ზ' => 'Ზ',
+ 'თ' => 'Თ',
+ 'ი' => 'Ი',
+ 'კ' => 'Კ',
+ 'ლ' => 'Ლ',
+ 'მ' => 'Მ',
+ 'ნ' => 'Ნ',
+ 'ო' => 'Ო',
+ 'პ' => 'Პ',
+ 'ჟ' => 'Ჟ',
+ 'რ' => 'Რ',
+ 'ს' => 'Ს',
+ 'ტ' => 'Ტ',
+ 'უ' => 'Უ',
+ 'ფ' => 'Ფ',
+ 'ქ' => 'Ქ',
+ 'ღ' => 'Ღ',
+ 'ყ' => 'Ყ',
+ 'შ' => 'Შ',
+ 'ჩ' => 'Ჩ',
+ 'ც' => 'Ც',
+ 'ძ' => 'Ძ',
+ 'წ' => 'Წ',
+ 'ჭ' => 'Ჭ',
+ 'ხ' => 'Ხ',
+ 'ჯ' => 'Ჯ',
+ 'ჰ' => 'Ჰ',
+ 'ჱ' => 'Ჱ',
+ 'ჲ' => 'Ჲ',
+ 'ჳ' => 'Ჳ',
+ 'ჴ' => 'Ჴ',
+ 'ჵ' => 'Ჵ',
+ 'ჶ' => 'Ჶ',
+ 'ჷ' => 'Ჷ',
+ 'ჸ' => 'Ჸ',
+ 'ჹ' => 'Ჹ',
+ 'ჺ' => 'Ჺ',
+ 'ჽ' => 'Ჽ',
+ 'ჾ' => 'Ჾ',
+ 'ჿ' => 'Ჿ',
+ 'ᏸ' => 'Ᏸ',
+ 'ᏹ' => 'Ᏹ',
+ 'ᏺ' => 'Ᏺ',
+ 'ᏻ' => 'Ᏻ',
+ 'ᏼ' => 'Ᏼ',
+ 'ᏽ' => 'Ᏽ',
+ 'ᲀ' => 'В',
+ 'ᲁ' => 'Д',
+ 'ᲂ' => 'О',
+ 'ᲃ' => 'С',
+ 'ᲄ' => 'Т',
+ 'ᲅ' => 'Т',
+ 'ᲆ' => 'Ъ',
+ 'ᲇ' => 'Ѣ',
+ 'ᲈ' => 'Ꙋ',
+ 'ᵹ' => 'Ᵹ',
+ 'ᵽ' => 'Ᵽ',
+ 'ᶎ' => 'Ᶎ',
+ 'ḁ' => 'Ḁ',
+ 'ḃ' => 'Ḃ',
+ 'ḅ' => 'Ḅ',
+ 'ḇ' => 'Ḇ',
+ 'ḉ' => 'Ḉ',
+ 'ḋ' => 'Ḋ',
+ 'ḍ' => 'Ḍ',
+ 'ḏ' => 'Ḏ',
+ 'ḑ' => 'Ḑ',
+ 'ḓ' => 'Ḓ',
+ 'ḕ' => 'Ḕ',
+ 'ḗ' => 'Ḗ',
+ 'ḙ' => 'Ḙ',
+ 'ḛ' => 'Ḛ',
+ 'ḝ' => 'Ḝ',
+ 'ḟ' => 'Ḟ',
+ 'ḡ' => 'Ḡ',
+ 'ḣ' => 'Ḣ',
+ 'ḥ' => 'Ḥ',
+ 'ḧ' => 'Ḧ',
+ 'ḩ' => 'Ḩ',
+ 'ḫ' => 'Ḫ',
+ 'ḭ' => 'Ḭ',
+ 'ḯ' => 'Ḯ',
+ 'ḱ' => 'Ḱ',
+ 'ḳ' => 'Ḳ',
+ 'ḵ' => 'Ḵ',
+ 'ḷ' => 'Ḷ',
+ 'ḹ' => 'Ḹ',
+ 'ḻ' => 'Ḻ',
+ 'ḽ' => 'Ḽ',
+ 'ḿ' => 'Ḿ',
+ 'ṁ' => 'Ṁ',
+ 'ṃ' => 'Ṃ',
+ 'ṅ' => 'Ṅ',
+ 'ṇ' => 'Ṇ',
+ 'ṉ' => 'Ṉ',
+ 'ṋ' => 'Ṋ',
+ 'ṍ' => 'Ṍ',
+ 'ṏ' => 'Ṏ',
+ 'ṑ' => 'Ṑ',
+ 'ṓ' => 'Ṓ',
+ 'ṕ' => 'Ṕ',
+ 'ṗ' => 'Ṗ',
+ 'ṙ' => 'Ṙ',
+ 'ṛ' => 'Ṛ',
+ 'ṝ' => 'Ṝ',
+ 'ṟ' => 'Ṟ',
+ 'ṡ' => 'Ṡ',
+ 'ṣ' => 'Ṣ',
+ 'ṥ' => 'Ṥ',
+ 'ṧ' => 'Ṧ',
+ 'ṩ' => 'Ṩ',
+ 'ṫ' => 'Ṫ',
+ 'ṭ' => 'Ṭ',
+ 'ṯ' => 'Ṯ',
+ 'ṱ' => 'Ṱ',
+ 'ṳ' => 'Ṳ',
+ 'ṵ' => 'Ṵ',
+ 'ṷ' => 'Ṷ',
+ 'ṹ' => 'Ṹ',
+ 'ṻ' => 'Ṻ',
+ 'ṽ' => 'Ṽ',
+ 'ṿ' => 'Ṿ',
+ 'ẁ' => 'Ẁ',
+ 'ẃ' => 'Ẃ',
+ 'ẅ' => 'Ẅ',
+ 'ẇ' => 'Ẇ',
+ 'ẉ' => 'Ẉ',
+ 'ẋ' => 'Ẋ',
+ 'ẍ' => 'Ẍ',
+ 'ẏ' => 'Ẏ',
+ 'ẑ' => 'Ẑ',
+ 'ẓ' => 'Ẓ',
+ 'ẕ' => 'Ẕ',
+ 'ẛ' => 'Ṡ',
+ 'ạ' => 'Ạ',
+ 'ả' => 'Ả',
+ 'ấ' => 'Ấ',
+ 'ầ' => 'Ầ',
+ 'ẩ' => 'Ẩ',
+ 'ẫ' => 'Ẫ',
+ 'ậ' => 'Ậ',
+ 'ắ' => 'Ắ',
+ 'ằ' => 'Ằ',
+ 'ẳ' => 'Ẳ',
+ 'ẵ' => 'Ẵ',
+ 'ặ' => 'Ặ',
+ 'ẹ' => 'Ẹ',
+ 'ẻ' => 'Ẻ',
+ 'ẽ' => 'Ẽ',
+ 'ế' => 'Ế',
+ 'ề' => 'Ề',
+ 'ể' => 'Ể',
+ 'ễ' => 'Ễ',
+ 'ệ' => 'Ệ',
+ 'ỉ' => 'Ỉ',
+ 'ị' => 'Ị',
+ 'ọ' => 'Ọ',
+ 'ỏ' => 'Ỏ',
+ 'ố' => 'Ố',
+ 'ồ' => 'Ồ',
+ 'ổ' => 'Ổ',
+ 'ỗ' => 'Ỗ',
+ 'ộ' => 'Ộ',
+ 'ớ' => 'Ớ',
+ 'ờ' => 'Ờ',
+ 'ở' => 'Ở',
+ 'ỡ' => 'Ỡ',
+ 'ợ' => 'Ợ',
+ 'ụ' => 'Ụ',
+ 'ủ' => 'Ủ',
+ 'ứ' => 'Ứ',
+ 'ừ' => 'Ừ',
+ 'ử' => 'Ử',
+ 'ữ' => 'Ữ',
+ 'ự' => 'Ự',
+ 'ỳ' => 'Ỳ',
+ 'ỵ' => 'Ỵ',
+ 'ỷ' => 'Ỷ',
+ 'ỹ' => 'Ỹ',
+ 'ỻ' => 'Ỻ',
+ 'ỽ' => 'Ỽ',
+ 'ỿ' => 'Ỿ',
+ 'ἀ' => 'Ἀ',
+ 'ἁ' => 'Ἁ',
+ 'ἂ' => 'Ἂ',
+ 'ἃ' => 'Ἃ',
+ 'ἄ' => 'Ἄ',
+ 'ἅ' => 'Ἅ',
+ 'ἆ' => 'Ἆ',
+ 'ἇ' => 'Ἇ',
+ 'ἐ' => 'Ἐ',
+ 'ἑ' => 'Ἑ',
+ 'ἒ' => 'Ἒ',
+ 'ἓ' => 'Ἓ',
+ 'ἔ' => 'Ἔ',
+ 'ἕ' => 'Ἕ',
+ 'ἠ' => 'Ἠ',
+ 'ἡ' => 'Ἡ',
+ 'ἢ' => 'Ἢ',
+ 'ἣ' => 'Ἣ',
+ 'ἤ' => 'Ἤ',
+ 'ἥ' => 'Ἥ',
+ 'ἦ' => 'Ἦ',
+ 'ἧ' => 'Ἧ',
+ 'ἰ' => 'Ἰ',
+ 'ἱ' => 'Ἱ',
+ 'ἲ' => 'Ἲ',
+ 'ἳ' => 'Ἳ',
+ 'ἴ' => 'Ἴ',
+ 'ἵ' => 'Ἵ',
+ 'ἶ' => 'Ἶ',
+ 'ἷ' => 'Ἷ',
+ 'ὀ' => 'Ὀ',
+ 'ὁ' => 'Ὁ',
+ 'ὂ' => 'Ὂ',
+ 'ὃ' => 'Ὃ',
+ 'ὄ' => 'Ὄ',
+ 'ὅ' => 'Ὅ',
+ 'ὑ' => 'Ὑ',
+ 'ὓ' => 'Ὓ',
+ 'ὕ' => 'Ὕ',
+ 'ὗ' => 'Ὗ',
+ 'ὠ' => 'Ὠ',
+ 'ὡ' => 'Ὡ',
+ 'ὢ' => 'Ὢ',
+ 'ὣ' => 'Ὣ',
+ 'ὤ' => 'Ὤ',
+ 'ὥ' => 'Ὥ',
+ 'ὦ' => 'Ὦ',
+ 'ὧ' => 'Ὧ',
+ 'ὰ' => 'Ὰ',
+ 'ά' => 'Ά',
+ 'ὲ' => 'Ὲ',
+ 'έ' => 'Έ',
+ 'ὴ' => 'Ὴ',
+ 'ή' => 'Ή',
+ 'ὶ' => 'Ὶ',
+ 'ί' => 'Ί',
+ 'ὸ' => 'Ὸ',
+ 'ό' => 'Ό',
+ 'ὺ' => 'Ὺ',
+ 'ύ' => 'Ύ',
+ 'ὼ' => 'Ὼ',
+ 'ώ' => 'Ώ',
+ 'ᾀ' => 'ᾈ',
+ 'ᾁ' => 'ᾉ',
+ 'ᾂ' => 'ᾊ',
+ 'ᾃ' => 'ᾋ',
+ 'ᾄ' => 'ᾌ',
+ 'ᾅ' => 'ᾍ',
+ 'ᾆ' => 'ᾎ',
+ 'ᾇ' => 'ᾏ',
+ 'ᾐ' => 'ᾘ',
+ 'ᾑ' => 'ᾙ',
+ 'ᾒ' => 'ᾚ',
+ 'ᾓ' => 'ᾛ',
+ 'ᾔ' => 'ᾜ',
+ 'ᾕ' => 'ᾝ',
+ 'ᾖ' => 'ᾞ',
+ 'ᾗ' => 'ᾟ',
+ 'ᾠ' => 'ᾨ',
+ 'ᾡ' => 'ᾩ',
+ 'ᾢ' => 'ᾪ',
+ 'ᾣ' => 'ᾫ',
+ 'ᾤ' => 'ᾬ',
+ 'ᾥ' => 'ᾭ',
+ 'ᾦ' => 'ᾮ',
+ 'ᾧ' => 'ᾯ',
+ 'ᾰ' => 'Ᾰ',
+ 'ᾱ' => 'Ᾱ',
+ 'ᾳ' => 'ᾼ',
+ 'ι' => 'Ι',
+ 'ῃ' => 'ῌ',
+ 'ῐ' => 'Ῐ',
+ 'ῑ' => 'Ῑ',
+ 'ῠ' => 'Ῠ',
+ 'ῡ' => 'Ῡ',
+ 'ῥ' => 'Ῥ',
+ 'ῳ' => 'ῼ',
+ 'ⅎ' => 'Ⅎ',
+ 'ⅰ' => 'Ⅰ',
+ 'ⅱ' => 'Ⅱ',
+ 'ⅲ' => 'Ⅲ',
+ 'ⅳ' => 'Ⅳ',
+ 'ⅴ' => 'Ⅴ',
+ 'ⅵ' => 'Ⅵ',
+ 'ⅶ' => 'Ⅶ',
+ 'ⅷ' => 'Ⅷ',
+ 'ⅸ' => 'Ⅸ',
+ 'ⅹ' => 'Ⅹ',
+ 'ⅺ' => 'Ⅺ',
+ 'ⅻ' => 'Ⅻ',
+ 'ⅼ' => 'Ⅼ',
+ 'ⅽ' => 'Ⅽ',
+ 'ⅾ' => 'Ⅾ',
+ 'ⅿ' => 'Ⅿ',
+ 'ↄ' => 'Ↄ',
+ 'ⓐ' => 'Ⓐ',
+ 'ⓑ' => 'Ⓑ',
+ 'ⓒ' => 'Ⓒ',
+ 'ⓓ' => 'Ⓓ',
+ 'ⓔ' => 'Ⓔ',
+ 'ⓕ' => 'Ⓕ',
+ 'ⓖ' => 'Ⓖ',
+ 'ⓗ' => 'Ⓗ',
+ 'ⓘ' => 'Ⓘ',
+ 'ⓙ' => 'Ⓙ',
+ 'ⓚ' => 'Ⓚ',
+ 'ⓛ' => 'Ⓛ',
+ 'ⓜ' => 'Ⓜ',
+ 'ⓝ' => 'Ⓝ',
+ 'ⓞ' => 'Ⓞ',
+ 'ⓟ' => 'Ⓟ',
+ 'ⓠ' => 'Ⓠ',
+ 'ⓡ' => 'Ⓡ',
+ 'ⓢ' => 'Ⓢ',
+ 'ⓣ' => 'Ⓣ',
+ 'ⓤ' => 'Ⓤ',
+ 'ⓥ' => 'Ⓥ',
+ 'ⓦ' => 'Ⓦ',
+ 'ⓧ' => 'Ⓧ',
+ 'ⓨ' => 'Ⓨ',
+ 'ⓩ' => 'Ⓩ',
+ 'ⰰ' => 'Ⰰ',
+ 'ⰱ' => 'Ⰱ',
+ 'ⰲ' => 'Ⰲ',
+ 'ⰳ' => 'Ⰳ',
+ 'ⰴ' => 'Ⰴ',
+ 'ⰵ' => 'Ⰵ',
+ 'ⰶ' => 'Ⰶ',
+ 'ⰷ' => 'Ⰷ',
+ 'ⰸ' => 'Ⰸ',
+ 'ⰹ' => 'Ⰹ',
+ 'ⰺ' => 'Ⰺ',
+ 'ⰻ' => 'Ⰻ',
+ 'ⰼ' => 'Ⰼ',
+ 'ⰽ' => 'Ⰽ',
+ 'ⰾ' => 'Ⰾ',
+ 'ⰿ' => 'Ⰿ',
+ 'ⱀ' => 'Ⱀ',
+ 'ⱁ' => 'Ⱁ',
+ 'ⱂ' => 'Ⱂ',
+ 'ⱃ' => 'Ⱃ',
+ 'ⱄ' => 'Ⱄ',
+ 'ⱅ' => 'Ⱅ',
+ 'ⱆ' => 'Ⱆ',
+ 'ⱇ' => 'Ⱇ',
+ 'ⱈ' => 'Ⱈ',
+ 'ⱉ' => 'Ⱉ',
+ 'ⱊ' => 'Ⱊ',
+ 'ⱋ' => 'Ⱋ',
+ 'ⱌ' => 'Ⱌ',
+ 'ⱍ' => 'Ⱍ',
+ 'ⱎ' => 'Ⱎ',
+ 'ⱏ' => 'Ⱏ',
+ 'ⱐ' => 'Ⱐ',
+ 'ⱑ' => 'Ⱑ',
+ 'ⱒ' => 'Ⱒ',
+ 'ⱓ' => 'Ⱓ',
+ 'ⱔ' => 'Ⱔ',
+ 'ⱕ' => 'Ⱕ',
+ 'ⱖ' => 'Ⱖ',
+ 'ⱗ' => 'Ⱗ',
+ 'ⱘ' => 'Ⱘ',
+ 'ⱙ' => 'Ⱙ',
+ 'ⱚ' => 'Ⱚ',
+ 'ⱛ' => 'Ⱛ',
+ 'ⱜ' => 'Ⱜ',
+ 'ⱝ' => 'Ⱝ',
+ 'ⱞ' => 'Ⱞ',
+ 'ⱡ' => 'Ⱡ',
+ 'ⱥ' => 'Ⱥ',
+ 'ⱦ' => 'Ⱦ',
+ 'ⱨ' => 'Ⱨ',
+ 'ⱪ' => 'Ⱪ',
+ 'ⱬ' => 'Ⱬ',
+ 'ⱳ' => 'Ⱳ',
+ 'ⱶ' => 'Ⱶ',
+ 'ⲁ' => 'Ⲁ',
+ 'ⲃ' => 'Ⲃ',
+ 'ⲅ' => 'Ⲅ',
+ 'ⲇ' => 'Ⲇ',
+ 'ⲉ' => 'Ⲉ',
+ 'ⲋ' => 'Ⲋ',
+ 'ⲍ' => 'Ⲍ',
+ 'ⲏ' => 'Ⲏ',
+ 'ⲑ' => 'Ⲑ',
+ 'ⲓ' => 'Ⲓ',
+ 'ⲕ' => 'Ⲕ',
+ 'ⲗ' => 'Ⲗ',
+ 'ⲙ' => 'Ⲙ',
+ 'ⲛ' => 'Ⲛ',
+ 'ⲝ' => 'Ⲝ',
+ 'ⲟ' => 'Ⲟ',
+ 'ⲡ' => 'Ⲡ',
+ 'ⲣ' => 'Ⲣ',
+ 'ⲥ' => 'Ⲥ',
+ 'ⲧ' => 'Ⲧ',
+ 'ⲩ' => 'Ⲩ',
+ 'ⲫ' => 'Ⲫ',
+ 'ⲭ' => 'Ⲭ',
+ 'ⲯ' => 'Ⲯ',
+ 'ⲱ' => 'Ⲱ',
+ 'ⲳ' => 'Ⲳ',
+ 'ⲵ' => 'Ⲵ',
+ 'ⲷ' => 'Ⲷ',
+ 'ⲹ' => 'Ⲹ',
+ 'ⲻ' => 'Ⲻ',
+ 'ⲽ' => 'Ⲽ',
+ 'ⲿ' => 'Ⲿ',
+ 'ⳁ' => 'Ⳁ',
+ 'ⳃ' => 'Ⳃ',
+ 'ⳅ' => 'Ⳅ',
+ 'ⳇ' => 'Ⳇ',
+ 'ⳉ' => 'Ⳉ',
+ 'ⳋ' => 'Ⳋ',
+ 'ⳍ' => 'Ⳍ',
+ 'ⳏ' => 'Ⳏ',
+ 'ⳑ' => 'Ⳑ',
+ 'ⳓ' => 'Ⳓ',
+ 'ⳕ' => 'Ⳕ',
+ 'ⳗ' => 'Ⳗ',
+ 'ⳙ' => 'Ⳙ',
+ 'ⳛ' => 'Ⳛ',
+ 'ⳝ' => 'Ⳝ',
+ 'ⳟ' => 'Ⳟ',
+ 'ⳡ' => 'Ⳡ',
+ 'ⳣ' => 'Ⳣ',
+ 'ⳬ' => 'Ⳬ',
+ 'ⳮ' => 'Ⳮ',
+ 'ⳳ' => 'Ⳳ',
+ 'ⴀ' => 'Ⴀ',
+ 'ⴁ' => 'Ⴁ',
+ 'ⴂ' => 'Ⴂ',
+ 'ⴃ' => 'Ⴃ',
+ 'ⴄ' => 'Ⴄ',
+ 'ⴅ' => 'Ⴅ',
+ 'ⴆ' => 'Ⴆ',
+ 'ⴇ' => 'Ⴇ',
+ 'ⴈ' => 'Ⴈ',
+ 'ⴉ' => 'Ⴉ',
+ 'ⴊ' => 'Ⴊ',
+ 'ⴋ' => 'Ⴋ',
+ 'ⴌ' => 'Ⴌ',
+ 'ⴍ' => 'Ⴍ',
+ 'ⴎ' => 'Ⴎ',
+ 'ⴏ' => 'Ⴏ',
+ 'ⴐ' => 'Ⴐ',
+ 'ⴑ' => 'Ⴑ',
+ 'ⴒ' => 'Ⴒ',
+ 'ⴓ' => 'Ⴓ',
+ 'ⴔ' => 'Ⴔ',
+ 'ⴕ' => 'Ⴕ',
+ 'ⴖ' => 'Ⴖ',
+ 'ⴗ' => 'Ⴗ',
+ 'ⴘ' => 'Ⴘ',
+ 'ⴙ' => 'Ⴙ',
+ 'ⴚ' => 'Ⴚ',
+ 'ⴛ' => 'Ⴛ',
+ 'ⴜ' => 'Ⴜ',
+ 'ⴝ' => 'Ⴝ',
+ 'ⴞ' => 'Ⴞ',
+ 'ⴟ' => 'Ⴟ',
+ 'ⴠ' => 'Ⴠ',
+ 'ⴡ' => 'Ⴡ',
+ 'ⴢ' => 'Ⴢ',
+ 'ⴣ' => 'Ⴣ',
+ 'ⴤ' => 'Ⴤ',
+ 'ⴥ' => 'Ⴥ',
+ 'ⴧ' => 'Ⴧ',
+ 'ⴭ' => 'Ⴭ',
+ 'ꙁ' => 'Ꙁ',
+ 'ꙃ' => 'Ꙃ',
+ 'ꙅ' => 'Ꙅ',
+ 'ꙇ' => 'Ꙇ',
+ 'ꙉ' => 'Ꙉ',
+ 'ꙋ' => 'Ꙋ',
+ 'ꙍ' => 'Ꙍ',
+ 'ꙏ' => 'Ꙏ',
+ 'ꙑ' => 'Ꙑ',
+ 'ꙓ' => 'Ꙓ',
+ 'ꙕ' => 'Ꙕ',
+ 'ꙗ' => 'Ꙗ',
+ 'ꙙ' => 'Ꙙ',
+ 'ꙛ' => 'Ꙛ',
+ 'ꙝ' => 'Ꙝ',
+ 'ꙟ' => 'Ꙟ',
+ 'ꙡ' => 'Ꙡ',
+ 'ꙣ' => 'Ꙣ',
+ 'ꙥ' => 'Ꙥ',
+ 'ꙧ' => 'Ꙧ',
+ 'ꙩ' => 'Ꙩ',
+ 'ꙫ' => 'Ꙫ',
+ 'ꙭ' => 'Ꙭ',
+ 'ꚁ' => 'Ꚁ',
+ 'ꚃ' => 'Ꚃ',
+ 'ꚅ' => 'Ꚅ',
+ 'ꚇ' => 'Ꚇ',
+ 'ꚉ' => 'Ꚉ',
+ 'ꚋ' => 'Ꚋ',
+ 'ꚍ' => 'Ꚍ',
+ 'ꚏ' => 'Ꚏ',
+ 'ꚑ' => 'Ꚑ',
+ 'ꚓ' => 'Ꚓ',
+ 'ꚕ' => 'Ꚕ',
+ 'ꚗ' => 'Ꚗ',
+ 'ꚙ' => 'Ꚙ',
+ 'ꚛ' => 'Ꚛ',
+ 'ꜣ' => 'Ꜣ',
+ 'ꜥ' => 'Ꜥ',
+ 'ꜧ' => 'Ꜧ',
+ 'ꜩ' => 'Ꜩ',
+ 'ꜫ' => 'Ꜫ',
+ 'ꜭ' => 'Ꜭ',
+ 'ꜯ' => 'Ꜯ',
+ 'ꜳ' => 'Ꜳ',
+ 'ꜵ' => 'Ꜵ',
+ 'ꜷ' => 'Ꜷ',
+ 'ꜹ' => 'Ꜹ',
+ 'ꜻ' => 'Ꜻ',
+ 'ꜽ' => 'Ꜽ',
+ 'ꜿ' => 'Ꜿ',
+ 'ꝁ' => 'Ꝁ',
+ 'ꝃ' => 'Ꝃ',
+ 'ꝅ' => 'Ꝅ',
+ 'ꝇ' => 'Ꝇ',
+ 'ꝉ' => 'Ꝉ',
+ 'ꝋ' => 'Ꝋ',
+ 'ꝍ' => 'Ꝍ',
+ 'ꝏ' => 'Ꝏ',
+ 'ꝑ' => 'Ꝑ',
+ 'ꝓ' => 'Ꝓ',
+ 'ꝕ' => 'Ꝕ',
+ 'ꝗ' => 'Ꝗ',
+ 'ꝙ' => 'Ꝙ',
+ 'ꝛ' => 'Ꝛ',
+ 'ꝝ' => 'Ꝝ',
+ 'ꝟ' => 'Ꝟ',
+ 'ꝡ' => 'Ꝡ',
+ 'ꝣ' => 'Ꝣ',
+ 'ꝥ' => 'Ꝥ',
+ 'ꝧ' => 'Ꝧ',
+ 'ꝩ' => 'Ꝩ',
+ 'ꝫ' => 'Ꝫ',
+ 'ꝭ' => 'Ꝭ',
+ 'ꝯ' => 'Ꝯ',
+ 'ꝺ' => 'Ꝺ',
+ 'ꝼ' => 'Ꝼ',
+ 'ꝿ' => 'Ꝿ',
+ 'ꞁ' => 'Ꞁ',
+ 'ꞃ' => 'Ꞃ',
+ 'ꞅ' => 'Ꞅ',
+ 'ꞇ' => 'Ꞇ',
+ 'ꞌ' => 'Ꞌ',
+ 'ꞑ' => 'Ꞑ',
+ 'ꞓ' => 'Ꞓ',
+ 'ꞔ' => 'Ꞔ',
+ 'ꞗ' => 'Ꞗ',
+ 'ꞙ' => 'Ꞙ',
+ 'ꞛ' => 'Ꞛ',
+ 'ꞝ' => 'Ꞝ',
+ 'ꞟ' => 'Ꞟ',
+ 'ꞡ' => 'Ꞡ',
+ 'ꞣ' => 'Ꞣ',
+ 'ꞥ' => 'Ꞥ',
+ 'ꞧ' => 'Ꞧ',
+ 'ꞩ' => 'Ꞩ',
+ 'ꞵ' => 'Ꞵ',
+ 'ꞷ' => 'Ꞷ',
+ 'ꞹ' => 'Ꞹ',
+ 'ꞻ' => 'Ꞻ',
+ 'ꞽ' => 'Ꞽ',
+ 'ꞿ' => 'Ꞿ',
+ 'ꟃ' => 'Ꟃ',
+ 'ꟈ' => 'Ꟈ',
+ 'ꟊ' => 'Ꟊ',
+ 'ꟶ' => 'Ꟶ',
+ 'ꭓ' => 'Ꭓ',
+ 'ꭰ' => 'Ꭰ',
+ 'ꭱ' => 'Ꭱ',
+ 'ꭲ' => 'Ꭲ',
+ 'ꭳ' => 'Ꭳ',
+ 'ꭴ' => 'Ꭴ',
+ 'ꭵ' => 'Ꭵ',
+ 'ꭶ' => 'Ꭶ',
+ 'ꭷ' => 'Ꭷ',
+ 'ꭸ' => 'Ꭸ',
+ 'ꭹ' => 'Ꭹ',
+ 'ꭺ' => 'Ꭺ',
+ 'ꭻ' => 'Ꭻ',
+ 'ꭼ' => 'Ꭼ',
+ 'ꭽ' => 'Ꭽ',
+ 'ꭾ' => 'Ꭾ',
+ 'ꭿ' => 'Ꭿ',
+ 'ꮀ' => 'Ꮀ',
+ 'ꮁ' => 'Ꮁ',
+ 'ꮂ' => 'Ꮂ',
+ 'ꮃ' => 'Ꮃ',
+ 'ꮄ' => 'Ꮄ',
+ 'ꮅ' => 'Ꮅ',
+ 'ꮆ' => 'Ꮆ',
+ 'ꮇ' => 'Ꮇ',
+ 'ꮈ' => 'Ꮈ',
+ 'ꮉ' => 'Ꮉ',
+ 'ꮊ' => 'Ꮊ',
+ 'ꮋ' => 'Ꮋ',
+ 'ꮌ' => 'Ꮌ',
+ 'ꮍ' => 'Ꮍ',
+ 'ꮎ' => 'Ꮎ',
+ 'ꮏ' => 'Ꮏ',
+ 'ꮐ' => 'Ꮐ',
+ 'ꮑ' => 'Ꮑ',
+ 'ꮒ' => 'Ꮒ',
+ 'ꮓ' => 'Ꮓ',
+ 'ꮔ' => 'Ꮔ',
+ 'ꮕ' => 'Ꮕ',
+ 'ꮖ' => 'Ꮖ',
+ 'ꮗ' => 'Ꮗ',
+ 'ꮘ' => 'Ꮘ',
+ 'ꮙ' => 'Ꮙ',
+ 'ꮚ' => 'Ꮚ',
+ 'ꮛ' => 'Ꮛ',
+ 'ꮜ' => 'Ꮜ',
+ 'ꮝ' => 'Ꮝ',
+ 'ꮞ' => 'Ꮞ',
+ 'ꮟ' => 'Ꮟ',
+ 'ꮠ' => 'Ꮠ',
+ 'ꮡ' => 'Ꮡ',
+ 'ꮢ' => 'Ꮢ',
+ 'ꮣ' => 'Ꮣ',
+ 'ꮤ' => 'Ꮤ',
+ 'ꮥ' => 'Ꮥ',
+ 'ꮦ' => 'Ꮦ',
+ 'ꮧ' => 'Ꮧ',
+ 'ꮨ' => 'Ꮨ',
+ 'ꮩ' => 'Ꮩ',
+ 'ꮪ' => 'Ꮪ',
+ 'ꮫ' => 'Ꮫ',
+ 'ꮬ' => 'Ꮬ',
+ 'ꮭ' => 'Ꮭ',
+ 'ꮮ' => 'Ꮮ',
+ 'ꮯ' => 'Ꮯ',
+ 'ꮰ' => 'Ꮰ',
+ 'ꮱ' => 'Ꮱ',
+ 'ꮲ' => 'Ꮲ',
+ 'ꮳ' => 'Ꮳ',
+ 'ꮴ' => 'Ꮴ',
+ 'ꮵ' => 'Ꮵ',
+ 'ꮶ' => 'Ꮶ',
+ 'ꮷ' => 'Ꮷ',
+ 'ꮸ' => 'Ꮸ',
+ 'ꮹ' => 'Ꮹ',
+ 'ꮺ' => 'Ꮺ',
+ 'ꮻ' => 'Ꮻ',
+ 'ꮼ' => 'Ꮼ',
+ 'ꮽ' => 'Ꮽ',
+ 'ꮾ' => 'Ꮾ',
+ 'ꮿ' => 'Ꮿ',
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ 'e' => 'E',
+ 'f' => 'F',
+ 'g' => 'G',
+ 'h' => 'H',
+ 'i' => 'I',
+ 'j' => 'J',
+ 'k' => 'K',
+ 'l' => 'L',
+ 'm' => 'M',
+ 'n' => 'N',
+ 'o' => 'O',
+ 'p' => 'P',
+ 'q' => 'Q',
+ 'r' => 'R',
+ 's' => 'S',
+ 't' => 'T',
+ 'u' => 'U',
+ 'v' => 'V',
+ 'w' => 'W',
+ 'x' => 'X',
+ 'y' => 'Y',
+ 'z' => 'Z',
+ '𐐨' => '𐐀',
+ '𐐩' => '𐐁',
+ '𐐪' => '𐐂',
+ '𐐫' => '𐐃',
+ '𐐬' => '𐐄',
+ '𐐭' => '𐐅',
+ '𐐮' => '𐐆',
+ '𐐯' => '𐐇',
+ '𐐰' => '𐐈',
+ '𐐱' => '𐐉',
+ '𐐲' => '𐐊',
+ '𐐳' => '𐐋',
+ '𐐴' => '𐐌',
+ '𐐵' => '𐐍',
+ '𐐶' => '𐐎',
+ '𐐷' => '𐐏',
+ '𐐸' => '𐐐',
+ '𐐹' => '𐐑',
+ '𐐺' => '𐐒',
+ '𐐻' => '𐐓',
+ '𐐼' => '𐐔',
+ '𐐽' => '𐐕',
+ '𐐾' => '𐐖',
+ '𐐿' => '𐐗',
+ '𐑀' => '𐐘',
+ '𐑁' => '𐐙',
+ '𐑂' => '𐐚',
+ '𐑃' => '𐐛',
+ '𐑄' => '𐐜',
+ '𐑅' => '𐐝',
+ '𐑆' => '𐐞',
+ '𐑇' => '𐐟',
+ '𐑈' => '𐐠',
+ '𐑉' => '𐐡',
+ '𐑊' => '𐐢',
+ '𐑋' => '𐐣',
+ '𐑌' => '𐐤',
+ '𐑍' => '𐐥',
+ '𐑎' => '𐐦',
+ '𐑏' => '𐐧',
+ '𐓘' => '𐒰',
+ '𐓙' => '𐒱',
+ '𐓚' => '𐒲',
+ '𐓛' => '𐒳',
+ '𐓜' => '𐒴',
+ '𐓝' => '𐒵',
+ '𐓞' => '𐒶',
+ '𐓟' => '𐒷',
+ '𐓠' => '𐒸',
+ '𐓡' => '𐒹',
+ '𐓢' => '𐒺',
+ '𐓣' => '𐒻',
+ '𐓤' => '𐒼',
+ '𐓥' => '𐒽',
+ '𐓦' => '𐒾',
+ '𐓧' => '𐒿',
+ '𐓨' => '𐓀',
+ '𐓩' => '𐓁',
+ '𐓪' => '𐓂',
+ '𐓫' => '𐓃',
+ '𐓬' => '𐓄',
+ '𐓭' => '𐓅',
+ '𐓮' => '𐓆',
+ '𐓯' => '𐓇',
+ '𐓰' => '𐓈',
+ '𐓱' => '𐓉',
+ '𐓲' => '𐓊',
+ '𐓳' => '𐓋',
+ '𐓴' => '𐓌',
+ '𐓵' => '𐓍',
+ '𐓶' => '𐓎',
+ '𐓷' => '𐓏',
+ '𐓸' => '𐓐',
+ '𐓹' => '𐓑',
+ '𐓺' => '𐓒',
+ '𐓻' => '𐓓',
+ '𐳀' => '𐲀',
+ '𐳁' => '𐲁',
+ '𐳂' => '𐲂',
+ '𐳃' => '𐲃',
+ '𐳄' => '𐲄',
+ '𐳅' => '𐲅',
+ '𐳆' => '𐲆',
+ '𐳇' => '𐲇',
+ '𐳈' => '𐲈',
+ '𐳉' => '𐲉',
+ '𐳊' => '𐲊',
+ '𐳋' => '𐲋',
+ '𐳌' => '𐲌',
+ '𐳍' => '𐲍',
+ '𐳎' => '𐲎',
+ '𐳏' => '𐲏',
+ '𐳐' => '𐲐',
+ '𐳑' => '𐲑',
+ '𐳒' => '𐲒',
+ '𐳓' => '𐲓',
+ '𐳔' => '𐲔',
+ '𐳕' => '𐲕',
+ '𐳖' => '𐲖',
+ '𐳗' => '𐲗',
+ '𐳘' => '𐲘',
+ '𐳙' => '𐲙',
+ '𐳚' => '𐲚',
+ '𐳛' => '𐲛',
+ '𐳜' => '𐲜',
+ '𐳝' => '𐲝',
+ '𐳞' => '𐲞',
+ '𐳟' => '𐲟',
+ '𐳠' => '𐲠',
+ '𐳡' => '𐲡',
+ '𐳢' => '𐲢',
+ '𐳣' => '𐲣',
+ '𐳤' => '𐲤',
+ '𐳥' => '𐲥',
+ '𐳦' => '𐲦',
+ '𐳧' => '𐲧',
+ '𐳨' => '𐲨',
+ '𐳩' => '𐲩',
+ '𐳪' => '𐲪',
+ '𐳫' => '𐲫',
+ '𐳬' => '𐲬',
+ '𐳭' => '𐲭',
+ '𐳮' => '𐲮',
+ '𐳯' => '𐲯',
+ '𐳰' => '𐲰',
+ '𐳱' => '𐲱',
+ '𐳲' => '𐲲',
+ '𑣀' => '𑢠',
+ '𑣁' => '𑢡',
+ '𑣂' => '𑢢',
+ '𑣃' => '𑢣',
+ '𑣄' => '𑢤',
+ '𑣅' => '𑢥',
+ '𑣆' => '𑢦',
+ '𑣇' => '𑢧',
+ '𑣈' => '𑢨',
+ '𑣉' => '𑢩',
+ '𑣊' => '𑢪',
+ '𑣋' => '𑢫',
+ '𑣌' => '𑢬',
+ '𑣍' => '𑢭',
+ '𑣎' => '𑢮',
+ '𑣏' => '𑢯',
+ '𑣐' => '𑢰',
+ '𑣑' => '𑢱',
+ '𑣒' => '𑢲',
+ '𑣓' => '𑢳',
+ '𑣔' => '𑢴',
+ '𑣕' => '𑢵',
+ '𑣖' => '𑢶',
+ '𑣗' => '𑢷',
+ '𑣘' => '𑢸',
+ '𑣙' => '𑢹',
+ '𑣚' => '𑢺',
+ '𑣛' => '𑢻',
+ '𑣜' => '𑢼',
+ '𑣝' => '𑢽',
+ '𑣞' => '𑢾',
+ '𑣟' => '𑢿',
+ '𖹠' => '𖹀',
+ '𖹡' => '𖹁',
+ '𖹢' => '𖹂',
+ '𖹣' => '𖹃',
+ '𖹤' => '𖹄',
+ '𖹥' => '𖹅',
+ '𖹦' => '𖹆',
+ '𖹧' => '𖹇',
+ '𖹨' => '𖹈',
+ '𖹩' => '𖹉',
+ '𖹪' => '𖹊',
+ '𖹫' => '𖹋',
+ '𖹬' => '𖹌',
+ '𖹭' => '𖹍',
+ '𖹮' => '𖹎',
+ '𖹯' => '𖹏',
+ '𖹰' => '𖹐',
+ '𖹱' => '𖹑',
+ '𖹲' => '𖹒',
+ '𖹳' => '𖹓',
+ '𖹴' => '𖹔',
+ '𖹵' => '𖹕',
+ '𖹶' => '𖹖',
+ '𖹷' => '𖹗',
+ '𖹸' => '𖹘',
+ '𖹹' => '𖹙',
+ '𖹺' => '𖹚',
+ '𖹻' => '𖹛',
+ '𖹼' => '𖹜',
+ '𖹽' => '𖹝',
+ '𖹾' => '𖹞',
+ '𖹿' => '𖹟',
+ '𞤢' => '𞤀',
+ '𞤣' => '𞤁',
+ '𞤤' => '𞤂',
+ '𞤥' => '𞤃',
+ '𞤦' => '𞤄',
+ '𞤧' => '𞤅',
+ '𞤨' => '𞤆',
+ '𞤩' => '𞤇',
+ '𞤪' => '𞤈',
+ '𞤫' => '𞤉',
+ '𞤬' => '𞤊',
+ '𞤭' => '𞤋',
+ '𞤮' => '𞤌',
+ '𞤯' => '𞤍',
+ '𞤰' => '𞤎',
+ '𞤱' => '𞤏',
+ '𞤲' => '𞤐',
+ '𞤳' => '𞤑',
+ '𞤴' => '𞤒',
+ '𞤵' => '𞤓',
+ '𞤶' => '𞤔',
+ '𞤷' => '𞤕',
+ '𞤸' => '𞤖',
+ '𞤹' => '𞤗',
+ '𞤺' => '𞤘',
+ '𞤻' => '𞤙',
+ '𞤼' => '𞤚',
+ '𞤽' => '𞤛',
+ '𞤾' => '𞤜',
+ '𞤿' => '𞤝',
+ '𞥀' => '𞤞',
+ '𞥁' => '𞤟',
+ '𞥂' => '𞤠',
+ '𞥃' => '𞤡',
+);
diff --git a/vendor/symfony/polyfill-mbstring/bootstrap.php b/vendor/symfony/polyfill-mbstring/bootstrap.php
new file mode 100644
index 0000000..a48f7e6
--- /dev/null
+++ b/vendor/symfony/polyfill-mbstring/bootstrap.php
@@ -0,0 +1,145 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Mbstring as p;
+
+if (!function_exists('mb_convert_encoding')) {
+ function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); }
+}
+if (!function_exists('mb_decode_mimeheader')) {
+ function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); }
+}
+if (!function_exists('mb_encode_mimeheader')) {
+ function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); }
+}
+if (!function_exists('mb_decode_numericentity')) {
+ function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); }
+}
+if (!function_exists('mb_encode_numericentity')) {
+ function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); }
+}
+if (!function_exists('mb_convert_case')) {
+ function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); }
+}
+if (!function_exists('mb_internal_encoding')) {
+ function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); }
+}
+if (!function_exists('mb_language')) {
+ function mb_language($language = null) { return p\Mbstring::mb_language($language); }
+}
+if (!function_exists('mb_list_encodings')) {
+ function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
+}
+if (!function_exists('mb_encoding_aliases')) {
+ function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
+}
+if (!function_exists('mb_check_encoding')) {
+ function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); }
+}
+if (!function_exists('mb_detect_encoding')) {
+ function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); }
+}
+if (!function_exists('mb_detect_order')) {
+ function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); }
+}
+if (!function_exists('mb_parse_str')) {
+ function mb_parse_str($string, &$result = array()) { parse_str($string, $result); }
+}
+if (!function_exists('mb_strlen')) {
+ function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); }
+}
+if (!function_exists('mb_strpos')) {
+ function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); }
+}
+if (!function_exists('mb_strtolower')) {
+ function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); }
+}
+if (!function_exists('mb_strtoupper')) {
+ function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); }
+}
+if (!function_exists('mb_substitute_character')) {
+ function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); }
+}
+if (!function_exists('mb_substr')) {
+ function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); }
+}
+if (!function_exists('mb_stripos')) {
+ function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); }
+}
+if (!function_exists('mb_stristr')) {
+ function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); }
+}
+if (!function_exists('mb_strrchr')) {
+ function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); }
+}
+if (!function_exists('mb_strrichr')) {
+ function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); }
+}
+if (!function_exists('mb_strripos')) {
+ function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); }
+}
+if (!function_exists('mb_strrpos')) {
+ function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); }
+}
+if (!function_exists('mb_strstr')) {
+ function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); }
+}
+if (!function_exists('mb_get_info')) {
+ function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
+}
+if (!function_exists('mb_http_output')) {
+ function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); }
+}
+if (!function_exists('mb_strwidth')) {
+ function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); }
+}
+if (!function_exists('mb_substr_count')) {
+ function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); }
+}
+if (!function_exists('mb_output_handler')) {
+ function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); }
+}
+if (!function_exists('mb_http_input')) {
+ function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
+}
+
+if (PHP_VERSION_ID >= 80000) {
+ require_once __DIR__.'/Resources/mb_convert_variables.php8';
+} elseif (!function_exists('mb_convert_variables')) {
+ function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); }
+}
+
+if (!function_exists('mb_ord')) {
+ function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); }
+}
+if (!function_exists('mb_chr')) {
+ function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); }
+}
+if (!function_exists('mb_scrub')) {
+ function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
+}
+if (!function_exists('mb_str_split')) {
+ function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); }
+}
+
+if (extension_loaded('mbstring')) {
+ return;
+}
+
+if (!defined('MB_CASE_UPPER')) {
+ define('MB_CASE_UPPER', 0);
+}
+if (!defined('MB_CASE_LOWER')) {
+ define('MB_CASE_LOWER', 1);
+}
+if (!defined('MB_CASE_TITLE')) {
+ define('MB_CASE_TITLE', 2);
+}
diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-mbstring/composer.json
new file mode 100644
index 0000000..abdfd3e
--- /dev/null
+++ b/vendor/symfony/polyfill-mbstring/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "symfony/polyfill-mbstring",
+ "type": "library",
+ "description": "Symfony polyfill for the Mbstring extension",
+ "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" },
+ "files": [ "bootstrap.php" ]
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.19-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ }
+}
diff --git a/vendor/symfony/translation/.gitignore b/vendor/symfony/translation/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/translation/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/translation/CHANGELOG.md b/vendor/symfony/translation/CHANGELOG.md
new file mode 100644
index 0000000..105a67e
--- /dev/null
+++ b/vendor/symfony/translation/CHANGELOG.md
@@ -0,0 +1,94 @@
+CHANGELOG
+=========
+
+3.4.0
+-----
+
+ * Added `TranslationDumperPass`
+ * Added `TranslationExtractorPass`
+ * Added `TranslatorPass`
+ * Added `TranslationReader` and `TranslationReaderInterface`
+ * Added `
+
+ This schema document describes the XML namespace, in a form
+ suitable for import by other schema documents.
+
+ See
+ http://www.w3.org/XML/1998/namespace.html and
+
+ http://www.w3.org/TR/REC-xml for information
+ about this namespace.
+
+ Note that local names in this namespace are intended to be
+ defined only by the World Wide Web Consortium or its subgroups.
+ The names currently defined in this namespace are listed below.
+ They should not be used with conflicting semantics by any Working
+ Group, specification, or document instance.
+
+ See further below in this document for more information about how to refer to this schema document from your own
+ XSD schema documents and about the
+ namespace-versioning policy governing this schema document.
+
+
+ denotes an attribute whose value
+ is a language code for the natural language of the content of
+ any element; its value is inherited. This name is reserved
+ by virtue of its definition in the XML specification.
+ Attempting to install the relevant ISO 2- and 3-letter
+ codes as the enumerated possible values is probably never
+ going to be a realistic possibility.
+
+
+ See BCP 47 at
+ http://www.rfc-editor.org/rfc/bcp/bcp47.txt
+ and the IANA language subtag registry at
+
+ http://www.iana.org/assignments/language-subtag-registry
+ for further information.
+
+
+ The union allows for the 'un-declaration' of xml:lang with
+ the empty string.
+
+ denotes an attribute whose
+ value is a keyword indicating what whitespace processing
+ discipline is intended for the content of the element; its
+ value is inherited. This name is reserved by virtue of its
+ definition in the XML specification.
+ denotes an attribute whose value
+ provides a URI to be used as the base for interpreting any
+ relative URIs in the scope of the element on which it
+ appears; its value is inherited. This name is reserved
+ by virtue of its definition in the XML Base specification.
+ See http://www.w3.org/TR/xmlbase/
+ for information about this attribute.
+
+
+ denotes an attribute whose value
+ should be interpreted as if declared to be of type ID.
+ This name is reserved by virtue of its definition in the
+ xml:id specification.
+ See http://www.w3.org/TR/xml-id/
+ for information about this attribute.
+
+ denotes Jon Bosak, the chair of
+ the original XML Working Group. This name is reserved by
+ the following decision of the W3C XML Plenary and
+ XML Coordination groups:
+
+
+ In appreciation for his vision, leadership and
+ dedication the W3C XML Plenary on this 10th day of
+ February, 2000, reserves for Jon Bosak in perpetuity
+ the XML name "xml:Father".
+
+ This schema defines attributes and an attribute group suitable
+ for use by schemas wishing to allow
+ To enable this, such a schema must import this schema for
+ the XML namespace, e.g. as follows:
+
+ or
+
+ Subsequently, qualified reference to any of the attributes or the
+ group defined below will have the desired effect, e.g.
+
+ will define a type which will schema-validate an instance element
+ with any of those attributes.
+
+ In keeping with the XML Schema WG's standard versioning
+ policy, this schema document will persist at
+
+ http://www.w3.org/2009/01/xml.xsd.
+
+ At the date of issue it can also be found at
+
+ http://www.w3.org/2001/xml.xsd.
+
+ The schema document at that URI may however change in the future,
+ in order to remain compatible with the latest version of XML
+ Schema itself, or with the XML namespace itself. In other words,
+ if the XML Schema or XML namespaces change, the version of this
+ document at
+ http://www.w3.org/2001/xml.xsd
+
+ will change accordingly; the version at
+
+ http://www.w3.org/2009/01/xml.xsd
+
+ will not change.
+
+
+ Previous dated (and unchanging) versions of this schema
+ document are at:
+ About the XML namespace
+
+ lang (as an attribute name)
+ Notes
+ space (as an attribute name)
+ base (as an attribute name)
+ id (as an attribute name)
+ Father (in any context at all)
+
+
+
+ About this schema document
+
+ xml:base
,
+ xml:lang
, xml:space
or
+ xml:id
attributes on elements they define.
+
+ <schema.. .>
+ .. .
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+
+
+
+ <import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+
+
+ <type.. .>
+ .. .
+ <attributeGroup ref="xml:specialAttrs"/>
+
+ Versioning policy for this schema document
+
+