1<?php
2
3/**
4 * Laravel Helpers File
5 * Extracted by Anthony Rappa
6 * rappa819@gmail.com
7 */
8
9if (!function_exists('append_config')) {
10    /**
11     * Assign high numeric IDs to a config item to force appending.
12     *
13     * @param  array $array
14     * @return array
15     */
16    function append_config(array $array)
17    {
18        $start = 9999;
19
20        foreach ($array as $key => $value) {
21            if (is_numeric($key)) {
22                $start++;
23
24                $array[$start] = array_pull($array, $key);
25            }
26        }
27
28        return $array;
29    }
30}
31
32if (!function_exists('array_add')) {
33    /**
34     * Add an element to an array using "dot" notation if it doesn't exist.
35     *
36     * @param  array $array
37     * @param  string $key
38     * @param  mixed $value
39     * @return array
40     */
41    function array_add($array, $key, $value)
42    {
43        if (is_null(get($array, $key))) {
44            set($array, $key, $value);
45        }
46
47        return $array;
48    }
49}
50
51if (!function_exists('array_build')) {
52    /**
53     * Build a new array using a callback.
54     *
55     * @param  array $array
56     * @param  \Closure $callback
57     * @return array
58     */
59    function array_build($array, Closure $callback)
60    {
61        $results = array();
62
63        foreach ($array as $key => $value) {
64            list($innerKey, $innerValue) = call_user_func($callback, $key, $value);
65
66            $results[$innerKey] = $innerValue;
67        }
68
69        return $results;
70    }
71}
72
73if (!function_exists('array_divide')) {
74    /**
75     * Divide an array into two arrays. One with keys and the other with values.
76     *
77     * @param  array $array
78     * @return array
79     */
80    function array_divide($array)
81    {
82        return array(array_keys($array), array_values($array));
83    }
84}
85
86if (!function_exists('array_dot')) {
87    /**
88     * Flatten a multi-dimensional associative array with dots.
89     *
90     * @param  array $array
91     * @param  string $prepend
92     * @return array
93     */
94    function array_dot($array, $prepend = '')
95    {
96        $results = array();
97
98        foreach ($array as $key => $value) {
99            if (is_array($value)) {
100                $results = array_merge($results, dot($value, $prepend . $key . '.'));
101            } else {
102                $results[$prepend . $key] = $value;
103            }
104        }
105
106        return $results;
107    }
108}
109
110if (!function_exists('array_except')) {
111    /**
112     * Get all of the given array except for a specified array of items.
113     *
114     * @param  array $array
115     * @param  array|string $keys
116     * @return array
117     */
118    function array_except($array, $keys)
119    {
120        return array_diff_key($array, array_flip((array)$keys));
121    }
122}
123
124if (!function_exists('array_fetch')) {
125    /**
126     * Fetch a flattened array of a nested array element.
127     *
128     * @param  array $array
129     * @param  string $key
130     * @return array
131     */
132    function array_fetch($array, $key)
133    {
134        $results = array();
135
136        foreach (explode('.', $key) as $segment) {
137            foreach ($array as $value) {
138                if (array_key_exists($segment, $value = (array)$value)) {
139                    $results[] = $value[$segment];
140                }
141            }
142
143            $array = array_values($results);
144        }
145
146        return array_values($results);
147    }
148}
149
150if (!function_exists('array_first')) {
151    /**
152     * Return the first element in an array passing a given truth test.
153     *
154     * @param  array $array
155     * @param  \Closure $callback
156     * @param  mixed $default
157     * @return mixed
158     */
159    function array_first($array, $callback, $default = null)
160    {
161        foreach ($array as $key => $value) {
162            if (call_user_func($callback, $key, $value)) {
163                return $value;
164            }
165        }
166
167        return value($default);
168    }
169}
170
171if (!function_exists('array_last')) {
172    /**
173     * Return the last element in an array passing a given truth test.
174     *
175     * @param  array $array
176     * @param  \Closure $callback
177     * @param  mixed $default
178     * @return mixed
179     */
180    function array_last($array, $callback, $default = null)
181    {
182        return first(array_reverse($array), $callback, $default);
183    }
184}
185
186if (!function_exists('array_flatten')) {
187    /**
188     * Flatten a multi-dimensional array into a single level.
189     *
190     * @param  array $array
191     * @return array
192     */
193    function array_flatten($array)
194    {
195        $return = array();
196
197        array_walk_recursive($array, function ($x) use (&$return) {
198            $return[] = $x;
199        });
200
201        return $return;
202    }
203}
204
205if (!function_exists('array_forget')) {
206    /**
207     * Remove one or many array items from a given array using "dot" notation.
208     *
209     * @param  array $array
210     * @param  array|string $keys
211     * @return void
212     */
213    function array_forget(&$array, $keys)
214    {
215        $original =& $array;
216
217        foreach ((array)$keys as $key) {
218            $parts = explode('.', $key);
219
220            while (count($parts) > 1) {
221                $part = array_shift($parts);
222
223                if (isset($array[$part]) && is_array($array[$part])) {
224                    $array =& $array[$part];
225                }
226            }
227
228            unset($array[array_shift($parts)]);
229
230            // clean up after each pass
231            $array =& $original;
232        }
233    }
234}
235
236if (!function_exists('array_get')) {
237    /**
238     * Get an item from an array using "dot" notation.
239     *
240     * @param  array $array
241     * @param  string $key
242     * @param  mixed $default
243     * @return mixed
244     */
245    function array_get($array, $key, $default = null)
246    {
247        if (is_null($key)) {
248            return $array;
249        }
250
251        if (isset($array[$key])) {
252            return $array[$key];
253        }
254
255        foreach (explode('.', $key) as $segment) {
256            if (!is_array($array) || !array_key_exists($segment, $array)) {
257                return value($default);
258            }
259
260            $array = $array[$segment];
261        }
262
263        return $array;
264    }
265}
266
267if (!function_exists('array_has')) {
268    /**
269     * Check if an item exists in an array using "dot" notation.
270     *
271     * @param  array $array
272     * @param  string $key
273     * @return bool
274     */
275    function array_has($array, $key)
276    {
277        if (empty($array) || is_null($key)) {
278            return false;
279        }
280
281        if (array_key_exists($key, $array)) {
282            return true;
283        }
284
285        foreach (explode('.', $key) as $segment) {
286            if (!is_array($array) || !array_key_exists($segment, $array)) {
287                return false;
288            }
289
290            $array = $array[$segment];
291        }
292
293        return true;
294    }
295}
296
297if (!function_exists('array_only')) {
298    /**
299     * Get a subset of the items from the given array.
300     *
301     * @param  array $array
302     * @param  array|string $keys
303     * @return array
304     */
305    function array_only($array, $keys)
306    {
307        return array_intersect_key($array, array_flip((array)$keys));
308    }
309}
310
311if (!function_exists('array_pluck')) {
312    /**
313     * Pluck an array of values from an array.
314     *
315     * @param  array $array
316     * @param  string $value
317     * @param  string $key
318     * @return array
319     */
320    function array_pluck($array, $value, $key = null)
321    {
322        $results = array();
323
324        foreach ($array as $item) {
325            $itemValue = data_get($item, $value);
326
327            // If the key is "null", we will just append the value to the array and keep
328            // looping. Otherwise we will key the array using the value of the key we
329            // received from the developer. Then we'll return the final array form.
330            if (is_null($key)) {
331                $results[] = $itemValue;
332            } else {
333                $itemKey = data_get($item, $key);
334
335                $results[$itemKey] = $itemValue;
336            }
337        }
338
339        return $results;
340    }
341}
342
343if (!function_exists('array_pull')) {
344    /**
345     * Get a value from the array, and remove it.
346     *
347     * @param  array $array
348     * @param  string $key
349     * @param  mixed $default
350     * @return mixed
351     */
352    function array_pull(&$array, $key, $default = null)
353    {
354        $value = get($array, $key, $default);
355
356        forget($array, $key);
357
358        return $value;
359    }
360}
361
362if (!function_exists('array_set')) {
363    /**
364     * Set an array item to a given value using "dot" notation.
365     *
366     * If no key is given to the method, the entire array will be replaced.
367     *
368     * @param  array $array
369     * @param  string $key
370     * @param  mixed $value
371     * @return array
372     */
373    function array_set(&$array, $key, $value)
374    {
375        if (is_null($key)) {
376            return $array = $value;
377        }
378
379        $keys = explode('.', $key);
380
381        while (count($keys) > 1) {
382            $key = array_shift($keys);
383
384            // If the key doesn't exist at this depth, we will just create an empty array
385            // to hold the next value, allowing us to create the arrays to hold final
386            // values at the correct depth. Then we'll keep digging into the array.
387            if (!isset($array[$key]) || !is_array($array[$key])) {
388                $array[$key] = array();
389            }
390
391            $array =& $array[$key];
392        }
393
394        $array[array_shift($keys)] = $value;
395
396        return $array;
397    }
398}
399
400if (!function_exists('array_where')) {
401    /**
402     * Filter the array using the given Closure.
403     *
404     * @param  array $array
405     * @param  \Closure $callback
406     * @return array
407     */
408    function array_where($array, Closure $callback)
409    {
410        $filtered = array();
411
412        foreach ($array as $key => $value) {
413            if (call_user_func($callback, $key, $value)) {
414                $filtered[$key] = $value;
415            }
416        }
417
418        return $filtered;
419    }
420}
421
422if (!function_exists('camel_case')) {
423    /**
424     * Convert a value to camel case.
425     *
426     * @param  string $value
427     * @return string
428     */
429    function camel_case($value)
430    {
431        static $camelCache = [];
432
433        if (isset($camelCache[$value])) {
434            return $camelCache[$value];
435        }
436
437        return $camelCache[$value] = lcfirst(studly($value));
438    }
439}
440
441if (!function_exists('class_basename')) {
442    /**
443     * Get the class "basename" of the given object / class.
444     *
445     * @param  string|object $class
446     * @return string
447     */
448    function class_basename($class)
449    {
450        $class = is_object($class) ? get_class($class) : $class;
451
452        return basename(str_replace('\\', '/', $class));
453    }
454}
455
456if (!function_exists('class_uses_recursive')) {
457    /**
458     * Returns all traits used by a class, it's subclasses and trait of their traits
459     *
460     * @param  string $class
461     * @return array
462     */
463    function class_uses_recursive($class)
464    {
465        $results = [];
466
467        foreach (array_merge([$class => $class], class_parents($class)) as $class) {
468            $results += trait_uses_recursive($class);
469        }
470
471        return array_unique($results);
472    }
473}
474
475if (!function_exists('data_get')) {
476    /**
477     * Get an item from an array or object using "dot" notation.
478     *
479     * @param  mixed $target
480     * @param  string $key
481     * @param  mixed $default
482     * @return mixed
483     */
484    function data_get($target, $key, $default = null)
485    {
486        if (is_null($key)) {
487            return $target;
488        }
489
490        foreach (explode('.', $key) as $segment) {
491            if (is_array($target)) {
492                if (!array_key_exists($segment, $target)) {
493                    return value($default);
494                }
495
496                $target = $target[$segment];
497            } elseif ($target instanceof ArrayAccess) {
498                if (!isset($target[$segment])) {
499                    return value($default);
500                }
501
502                $target = $target[$segment];
503            } elseif (is_object($target)) {
504                if (!isset($target->{$segment})) {
505                    return value($default);
506                }
507
508                $target = $target->{$segment};
509            } else {
510                return value($default);
511            }
512        }
513
514        return $target;
515    }
516}
517
518if (!function_exists('e')) {
519    /**
520     * Escape HTML entities in a string.
521     *
522     * @param  string $value
523     * @return string
524     */
525    function e($value)
526    {
527        return htmlentities($value, ENT_QUOTES, 'UTF-8', false);
528    }
529}
530
531if (!function_exists('ends_with')) {
532    /**
533     * Determine if a given string ends with a given substring.
534     *
535     * @param  string $haystack
536     * @param  string|array $needles
537     * @return bool
538     */
539    function ends_with($haystack, $needles)
540    {
541        foreach ((array)$needles as $needle) {
542            if ((string)$needle === substr($haystack, -strlen($needle))) {
543                return true;
544            }
545        }
546
547        return false;
548    }
549}
550
551if (!function_exists('head')) {
552    /**
553     * Get the first element of an array. Useful for method chaining.
554     *
555     * @param  array $array
556     * @return mixed
557     */
558    function head($array)
559    {
560        return reset($array);
561    }
562}
563
564if (!function_exists('last')) {
565    /**
566     * Get the last element from an array.
567     *
568     * @param  array $array
569     * @return mixed
570     */
571    function last($array)
572    {
573        return end($array);
574    }
575}
576
577if (!function_exists('object_get')) {
578    /**
579     * Get an item from an object using "dot" notation.
580     *
581     * @param  object $object
582     * @param  string $key
583     * @param  mixed $default
584     * @return mixed
585     */
586    function object_get($object, $key, $default = null)
587    {
588        if (is_null($key) || trim($key) == '') {
589            return $object;
590        }
591
592        foreach (explode('.', $key) as $segment) {
593            if (!is_object($object) || !isset($object->{$segment})) {
594                return value($default);
595            }
596
597            $object = $object->{$segment};
598        }
599
600        return $object;
601    }
602}
603
604if (!function_exists('preg_replace_sub')) {
605    /**
606     * Replace a given pattern with each value in the array in sequentially.
607     *
608     * @param  string $pattern
609     * @param  array $replacements
610     * @param  string $subject
611     * @return string
612     */
613    function preg_replace_sub($pattern, &$replacements, $subject)
614    {
615        return preg_replace_callback($pattern, function () use (&$replacements) {
616            return array_shift($replacements);
617
618        }, $subject);
619    }
620}
621
622if (!function_exists('snake_case')) {
623    /**
624     * Convert a string to snake case.
625     *
626     * @param  string $value
627     * @param  string $delimiter
628     * @return string
629     */
630    function snake_case($value, $delimiter = '_')
631    {
632        static $snakeCache = [];
633        $key = $value . $delimiter;
634
635        if (isset($snakeCache[$key])) {
636            return $snakeCache[$key];
637        }
638
639        if (!ctype_lower($value)) {
640            $value = strtolower(preg_replace('/(.)(?=[A-Z])/', '$1' . $delimiter, $value));
641        }
642
643        return $snakeCache[$key] = $value;
644    }
645}
646
647if (!function_exists('starts_with')) {
648    /**
649     * Determine if a given string starts with a given substring.
650     *
651     * @param  string $haystack
652     * @param  string|array $needles
653     * @return bool
654     */
655    function starts_with($haystack, $needles)
656    {
657        foreach ((array)$needles as $needle) {
658            if ($needle != '' && strpos($haystack, $needle) === 0) {
659                return true;
660            }
661        }
662
663        return false;
664    }
665}
666
667if (!function_exists('str_contains')) {
668    /**
669     * Determine if a given string contains a given substring.
670     *
671     * @param  string $haystack
672     * @param  string|array $needles
673     * @return bool
674     */
675    function str_contains($haystack, $needles)
676    {
677        foreach ((array)$needles as $needle) {
678            if ($needle != '' && strpos($haystack, $needle) !== false) {
679                return true;
680            }
681        }
682
683        return false;
684    }
685}
686
687if (!function_exists('str_finish')) {
688    /**
689     * Cap a string with a single instance of a given value.
690     *
691     * @param  string $value
692     * @param  string $cap
693     * @return string
694     */
695    function str_finish($value, $cap)
696    {
697        $quoted = preg_quote($cap, '/');
698
699        return preg_replace('/(?:' . $quoted . ')+$/', '', $value) . $cap;
700    }
701}
702
703if (!function_exists('str_is')) {
704    /**
705     * Determine if a given string matches a given pattern.
706     *
707     * @param  string $pattern
708     * @param  string $value
709     * @return bool
710     */
711    function str_is($pattern, $value)
712    {
713        if ($pattern == $value) {
714            return true;
715        }
716
717        $pattern = preg_quote($pattern, '#');
718
719        // Asterisks are translated into zero-or-more regular expression wildcards
720        // to make it convenient to check if the strings starts with the given
721        // pattern such as "library/*", making any string check convenient.
722        $pattern = str_replace('\*', '.*', $pattern) . '\z';
723
724        return (bool)preg_match('#^' . $pattern . '#', $value);
725    }
726}
727
728if (!function_exists('str_limit')) {
729    /**
730     * Limit the number of characters in a string.
731     *
732     * @param  string $value
733     * @param  int $limit
734     * @param  string $end
735     * @return string
736     */
737    function str_limit($value, $limit = 100, $end = '...')
738    {
739        if (mb_strlen($value) <= $limit) {
740            return $value;
741        }
742
743        return rtrim(mb_substr($value, 0, $limit, 'UTF-8')) . $end;
744    }
745}
746
747if (!function_exists('str_random')) {
748    /**
749     * Generate a more truly "random" alpha-numeric string.
750     *
751     * @param  int $length
752     * @return string
753     *
754     * @throws \RuntimeException
755     */
756    function str_random($length = 16)
757    {
758        if (!function_exists('openssl_random_pseudo_bytes')) {
759            throw new RuntimeException('OpenSSL extension is required.');
760        }
761
762        $bytes = openssl_random_pseudo_bytes($length * 2);
763
764        if ($bytes === false) {
765            throw new RuntimeException('Unable to generate random string.');
766        }
767
768        return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $length);
769    }
770}
771
772if (!function_exists('str_replace_array')) {
773    /**
774     * Replace a given value in the string sequentially with an array.
775     *
776     * @param  string $search
777     * @param  array $replace
778     * @param  string $subject
779     * @return string
780     */
781    function str_replace_array($search, array $replace, $subject)
782    {
783        foreach ($replace as $value) {
784            $subject = preg_replace('/' . $search . '/', $value, $subject, 1);
785        }
786
787        return $subject;
788    }
789}
790
791if (!function_exists('str_slug')) {
792    /**
793     * Generate a URL friendly "slug" from a given string.
794     *
795     * @param  string $title
796     * @param  string $separator
797     * @return string
798     */
799    function str_slug($title, $separator = '-')
800    {
801        $title = ascii($title);
802
803        // Convert all dashes/underscores into separator
804        $flip = $separator == '-' ? '_' : '-';
805
806        $title = preg_replace('![' . preg_quote($flip) . ']+!u', $separator, $title);
807
808        // Remove all characters that are not the separator, letters, numbers, or whitespace.
809        $title = preg_replace('![^' . preg_quote($separator) . '\pL\pN\s]+!u', '', mb_strtolower($title));
810
811        // Replace all separator characters and whitespace by a single separator
812        $title = preg_replace('![' . preg_quote($separator) . '\s]+!u', $separator, $title);
813
814        return trim($title, $separator);
815    }
816}
817
818if (!function_exists('ascii')) {
819    /**
820     * Transliterate a UTF-8 value to ASCII.
821     *
822     * @param  string $value
823     * @return string
824     */
825    function ascii($value)
826    {
827        foreach (charsArray() as $key => $val) {
828            $value = str_replace($val, $key, $value);
829        }
830
831        return preg_replace('/[^\x20-\x7E]/u', '', $value);
832    }
833}
834
835if (!function_exists('charsArray')) {
836    /**
837     * Returns the replacements for the ascii method.
838     *
839     * Note: Adapted from Stringy\Stringy.
840     *
841     * @see https://github.com/danielstjules/Stringy/blob/2.3.1/LICENSE.txt
842     *
843     * @return array
844     */
845    function charsArray()
846    {
847        static $charsArray;
848
849        if (isset($charsArray)) {
850            return $charsArray;
851        }
852
853        return $charsArray = [
854            '0' => ['°', '₀', '۰'],
855            '1' => ['¹', '₁', '۱'],
856            '2' => ['²', '₂', '۲'],
857            '3' => ['³', '₃', '۳'],
858            '4' => ['⁴', '₄', '۴', '٤'],
859            '5' => ['⁵', '₅', '۵', '٥'],
860            '6' => ['⁶', '₆', '۶', '٦'],
861            '7' => ['⁷', '₇', '۷'],
862            '8' => ['⁸', '₈', '۸'],
863            '9' => ['⁹', '₉', '۹'],
864            'a' => [
865                'à',
866                'á',
867                'ả',
868                'ã',
869                'ạ',
870                'ă',
871                'ắ',
872                'ằ',
873                'ẳ',
874                'ẵ',
875                'ặ',
876                'â',
877                'ấ',
878                'ầ',
879                'ẩ',
880                'ẫ',
881                'ậ',
882                'ā',
883                'ą',
884                'å',
885                'α',
886                'ά',
887                'ἀ',
888                'ἁ',
889                'ἂ',
890                'ἃ',
891                'ἄ',
892                'ἅ',
893                'ἆ',
894                'ἇ',
895                'ᾀ',
896                'ᾁ',
897                'ᾂ',
898                'ᾃ',
899                'ᾄ',
900                'ᾅ',
901                'ᾆ',
902                'ᾇ',
903                'ὰ',
904                'ά',
905                'ᾰ',
906                'ᾱ',
907                'ᾲ',
908                'ᾳ',
909                'ᾴ',
910                'ᾶ',
911                'ᾷ',
912                'а',
913                'أ',
914                'အ',
915                'ာ',
916                'ါ',
917                'ǻ',
918                'ǎ',
919                'ª',
920                'ა',
921                'अ',
922                'ا'
923            ],
924            'b' => ['б', 'β', 'Ъ', 'Ь', 'ب', 'ဗ', 'ბ'],
925            'c' => ['ç', 'ć', 'č', 'ĉ', 'ċ'],
926            'd' => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', 'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ'],
927            'e' => [
928                'é',
929                'è',
930                'ẻ',
931                'ẽ',
932                'ẹ',
933                'ê',
934                'ế',
935                'ề',
936                'ể',
937                'ễ',
938                'ệ',
939                'ë',
940                'ē',
941                'ę',
942                'ě',
943                'ĕ',
944                'ė',
945                'ε',
946                'έ',
947                'ἐ',
948                'ἑ',
949                'ἒ',
950                'ἓ',
951                'ἔ',
952                'ἕ',
953                'ὲ',
954                'έ',
955                'е',
956                'ё',
957                'э',
958                'є',
959                'ə',
960                'ဧ',
961                'ေ',
962                'ဲ',
963                'ე',
964                'ए',
965                'إ',
966                'ئ'
967            ],
968            'f' => ['ф', 'φ', 'ف', 'ƒ', 'ფ'],
969            'g' => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', 'گ'],
970            'h' => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ'],
971            'i' => [
972                'í',
973                'ì',
974                'ỉ',
975                'ĩ',
976                'ị',
977                'î',
978                'ï',
979                'ī',
980                'ĭ',
981                'į',
982                'ı',
983                'ι',
984                'ί',
985                'ϊ',
986                'ΐ',
987                'ἰ',
988                'ἱ',
989                'ἲ',
990                'ἳ',
991                'ἴ',
992                'ἵ',
993                'ἶ',
994                'ἷ',
995                'ὶ',
996                'ί',
997                'ῐ',
998                'ῑ',
999                'ῒ',
1000                'ΐ',
1001                'ῖ',
1002                'ῗ',
1003                'і',
1004                'ї',
1005                'и',
1006                'ဣ',
1007                'ိ',
1008                'ီ',
1009                'ည်',
1010                'ǐ',
1011                'ი',
1012                'इ'
1013            ],
1014            'j' => ['ĵ', 'ј', 'Ј', 'ჯ', 'ج'],
1015            'k' => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك', 'က', 'კ', 'ქ', 'ک'],
1016            'l' => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل', 'လ', 'ლ'],
1017            'm' => ['м', 'μ', 'م', 'မ', 'მ'],
1018            'n' => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န', 'ნ'],
1019            'o' => [
1020                'ó',
1021                'ò',
1022                'ỏ',
1023                'õ',
1024                'ọ',
1025                'ô',
1026                'ố',
1027                'ồ',
1028                'ổ',
1029                'ỗ',
1030                'ộ',
1031                'ơ',
1032                'ớ',
1033                'ờ',
1034                'ở',
1035                'ỡ',
1036                'ợ',
1037                'ø',
1038                'ō',
1039                'ő',
1040                'ŏ',
1041                'ο',
1042                'ὀ',
1043                'ὁ',
1044                'ὂ',
1045                'ὃ',
1046                'ὄ',
1047                'ὅ',
1048                'ὸ',
1049                'ό',
1050                'о',
1051                'و',
1052                'θ',
1053                'ို',
1054                'ǒ',
1055                'ǿ',
1056                'º',
1057                'ო',
1058                'ओ'
1059            ],
1060            'p' => ['п', 'π', 'ပ', 'პ', 'پ'],
1061            'q' => ['ყ'],
1062            'r' => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', 'რ'],
1063            's' => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ', 'ſ', 'ს'],
1064            't' => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ', 'თ', 'ტ'],
1065            'u' => [
1066                'ú',
1067                'ù',
1068                'ủ',
1069                'ũ',
1070                'ụ',
1071                'ư',
1072                'ứ',
1073                'ừ',
1074                'ử',
1075                'ữ',
1076                'ự',
1077                'û',
1078                'ū',
1079                'ů',
1080                'ű',
1081                'ŭ',
1082                'ų',
1083                'µ',
1084                'у',
1085                'ဉ',
1086                'ု',
1087                'ူ',
1088                'ǔ',
1089                'ǖ',
1090                'ǘ',
1091                'ǚ',
1092                'ǜ',
1093                'უ',
1094                'उ'
1095            ],
1096            'v' => ['в', 'ვ', 'ϐ'],
1097            'w' => ['ŵ', 'ω', 'ώ', 'ဝ', 'ွ'],
1098            'x' => ['χ', 'ξ'],
1099            'y' => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', 'ϋ', 'ύ', 'ΰ', 'ي', 'ယ'],
1100            'z' => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ'],
1101            'aa' => ['ع', 'आ', 'آ'],
1102            'ae' => ['ä', 'æ', 'ǽ'],
1103            'ai' => ['ऐ'],
1104            'at' => ['@'],
1105            'ch' => ['ч', 'ჩ', 'ჭ', 'چ'],
1106            'dj' => ['ђ', 'đ'],
1107            'dz' => ['џ', 'ძ'],
1108            'ei' => ['ऍ'],
1109            'gh' => ['غ', 'ღ'],
1110            'ii' => ['ई'],
1111            'ij' => ['ij'],
1112            'kh' => ['х', 'خ', 'ხ'],
1113            'lj' => ['љ'],
1114            'nj' => ['њ'],
1115            'oe' => ['ö', 'œ', 'ؤ'],
1116            'oi' => ['ऑ'],
1117            'oii' => ['ऒ'],
1118            'ps' => ['ψ'],
1119            'sh' => ['ш', 'შ', 'ش'],
1120            'shch' => ['щ'],
1121            'ss' => ['ß'],
1122            'sx' => ['ŝ'],
1123            'th' => ['þ', 'ϑ', 'ث', 'ذ', 'ظ'],
1124            'ts' => ['ц', 'ც', 'წ'],
1125            'ue' => ['ü'],
1126            'uu' => ['ऊ'],
1127            'ya' => ['я'],
1128            'yu' => ['ю'],
1129            'zh' => ['ж', 'ჟ', 'ژ'],
1130            '(c)' => ['©'],
1131            'A' => [
1132                'Á',
1133                'À',
1134                'Ả',
1135                'Ã',
1136                'Ạ',
1137                'Ă',
1138                'Ắ',
1139                'Ằ',
1140                'Ẳ',
1141                'Ẵ',
1142                'Ặ',
1143                'Â',
1144                'Ấ',
1145                'Ầ',
1146                'Ẩ',
1147                'Ẫ',
1148                'Ậ',
1149                'Å',
1150                'Ā',
1151                'Ą',
1152                'Α',
1153                'Ά',
1154                'Ἀ',
1155                'Ἁ',
1156                'Ἂ',
1157                'Ἃ',
1158                'Ἄ',
1159                'Ἅ',
1160                'Ἆ',
1161                'Ἇ',
1162                'ᾈ',
1163                'ᾉ',
1164                'ᾊ',
1165                'ᾋ',
1166                'ᾌ',
1167                'ᾍ',
1168                'ᾎ',
1169                'ᾏ',
1170                'Ᾰ',
1171                'Ᾱ',
1172                'Ὰ',
1173                'Ά',
1174                'ᾼ',
1175                'А',
1176                'Ǻ',
1177                'Ǎ'
1178            ],
1179            'B' => ['Б', 'Β', 'ब'],
1180            'C' => ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ'],
1181            'D' => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ'],
1182            'E' => [
1183                'É',
1184                'È',
1185                'Ẻ',
1186                'Ẽ',
1187                'Ẹ',
1188                'Ê',
1189                'Ế',
1190                'Ề',
1191                'Ể',
1192                'Ễ',
1193                'Ệ',
1194                'Ë',
1195                'Ē',
1196                'Ę',
1197                'Ě',
1198                'Ĕ',
1199                'Ė',
1200                'Ε',
1201                'Έ',
1202                'Ἐ',
1203                'Ἑ',
1204                'Ἒ',
1205                'Ἓ',
1206                'Ἔ',
1207                'Ἕ',
1208                'Έ',
1209                'Ὲ',
1210                'Е',
1211                'Ё',
1212                'Э',
1213                'Є',
1214                'Ə'
1215            ],
1216            'F' => ['Ф', 'Φ'],
1217            'G' => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ'],
1218            'H' => ['Η', 'Ή', 'Ħ'],
1219            'I' => [
1220                'Í',
1221                'Ì',
1222                'Ỉ',
1223                'Ĩ',
1224                'Ị',
1225                'Î',
1226                'Ï',
1227                'Ī',
1228                'Ĭ',
1229                'Į',
1230                'İ',
1231                'Ι',
1232                'Ί',
1233                'Ϊ',
1234                'Ἰ',
1235                'Ἱ',
1236                'Ἳ',
1237                'Ἴ',
1238                'Ἵ',
1239                'Ἶ',
1240                'Ἷ',
1241                'Ῐ',
1242                'Ῑ',
1243                'Ὶ',
1244                'Ί',
1245                'И',
1246                'І',
1247                'Ї',
1248                'Ǐ',
1249                'ϒ'
1250            ],
1251            'K' => ['К', 'Κ'],
1252            'L' => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल'],
1253            'M' => ['М', 'Μ'],
1254            'N' => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν'],
1255            'O' => [
1256                'Ó',
1257                'Ò',
1258                'Ỏ',
1259                'Õ',
1260                'Ọ',
1261                'Ô',
1262                'Ố',
1263                'Ồ',
1264                'Ổ',
1265                'Ỗ',
1266                'Ộ',
1267                'Ơ',
1268                'Ớ',
1269                'Ờ',
1270                'Ở',
1271                'Ỡ',
1272                'Ợ',
1273                'Ø',
1274                'Ō',
1275                'Ő',
1276                'Ŏ',
1277                'Ο',
1278                'Ό',
1279                'Ὀ',
1280                'Ὁ',
1281                'Ὂ',
1282                'Ὃ',
1283                'Ὄ',
1284                'Ὅ',
1285                'Ὸ',
1286                'Ό',
1287                'О',
1288                'Θ',
1289                'Ө',
1290                'Ǒ',
1291                'Ǿ'
1292            ],
1293            'P' => ['П', 'Π'],
1294            'R' => ['Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ'],
1295            'S' => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ'],
1296            'T' => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ'],
1297            'U' => [
1298                'Ú',
1299                'Ù',
1300                'Ủ',
1301                'Ũ',
1302                'Ụ',
1303                'Ư',
1304                'Ứ',
1305                'Ừ',
1306                'Ử',
1307                'Ữ',
1308                'Ự',
1309                'Û',
1310                'Ū',
1311                'Ů',
1312                'Ű',
1313                'Ŭ',
1314                'Ų',
1315                'У',
1316                'Ǔ',
1317                'Ǖ',
1318                'Ǘ',
1319                'Ǚ',
1320                'Ǜ'
1321            ],
1322            'V' => ['В'],
1323            'W' => ['Ω', 'Ώ', 'Ŵ'],
1324            'X' => ['Χ', 'Ξ'],
1325            'Y' => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', 'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ'],
1326            'Z' => ['Ź', 'Ž', 'Ż', 'З', 'Ζ'],
1327            'AE' => ['Ä', 'Æ', 'Ǽ'],
1328            'CH' => ['Ч'],
1329            'DJ' => ['Ђ'],
1330            'DZ' => ['Џ'],
1331            'GX' => ['Ĝ'],
1332            'HX' => ['Ĥ'],
1333            'IJ' => ['IJ'],
1334            'JX' => ['Ĵ'],
1335            'KH' => ['Х'],
1336            'LJ' => ['Љ'],
1337            'NJ' => ['Њ'],
1338            'OE' => ['Ö', 'Œ'],
1339            'PS' => ['Ψ'],
1340            'SH' => ['Ш'],
1341            'SHCH' => ['Щ'],
1342            'SS' => ['ẞ'],
1343            'TH' => ['Þ'],
1344            'TS' => ['Ц'],
1345            'UE' => ['Ü'],
1346            'YA' => ['Я'],
1347            'YU' => ['Ю'],
1348            'ZH' => ['Ж'],
1349            ' ' => [
1350                "\xC2\xA0",
1351                "\xE2\x80\x80",
1352                "\xE2\x80\x81",
1353                "\xE2\x80\x82",
1354                "\xE2\x80\x83",
1355                "\xE2\x80\x84",
1356                "\xE2\x80\x85",
1357                "\xE2\x80\x86",
1358                "\xE2\x80\x87",
1359                "\xE2\x80\x88",
1360                "\xE2\x80\x89",
1361                "\xE2\x80\x8A",
1362                "\xE2\x80\xAF",
1363                "\xE2\x81\x9F",
1364                "\xE3\x80\x80"
1365            ],
1366        ];
1367    }
1368}
1369
1370if (!function_exists('studly_case')) {
1371    /**
1372     * Convert a value to studly caps case.
1373     *
1374     * @param  string $value
1375     * @return string
1376     */
1377    function studly_case($value)
1378    {
1379        static $studlyCache = [];
1380        $key = $value;
1381
1382        if (isset($studlyCache[$key])) {
1383            return $studlyCache[$key];
1384        }
1385
1386        $value = ucwords(str_replace(array('-', '_'), ' ', $value));
1387
1388        return $studlyCache[$key] = str_replace(' ', '', $value);
1389    }
1390}
1391
1392if (!function_exists('title_case')) {
1393    /**
1394     * Convert a value to title case.
1395     *
1396     * @param  string $value
1397     * @return string
1398     */
1399    function title_case($value)
1400    {
1401        return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
1402    }
1403}
1404
1405if (!function_exists('trait_uses_recursive')) {
1406    /**
1407     * Returns all traits used by a trait and its traits
1408     *
1409     * @param  string $trait
1410     * @return array
1411     */
1412    function trait_uses_recursive($trait)
1413    {
1414        $traits = class_uses($trait);
1415
1416        foreach ($traits as $trait) {
1417            $traits += trait_uses_recursive($trait);
1418        }
1419
1420        return $traits;
1421    }
1422}
1423
1424if (!function_exists('value')) {
1425    /**
1426     * Return the default value of the given value.
1427     *
1428     * @param  mixed $value
1429     * @return mixed
1430     */
1431    function value($value)
1432    {
1433        return $value instanceof Closure ? $value() : $value;
1434    }
1435}
1436
1437if (!function_exists('with')) {
1438    /**
1439     * Return the given object. Useful for chaining.
1440     *
1441     * @param  mixed $object
1442     * @return mixed
1443     */
1444    function with($object)
1445    {
1446        return $object;
1447    }
1448}
1449
1450/**
1451 * Helper functions for the helper functions, that can still be used standalone
1452 */
1453if (!function_exists('studly')) {
1454    /**
1455     * Convert a value to studly caps case.
1456     *
1457     * @param  string $value
1458     * @return string
1459     */
1460    function studly($value)
1461    {
1462        static $studlyCache = [];
1463        $key = $value;
1464
1465        if (isset($studlyCache[$key])) {
1466            return $studlyCache[$key];
1467        }
1468
1469        $value = ucwords(str_replace(array('-', '_'), ' ', $value));
1470
1471        return $studlyCache[$key] = str_replace(' ', '', $value);
1472    }
1473}
1474
1475if (!function_exists('get')) {
1476    /**
1477     * Get an item from an array using "dot" notation.
1478     *
1479     * @param  array $array
1480     * @param  string $key
1481     * @param  mixed $default
1482     * @return mixed
1483     */
1484    function get($array, $key, $default = null)
1485    {
1486        if (is_null($key)) {
1487            return $array;
1488        }
1489
1490        if (isset($array[$key])) {
1491            return $array[$key];
1492        }
1493
1494        foreach (explode('.', $key) as $segment) {
1495            if (!is_array($array) || !array_key_exists($segment, $array)) {
1496                return value($default);
1497            }
1498
1499            $array = $array[$segment];
1500        }
1501
1502        return $array;
1503    }
1504}
1505
1506if (!function_exists('set')) {
1507    /**
1508     * Set an array item to a given value using "dot" notation.
1509     *
1510     * If no key is given to the method, the entire array will be replaced.
1511     *
1512     * @param  array $array
1513     * @param  string $key
1514     * @param  mixed $value
1515     * @return array
1516     */
1517    function set(&$array, $key, $value)
1518    {
1519        if (is_null($key)) {
1520            return $array = $value;
1521        }
1522
1523        $keys = explode('.', $key);
1524
1525        while (count($keys) > 1) {
1526            $key = array_shift($keys);
1527
1528            // If the key doesn't exist at this depth, we will just create an empty array
1529            // to hold the next value, allowing us to create the arrays to hold final
1530            // values at the correct depth. Then we'll keep digging into the array.
1531            if (!isset($array[$key]) || !is_array($array[$key])) {
1532                $array[$key] = array();
1533            }
1534
1535            $array =& $array[$key];
1536        }
1537
1538        $array[array_shift($keys)] = $value;
1539
1540        return $array;
1541    }
1542}
1543
1544if (!function_exists('dot')) {
1545    /**
1546     * Flatten a multi-dimensional associative array with dots.
1547     *
1548     * @param  array $array
1549     * @param  string $prepend
1550     * @return array
1551     */
1552    function dot($array, $prepend = '')
1553    {
1554        $results = array();
1555
1556        foreach ($array as $key => $value) {
1557            if (is_array($value)) {
1558                $results = array_merge($results, dot($value, $prepend . $key . '.'));
1559            } else {
1560                $results[$prepend . $key] = $value;
1561            }
1562        }
1563
1564        return $results;
1565    }
1566}
1567
1568if (!function_exists('first')) {
1569    /**
1570     * Return the first element in an array passing a given truth test.
1571     *
1572     * @param  array $array
1573     * @param  \Closure $callback
1574     * @param  mixed $default
1575     * @return mixed
1576     */
1577    function first($array, $callback, $default = null)
1578    {
1579        foreach ($array as $key => $value) {
1580            if (call_user_func($callback, $key, $value)) {
1581                return $value;
1582            }
1583        }
1584
1585        return value($default);
1586    }
1587}
1588
1589if (!function_exists('forget')) {
1590    /**
1591     * Remove one or many array items from a given array using "dot" notation.
1592     *
1593     * @param  array $array
1594     * @param  array|string $keys
1595     * @return void
1596     */
1597    function forget(&$array, $keys)
1598    {
1599        $original =& $array;
1600
1601        foreach ((array)$keys as $key) {
1602            $parts = explode('.', $key);
1603
1604            while (count($parts) > 1) {
1605                $part = array_shift($parts);
1606
1607                if (isset($array[$part]) && is_array($array[$part])) {
1608                    $array =& $array[$part];
1609                }
1610            }
1611
1612            unset($array[array_shift($parts)]);
1613
1614            // clean up after each pass
1615            $array =& $original;
1616        }
1617    }
1618}
1619
1620if (!function_exists('bcrypt')) {
1621    /**
1622     * Password hash the given value.
1623     *
1624     * @param  string $value
1625     * @param  array $options
1626     * @return string
1627     *
1628     * @throws \RuntimeException
1629     */
1630    function bcrypt($value, $options = [])
1631    {
1632        $cost = isset($options['rounds']) ? $options['rounds'] : 10;
1633
1634        $hashedValue = password_hash($value, PASSWORD_BCRYPT, ['cost' => $cost]);
1635
1636        if ($hashedValue === false) {
1637            throw new RuntimeException('Bcrypt hashing not supported.');
1638        }
1639
1640        return $hashedValue;
1641    }
1642}
1643
1644if (!function_exists('tap')) {
1645    /**
1646     * Call the given Closure with the given value then return the value.
1647     *
1648     * @param  mixed $value
1649     * @param  callable $callback
1650     * @return mixed
1651     */
1652    function tap($value, $callback)
1653    {
1654        $callback($value);
1655
1656        return $value;
1657    }
1658}
1659
1660if (!function_exists('dd')) {
1661    /**
1662     * Dump the passed variables and end the script.
1663     *
1664     * @param  mixed
1665     * @return void
1666     */
1667    function dd()
1668    {
1669        array_map(function ($x) {
1670            var_dump($x);
1671        }, func_get_args());
1672
1673        die(1);
1674    }
1675
1676}
1677
1678if (!function_exists('data_fill')) {
1679    /**
1680     * Fill in data where it's missing.
1681     *
1682     * @param  mixed $target
1683     * @param  string|array $key
1684     * @param  mixed $value
1685     * @return mixed
1686     */
1687    function data_fill(&$target, $key, $value)
1688    {
1689        return data_set($target, $key, $value, false);
1690    }
1691}
1692
1693if (! function_exists('data_set')) {
1694    /**
1695     * Set an item on an array or object using dot notation.
1696     *
1697     * @param  mixed  $target
1698     * @param  string|array  $key
1699     * @param  mixed  $value
1700     * @param  bool  $overwrite
1701     * @return mixed
1702     */
1703    function data_set(&$target, $key, $value, $overwrite = true)
1704    {
1705        $segments = is_array($key) ? $key : explode('.', $key);
1706        if (($segment = array_shift($segments)) === '*') {
1707            if (! accessible($target)) {
1708                $target = [];
1709            }
1710            if ($segments) {
1711                foreach ($target as &$inner) {
1712                    data_set($inner, $segments, $value, $overwrite);
1713                }
1714            } elseif ($overwrite) {
1715                foreach ($target as &$inner) {
1716                    $inner = $value;
1717                }
1718            }
1719        } elseif (accessible($target)) {
1720            if ($segments) {
1721                if (! exists($target, $segment)) {
1722                    $target[$segment] = [];
1723                }
1724                data_set($target[$segment], $segments, $value, $overwrite);
1725            } elseif ($overwrite || ! exists($target, $segment)) {
1726                $target[$segment] = $value;
1727            }
1728        } elseif (is_object($target)) {
1729            if ($segments) {
1730                if (! isset($target->{$segment})) {
1731                    $target->{$segment} = [];
1732                }
1733                data_set($target->{$segment}, $segments, $value, $overwrite);
1734            } elseif ($overwrite || ! isset($target->{$segment})) {
1735                $target->{$segment} = $value;
1736            }
1737        } else {
1738            $target = [];
1739            if ($segments) {
1740                data_set($target[$segment], $segments, $value, $overwrite);
1741            } elseif ($overwrite) {
1742                $target[$segment] = $value;
1743            }
1744        }
1745        return $target;
1746    }
1747
1748    /**
1749     * Determine whether the given value is array accessible.
1750     *
1751     * @param  mixed  $value
1752     * @return bool
1753     */
1754    function accessible($value)
1755    {
1756        return is_array($value) || $value instanceof ArrayAccess;
1757    }
1758
1759
1760    /**
1761     * Determine if the given key exists in the provided array.
1762     *
1763     * @param  \ArrayAccess|array  $array
1764     * @param  string|int  $key
1765     * @return bool
1766     */
1767    function exists($array, $key)
1768    {
1769        if ($array instanceof ArrayAccess) {
1770            return $array->offsetExists($key);
1771        }
1772        return array_key_exists($key, $array);
1773    }
1774}
1775
1776