소스 검색

初始化

兔姬桑 4 년 전
커밋
a0922521cf
100개의 변경된 파일30207개의 추가작업 그리고 0개의 파일을 삭제
  1. 16 0
      .editorconfig
  2. 62 0
      .env.example
  3. 5 0
      .gitattributes
  4. 21 0
      .gitignore
  5. 21 0
      LICENSE
  6. 18246 0
      _ide_helper.php
  7. 249 0
      app/Components/AlipayNotify.php
  8. 267 0
      app/Components/AlipaySubmit.php
  9. 36 0
      app/Components/CaptchaVerify.php
  10. 64 0
      app/Components/Curl.php
  11. 192 0
      app/Components/Helpers.php
  12. 25 0
      app/Components/IPIP.php
  13. 105 0
      app/Components/Namesilo.php
  14. 22 0
      app/Components/QQWry.php
  15. 61 0
      app/Components/ServerChan.php
  16. 59 0
      app/Components/Sms.php
  17. 67 0
      app/Components/TelegramBot.php
  18. 73 0
      app/Components/Yzy.php
  19. 209 0
      app/Console/Commands/AutoCheckNodeTCP.php
  20. 84 0
      app/Console/Commands/AutoClearLog.php
  21. 125 0
      app/Console/Commands/AutoDecGoodsTraffic.php
  22. 618 0
      app/Console/Commands/AutoJob.php
  23. 55 0
      app/Console/Commands/AutoReportNode.php
  24. 80 0
      app/Console/Commands/AutoResetUserTraffic.php
  25. 58 0
      app/Console/Commands/AutoStatisticsNodeDailyTraffic.php
  26. 58 0
      app/Console/Commands/AutoStatisticsNodeHourlyTraffic.php
  27. 71 0
      app/Console/Commands/AutoStatisticsUserDailyTraffic.php
  28. 71 0
      app/Console/Commands/AutoStatisticsUserHourlyTraffic.php
  29. 67 0
      app/Console/Commands/UserExpireAutoWarning.php
  30. 59 0
      app/Console/Commands/UserTrafficAbnormalAutoWarning.php
  31. 59 0
      app/Console/Commands/UserTrafficAutoWarning.php
  32. 54 0
      app/Console/Commands/upgradeUserLabels.php
  33. 33 0
      app/Console/Commands/upgradeUserPassword.php
  34. 36 0
      app/Console/Commands/upgradeUserSpeedLimit.php
  35. 42 0
      app/Console/Commands/upgradeUserSubscribe.php
  36. 32 0
      app/Console/Commands/upgradeUserVmessId.php
  37. 71 0
      app/Console/Kernel.php
  38. 36 0
      app/Events/Event.php
  39. 171 0
      app/Exceptions/Handler.php
  40. 2641 0
      app/Http/Controllers/AdminController.php
  41. 279 0
      app/Http/Controllers/Api/AlipayController.php
  42. 299 0
      app/Http/Controllers/Api/F2fpayController.php
  43. 150 0
      app/Http/Controllers/Api/LoginController.php
  44. 81 0
      app/Http/Controllers/Api/PingController.php
  45. 393 0
      app/Http/Controllers/Api/YzyController.php
  46. 766 0
      app/Http/Controllers/AuthController.php
  47. 166 0
      app/Http/Controllers/Controller.php
  48. 182 0
      app/Http/Controllers/CouponController.php
  49. 107 0
      app/Http/Controllers/MarketingController.php
  50. 287 0
      app/Http/Controllers/PaymentController.php
  51. 62 0
      app/Http/Controllers/SensitiveWordsController.php
  52. 253 0
      app/Http/Controllers/ShopController.php
  53. 281 0
      app/Http/Controllers/SubscribeController.php
  54. 120 0
      app/Http/Controllers/TicketController.php
  55. 953 0
      app/Http/Controllers/UserController.php
  56. 70 0
      app/Http/Kernel.php
  57. 27 0
      app/Http/Middleware/Affiliate.php
  58. 17 0
      app/Http/Middleware/CheckForMaintenanceMode.php
  59. 17 0
      app/Http/Middleware/EncryptCookies.php
  60. 26 0
      app/Http/Middleware/RedirectIfAuthenticated.php
  61. 32 0
      app/Http/Middleware/SetLocale.php
  62. 18 0
      app/Http/Middleware/TrimStrings.php
  63. 23 0
      app/Http/Middleware/TrustProxies.php
  64. 18 0
      app/Http/Middleware/VerifyCsrfToken.php
  65. 27 0
      app/Http/Middleware/isAdmin.php
  66. 94 0
      app/Http/Middleware/isForbidden.php
  67. 26 0
      app/Http/Middleware/isLogin.php
  68. 39 0
      app/Http/Middleware/isSecurity.php
  69. 28 0
      app/Http/Models/Article.php
  70. 20 0
      app/Http/Models/Config.php
  71. 19 0
      app/Http/Models/Country.php
  72. 48 0
      app/Http/Models/Coupon.php
  73. 19 0
      app/Http/Models/CouponLog.php
  74. 61 0
      app/Http/Models/Device.php
  75. 19 0
      app/Http/Models/EmailLog.php
  76. 48 0
      app/Http/Models/Goods.php
  77. 24 0
      app/Http/Models/GoodsLabel.php
  78. 39 0
      app/Http/Models/Invite.php
  79. 19 0
      app/Http/Models/Label.php
  80. 19 0
      app/Http/Models/Level.php
  81. 37 0
      app/Http/Models/Marketing.php
  82. 85 0
      app/Http/Models/Order.php
  83. 48 0
      app/Http/Models/OrderGoods.php
  84. 78 0
      app/Http/Models/Payment.php
  85. 40 0
      app/Http/Models/PaymentCallback.php
  86. 59 0
      app/Http/Models/ReferralApply.php
  87. 59 0
      app/Http/Models/ReferralLog.php
  88. 19 0
      app/Http/Models/SensitiveWords.php
  89. 31 0
      app/Http/Models/SsConfig.php
  90. 19 0
      app/Http/Models/SsGroup.php
  91. 20 0
      app/Http/Models/SsGroupNode.php
  92. 23 0
      app/Http/Models/SsNode.php
  93. 20 0
      app/Http/Models/SsNodeInfo.php
  94. 28 0
      app/Http/Models/SsNodeIp.php
  95. 25 0
      app/Http/Models/SsNodeLabel.php
  96. 20 0
      app/Http/Models/SsNodeOnlineLog.php
  97. 24 0
      app/Http/Models/SsNodeTrafficDaily.php
  98. 23 0
      app/Http/Models/SsNodeTrafficHourly.php
  99. 29 0
      app/Http/Models/Ticket.php
  100. 23 0
      app/Http/Models/TicketReply.php

+ 16 - 0
.editorconfig

@@ -0,0 +1,16 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.yml]
+indent_style = space
+indent_size = 2

+ 62 - 0
.env.example

@@ -0,0 +1,62 @@
+APP_DEMO=false
+APP_NAME=SSRPanel_OtakuMod
+APP_ENV=local
+APP_KEY=
+APP_DEBUG=false
+APP_URL=http://localhost
+APP_TIMEZONE=Asia/Shanghai
+APP_LOCALE=zh-CN
+APP_FALLBACK_LOCALE=en
+LOG_CHANNEL=daily
+
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=SSRPanel_OtakuMod
+DB_USERNAME=root
+DB_USERNAME=root
+DB_PASSWORD=root
+DB_STRICT=false
+
+BROADCAST_DRIVER=redis
+CACHE_DRIVER=redis
+SESSION_DRIVER=redis
+SESSION_LIFETIME=120
+QUEUE_DRIVER=redis
+
+REDIS_HOST=127.0.0.1
+REDIS_PASSWORD=null
+REDIS_PORT=6379
+
+MAIL_DRIVER=smtp
+MAIL_HOST=smtp.exmail.qq.com
+MAIL_PORT=465
+MAIL_USERNAME=admin@ssrpanel.com
+MAIL_PASSWORD=password
+MAIL_ENCRYPTION=ssl
+MAIL_FROM_ADDRESS=admin@ssrpanel.com
+MAIL_FROM_NAME=SSRPanel
+MAILGUN_DOMAIN=
+MAILGUN_SECRET=
+
+PUSHER_APP_ID=
+PUSHER_APP_KEY=
+PUSHER_APP_SECRET=
+PUSHER_APP_CLUSTER=mt1
+
+MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
+MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
+
+REDIRECT_HTTPS=true
+
+GEETEST_ID=
+GEETEST_KEY=
+NOCAPTCHA_SECRET=
+NOCAPTCHA_SITEKEY=
+
+JWT_SECRET=oIJCMcUw9jEYDhKtVmBlgbEL7S4QZjQQWGUhj84JjPeifRle0NEWzwHv6E1S7WAv
+
+TELEGRAM_BOT_TOKEN=599655509:AAGBiSB-eh48PeMBSQXAzTcBnT28htoMhKI
+TELEGRAM_CERTIFICATE_PATH=
+TELEGRAM_WEBHOOK_URL=
+TELEGRAM_ASYNC_REQUESTS=

+ 5 - 0
.gitattributes

@@ -0,0 +1,5 @@
+*.js linguist-language=php
+*.css linguist-language=php
+*.scss linguist-language=php
+*.html linguist-language=php
+CHANGELOG.md export-ignore

+ 21 - 0
.gitignore

@@ -0,0 +1,21 @@
+/public/upload
+/storage/framework/cache/*
+/storage/framework/cookies/*
+/storage/framework/sessions/*
+/storage/framework/testing/*
+/storage/framework/views/*
+/storage/logs/*
+/storage/app/public
+/storage/*.key
+/vendor
+/.idea
+/.vagrant
+/.vscode
+Homestead.json
+Homestead.yaml
+npm-debug.log
+.DS_Store
+.phpstorm.meta.php
+yarn-error.log
+.env
+.phpunit.result.cache

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017-2019 Bruskyii Panda
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 18246 - 0
_ide_helper.php

@@ -0,0 +1,18246 @@
+<?php
+// @formatter:off
+
+/**
+ * A helper file for Laravel 5, to provide autocomplete information to your IDE
+ * Generated for Laravel 5.6.39 on 2019-06-09 16:33:20.
+ *
+ * This file should not be included in your code, only analyzed by your IDE!
+ *
+ * @author Barry vd. Heuvel <barryvdh@gmail.com>
+ * @see https://github.com/barryvdh/laravel-ide-helper
+ */
+
+namespace Illuminate\Support\Facades { 
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Foundation\Application
+     */ 
+    class App {
+        
+        /**
+         * Get the version number of the application.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function version()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->version();
+        }
+        
+        /**
+         * Run the given array of bootstrap classes.
+         *
+         * @param array $bootstrappers
+         * @return void 
+         * @static 
+         */ 
+        public static function bootstrapWith($bootstrappers)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->bootstrapWith($bootstrappers);
+        }
+        
+        /**
+         * Register a callback to run after loading the environment.
+         *
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function afterLoadingEnvironment($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->afterLoadingEnvironment($callback);
+        }
+        
+        /**
+         * Register a callback to run before a bootstrapper.
+         *
+         * @param string $bootstrapper
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function beforeBootstrapping($bootstrapper, $callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->beforeBootstrapping($bootstrapper, $callback);
+        }
+        
+        /**
+         * Register a callback to run after a bootstrapper.
+         *
+         * @param string $bootstrapper
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function afterBootstrapping($bootstrapper, $callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->afterBootstrapping($bootstrapper, $callback);
+        }
+        
+        /**
+         * Determine if the application has been bootstrapped before.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasBeenBootstrapped()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->hasBeenBootstrapped();
+        }
+        
+        /**
+         * Set the base path for the application.
+         *
+         * @param string $basePath
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function setBasePath($basePath)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->setBasePath($basePath);
+        }
+        
+        /**
+         * Get the path to the application "app" directory.
+         *
+         * @param string $path Optionally, a path to append to the app path
+         * @return string 
+         * @static 
+         */ 
+        public static function path($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->path($path);
+        }
+        
+        /**
+         * Get the base path of the Laravel installation.
+         *
+         * @param string $path Optionally, a path to append to the base path
+         * @return string 
+         * @static 
+         */ 
+        public static function basePath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->basePath($path);
+        }
+        
+        /**
+         * Get the path to the bootstrap directory.
+         *
+         * @param string $path Optionally, a path to append to the bootstrap path
+         * @return string 
+         * @static 
+         */ 
+        public static function bootstrapPath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->bootstrapPath($path);
+        }
+        
+        /**
+         * Get the path to the application configuration files.
+         *
+         * @param string $path Optionally, a path to append to the config path
+         * @return string 
+         * @static 
+         */ 
+        public static function configPath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->configPath($path);
+        }
+        
+        /**
+         * Get the path to the database directory.
+         *
+         * @param string $path Optionally, a path to append to the database path
+         * @return string 
+         * @static 
+         */ 
+        public static function databasePath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->databasePath($path);
+        }
+        
+        /**
+         * Set the database directory.
+         *
+         * @param string $path
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function useDatabasePath($path)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->useDatabasePath($path);
+        }
+        
+        /**
+         * Get the path to the language files.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function langPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->langPath();
+        }
+        
+        /**
+         * Get the path to the public / web directory.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function publicPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->publicPath();
+        }
+        
+        /**
+         * Get the path to the storage directory.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function storagePath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->storagePath();
+        }
+        
+        /**
+         * Set the storage directory.
+         *
+         * @param string $path
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function useStoragePath($path)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->useStoragePath($path);
+        }
+        
+        /**
+         * Get the path to the resources directory.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function resourcePath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->resourcePath($path);
+        }
+        
+        /**
+         * Get the path to the environment file directory.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function environmentPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->environmentPath();
+        }
+        
+        /**
+         * Set the directory for the environment file.
+         *
+         * @param string $path
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function useEnvironmentPath($path)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->useEnvironmentPath($path);
+        }
+        
+        /**
+         * Set the environment file to be loaded during bootstrapping.
+         *
+         * @param string $file
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function loadEnvironmentFrom($file)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->loadEnvironmentFrom($file);
+        }
+        
+        /**
+         * Get the environment file the application is using.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function environmentFile()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->environmentFile();
+        }
+        
+        /**
+         * Get the fully qualified path to the environment file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function environmentFilePath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->environmentFilePath();
+        }
+        
+        /**
+         * Get or check the current application environment.
+         *
+         * @return string|bool 
+         * @static 
+         */ 
+        public static function environment()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->environment();
+        }
+        
+        /**
+         * Determine if application is in local environment.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isLocal()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isLocal();
+        }
+        
+        /**
+         * Detect the application's current environment.
+         *
+         * @param \Closure $callback
+         * @return string 
+         * @static 
+         */ 
+        public static function detectEnvironment($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->detectEnvironment($callback);
+        }
+        
+        /**
+         * Determine if the application is running in the console.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function runningInConsole()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->runningInConsole();
+        }
+        
+        /**
+         * Determine if the application is running unit tests.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function runningUnitTests()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->runningUnitTests();
+        }
+        
+        /**
+         * Register all of the configured providers.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function registerConfiguredProviders()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->registerConfiguredProviders();
+        }
+        
+        /**
+         * Register a service provider with the application.
+         *
+         * @param \Illuminate\Support\ServiceProvider|string $provider
+         * @param array $options
+         * @param bool $force
+         * @return \Illuminate\Support\ServiceProvider 
+         * @static 
+         */ 
+        public static function register($provider, $options = array(), $force = false)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->register($provider, $options, $force);
+        }
+        
+        /**
+         * Get the registered service provider instance if it exists.
+         *
+         * @param \Illuminate\Support\ServiceProvider|string $provider
+         * @return \Illuminate\Support\ServiceProvider|null 
+         * @static 
+         */ 
+        public static function getProvider($provider)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getProvider($provider);
+        }
+        
+        /**
+         * Get the registered service provider instances if any exist.
+         *
+         * @param \Illuminate\Support\ServiceProvider|string $provider
+         * @return array 
+         * @static 
+         */ 
+        public static function getProviders($provider)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getProviders($provider);
+        }
+        
+        /**
+         * Resolve a service provider instance from the class name.
+         *
+         * @param string $provider
+         * @return \Illuminate\Support\ServiceProvider 
+         * @static 
+         */ 
+        public static function resolveProvider($provider)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->resolveProvider($provider);
+        }
+        
+        /**
+         * Load and boot all of the remaining deferred providers.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function loadDeferredProviders()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->loadDeferredProviders();
+        }
+        
+        /**
+         * Load the provider for a deferred service.
+         *
+         * @param string $service
+         * @return void 
+         * @static 
+         */ 
+        public static function loadDeferredProvider($service)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->loadDeferredProvider($service);
+        }
+        
+        /**
+         * Register a deferred provider and service.
+         *
+         * @param string $provider
+         * @param string|null $service
+         * @return void 
+         * @static 
+         */ 
+        public static function registerDeferredProvider($provider, $service = null)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->registerDeferredProvider($provider, $service);
+        }
+        
+        /**
+         * Resolve the given type from the container.
+         * 
+         * (Overriding Container::make)
+         *
+         * @param string $abstract
+         * @param array $parameters
+         * @return mixed 
+         * @static 
+         */ 
+        public static function make($abstract, $parameters = array())
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->make($abstract, $parameters);
+        }
+        
+        /**
+         * Determine if the given abstract type has been bound.
+         * 
+         * (Overriding Container::bound)
+         *
+         * @param string $abstract
+         * @return bool 
+         * @static 
+         */ 
+        public static function bound($abstract)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->bound($abstract);
+        }
+        
+        /**
+         * Determine if the application has booted.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isBooted()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isBooted();
+        }
+        
+        /**
+         * Boot the application's service providers.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function boot()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->boot();
+        }
+        
+        /**
+         * Register a new boot listener.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function booting($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->booting($callback);
+        }
+        
+        /**
+         * Register a new "booted" listener.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function booted($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->booted($callback);
+        }
+        
+        /**
+         * {@inheritdoc}
+         *
+         * @static 
+         */ 
+        public static function handle($request, $type = 1, $catch = true)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->handle($request, $type, $catch);
+        }
+        
+        /**
+         * Determine if middleware has been disabled for the application.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function shouldSkipMiddleware()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->shouldSkipMiddleware();
+        }
+        
+        /**
+         * Get the path to the cached services.php file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedServicesPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedServicesPath();
+        }
+        
+        /**
+         * Get the path to the cached packages.php file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedPackagesPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedPackagesPath();
+        }
+        
+        /**
+         * Determine if the application configuration is cached.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function configurationIsCached()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->configurationIsCached();
+        }
+        
+        /**
+         * Get the path to the configuration cache file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedConfigPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedConfigPath();
+        }
+        
+        /**
+         * Determine if the application routes are cached.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function routesAreCached()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->routesAreCached();
+        }
+        
+        /**
+         * Get the path to the routes cache file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedRoutesPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedRoutesPath();
+        }
+        
+        /**
+         * Determine if the application is currently down for maintenance.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDownForMaintenance()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isDownForMaintenance();
+        }
+        
+        /**
+         * Throw an HttpException with the given data.
+         *
+         * @param int $code
+         * @param string $message
+         * @param array $headers
+         * @return void 
+         * @throws \Symfony\Component\HttpKernel\Exception\HttpException
+         * @static 
+         */ 
+        public static function abort($code, $message = '', $headers = array())
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->abort($code, $message, $headers);
+        }
+        
+        /**
+         * Register a terminating callback with the application.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function terminating($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->terminating($callback);
+        }
+        
+        /**
+         * Terminate the application.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function terminate()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->terminate();
+        }
+        
+        /**
+         * Get the service providers that have been loaded.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getLoadedProviders()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getLoadedProviders();
+        }
+        
+        /**
+         * Get the application's deferred services.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDeferredServices()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getDeferredServices();
+        }
+        
+        /**
+         * Set the application's deferred services.
+         *
+         * @param array $services
+         * @return void 
+         * @static 
+         */ 
+        public static function setDeferredServices($services)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->setDeferredServices($services);
+        }
+        
+        /**
+         * Add an array of services to the application's deferred services.
+         *
+         * @param array $services
+         * @return void 
+         * @static 
+         */ 
+        public static function addDeferredServices($services)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->addDeferredServices($services);
+        }
+        
+        /**
+         * Determine if the given service is a deferred service.
+         *
+         * @param string $service
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDeferredService($service)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isDeferredService($service);
+        }
+        
+        /**
+         * Configure the real-time facade namespace.
+         *
+         * @param string $namespace
+         * @return void 
+         * @static 
+         */ 
+        public static function provideFacades($namespace)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->provideFacades($namespace);
+        }
+        
+        /**
+         * Get the current application locale.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getLocale()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getLocale();
+        }
+        
+        /**
+         * Set the current application locale.
+         *
+         * @param string $locale
+         * @return void 
+         * @static 
+         */ 
+        public static function setLocale($locale)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->setLocale($locale);
+        }
+        
+        /**
+         * Determine if application locale is the given locale.
+         *
+         * @param string $locale
+         * @return bool 
+         * @static 
+         */ 
+        public static function isLocale($locale)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isLocale($locale);
+        }
+        
+        /**
+         * Register the core class aliases in the container.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function registerCoreContainerAliases()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->registerCoreContainerAliases();
+        }
+        
+        /**
+         * Flush the container of all bindings and resolved instances.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flush()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->flush();
+        }
+        
+        /**
+         * Get the application namespace.
+         *
+         * @return string 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function getNamespace()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getNamespace();
+        }
+        
+        /**
+         * Define a contextual binding.
+         *
+         * @param string $concrete
+         * @return \Illuminate\Contracts\Container\ContextualBindingBuilder 
+         * @static 
+         */ 
+        public static function when($concrete)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->when($concrete);
+        }
+        
+        /**
+         * Returns true if the container can return an entry for the given identifier.
+         * 
+         * Returns false otherwise.
+         * 
+         * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
+         * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
+         *
+         * @param string $id Identifier of the entry to look for.
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($id)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->has($id);
+        }
+        
+        /**
+         * Determine if the given abstract type has been resolved.
+         *
+         * @param string $abstract
+         * @return bool 
+         * @static 
+         */ 
+        public static function resolved($abstract)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->resolved($abstract);
+        }
+        
+        /**
+         * Determine if a given type is shared.
+         *
+         * @param string $abstract
+         * @return bool 
+         * @static 
+         */ 
+        public static function isShared($abstract)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isShared($abstract);
+        }
+        
+        /**
+         * Determine if a given string is an alias.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function isAlias($name)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isAlias($name);
+        }
+        
+        /**
+         * Register a binding with the container.
+         *
+         * @param string $abstract
+         * @param \Closure|string|null $concrete
+         * @param bool $shared
+         * @return void 
+         * @static 
+         */ 
+        public static function bind($abstract, $concrete = null, $shared = false)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->bind($abstract, $concrete, $shared);
+        }
+        
+        /**
+         * Determine if the container has a method binding.
+         *
+         * @param string $method
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMethodBinding($method)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->hasMethodBinding($method);
+        }
+        
+        /**
+         * Bind a callback to resolve with Container::call.
+         *
+         * @param array|string $method
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function bindMethod($method, $callback)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->bindMethod($method, $callback);
+        }
+        
+        /**
+         * Get the method binding for the given method.
+         *
+         * @param string $method
+         * @param mixed $instance
+         * @return mixed 
+         * @static 
+         */ 
+        public static function callMethodBinding($method, $instance)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->callMethodBinding($method, $instance);
+        }
+        
+        /**
+         * Add a contextual binding to the container.
+         *
+         * @param string $concrete
+         * @param string $abstract
+         * @param \Closure|string $implementation
+         * @return void 
+         * @static 
+         */ 
+        public static function addContextualBinding($concrete, $abstract, $implementation)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->addContextualBinding($concrete, $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 
+         * @static 
+         */ 
+        public static function bindIf($abstract, $concrete = null, $shared = false)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->bindIf($abstract, $concrete, $shared);
+        }
+        
+        /**
+         * Register a shared binding in the container.
+         *
+         * @param string $abstract
+         * @param \Closure|string|null $concrete
+         * @return void 
+         * @static 
+         */ 
+        public static function singleton($abstract, $concrete = null)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->singleton($abstract, $concrete);
+        }
+        
+        /**
+         * "Extend" an abstract type in the container.
+         *
+         * @param string $abstract
+         * @param \Closure $closure
+         * @return void 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function extend($abstract, $closure)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->extend($abstract, $closure);
+        }
+        
+        /**
+         * Register an existing instance as shared in the container.
+         *
+         * @param string $abstract
+         * @param mixed $instance
+         * @return mixed 
+         * @static 
+         */ 
+        public static function instance($abstract, $instance)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->instance($abstract, $instance);
+        }
+        
+        /**
+         * Assign a set of tags to a given binding.
+         *
+         * @param array|string $abstracts
+         * @param array|mixed $tags
+         * @return void 
+         * @static 
+         */ 
+        public static function tag($abstracts, $tags)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->tag($abstracts, $tags);
+        }
+        
+        /**
+         * Resolve all of the bindings for a given tag.
+         *
+         * @param string $tag
+         * @return array 
+         * @static 
+         */ 
+        public static function tagged($tag)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->tagged($tag);
+        }
+        
+        /**
+         * Alias a type to a different name.
+         *
+         * @param string $abstract
+         * @param string $alias
+         * @return void 
+         * @static 
+         */ 
+        public static function alias($abstract, $alias)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->alias($abstract, $alias);
+        }
+        
+        /**
+         * Bind a new callback to an abstract's rebind event.
+         *
+         * @param string $abstract
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function rebinding($abstract, $callback)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->rebinding($abstract, $callback);
+        }
+        
+        /**
+         * Refresh an instance on the given target and method.
+         *
+         * @param string $abstract
+         * @param mixed $target
+         * @param string $method
+         * @return mixed 
+         * @static 
+         */ 
+        public static function refresh($abstract, $target, $method)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->refresh($abstract, $target, $method);
+        }
+        
+        /**
+         * Wrap the given closure such that its dependencies will be injected when executed.
+         *
+         * @param \Closure $callback
+         * @param array $parameters
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function wrap($callback, $parameters = array())
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->wrap($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 
+         * @static 
+         */ 
+        public static function call($callback, $parameters = array(), $defaultMethod = null)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->call($callback, $parameters, $defaultMethod);
+        }
+        
+        /**
+         * Get a closure to resolve the given type from the container.
+         *
+         * @param string $abstract
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function factory($abstract)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->factory($abstract);
+        }
+        
+        /**
+         * An alias function name for make().
+         *
+         * @param string $abstract
+         * @param array $parameters
+         * @return mixed 
+         * @static 
+         */ 
+        public static function makeWith($abstract, $parameters = array())
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->makeWith($abstract, $parameters);
+        }
+        
+        /**
+         * Finds an entry of the container by its identifier and returns it.
+         *
+         * @param string $id Identifier of the entry to look for.
+         * @throws NotFoundExceptionInterface  No entry was found for **this** identifier.
+         * @throws ContainerExceptionInterface Error while retrieving the entry.
+         * @return mixed Entry.
+         * @static 
+         */ 
+        public static function get($id)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->get($id);
+        }
+        
+        /**
+         * Instantiate a concrete instance of the given type.
+         *
+         * @param string $concrete
+         * @return mixed 
+         * @throws \Illuminate\Contracts\Container\BindingResolutionException
+         * @static 
+         */ 
+        public static function build($concrete)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->build($concrete);
+        }
+        
+        /**
+         * Register a new resolving callback.
+         *
+         * @param \Closure|string $abstract
+         * @param \Closure|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function resolving($abstract, $callback = null)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->resolving($abstract, $callback);
+        }
+        
+        /**
+         * Register a new after resolving callback for all types.
+         *
+         * @param \Closure|string $abstract
+         * @param \Closure|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function afterResolving($abstract, $callback = null)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->afterResolving($abstract, $callback);
+        }
+        
+        /**
+         * Get the container's bindings.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getBindings()
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getBindings();
+        }
+        
+        /**
+         * Get the alias for an abstract if available.
+         *
+         * @param string $abstract
+         * @return string 
+         * @throws \LogicException
+         * @static 
+         */ 
+        public static function getAlias($abstract)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getAlias($abstract);
+        }
+        
+        /**
+         * Remove all of the extender callbacks for a given type.
+         *
+         * @param string $abstract
+         * @return void 
+         * @static 
+         */ 
+        public static function forgetExtenders($abstract)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->forgetExtenders($abstract);
+        }
+        
+        /**
+         * Remove a resolved instance from the instance cache.
+         *
+         * @param string $abstract
+         * @return void 
+         * @static 
+         */ 
+        public static function forgetInstance($abstract)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->forgetInstance($abstract);
+        }
+        
+        /**
+         * Clear all of the instances from the container.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function forgetInstances()
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->forgetInstances();
+        }
+        
+        /**
+         * Set the globally available instance of the container.
+         *
+         * @return static 
+         * @static 
+         */ 
+        public static function getInstance()
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        return \Illuminate\Foundation\Application::getInstance();
+        }
+        
+        /**
+         * Set the shared instance of the container.
+         *
+         * @param \Illuminate\Contracts\Container\Container|null $container
+         * @return \Illuminate\Contracts\Container\Container|static 
+         * @static 
+         */ 
+        public static function setInstance($container = null)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        return \Illuminate\Foundation\Application::setInstance($container);
+        }
+        
+        /**
+         * Determine if a given offset exists.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function offsetExists($key)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->offsetExists($key);
+        }
+        
+        /**
+         * Get the value at a given offset.
+         *
+         * @param string $key
+         * @return mixed 
+         * @static 
+         */ 
+        public static function offsetGet($key)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->offsetGet($key);
+        }
+        
+        /**
+         * Set the value at a given offset.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetSet($key, $value)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->offsetSet($key, $value);
+        }
+        
+        /**
+         * Unset the value at a given offset.
+         *
+         * @param string $key
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetUnset($key)
+        {
+            //Method inherited from \Illuminate\Container\Container            
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->offsetUnset($key);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Console\Kernel
+     */ 
+    class Artisan {
+        
+        /**
+         * Run the console application.
+         *
+         * @param \Symfony\Component\Console\Input\InputInterface $input
+         * @param \Symfony\Component\Console\Output\OutputInterface $output
+         * @return int 
+         * @static 
+         */ 
+        public static function handle($input, $output = null)
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->handle($input, $output);
+        }
+        
+        /**
+         * Terminate the application.
+         *
+         * @param \Symfony\Component\Console\Input\InputInterface $input
+         * @param int $status
+         * @return void 
+         * @static 
+         */ 
+        public static function terminate($input, $status)
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        $instance->terminate($input, $status);
+        }
+        
+        /**
+         * Register a Closure based command with the application.
+         *
+         * @param string $signature
+         * @param \Closure $callback
+         * @return \Illuminate\Foundation\Console\ClosureCommand 
+         * @static 
+         */ 
+        public static function command($signature, $callback)
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->command($signature, $callback);
+        }
+        
+        /**
+         * Register the given command with the console application.
+         *
+         * @param \Symfony\Component\Console\Command\Command $command
+         * @return void 
+         * @static 
+         */ 
+        public static function registerCommand($command)
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        $instance->registerCommand($command);
+        }
+        
+        /**
+         * Run an Artisan console command by name.
+         *
+         * @param string $command
+         * @param array $parameters
+         * @param \Symfony\Component\Console\Output\OutputInterface $outputBuffer
+         * @return int 
+         * @static 
+         */ 
+        public static function call($command, $parameters = array(), $outputBuffer = null)
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->call($command, $parameters, $outputBuffer);
+        }
+        
+        /**
+         * Queue the given console command.
+         *
+         * @param string $command
+         * @param array $parameters
+         * @return \Illuminate\Foundation\Bus\PendingDispatch 
+         * @static 
+         */ 
+        public static function queue($command, $parameters = array())
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->queue($command, $parameters);
+        }
+        
+        /**
+         * Get all of the commands registered with the console.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function all()
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->all();
+        }
+        
+        /**
+         * Get the output for the last run command.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function output()
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->output();
+        }
+        
+        /**
+         * Bootstrap the application for artisan commands.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function bootstrap()
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        $instance->bootstrap();
+        }
+        
+        /**
+         * Set the Artisan application instance.
+         *
+         * @param \Illuminate\Console\Application $artisan
+         * @return void 
+         * @static 
+         */ 
+        public static function setArtisan($artisan)
+        {
+            //Method inherited from \Illuminate\Foundation\Console\Kernel            
+                        /** @var \App\Console\Kernel $instance */
+                        $instance->setArtisan($artisan);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Auth\AuthManager
+     * @see \Illuminate\Contracts\Auth\Factory
+     * @see \Illuminate\Contracts\Auth\Guard
+     * @see \Illuminate\Contracts\Auth\StatefulGuard
+     */ 
+    class Auth {
+        
+        /**
+         * Attempt to get the guard from the local cache.
+         *
+         * @param string $name
+         * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard 
+         * @static 
+         */ 
+        public static function guard($name = null)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->guard($name);
+        }
+        
+        /**
+         * Create a session based authentication guard.
+         *
+         * @param string $name
+         * @param array $config
+         * @return \Illuminate\Auth\SessionGuard 
+         * @static 
+         */ 
+        public static function createSessionDriver($name, $config)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->createSessionDriver($name, $config);
+        }
+        
+        /**
+         * Create a token based authentication guard.
+         *
+         * @param string $name
+         * @param array $config
+         * @return \Illuminate\Auth\TokenGuard 
+         * @static 
+         */ 
+        public static function createTokenDriver($name, $config)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->createTokenDriver($name, $config);
+        }
+        
+        /**
+         * Get the default authentication driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Set the default guard driver the factory should serve.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function shouldUse($name)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        $instance->shouldUse($name);
+        }
+        
+        /**
+         * Set the default authentication driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+        
+        /**
+         * Register a new callback based request guard.
+         *
+         * @param string $driver
+         * @param callable $callback
+         * @return \Illuminate\Auth\AuthManager 
+         * @static 
+         */ 
+        public static function viaRequest($driver, $callback)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->viaRequest($driver, $callback);
+        }
+        
+        /**
+         * Get the user resolver callback.
+         *
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function userResolver()
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->userResolver();
+        }
+        
+        /**
+         * Set the callback to be used to resolve users.
+         *
+         * @param \Closure $userResolver
+         * @return \Illuminate\Auth\AuthManager 
+         * @static 
+         */ 
+        public static function resolveUsersUsing($userResolver)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->resolveUsersUsing($userResolver);
+        }
+        
+        /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Auth\AuthManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+        
+        /**
+         * Register a custom provider creator Closure.
+         *
+         * @param string $name
+         * @param \Closure $callback
+         * @return \Illuminate\Auth\AuthManager 
+         * @static 
+         */ 
+        public static function provider($name, $callback)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->provider($name, $callback);
+        }
+        
+        /**
+         * Create the user provider implementation for the driver.
+         *
+         * @param string|null $provider
+         * @return \Illuminate\Contracts\Auth\UserProvider|null 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function createUserProvider($provider = null)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->createUserProvider($provider);
+        }
+        
+        /**
+         * Get the default user provider name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultUserProvider()
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->getDefaultUserProvider();
+        }
+        
+        /**
+         * Get the currently authenticated user.
+         *
+         * @return \App\Http\Models\User|null 
+         * @static 
+         */ 
+        public static function user()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->user();
+        }
+        
+        /**
+         * Get the ID for the currently authenticated user.
+         *
+         * @return int|null 
+         * @static 
+         */ 
+        public static function id()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->id();
+        }
+        
+        /**
+         * Log a user into the application without sessions or cookies.
+         *
+         * @param array $credentials
+         * @return bool 
+         * @static 
+         */ 
+        public static function once($credentials = array())
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->once($credentials);
+        }
+        
+        /**
+         * Log the given user ID into the application without sessions or cookies.
+         *
+         * @param mixed $id
+         * @return \App\Http\Models\User|false 
+         * @static 
+         */ 
+        public static function onceUsingId($id)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->onceUsingId($id);
+        }
+        
+        /**
+         * Validate a user's credentials.
+         *
+         * @param array $credentials
+         * @return bool 
+         * @static 
+         */ 
+        public static function validate($credentials = array())
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->validate($credentials);
+        }
+        
+        /**
+         * Attempt to authenticate using HTTP Basic Auth.
+         *
+         * @param string $field
+         * @param array $extraConditions
+         * @return \Symfony\Component\HttpFoundation\Response|null 
+         * @static 
+         */ 
+        public static function basic($field = 'email', $extraConditions = array())
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->basic($field, $extraConditions);
+        }
+        
+        /**
+         * Perform a stateless HTTP Basic login attempt.
+         *
+         * @param string $field
+         * @param array $extraConditions
+         * @return \Symfony\Component\HttpFoundation\Response|null 
+         * @static 
+         */ 
+        public static function onceBasic($field = 'email', $extraConditions = array())
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->onceBasic($field, $extraConditions);
+        }
+        
+        /**
+         * Attempt to authenticate a user using the given credentials.
+         *
+         * @param array $credentials
+         * @param bool $remember
+         * @return bool 
+         * @static 
+         */ 
+        public static function attempt($credentials = array(), $remember = false)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->attempt($credentials, $remember);
+        }
+        
+        /**
+         * Log the given user ID into the application.
+         *
+         * @param mixed $id
+         * @param bool $remember
+         * @return \App\Http\Models\User|false 
+         * @static 
+         */ 
+        public static function loginUsingId($id, $remember = false)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->loginUsingId($id, $remember);
+        }
+        
+        /**
+         * Log a user into the application.
+         *
+         * @param \Illuminate\Contracts\Auth\Authenticatable $user
+         * @param bool $remember
+         * @return void 
+         * @static 
+         */ 
+        public static function login($user, $remember = false)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->login($user, $remember);
+        }
+        
+        /**
+         * Log the user out of the application.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function logout()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->logout();
+        }
+        
+        /**
+         * Invalidate other sessions for the current user.
+         * 
+         * The application must be using the AuthenticateSession middleware.
+         *
+         * @param string $password
+         * @param string $attribute
+         * @return bool|null 
+         * @static 
+         */ 
+        public static function logoutOtherDevices($password, $attribute = 'password')
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->logoutOtherDevices($password, $attribute);
+        }
+        
+        /**
+         * Register an authentication attempt event listener.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function attempting($callback)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->attempting($callback);
+        }
+        
+        /**
+         * Get the last user we attempted to authenticate.
+         *
+         * @return \App\Http\Models\User 
+         * @static 
+         */ 
+        public static function getLastAttempted()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getLastAttempted();
+        }
+        
+        /**
+         * Get a unique identifier for the auth session value.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getName()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getName();
+        }
+        
+        /**
+         * Get the name of the cookie used to store the "recaller".
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getRecallerName()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getRecallerName();
+        }
+        
+        /**
+         * Determine if the user was authenticated via "remember me" cookie.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function viaRemember()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->viaRemember();
+        }
+        
+        /**
+         * Get the cookie creator instance used by the guard.
+         *
+         * @return \Illuminate\Contracts\Cookie\QueueingFactory 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function getCookieJar()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getCookieJar();
+        }
+        
+        /**
+         * Set the cookie creator instance used by the guard.
+         *
+         * @param \Illuminate\Contracts\Cookie\QueueingFactory $cookie
+         * @return void 
+         * @static 
+         */ 
+        public static function setCookieJar($cookie)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->setCookieJar($cookie);
+        }
+        
+        /**
+         * Get the event dispatcher instance.
+         *
+         * @return \Illuminate\Contracts\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function getDispatcher()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getDispatcher();
+        }
+        
+        /**
+         * Set the event dispatcher instance.
+         *
+         * @param \Illuminate\Contracts\Events\Dispatcher $events
+         * @return void 
+         * @static 
+         */ 
+        public static function setDispatcher($events)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->setDispatcher($events);
+        }
+        
+        /**
+         * Get the session store used by the guard.
+         *
+         * @return \Illuminate\Contracts\Session\Session 
+         * @static 
+         */ 
+        public static function getSession()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getSession();
+        }
+        
+        /**
+         * Return the currently cached user.
+         *
+         * @return \App\Http\Models\User|null 
+         * @static 
+         */ 
+        public static function getUser()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getUser();
+        }
+        
+        /**
+         * Set the current user.
+         *
+         * @param \Illuminate\Contracts\Auth\Authenticatable $user
+         * @return \Illuminate\Auth\SessionGuard 
+         * @static 
+         */ 
+        public static function setUser($user)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->setUser($user);
+        }
+        
+        /**
+         * Get the current request instance.
+         *
+         * @return \Symfony\Component\HttpFoundation\Request 
+         * @static 
+         */ 
+        public static function getRequest()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getRequest();
+        }
+        
+        /**
+         * Set the current request instance.
+         *
+         * @param \Symfony\Component\HttpFoundation\Request $request
+         * @return \Illuminate\Auth\SessionGuard 
+         * @static 
+         */ 
+        public static function setRequest($request)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->setRequest($request);
+        }
+        
+        /**
+         * Determine if the current user is authenticated.
+         *
+         * @return \App\Http\Models\User 
+         * @throws \Illuminate\Auth\AuthenticationException
+         * @static 
+         */ 
+        public static function authenticate()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->authenticate();
+        }
+        
+        /**
+         * Determine if the guard has a user instance.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasUser()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->hasUser();
+        }
+        
+        /**
+         * Determine if the current user is authenticated.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function check()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->check();
+        }
+        
+        /**
+         * Determine if the current user is a guest.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function guest()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->guest();
+        }
+        
+        /**
+         * Get the user provider used by the guard.
+         *
+         * @return \Illuminate\Contracts\Auth\UserProvider 
+         * @static 
+         */ 
+        public static function getProvider()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getProvider();
+        }
+        
+        /**
+         * Set the user provider used by the guard.
+         *
+         * @param \Illuminate\Contracts\Auth\UserProvider $provider
+         * @return void 
+         * @static 
+         */ 
+        public static function setProvider($provider)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->setProvider($provider);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Auth\SessionGuard::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Auth\SessionGuard::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Auth\SessionGuard::hasMacro($name);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\View\Compilers\BladeCompiler
+     */ 
+    class Blade {
+        
+        /**
+         * Compile the view at the given path.
+         *
+         * @param string $path
+         * @return void 
+         * @static 
+         */ 
+        public static function compile($path = null)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->compile($path);
+        }
+        
+        /**
+         * Get the path currently being compiled.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getPath()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getPath();
+        }
+        
+        /**
+         * Set the path currently being compiled.
+         *
+         * @param string $path
+         * @return void 
+         * @static 
+         */ 
+        public static function setPath($path)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->setPath($path);
+        }
+        
+        /**
+         * Compile the given Blade template contents.
+         *
+         * @param string $value
+         * @return string 
+         * @static 
+         */ 
+        public static function compileString($value)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->compileString($value);
+        }
+        
+        /**
+         * Strip the parentheses from the given expression.
+         *
+         * @param string $expression
+         * @return string 
+         * @static 
+         */ 
+        public static function stripParentheses($expression)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->stripParentheses($expression);
+        }
+        
+        /**
+         * Register a custom Blade compiler.
+         *
+         * @param callable $compiler
+         * @return void 
+         * @static 
+         */ 
+        public static function extend($compiler)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->extend($compiler);
+        }
+        
+        /**
+         * Get the extensions used by the compiler.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getExtensions()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getExtensions();
+        }
+        
+        /**
+         * Register an "if" statement directive.
+         *
+         * @param string $name
+         * @param callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function if($name, $callback)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->if($name, $callback);
+        }
+        
+        /**
+         * Check the result of a condition.
+         *
+         * @param string $name
+         * @param array $parameters
+         * @return bool 
+         * @static 
+         */ 
+        public static function check($name, $parameters = null)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->check($name, $parameters);
+        }
+        
+        /**
+         * Register a component alias directive.
+         *
+         * @param string $path
+         * @param string $alias
+         * @return void 
+         * @static 
+         */ 
+        public static function component($path, $alias = null)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->component($path, $alias);
+        }
+        
+        /**
+         * Register an include alias directive.
+         *
+         * @param string $path
+         * @param string $alias
+         * @return void 
+         * @static 
+         */ 
+        public static function include($path, $alias = null)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->include($path, $alias);
+        }
+        
+        /**
+         * Register a handler for custom directives.
+         *
+         * @param string $name
+         * @param callable $handler
+         * @return void 
+         * @static 
+         */ 
+        public static function directive($name, $handler)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->directive($name, $handler);
+        }
+        
+        /**
+         * Get the list of custom directives.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getCustomDirectives()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getCustomDirectives();
+        }
+        
+        /**
+         * Set the echo format to be used by the compiler.
+         *
+         * @param string $format
+         * @return void 
+         * @static 
+         */ 
+        public static function setEchoFormat($format)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->setEchoFormat($format);
+        }
+        
+        /**
+         * Set the "echo" format to double encode entities.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function withDoubleEncoding()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->withDoubleEncoding();
+        }
+        
+        /**
+         * Set the "echo" format to not double encode entities.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function withoutDoubleEncoding()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->withoutDoubleEncoding();
+        }
+        
+        /**
+         * Get the path to the compiled version of a view.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function getCompiledPath($path)
+        {
+            //Method inherited from \Illuminate\View\Compilers\Compiler            
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getCompiledPath($path);
+        }
+        
+        /**
+         * Determine if the view at the given path is expired.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function isExpired($path)
+        {
+            //Method inherited from \Illuminate\View\Compilers\Compiler            
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->isExpired($path);
+        }
+        
+        /**
+         * Compile the default values for the echo statement.
+         *
+         * @param string $value
+         * @return string 
+         * @static 
+         */ 
+        public static function compileEchoDefaults($value)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->compileEchoDefaults($value);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @method static \Illuminate\Broadcasting\Broadcasters\Broadcaster channel(string $channel, callable|string  $callback)
+     * @method static mixed auth(\Illuminate\Http\Request $request)
+     * @see \Illuminate\Contracts\Broadcasting\Factory
+     */ 
+    class Broadcast {
+        
+        /**
+         * Register the routes for handling broadcast authentication and sockets.
+         *
+         * @param array|null $attributes
+         * @return void 
+         * @static 
+         */ 
+        public static function routes($attributes = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        $instance->routes($attributes);
+        }
+        
+        /**
+         * Get the socket ID for the given request.
+         *
+         * @param \Illuminate\Http\Request|null $request
+         * @return string|null 
+         * @static 
+         */ 
+        public static function socket($request = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->socket($request);
+        }
+        
+        /**
+         * Begin broadcasting an event.
+         *
+         * @param mixed|null $event
+         * @return \Illuminate\Broadcasting\PendingBroadcast|void 
+         * @static 
+         */ 
+        public static function event($event = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->event($event);
+        }
+        
+        /**
+         * Queue the given event for broadcast.
+         *
+         * @param mixed $event
+         * @return void 
+         * @static 
+         */ 
+        public static function queue($event)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        $instance->queue($event);
+        }
+        
+        /**
+         * Get a driver instance.
+         *
+         * @param string $driver
+         * @return mixed 
+         * @static 
+         */ 
+        public static function connection($driver = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->connection($driver);
+        }
+        
+        /**
+         * Get a driver instance.
+         *
+         * @param string|null $name
+         * @return mixed 
+         * @static 
+         */ 
+        public static function driver($name = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->driver($name);
+        }
+        
+        /**
+         * Get the default driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Set the default driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+        
+        /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Broadcasting\BroadcastManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Bus\Dispatcher
+     */ 
+    class Bus {
+        
+        /**
+         * Dispatch a command to its appropriate handler.
+         *
+         * @param mixed $command
+         * @return mixed 
+         * @static 
+         */ 
+        public static function dispatch($command)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->dispatch($command);
+        }
+        
+        /**
+         * Dispatch a command to its appropriate handler in the current process.
+         *
+         * @param mixed $command
+         * @param mixed $handler
+         * @return mixed 
+         * @static 
+         */ 
+        public static function dispatchNow($command, $handler = null)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->dispatchNow($command, $handler);
+        }
+        
+        /**
+         * Determine if the given command has a handler.
+         *
+         * @param mixed $command
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasCommandHandler($command)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->hasCommandHandler($command);
+        }
+        
+        /**
+         * Retrieve the handler for a command.
+         *
+         * @param mixed $command
+         * @return bool|mixed 
+         * @static 
+         */ 
+        public static function getCommandHandler($command)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->getCommandHandler($command);
+        }
+        
+        /**
+         * Dispatch a command to its appropriate handler behind a queue.
+         *
+         * @param mixed $command
+         * @return mixed 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function dispatchToQueue($command)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->dispatchToQueue($command);
+        }
+        
+        /**
+         * Set the pipes through which commands should be piped before dispatching.
+         *
+         * @param array $pipes
+         * @return \Illuminate\Bus\Dispatcher 
+         * @static 
+         */ 
+        public static function pipeThrough($pipes)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->pipeThrough($pipes);
+        }
+        
+        /**
+         * Map a command to a handler.
+         *
+         * @param array $map
+         * @return \Illuminate\Bus\Dispatcher 
+         * @static 
+         */ 
+        public static function map($map)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->map($map);
+        }
+        
+        /**
+         * Assert if a job was dispatched based on a truth-test callback.
+         *
+         * @param string $command
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatched($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        $instance->assertDispatched($command, $callback);
+        }
+        
+        /**
+         * Determine if a job was dispatched based on a truth-test callback.
+         *
+         * @param string $command
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotDispatched($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        $instance->assertNotDispatched($command, $callback);
+        }
+        
+        /**
+         * Get all of the jobs matching a truth-test callback.
+         *
+         * @param string $command
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function dispatched($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        return $instance->dispatched($command, $callback);
+        }
+        
+        /**
+         * Determine if there are any stored commands for a given class.
+         *
+         * @param string $command
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasDispatched($command)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        return $instance->hasDispatched($command);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Cache\CacheManager
+     * @see \Illuminate\Cache\Repository
+     */ 
+    class Cache {
+        
+        /**
+         * Get a cache store instance by name.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Contracts\Cache\Repository 
+         * @static 
+         */ 
+        public static function store($name = null)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->store($name);
+        }
+        
+        /**
+         * Get a cache driver instance.
+         *
+         * @param string|null $driver
+         * @return mixed 
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->driver($driver);
+        }
+        
+        /**
+         * Create a new cache repository with the given implementation.
+         *
+         * @param \Illuminate\Contracts\Cache\Store $store
+         * @return \Illuminate\Cache\Repository 
+         * @static 
+         */ 
+        public static function repository($store)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->repository($store);
+        }
+        
+        /**
+         * Get the default cache driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Set the default cache driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+        
+        /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Cache\CacheManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+        
+        /**
+         * Determine if an item exists in the cache.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->has($key);
+        }
+        
+        /**
+         * Retrieve an item from the cache by key.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function get($key, $default = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->get($key, $default);
+        }
+        
+        /**
+         * Retrieve multiple items from the cache by key.
+         * 
+         * Items not found in the cache will have a null value.
+         *
+         * @param array $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function many($keys)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->many($keys);
+        }
+        
+        /**
+         * Obtains multiple cache items by their unique keys.
+         *
+         * @param \Psr\SimpleCache\iterable $keys A list of keys that can obtained in a single operation.
+         * @param mixed $default Default value to return for keys that do not exist.
+         * @return \Psr\SimpleCache\iterable A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if $keys is neither an array nor a Traversable,
+         *   or if any of the $keys are not a legal value.
+         * @static 
+         */ 
+        public static function getMultiple($keys, $default = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->getMultiple($keys, $default);
+        }
+        
+        /**
+         * Retrieve an item from the cache and delete it.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function pull($key, $default = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->pull($key, $default);
+        }
+        
+        /**
+         * Store an item in the cache.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @param \DateTimeInterface|\DateInterval|float|int|null $minutes
+         * @return void 
+         * @static 
+         */ 
+        public static function put($key, $value, $minutes = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->put($key, $value, $minutes);
+        }
+        
+        /**
+         * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
+         *
+         * @param string $key The key of the item to store.
+         * @param mixed $value The value of the item to store, must be serializable.
+         * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
+         *                                      the driver supports TTL then the library may set a default value
+         *                                      for it or let the driver take care of that.
+         * @return bool True on success and false on failure.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if the $key string is not a legal value.
+         * @static 
+         */ 
+        public static function set($key, $value, $ttl = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->set($key, $value, $ttl);
+        }
+        
+        /**
+         * Store multiple items in the cache for a given number of minutes.
+         *
+         * @param array $values
+         * @param \DateTimeInterface|\DateInterval|float|int $minutes
+         * @return void 
+         * @static 
+         */ 
+        public static function putMany($values, $minutes)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->putMany($values, $minutes);
+        }
+        
+        /**
+         * Persists a set of key => value pairs in the cache, with an optional TTL.
+         *
+         * @param \Psr\SimpleCache\iterable $values A list of key => value pairs for a multiple-set operation.
+         * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
+         *                                       the driver supports TTL then the library may set a default value
+         *                                       for it or let the driver take care of that.
+         * @return bool True on success and false on failure.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if $values is neither an array nor a Traversable,
+         *   or if any of the $values are not a legal value.
+         * @static 
+         */ 
+        public static function setMultiple($values, $ttl = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->setMultiple($values, $ttl);
+        }
+        
+        /**
+         * Store an item in the cache if the key does not exist.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @param \DateTimeInterface|\DateInterval|float|int $minutes
+         * @return bool 
+         * @static 
+         */ 
+        public static function add($key, $value, $minutes)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->add($key, $value, $minutes);
+        }
+        
+        /**
+         * Increment the value of an item in the cache.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return int|bool 
+         * @static 
+         */ 
+        public static function increment($key, $value = 1)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->increment($key, $value);
+        }
+        
+        /**
+         * Decrement the value of an item in the cache.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return int|bool 
+         * @static 
+         */ 
+        public static function decrement($key, $value = 1)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->decrement($key, $value);
+        }
+        
+        /**
+         * Store an item in the cache indefinitely.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function forever($key, $value)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->forever($key, $value);
+        }
+        
+        /**
+         * Get an item from the cache, or store the default value.
+         *
+         * @param string $key
+         * @param \DateTimeInterface|\DateInterval|float|int $minutes
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function remember($key, $minutes, $callback)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->remember($key, $minutes, $callback);
+        }
+        
+        /**
+         * Get an item from the cache, or store the default value forever.
+         *
+         * @param string $key
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function sear($key, $callback)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->sear($key, $callback);
+        }
+        
+        /**
+         * Get an item from the cache, or store the default value forever.
+         *
+         * @param string $key
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function rememberForever($key, $callback)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->rememberForever($key, $callback);
+        }
+        
+        /**
+         * Remove an item from the cache.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function forget($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->forget($key);
+        }
+        
+        /**
+         * Delete an item from the cache by its unique key.
+         *
+         * @param string $key The unique cache key of the item to delete.
+         * @return bool True if the item was successfully removed. False if there was an error.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if the $key string is not a legal value.
+         * @static 
+         */ 
+        public static function delete($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->delete($key);
+        }
+        
+        /**
+         * Deletes multiple cache items in a single operation.
+         *
+         * @param \Psr\SimpleCache\iterable $keys A list of string-based keys to be deleted.
+         * @return bool True if the items were successfully removed. False if there was an error.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if $keys is neither an array nor a Traversable,
+         *   or if any of the $keys are not a legal value.
+         * @static 
+         */ 
+        public static function deleteMultiple($keys)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->deleteMultiple($keys);
+        }
+        
+        /**
+         * Wipes clean the entire cache's keys.
+         *
+         * @return bool True on success and false on failure.
+         * @static 
+         */ 
+        public static function clear()
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->clear();
+        }
+        
+        /**
+         * Begin executing a new tags operation if the store supports it.
+         *
+         * @param array|mixed $names
+         * @return \Illuminate\Cache\TaggedCache 
+         * @throws \BadMethodCallException
+         * @static 
+         */ 
+        public static function tags($names)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->tags($names);
+        }
+        
+        /**
+         * Get the default cache time.
+         *
+         * @return float|int 
+         * @static 
+         */ 
+        public static function getDefaultCacheTime()
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->getDefaultCacheTime();
+        }
+        
+        /**
+         * Set the default cache time in minutes.
+         *
+         * @param float|int $minutes
+         * @return \Illuminate\Cache\Repository 
+         * @static 
+         */ 
+        public static function setDefaultCacheTime($minutes)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->setDefaultCacheTime($minutes);
+        }
+        
+        /**
+         * Get the cache store implementation.
+         *
+         * @return \Illuminate\Contracts\Cache\Store 
+         * @static 
+         */ 
+        public static function getStore()
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->getStore();
+        }
+        
+        /**
+         * Set the event dispatcher instance.
+         *
+         * @param \Illuminate\Contracts\Events\Dispatcher $events
+         * @return void 
+         * @static 
+         */ 
+        public static function setEventDispatcher($events)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->setEventDispatcher($events);
+        }
+        
+        /**
+         * Determine if a cached value exists.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function offsetExists($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->offsetExists($key);
+        }
+        
+        /**
+         * Retrieve an item from the cache by key.
+         *
+         * @param string $key
+         * @return mixed 
+         * @static 
+         */ 
+        public static function offsetGet($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->offsetGet($key);
+        }
+        
+        /**
+         * Store an item in the cache for the default time.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetSet($key, $value)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->offsetSet($key, $value);
+        }
+        
+        /**
+         * Remove an item from the cache.
+         *
+         * @param string $key
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetUnset($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->offsetUnset($key);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Cache\Repository::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Cache\Repository::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Cache\Repository::hasMacro($name);
+        }
+        
+        /**
+         * Dynamically handle calls to the class.
+         *
+         * @param string $method
+         * @param array $parameters
+         * @return mixed 
+         * @throws \BadMethodCallException
+         * @static 
+         */ 
+        public static function macroCall($method, $parameters)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->macroCall($method, $parameters);
+        }
+        
+        /**
+         * Remove all items from the cache.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function flush()
+        {
+                        /** @var \Illuminate\Cache\FileStore $instance */
+                        return $instance->flush();
+        }
+        
+        /**
+         * Get the Filesystem instance.
+         *
+         * @return \Illuminate\Filesystem\Filesystem 
+         * @static 
+         */ 
+        public static function getFilesystem()
+        {
+                        /** @var \Illuminate\Cache\FileStore $instance */
+                        return $instance->getFilesystem();
+        }
+        
+        /**
+         * Get the working directory of the cache.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDirectory()
+        {
+                        /** @var \Illuminate\Cache\FileStore $instance */
+                        return $instance->getDirectory();
+        }
+        
+        /**
+         * Get the cache key prefix.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getPrefix()
+        {
+                        /** @var \Illuminate\Cache\FileStore $instance */
+                        return $instance->getPrefix();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Config\Repository
+     */ 
+    class Config {
+        
+        /**
+         * Determine if the given configuration value exists.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->has($key);
+        }
+        
+        /**
+         * Get the specified configuration value.
+         *
+         * @param array|string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function get($key, $default = null)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->get($key, $default);
+        }
+        
+        /**
+         * Get many configuration values.
+         *
+         * @param array $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function getMany($keys)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->getMany($keys);
+        }
+        
+        /**
+         * Set a given configuration value.
+         *
+         * @param array|string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function set($key, $value = null)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->set($key, $value);
+        }
+        
+        /**
+         * Prepend a value onto an array configuration value.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function prepend($key, $value)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->prepend($key, $value);
+        }
+        
+        /**
+         * Push a value onto an array configuration value.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function push($key, $value)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->push($key, $value);
+        }
+        
+        /**
+         * Get all of the configuration items for the application.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function all()
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->all();
+        }
+        
+        /**
+         * Determine if the given configuration option exists.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function offsetExists($key)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->offsetExists($key);
+        }
+        
+        /**
+         * Get a configuration option.
+         *
+         * @param string $key
+         * @return mixed 
+         * @static 
+         */ 
+        public static function offsetGet($key)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->offsetGet($key);
+        }
+        
+        /**
+         * Set a configuration option.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetSet($key, $value)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->offsetSet($key, $value);
+        }
+        
+        /**
+         * Unset a configuration option.
+         *
+         * @param string $key
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetUnset($key)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->offsetUnset($key);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Cookie\CookieJar
+     */ 
+    class Cookie {
+        
+        /**
+         * Create a new cookie instance.
+         *
+         * @param string $name
+         * @param string $value
+         * @param int $minutes
+         * @param string $path
+         * @param string $domain
+         * @param bool|null $secure
+         * @param bool $httpOnly
+         * @param bool $raw
+         * @param string|null $sameSite
+         * @return \Symfony\Component\HttpFoundation\Cookie 
+         * @static 
+         */ 
+        public static function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->make($name, $value, $minutes, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
+        }
+        
+        /**
+         * Create a cookie that lasts "forever" (five years).
+         *
+         * @param string $name
+         * @param string $value
+         * @param string $path
+         * @param string $domain
+         * @param bool|null $secure
+         * @param bool $httpOnly
+         * @param bool $raw
+         * @param string|null $sameSite
+         * @return \Symfony\Component\HttpFoundation\Cookie 
+         * @static 
+         */ 
+        public static function forever($name, $value, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->forever($name, $value, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
+        }
+        
+        /**
+         * Expire the given cookie.
+         *
+         * @param string $name
+         * @param string $path
+         * @param string $domain
+         * @return \Symfony\Component\HttpFoundation\Cookie 
+         * @static 
+         */ 
+        public static function forget($name, $path = null, $domain = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->forget($name, $path, $domain);
+        }
+        
+        /**
+         * Determine if a cookie has been queued.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasQueued($key)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->hasQueued($key);
+        }
+        
+        /**
+         * Get a queued cookie instance.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return \Symfony\Component\HttpFoundation\Cookie 
+         * @static 
+         */ 
+        public static function queued($key, $default = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->queued($key, $default);
+        }
+        
+        /**
+         * Queue a cookie to send with the next response.
+         *
+         * @param array $parameters
+         * @return void 
+         * @static 
+         */ 
+        public static function queue($parameters = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        $instance->queue($parameters);
+        }
+        
+        /**
+         * Remove a cookie from the queue.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function unqueue($name)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        $instance->unqueue($name);
+        }
+        
+        /**
+         * Set the default path and domain for the jar.
+         *
+         * @param string $path
+         * @param string $domain
+         * @param bool $secure
+         * @param string $sameSite
+         * @return \Illuminate\Cookie\CookieJar 
+         * @static 
+         */ 
+        public static function setDefaultPathAndDomain($path, $domain, $secure = false, $sameSite = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->setDefaultPathAndDomain($path, $domain, $secure, $sameSite);
+        }
+        
+        /**
+         * Get the cookies which have been queued for the next request.
+         *
+         * @return \Symfony\Component\HttpFoundation\Cookie[] 
+         * @static 
+         */ 
+        public static function getQueuedCookies()
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->getQueuedCookies();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Encryption\Encrypter
+     */ 
+    class Crypt {
+        
+        /**
+         * Determine if the given key and cipher combination is valid.
+         *
+         * @param string $key
+         * @param string $cipher
+         * @return bool 
+         * @static 
+         */ 
+        public static function supported($key, $cipher)
+        {
+                        return \Illuminate\Encryption\Encrypter::supported($key, $cipher);
+        }
+        
+        /**
+         * Create a new encryption key for the given cipher.
+         *
+         * @param string $cipher
+         * @return string 
+         * @static 
+         */ 
+        public static function generateKey($cipher)
+        {
+                        return \Illuminate\Encryption\Encrypter::generateKey($cipher);
+        }
+        
+        /**
+         * Encrypt the given value.
+         *
+         * @param mixed $value
+         * @param bool $serialize
+         * @return string 
+         * @throws \Illuminate\Contracts\Encryption\EncryptException
+         * @static 
+         */ 
+        public static function encrypt($value, $serialize = true)
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->encrypt($value, $serialize);
+        }
+        
+        /**
+         * Encrypt a string without serialization.
+         *
+         * @param string $value
+         * @return string 
+         * @static 
+         */ 
+        public static function encryptString($value)
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->encryptString($value);
+        }
+        
+        /**
+         * Decrypt the given value.
+         *
+         * @param mixed $payload
+         * @param bool $unserialize
+         * @return mixed 
+         * @throws \Illuminate\Contracts\Encryption\DecryptException
+         * @static 
+         */ 
+        public static function decrypt($payload, $unserialize = true)
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->decrypt($payload, $unserialize);
+        }
+        
+        /**
+         * Decrypt the given string without unserialization.
+         *
+         * @param string $payload
+         * @return string 
+         * @static 
+         */ 
+        public static function decryptString($payload)
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->decryptString($payload);
+        }
+        
+        /**
+         * Get the encryption key.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getKey()
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->getKey();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Database\DatabaseManager
+     * @see \Illuminate\Database\Connection
+     */ 
+    class DB {
+        
+        /**
+         * Get a database connection instance.
+         *
+         * @param string $name
+         * @return \Illuminate\Database\Connection 
+         * @static 
+         */ 
+        public static function connection($name = null)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->connection($name);
+        }
+        
+        /**
+         * Disconnect from the given database and remove from local cache.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function purge($name = null)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->purge($name);
+        }
+        
+        /**
+         * Disconnect from the given database.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function disconnect($name = null)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->disconnect($name);
+        }
+        
+        /**
+         * Reconnect to the given database.
+         *
+         * @param string $name
+         * @return \Illuminate\Database\Connection 
+         * @static 
+         */ 
+        public static function reconnect($name = null)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->reconnect($name);
+        }
+        
+        /**
+         * Get the default connection name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultConnection()
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->getDefaultConnection();
+        }
+        
+        /**
+         * Set the default connection name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultConnection($name)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->setDefaultConnection($name);
+        }
+        
+        /**
+         * Get all of the support drivers.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function supportedDrivers()
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->supportedDrivers();
+        }
+        
+        /**
+         * Get all of the drivers that are actually available.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function availableDrivers()
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->availableDrivers();
+        }
+        
+        /**
+         * Register an extension connection resolver.
+         *
+         * @param string $name
+         * @param callable $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function extend($name, $resolver)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->extend($name, $resolver);
+        }
+        
+        /**
+         * Return all of the created connections.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getConnections()
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->getConnections();
+        }
+        
+        /**
+         * Get a schema builder instance for the connection.
+         *
+         * @return \Illuminate\Database\Schema\MySqlBuilder 
+         * @static 
+         */ 
+        public static function getSchemaBuilder()
+        {
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getSchemaBuilder();
+        }
+        
+        /**
+         * Bind values to their parameters in the given statement.
+         *
+         * @param \PDOStatement $statement
+         * @param array $bindings
+         * @return void 
+         * @static 
+         */ 
+        public static function bindValues($statement, $bindings)
+        {
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->bindValues($statement, $bindings);
+        }
+        
+        /**
+         * Set the query grammar to the default implementation.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function useDefaultQueryGrammar()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->useDefaultQueryGrammar();
+        }
+        
+        /**
+         * Set the schema grammar to the default implementation.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function useDefaultSchemaGrammar()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->useDefaultSchemaGrammar();
+        }
+        
+        /**
+         * Set the query post processor to the default implementation.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function useDefaultPostProcessor()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->useDefaultPostProcessor();
+        }
+        
+        /**
+         * Begin a fluent query against a database table.
+         *
+         * @param string $table
+         * @return \Illuminate\Database\Query\Builder 
+         * @static 
+         */ 
+        public static function table($table)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->table($table);
+        }
+        
+        /**
+         * Get a new query builder instance.
+         *
+         * @return \Illuminate\Database\Query\Builder 
+         * @static 
+         */ 
+        public static function query()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->query();
+        }
+        
+        /**
+         * Run a select statement and return a single result.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @param bool $useReadPdo
+         * @return mixed 
+         * @static 
+         */ 
+        public static function selectOne($query, $bindings = array(), $useReadPdo = true)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->selectOne($query, $bindings, $useReadPdo);
+        }
+        
+        /**
+         * Run a select statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return array 
+         * @static 
+         */ 
+        public static function selectFromWriteConnection($query, $bindings = array())
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->selectFromWriteConnection($query, $bindings);
+        }
+        
+        /**
+         * Run a select statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @param bool $useReadPdo
+         * @return array 
+         * @static 
+         */ 
+        public static function select($query, $bindings = array(), $useReadPdo = true)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->select($query, $bindings, $useReadPdo);
+        }
+        
+        /**
+         * Run a select statement against the database and returns a generator.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @param bool $useReadPdo
+         * @return \Generator 
+         * @static 
+         */ 
+        public static function cursor($query, $bindings = array(), $useReadPdo = true)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->cursor($query, $bindings, $useReadPdo);
+        }
+        
+        /**
+         * Run an insert statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return bool 
+         * @static 
+         */ 
+        public static function insert($query, $bindings = array())
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->insert($query, $bindings);
+        }
+        
+        /**
+         * Run an update statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return int 
+         * @static 
+         */ 
+        public static function update($query, $bindings = array())
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->update($query, $bindings);
+        }
+        
+        /**
+         * Run a delete statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return int 
+         * @static 
+         */ 
+        public static function delete($query, $bindings = array())
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->delete($query, $bindings);
+        }
+        
+        /**
+         * Execute an SQL statement and return the boolean result.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return bool 
+         * @static 
+         */ 
+        public static function statement($query, $bindings = array())
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->statement($query, $bindings);
+        }
+        
+        /**
+         * Run an SQL statement and get the number of rows affected.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return int 
+         * @static 
+         */ 
+        public static function affectingStatement($query, $bindings = array())
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->affectingStatement($query, $bindings);
+        }
+        
+        /**
+         * Run a raw, unprepared query against the PDO connection.
+         *
+         * @param string $query
+         * @return bool 
+         * @static 
+         */ 
+        public static function unprepared($query)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->unprepared($query);
+        }
+        
+        /**
+         * Execute the given callback in "dry run" mode.
+         *
+         * @param \Closure $callback
+         * @return array 
+         * @static 
+         */ 
+        public static function pretend($callback)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->pretend($callback);
+        }
+        
+        /**
+         * Prepare the query bindings for execution.
+         *
+         * @param array $bindings
+         * @return array 
+         * @static 
+         */ 
+        public static function prepareBindings($bindings)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->prepareBindings($bindings);
+        }
+        
+        /**
+         * Log a query in the connection's query log.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @param float|null $time
+         * @return void 
+         * @static 
+         */ 
+        public static function logQuery($query, $bindings, $time = null)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->logQuery($query, $bindings, $time);
+        }
+        
+        /**
+         * Register a database query listener with the connection.
+         *
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function listen($callback)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->listen($callback);
+        }
+        
+        /**
+         * Get a new raw query expression.
+         *
+         * @param mixed $value
+         * @return \Illuminate\Database\Query\Expression 
+         * @static 
+         */ 
+        public static function raw($value)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->raw($value);
+        }
+        
+        /**
+         * Indicate if any records have been modified.
+         *
+         * @param bool $value
+         * @return void 
+         * @static 
+         */ 
+        public static function recordsHaveBeenModified($value = true)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->recordsHaveBeenModified($value);
+        }
+        
+        /**
+         * Is Doctrine available?
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDoctrineAvailable()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->isDoctrineAvailable();
+        }
+        
+        /**
+         * Get a Doctrine Schema Column instance.
+         *
+         * @param string $table
+         * @param string $column
+         * @return \Doctrine\DBAL\Schema\Column 
+         * @static 
+         */ 
+        public static function getDoctrineColumn($table, $column)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDoctrineColumn($table, $column);
+        }
+        
+        /**
+         * Get the Doctrine DBAL schema manager for the connection.
+         *
+         * @return \Doctrine\DBAL\Schema\AbstractSchemaManager 
+         * @static 
+         */ 
+        public static function getDoctrineSchemaManager()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDoctrineSchemaManager();
+        }
+        
+        /**
+         * Get the Doctrine DBAL database connection instance.
+         *
+         * @return \Doctrine\DBAL\Connection 
+         * @static 
+         */ 
+        public static function getDoctrineConnection()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDoctrineConnection();
+        }
+        
+        /**
+         * Get the current PDO connection.
+         *
+         * @return \PDO 
+         * @static 
+         */ 
+        public static function getPdo()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getPdo();
+        }
+        
+        /**
+         * Get the current PDO connection used for reading.
+         *
+         * @return \PDO 
+         * @static 
+         */ 
+        public static function getReadPdo()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getReadPdo();
+        }
+        
+        /**
+         * Set the PDO connection.
+         *
+         * @param \PDO|\Closure|null $pdo
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setPdo($pdo)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setPdo($pdo);
+        }
+        
+        /**
+         * Set the PDO connection used for reading.
+         *
+         * @param \PDO|\Closure|null $pdo
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setReadPdo($pdo)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setReadPdo($pdo);
+        }
+        
+        /**
+         * Set the reconnect instance on the connection.
+         *
+         * @param callable $reconnector
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setReconnector($reconnector)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setReconnector($reconnector);
+        }
+        
+        /**
+         * Get the database connection name.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function getName()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getName();
+        }
+        
+        /**
+         * Get an option from the configuration options.
+         *
+         * @param string|null $option
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getConfig($option = null)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getConfig($option);
+        }
+        
+        /**
+         * Get the PDO driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDriverName()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDriverName();
+        }
+        
+        /**
+         * Get the query grammar used by the connection.
+         *
+         * @return \Illuminate\Database\Query\Grammars\Grammar 
+         * @static 
+         */ 
+        public static function getQueryGrammar()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getQueryGrammar();
+        }
+        
+        /**
+         * Set the query grammar used by the connection.
+         *
+         * @param \Illuminate\Database\Query\Grammars\Grammar $grammar
+         * @return void 
+         * @static 
+         */ 
+        public static function setQueryGrammar($grammar)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->setQueryGrammar($grammar);
+        }
+        
+        /**
+         * Get the schema grammar used by the connection.
+         *
+         * @return \Illuminate\Database\Schema\Grammars\Grammar 
+         * @static 
+         */ 
+        public static function getSchemaGrammar()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getSchemaGrammar();
+        }
+        
+        /**
+         * Set the schema grammar used by the connection.
+         *
+         * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
+         * @return void 
+         * @static 
+         */ 
+        public static function setSchemaGrammar($grammar)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->setSchemaGrammar($grammar);
+        }
+        
+        /**
+         * Get the query post processor used by the connection.
+         *
+         * @return \Illuminate\Database\Query\Processors\Processor 
+         * @static 
+         */ 
+        public static function getPostProcessor()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getPostProcessor();
+        }
+        
+        /**
+         * Set the query post processor used by the connection.
+         *
+         * @param \Illuminate\Database\Query\Processors\Processor $processor
+         * @return void 
+         * @static 
+         */ 
+        public static function setPostProcessor($processor)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->setPostProcessor($processor);
+        }
+        
+        /**
+         * Get the event dispatcher used by the connection.
+         *
+         * @return \Illuminate\Contracts\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function getEventDispatcher()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getEventDispatcher();
+        }
+        
+        /**
+         * Set the event dispatcher instance on the connection.
+         *
+         * @param \Illuminate\Contracts\Events\Dispatcher $events
+         * @return void 
+         * @static 
+         */ 
+        public static function setEventDispatcher($events)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->setEventDispatcher($events);
+        }
+        
+        /**
+         * Unset the event dispatcher for this connection.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function unsetEventDispatcher()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->unsetEventDispatcher();
+        }
+        
+        /**
+         * Determine if the connection in a "dry run".
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function pretending()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->pretending();
+        }
+        
+        /**
+         * Get the connection query log.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getQueryLog()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getQueryLog();
+        }
+        
+        /**
+         * Clear the query log.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushQueryLog()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->flushQueryLog();
+        }
+        
+        /**
+         * Enable the query log on the connection.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function enableQueryLog()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->enableQueryLog();
+        }
+        
+        /**
+         * Disable the query log on the connection.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function disableQueryLog()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->disableQueryLog();
+        }
+        
+        /**
+         * Determine whether we're logging queries.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function logging()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->logging();
+        }
+        
+        /**
+         * Get the name of the connected database.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDatabaseName()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDatabaseName();
+        }
+        
+        /**
+         * Set the name of the connected database.
+         *
+         * @param string $database
+         * @return string 
+         * @static 
+         */ 
+        public static function setDatabaseName($database)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setDatabaseName($database);
+        }
+        
+        /**
+         * Get the table prefix for the connection.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getTablePrefix()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getTablePrefix();
+        }
+        
+        /**
+         * Set the table prefix in use by the connection.
+         *
+         * @param string $prefix
+         * @return void 
+         * @static 
+         */ 
+        public static function setTablePrefix($prefix)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->setTablePrefix($prefix);
+        }
+        
+        /**
+         * Set the table prefix and return the grammar.
+         *
+         * @param \Illuminate\Database\Grammar $grammar
+         * @return \Illuminate\Database\Grammar 
+         * @static 
+         */ 
+        public static function withTablePrefix($grammar)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->withTablePrefix($grammar);
+        }
+        
+        /**
+         * Register a connection resolver.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function resolverFor($driver, $callback)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        \Illuminate\Database\MySqlConnection::resolverFor($driver, $callback);
+        }
+        
+        /**
+         * Get the connection resolver for the given driver.
+         *
+         * @param string $driver
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getResolver($driver)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        return \Illuminate\Database\MySqlConnection::getResolver($driver);
+        }
+        
+        /**
+         * Execute a Closure within a transaction.
+         *
+         * @param \Closure $callback
+         * @param int $attempts
+         * @return mixed 
+         * @throws \Exception|\Throwable
+         * @static 
+         */ 
+        public static function transaction($callback, $attempts = 1)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->transaction($callback, $attempts);
+        }
+        
+        /**
+         * Start a new database transaction.
+         *
+         * @return void 
+         * @throws \Exception
+         * @static 
+         */ 
+        public static function beginTransaction()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->beginTransaction();
+        }
+        
+        /**
+         * Commit the active database transaction.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function commit()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->commit();
+        }
+        
+        /**
+         * Rollback the active database transaction.
+         *
+         * @param int|null $toLevel
+         * @return void 
+         * @throws \Exception
+         * @static 
+         */ 
+        public static function rollBack($toLevel = null)
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->rollBack($toLevel);
+        }
+        
+        /**
+         * Get the number of active transactions.
+         *
+         * @return int 
+         * @static 
+         */ 
+        public static function transactionLevel()
+        {
+            //Method inherited from \Illuminate\Database\Connection            
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->transactionLevel();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Events\Dispatcher
+     */ 
+    class Event {
+        
+        /**
+         * Register an event listener with the dispatcher.
+         *
+         * @param string|array $events
+         * @param mixed $listener
+         * @return void 
+         * @static 
+         */ 
+        public static function listen($events, $listener)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->listen($events, $listener);
+        }
+        
+        /**
+         * Determine if a given event has listeners.
+         *
+         * @param string $eventName
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasListeners($eventName)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->hasListeners($eventName);
+        }
+        
+        /**
+         * Register an event and payload to be fired later.
+         *
+         * @param string $event
+         * @param array $payload
+         * @return void 
+         * @static 
+         */ 
+        public static function push($event, $payload = array())
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->push($event, $payload);
+        }
+        
+        /**
+         * Flush a set of pushed events.
+         *
+         * @param string $event
+         * @return void 
+         * @static 
+         */ 
+        public static function flush($event)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->flush($event);
+        }
+        
+        /**
+         * Register an event subscriber with the dispatcher.
+         *
+         * @param object|string $subscriber
+         * @return void 
+         * @static 
+         */ 
+        public static function subscribe($subscriber)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->subscribe($subscriber);
+        }
+        
+        /**
+         * Fire an event until the first non-null response is returned.
+         *
+         * @param string|object $event
+         * @param mixed $payload
+         * @return array|null 
+         * @static 
+         */ 
+        public static function until($event, $payload = array())
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->until($event, $payload);
+        }
+        
+        /**
+         * Fire an event and call the listeners.
+         *
+         * @param string|object $event
+         * @param mixed $payload
+         * @param bool $halt
+         * @return array|null 
+         * @static 
+         */ 
+        public static function fire($event, $payload = array(), $halt = false)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->fire($event, $payload, $halt);
+        }
+        
+        /**
+         * Fire an event and call the listeners.
+         *
+         * @param string|object $event
+         * @param mixed $payload
+         * @param bool $halt
+         * @return array|null 
+         * @static 
+         */ 
+        public static function dispatch($event, $payload = array(), $halt = false)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->dispatch($event, $payload, $halt);
+        }
+        
+        /**
+         * Get all of the listeners for a given event name.
+         *
+         * @param string $eventName
+         * @return array 
+         * @static 
+         */ 
+        public static function getListeners($eventName)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->getListeners($eventName);
+        }
+        
+        /**
+         * Register an event listener with the dispatcher.
+         *
+         * @param \Closure|string $listener
+         * @param bool $wildcard
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function makeListener($listener, $wildcard = false)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->makeListener($listener, $wildcard);
+        }
+        
+        /**
+         * Create a class based listener using the IoC container.
+         *
+         * @param string $listener
+         * @param bool $wildcard
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function createClassListener($listener, $wildcard = false)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->createClassListener($listener, $wildcard);
+        }
+        
+        /**
+         * Remove a set of listeners from the dispatcher.
+         *
+         * @param string $event
+         * @return void 
+         * @static 
+         */ 
+        public static function forget($event)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->forget($event);
+        }
+        
+        /**
+         * Forget all of the pushed listeners.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function forgetPushed()
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->forgetPushed();
+        }
+        
+        /**
+         * Set the queue resolver implementation.
+         *
+         * @param callable $resolver
+         * @return \Illuminate\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function setQueueResolver($resolver)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->setQueueResolver($resolver);
+        }
+        
+        /**
+         * Assert if an event was dispatched based on a truth-test callback.
+         *
+         * @param string $event
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatched($event, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        $instance->assertDispatched($event, $callback);
+        }
+        
+        /**
+         * Assert if a event was dispatched a number of times.
+         *
+         * @param string $event
+         * @param int $times
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatchedTimes($event, $times = 1)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        $instance->assertDispatchedTimes($event, $times);
+        }
+        
+        /**
+         * Determine if an event was dispatched based on a truth-test callback.
+         *
+         * @param string $event
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotDispatched($event, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        $instance->assertNotDispatched($event, $callback);
+        }
+        
+        /**
+         * Get all of the events matching a truth-test callback.
+         *
+         * @param string $event
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function dispatched($event, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        return $instance->dispatched($event, $callback);
+        }
+        
+        /**
+         * Determine if the given event has been dispatched.
+         *
+         * @param string $event
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasDispatched($event)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        return $instance->hasDispatched($event);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Filesystem\Filesystem
+     */ 
+    class File {
+        
+        /**
+         * Determine if a file or directory exists.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->exists($path);
+        }
+        
+        /**
+         * Get the contents of a file.
+         *
+         * @param string $path
+         * @param bool $lock
+         * @return string 
+         * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+         * @static 
+         */ 
+        public static function get($path, $lock = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->get($path, $lock);
+        }
+        
+        /**
+         * Get contents of a file with shared access.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function sharedGet($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->sharedGet($path);
+        }
+        
+        /**
+         * Get the returned value of a file.
+         *
+         * @param string $path
+         * @return mixed 
+         * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+         * @static 
+         */ 
+        public static function getRequire($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->getRequire($path);
+        }
+        
+        /**
+         * Require the given file once.
+         *
+         * @param string $file
+         * @return mixed 
+         * @static 
+         */ 
+        public static function requireOnce($file)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->requireOnce($file);
+        }
+        
+        /**
+         * Get the MD5 hash of the file at the given path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function hash($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->hash($path);
+        }
+        
+        /**
+         * Write the contents of a file.
+         *
+         * @param string $path
+         * @param string $contents
+         * @param bool $lock
+         * @return int 
+         * @static 
+         */ 
+        public static function put($path, $contents, $lock = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->put($path, $contents, $lock);
+        }
+        
+        /**
+         * Prepend to a file.
+         *
+         * @param string $path
+         * @param string $data
+         * @return int 
+         * @static 
+         */ 
+        public static function prepend($path, $data)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->prepend($path, $data);
+        }
+        
+        /**
+         * Append to a file.
+         *
+         * @param string $path
+         * @param string $data
+         * @return int 
+         * @static 
+         */ 
+        public static function append($path, $data)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->append($path, $data);
+        }
+        
+        /**
+         * Get or set UNIX mode of a file or directory.
+         *
+         * @param string $path
+         * @param int $mode
+         * @return mixed 
+         * @static 
+         */ 
+        public static function chmod($path, $mode = null)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->chmod($path, $mode);
+        }
+        
+        /**
+         * Delete the file at a given path.
+         *
+         * @param string|array $paths
+         * @return bool 
+         * @static 
+         */ 
+        public static function delete($paths)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->delete($paths);
+        }
+        
+        /**
+         * Move a file to a new location.
+         *
+         * @param string $path
+         * @param string $target
+         * @return bool 
+         * @static 
+         */ 
+        public static function move($path, $target)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->move($path, $target);
+        }
+        
+        /**
+         * Copy a file to a new location.
+         *
+         * @param string $path
+         * @param string $target
+         * @return bool 
+         * @static 
+         */ 
+        public static function copy($path, $target)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->copy($path, $target);
+        }
+        
+        /**
+         * Create a hard link to the target file or directory.
+         *
+         * @param string $target
+         * @param string $link
+         * @return void 
+         * @static 
+         */ 
+        public static function link($target, $link)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        $instance->link($target, $link);
+        }
+        
+        /**
+         * Extract the file name from a file path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function name($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->name($path);
+        }
+        
+        /**
+         * Extract the trailing name component from a file path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function basename($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->basename($path);
+        }
+        
+        /**
+         * Extract the parent directory from a file path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function dirname($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->dirname($path);
+        }
+        
+        /**
+         * Extract the file extension from a file path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function extension($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->extension($path);
+        }
+        
+        /**
+         * Get the file type of a given file.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function type($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->type($path);
+        }
+        
+        /**
+         * Get the mime-type of a given file.
+         *
+         * @param string $path
+         * @return string|false 
+         * @static 
+         */ 
+        public static function mimeType($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->mimeType($path);
+        }
+        
+        /**
+         * Get the file size of a given file.
+         *
+         * @param string $path
+         * @return int 
+         * @static 
+         */ 
+        public static function size($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->size($path);
+        }
+        
+        /**
+         * Get the file's last modification time.
+         *
+         * @param string $path
+         * @return int 
+         * @static 
+         */ 
+        public static function lastModified($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->lastModified($path);
+        }
+        
+        /**
+         * Determine if the given path is a directory.
+         *
+         * @param string $directory
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDirectory($directory)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->isDirectory($directory);
+        }
+        
+        /**
+         * Determine if the given path is readable.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function isReadable($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->isReadable($path);
+        }
+        
+        /**
+         * Determine if the given path is writable.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function isWritable($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->isWritable($path);
+        }
+        
+        /**
+         * Determine if the given path is a file.
+         *
+         * @param string $file
+         * @return bool 
+         * @static 
+         */ 
+        public static function isFile($file)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->isFile($file);
+        }
+        
+        /**
+         * Find path names matching a given pattern.
+         *
+         * @param string $pattern
+         * @param int $flags
+         * @return array 
+         * @static 
+         */ 
+        public static function glob($pattern, $flags = 0)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->glob($pattern, $flags);
+        }
+        
+        /**
+         * Get an array of all files in a directory.
+         *
+         * @param string $directory
+         * @param bool $hidden
+         * @return \Symfony\Component\Finder\SplFileInfo[] 
+         * @static 
+         */ 
+        public static function files($directory, $hidden = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->files($directory, $hidden);
+        }
+        
+        /**
+         * Get all of the files from the given directory (recursive).
+         *
+         * @param string $directory
+         * @param bool $hidden
+         * @return \Symfony\Component\Finder\SplFileInfo[] 
+         * @static 
+         */ 
+        public static function allFiles($directory, $hidden = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->allFiles($directory, $hidden);
+        }
+        
+        /**
+         * Get all of the directories within a given directory.
+         *
+         * @param string $directory
+         * @return array 
+         * @static 
+         */ 
+        public static function directories($directory)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->directories($directory);
+        }
+        
+        /**
+         * Create a directory.
+         *
+         * @param string $path
+         * @param int $mode
+         * @param bool $recursive
+         * @param bool $force
+         * @return bool 
+         * @static 
+         */ 
+        public static function makeDirectory($path, $mode = 493, $recursive = false, $force = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->makeDirectory($path, $mode, $recursive, $force);
+        }
+        
+        /**
+         * Move a directory.
+         *
+         * @param string $from
+         * @param string $to
+         * @param bool $overwrite
+         * @return bool 
+         * @static 
+         */ 
+        public static function moveDirectory($from, $to, $overwrite = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->moveDirectory($from, $to, $overwrite);
+        }
+        
+        /**
+         * Copy a directory from one location to another.
+         *
+         * @param string $directory
+         * @param string $destination
+         * @param int $options
+         * @return bool 
+         * @static 
+         */ 
+        public static function copyDirectory($directory, $destination, $options = null)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->copyDirectory($directory, $destination, $options);
+        }
+        
+        /**
+         * Recursively delete a directory.
+         * 
+         * The directory itself may be optionally preserved.
+         *
+         * @param string $directory
+         * @param bool $preserve
+         * @return bool 
+         * @static 
+         */ 
+        public static function deleteDirectory($directory, $preserve = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->deleteDirectory($directory, $preserve);
+        }
+        
+        /**
+         * Remove all of the directories within a given directory.
+         *
+         * @param string $directory
+         * @return bool 
+         * @static 
+         */ 
+        public static function deleteDirectories($directory)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->deleteDirectories($directory);
+        }
+        
+        /**
+         * Empty the specified directory of all files and folders.
+         *
+         * @param string $directory
+         * @return bool 
+         * @static 
+         */ 
+        public static function cleanDirectory($directory)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->cleanDirectory($directory);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Filesystem\Filesystem::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Filesystem\Filesystem::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Filesystem\Filesystem::hasMacro($name);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Auth\Access\Gate
+     */ 
+    class Gate {
+        
+        /**
+         * Determine if a given ability has been defined.
+         *
+         * @param string|array $ability
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($ability)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->has($ability);
+        }
+        
+        /**
+         * Define a new ability.
+         *
+         * @param string $ability
+         * @param callable|string $callback
+         * @return \Illuminate\Auth\Access\Gate 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function define($ability, $callback)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->define($ability, $callback);
+        }
+        
+        /**
+         * Define abilities for a resource.
+         *
+         * @param string $name
+         * @param string $class
+         * @param array|null $abilities
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function resource($name, $class, $abilities = null)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->resource($name, $class, $abilities);
+        }
+        
+        /**
+         * Define a policy class for a given class type.
+         *
+         * @param string $class
+         * @param string $policy
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function policy($class, $policy)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->policy($class, $policy);
+        }
+        
+        /**
+         * Register a callback to run before all Gate checks.
+         *
+         * @param callable $callback
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function before($callback)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->before($callback);
+        }
+        
+        /**
+         * Register a callback to run after all Gate checks.
+         *
+         * @param callable $callback
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function after($callback)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->after($callback);
+        }
+        
+        /**
+         * Determine if the given ability should be granted for the current user.
+         *
+         * @param string $ability
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function allows($ability, $arguments = array())
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->allows($ability, $arguments);
+        }
+        
+        /**
+         * Determine if the given ability should be denied for the current user.
+         *
+         * @param string $ability
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function denies($ability, $arguments = array())
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->denies($ability, $arguments);
+        }
+        
+        /**
+         * Determine if all of the given abilities should be granted for the current user.
+         *
+         * @param \Illuminate\Auth\Access\iterable|string $abilities
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function check($abilities, $arguments = array())
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->check($abilities, $arguments);
+        }
+        
+        /**
+         * Determine if any one of the given abilities should be granted for the current user.
+         *
+         * @param \Illuminate\Auth\Access\iterable|string $abilities
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function any($abilities, $arguments = array())
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->any($abilities, $arguments);
+        }
+        
+        /**
+         * Determine if the given ability should be granted for the current user.
+         *
+         * @param string $ability
+         * @param array|mixed $arguments
+         * @return \Illuminate\Auth\Access\Response 
+         * @throws \Illuminate\Auth\Access\AuthorizationException
+         * @static 
+         */ 
+        public static function authorize($ability, $arguments = array())
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->authorize($ability, $arguments);
+        }
+        
+        /**
+         * Get a policy instance for a given class.
+         *
+         * @param object|string $class
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getPolicyFor($class)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->getPolicyFor($class);
+        }
+        
+        /**
+         * Build a policy class instance of the given type.
+         *
+         * @param object|string $class
+         * @return mixed 
+         * @static 
+         */ 
+        public static function resolvePolicy($class)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->resolvePolicy($class);
+        }
+        
+        /**
+         * Get a gate instance for the given user.
+         *
+         * @param \Illuminate\Contracts\Auth\Authenticatable|mixed $user
+         * @return static 
+         * @static 
+         */ 
+        public static function forUser($user)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->forUser($user);
+        }
+        
+        /**
+         * Get all of the defined abilities.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function abilities()
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->abilities();
+        }
+        
+        /**
+         * Get all of the defined policies.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function policies()
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->policies();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Hashing\HashManager
+     */ 
+    class Hash {
+        
+        /**
+         * Create an instance of the Bcrypt hash Driver.
+         *
+         * @return \Illuminate\Hashing\BcryptHasher 
+         * @static 
+         */ 
+        public static function createBcryptDriver()
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->createBcryptDriver();
+        }
+        
+        /**
+         * Create an instance of the Argon2 hash Driver.
+         *
+         * @return \Illuminate\Hashing\ArgonHasher 
+         * @static 
+         */ 
+        public static function createArgonDriver()
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->createArgonDriver();
+        }
+        
+        /**
+         * Get information about the given hashed value.
+         *
+         * @param string $hashedValue
+         * @return array 
+         * @static 
+         */ 
+        public static function info($hashedValue)
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->info($hashedValue);
+        }
+        
+        /**
+         * Hash the given value.
+         *
+         * @param string $value
+         * @param array $options
+         * @return string 
+         * @static 
+         */ 
+        public static function make($value, $options = array())
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->make($value, $options);
+        }
+        
+        /**
+         * Check the given plain value against a hash.
+         *
+         * @param string $value
+         * @param string $hashedValue
+         * @param array $options
+         * @return bool 
+         * @static 
+         */ 
+        public static function check($value, $hashedValue, $options = array())
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->check($value, $hashedValue, $options);
+        }
+        
+        /**
+         * Check if the given hash has been hashed using the given options.
+         *
+         * @param string $hashedValue
+         * @param array $options
+         * @return bool 
+         * @static 
+         */ 
+        public static function needsRehash($hashedValue, $options = array())
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->needsRehash($hashedValue, $options);
+        }
+        
+        /**
+         * Get the default driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Get a driver instance.
+         *
+         * @param string $driver
+         * @return mixed 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->driver($driver);
+        }
+        
+        /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Hashing\HashManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+        
+        /**
+         * Get all of the created "drivers".
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDrivers()
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->getDrivers();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Translation\Translator
+     */ 
+    class Lang {
+        
+        /**
+         * Determine if a translation exists for a given locale.
+         *
+         * @param string $key
+         * @param string|null $locale
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasForLocale($key, $locale = null)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->hasForLocale($key, $locale);
+        }
+        
+        /**
+         * Determine if a translation exists.
+         *
+         * @param string $key
+         * @param string|null $locale
+         * @param bool $fallback
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key, $locale = null, $fallback = true)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->has($key, $locale, $fallback);
+        }
+        
+        /**
+         * Get the translation for a given key.
+         *
+         * @param string $key
+         * @param array $replace
+         * @param string $locale
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function trans($key, $replace = array(), $locale = null)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->trans($key, $replace, $locale);
+        }
+        
+        /**
+         * Get the translation for the given key.
+         *
+         * @param string $key
+         * @param array $replace
+         * @param string|null $locale
+         * @param bool $fallback
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function get($key, $replace = array(), $locale = null, $fallback = true)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->get($key, $replace, $locale, $fallback);
+        }
+        
+        /**
+         * Get the translation for a given key from the JSON translation files.
+         *
+         * @param string $key
+         * @param array $replace
+         * @param string $locale
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function getFromJson($key, $replace = array(), $locale = null)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getFromJson($key, $replace, $locale);
+        }
+        
+        /**
+         * Get a translation according to an integer value.
+         *
+         * @param string $key
+         * @param int|array|\Countable $number
+         * @param array $replace
+         * @param string $locale
+         * @return string 
+         * @static 
+         */ 
+        public static function transChoice($key, $number, $replace = array(), $locale = null)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->transChoice($key, $number, $replace, $locale);
+        }
+        
+        /**
+         * Get a translation according to an integer value.
+         *
+         * @param string $key
+         * @param int|array|\Countable $number
+         * @param array $replace
+         * @param string $locale
+         * @return string 
+         * @static 
+         */ 
+        public static function choice($key, $number, $replace = array(), $locale = null)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->choice($key, $number, $replace, $locale);
+        }
+        
+        /**
+         * Add translation lines to the given locale.
+         *
+         * @param array $lines
+         * @param string $locale
+         * @param string $namespace
+         * @return void 
+         * @static 
+         */ 
+        public static function addLines($lines, $locale, $namespace = '*')
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->addLines($lines, $locale, $namespace);
+        }
+        
+        /**
+         * Load the specified language group.
+         *
+         * @param string $namespace
+         * @param string $group
+         * @param string $locale
+         * @return void 
+         * @static 
+         */ 
+        public static function load($namespace, $group, $locale)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->load($namespace, $group, $locale);
+        }
+        
+        /**
+         * Add a new namespace to the loader.
+         *
+         * @param string $namespace
+         * @param string $hint
+         * @return void 
+         * @static 
+         */ 
+        public static function addNamespace($namespace, $hint)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->addNamespace($namespace, $hint);
+        }
+        
+        /**
+         * Add a new JSON path to the loader.
+         *
+         * @param string $path
+         * @return void 
+         * @static 
+         */ 
+        public static function addJsonPath($path)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->addJsonPath($path);
+        }
+        
+        /**
+         * Parse a key into namespace, group, and item.
+         *
+         * @param string $key
+         * @return array 
+         * @static 
+         */ 
+        public static function parseKey($key)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->parseKey($key);
+        }
+        
+        /**
+         * Get the message selector instance.
+         *
+         * @return \Illuminate\Translation\MessageSelector 
+         * @static 
+         */ 
+        public static function getSelector()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getSelector();
+        }
+        
+        /**
+         * Set the message selector instance.
+         *
+         * @param \Illuminate\Translation\MessageSelector $selector
+         * @return void 
+         * @static 
+         */ 
+        public static function setSelector($selector)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setSelector($selector);
+        }
+        
+        /**
+         * Get the language line loader implementation.
+         *
+         * @return \Illuminate\Contracts\Translation\Loader 
+         * @static 
+         */ 
+        public static function getLoader()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getLoader();
+        }
+        
+        /**
+         * Get the default locale being used.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function locale()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->locale();
+        }
+        
+        /**
+         * Get the default locale being used.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getLocale()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getLocale();
+        }
+        
+        /**
+         * Set the default locale.
+         *
+         * @param string $locale
+         * @return void 
+         * @static 
+         */ 
+        public static function setLocale($locale)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setLocale($locale);
+        }
+        
+        /**
+         * Get the fallback locale being used.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getFallback()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getFallback();
+        }
+        
+        /**
+         * Set the fallback locale being used.
+         *
+         * @param string $fallback
+         * @return void 
+         * @static 
+         */ 
+        public static function setFallback($fallback)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setFallback($fallback);
+        }
+        
+        /**
+         * Set the loaded translation groups.
+         *
+         * @param array $loaded
+         * @return void 
+         * @static 
+         */ 
+        public static function setLoaded($loaded)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setLoaded($loaded);
+        }
+        
+        /**
+         * Set the parsed value of a key.
+         *
+         * @param string $key
+         * @param array $parsed
+         * @return void 
+         * @static 
+         */ 
+        public static function setParsedKey($key, $parsed)
+        {
+            //Method inherited from \Illuminate\Support\NamespacedItemResolver            
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setParsedKey($key, $parsed);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Translation\Translator::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Translation\Translator::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Translation\Translator::hasMacro($name);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Log\Logger
+     */ 
+    class Log {
+        
+        /**
+         * Adds a log record at the DEBUG level.
+         *
+         * @param string $message The log message
+         * @param array $context The log context
+         * @return bool Whether the record has been processed
+         * @static 
+         */ 
+        public static function debug($message, $context = array())
+        {
+                        /** @var \Monolog\Logger $instance */
+                        return $instance->addDebug($message, $context);
+        }
+        
+        /**
+         * Adds a log record at the INFO level.
+         *
+         * @param string $message The log message
+         * @param array $context The log context
+         * @return bool Whether the record has been processed
+         * @static 
+         */ 
+        public static function info($message, $context = array())
+        {
+                        /** @var \Monolog\Logger $instance */
+                        return $instance->addInfo($message, $context);
+        }
+        
+        /**
+         * Adds a log record at the NOTICE level.
+         *
+         * @param string $message The log message
+         * @param array $context The log context
+         * @return bool Whether the record has been processed
+         * @static 
+         */ 
+        public static function notice($message, $context = array())
+        {
+                        /** @var \Monolog\Logger $instance */
+                        return $instance->addNotice($message, $context);
+        }
+        
+        /**
+         * Adds a log record at the WARNING level.
+         *
+         * @param string $message The log message
+         * @param array $context The log context
+         * @return bool Whether the record has been processed
+         * @static 
+         */ 
+        public static function warning($message, $context = array())
+        {
+                        /** @var \Monolog\Logger $instance */
+                        return $instance->addWarning($message, $context);
+        }
+        
+        /**
+         * Adds a log record at the ERROR level.
+         *
+         * @param string $message The log message
+         * @param array $context The log context
+         * @return bool Whether the record has been processed
+         * @static 
+         */ 
+        public static function error($message, $context = array())
+        {
+                        /** @var \Monolog\Logger $instance */
+                        return $instance->addError($message, $context);
+        }
+        
+        /**
+         * Adds a log record at the CRITICAL level.
+         *
+         * @param string $message The log message
+         * @param array $context The log context
+         * @return bool Whether the record has been processed
+         * @static 
+         */ 
+        public static function critical($message, $context = array())
+        {
+                        /** @var \Monolog\Logger $instance */
+                        return $instance->addCritical($message, $context);
+        }
+        
+        /**
+         * Adds a log record at the ALERT level.
+         *
+         * @param string $message The log message
+         * @param array $context The log context
+         * @return bool Whether the record has been processed
+         * @static 
+         */ 
+        public static function alert($message, $context = array())
+        {
+                        /** @var \Monolog\Logger $instance */
+                        return $instance->addAlert($message, $context);
+        }
+        
+        /**
+         * Adds a log record at the EMERGENCY level.
+         *
+         * @param string $message The log message
+         * @param array $context The log context
+         * @return bool Whether the record has been processed
+         * @static 
+         */ 
+        public static function emergency($message, $context = array())
+        {
+                        /** @var \Monolog\Logger $instance */
+                        return $instance->addEmergency($message, $context);
+        }
+        
+        /**
+         * Create a new, on-demand aggregate logger instance.
+         *
+         * @param array $channels
+         * @param string|null $channel
+         * @return \Psr\Log\LoggerInterface 
+         * @static 
+         */ 
+        public static function stack($channels, $channel = null)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->stack($channels, $channel);
+        }
+        
+        /**
+         * Get a log channel instance.
+         *
+         * @param string|null $channel
+         * @return mixed 
+         * @static 
+         */ 
+        public static function channel($channel = null)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->channel($channel);
+        }
+        
+        /**
+         * Get a log driver instance.
+         *
+         * @param string|null $driver
+         * @return mixed 
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->driver($driver);
+        }
+        
+        /**
+         * Get the default log driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Set the default log driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+        
+        /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Log\LogManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+        
+        /**
+         * Logs with an arbitrary level.
+         *
+         * @param mixed $level
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function log($level, $message, $context = array())
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->log($level, $message, $context);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Mail\Mailer
+     */ 
+    class Mail {
+        
+        /**
+         * Set the global from address and name.
+         *
+         * @param string $address
+         * @param string|null $name
+         * @return void 
+         * @static 
+         */ 
+        public static function alwaysFrom($address, $name = null)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        $instance->alwaysFrom($address, $name);
+        }
+        
+        /**
+         * Set the global reply-to address and name.
+         *
+         * @param string $address
+         * @param string|null $name
+         * @return void 
+         * @static 
+         */ 
+        public static function alwaysReplyTo($address, $name = null)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        $instance->alwaysReplyTo($address, $name);
+        }
+        
+        /**
+         * Set the global to address and name.
+         *
+         * @param string $address
+         * @param string|null $name
+         * @return void 
+         * @static 
+         */ 
+        public static function alwaysTo($address, $name = null)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        $instance->alwaysTo($address, $name);
+        }
+        
+        /**
+         * Begin the process of mailing a mailable class instance.
+         *
+         * @param mixed $users
+         * @return \Illuminate\Mail\PendingMail 
+         * @static 
+         */ 
+        public static function to($users)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->to($users);
+        }
+        
+        /**
+         * Begin the process of mailing a mailable class instance.
+         *
+         * @param mixed $users
+         * @return \Illuminate\Mail\PendingMail 
+         * @static 
+         */ 
+        public static function bcc($users)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->bcc($users);
+        }
+        
+        /**
+         * Send a new message with only an HTML part.
+         *
+         * @param string $html
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function html($html, $callback)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        $instance->html($html, $callback);
+        }
+        
+        /**
+         * Send a new message when only a raw text part.
+         *
+         * @param string $text
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function raw($text, $callback)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        $instance->raw($text, $callback);
+        }
+        
+        /**
+         * Send a new message when only a plain part.
+         *
+         * @param string $view
+         * @param array $data
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function plain($view, $data, $callback)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        $instance->plain($view, $data, $callback);
+        }
+        
+        /**
+         * Render the given message as a view.
+         *
+         * @param string|array $view
+         * @param array $data
+         * @return string 
+         * @static 
+         */ 
+        public static function render($view, $data = array())
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->render($view, $data);
+        }
+        
+        /**
+         * Send a new message using a view.
+         *
+         * @param string|array|\Illuminate\Mail\MailableContract $view
+         * @param array $data
+         * @param \Closure|string $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function send($view, $data = array(), $callback = null)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        $instance->send($view, $data, $callback);
+        }
+        
+        /**
+         * Queue a new e-mail message for sending.
+         *
+         * @param string|array|\Illuminate\Mail\MailableContract $view
+         * @param string|null $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function queue($view, $queue = null)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->queue($view, $queue);
+        }
+        
+        /**
+         * Queue a new e-mail message for sending on the given queue.
+         *
+         * @param string $queue
+         * @param string|array $view
+         * @return mixed 
+         * @static 
+         */ 
+        public static function onQueue($queue, $view)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->onQueue($queue, $view);
+        }
+        
+        /**
+         * Queue a new e-mail message for sending on the given queue.
+         * 
+         * This method didn't match rest of framework's "onQueue" phrasing. Added "onQueue".
+         *
+         * @param string $queue
+         * @param string|array $view
+         * @return mixed 
+         * @static 
+         */ 
+        public static function queueOn($queue, $view)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->queueOn($queue, $view);
+        }
+        
+        /**
+         * Queue a new e-mail message for sending after (n) seconds.
+         *
+         * @param \DateTimeInterface|\DateInterval|int $delay
+         * @param string|array|\Illuminate\Mail\MailableContract $view
+         * @param string|null $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function later($delay, $view, $queue = null)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->later($delay, $view, $queue);
+        }
+        
+        /**
+         * Queue a new e-mail message for sending after (n) seconds on the given queue.
+         *
+         * @param string $queue
+         * @param \DateTimeInterface|\DateInterval|int $delay
+         * @param string|array $view
+         * @return mixed 
+         * @static 
+         */ 
+        public static function laterOn($queue, $delay, $view)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->laterOn($queue, $delay, $view);
+        }
+        
+        /**
+         * Get the view factory instance.
+         *
+         * @return \Illuminate\Contracts\View\Factory 
+         * @static 
+         */ 
+        public static function getViewFactory()
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->getViewFactory();
+        }
+        
+        /**
+         * Get the Swift Mailer instance.
+         *
+         * @return \Swift_Mailer 
+         * @static 
+         */ 
+        public static function getSwiftMailer()
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->getSwiftMailer();
+        }
+        
+        /**
+         * Get the array of failed recipients.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function failures()
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->failures();
+        }
+        
+        /**
+         * Set the Swift Mailer instance.
+         *
+         * @param \Swift_Mailer $swift
+         * @return void 
+         * @static 
+         */ 
+        public static function setSwiftMailer($swift)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        $instance->setSwiftMailer($swift);
+        }
+        
+        /**
+         * Set the queue manager instance.
+         *
+         * @param \Illuminate\Contracts\Queue\Factory $queue
+         * @return \Illuminate\Mail\Mailer 
+         * @static 
+         */ 
+        public static function setQueue($queue)
+        {
+                        /** @var \Illuminate\Mail\Mailer $instance */
+                        return $instance->setQueue($queue);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Mail\Mailer::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Mail\Mailer::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Mail\Mailer::hasMacro($name);
+        }
+        
+        /**
+         * Assert if a mailable was sent based on a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertSent($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertSent($mailable, $callback);
+        }
+        
+        /**
+         * Determine if a mailable was not sent based on a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotSent($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertNotSent($mailable, $callback);
+        }
+        
+        /**
+         * Assert that no mailables were sent.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingSent()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertNothingSent();
+        }
+        
+        /**
+         * Assert if a mailable was queued based on a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertQueued($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertQueued($mailable, $callback);
+        }
+        
+        /**
+         * Determine if a mailable was not queued based on a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotQueued($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertNotQueued($mailable, $callback);
+        }
+        
+        /**
+         * Assert that no mailables were queued.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingQueued()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertNothingQueued();
+        }
+        
+        /**
+         * Get all of the mailables matching a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function sent($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->sent($mailable, $callback);
+        }
+        
+        /**
+         * Determine if the given mailable has been sent.
+         *
+         * @param string $mailable
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasSent($mailable)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->hasSent($mailable);
+        }
+        
+        /**
+         * Get all of the queued mailables matching a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function queued($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->queued($mailable, $callback);
+        }
+        
+        /**
+         * Determine if the given mailable has been queued.
+         *
+         * @param string $mailable
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasQueued($mailable)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->hasQueued($mailable);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Notifications\ChannelManager
+     */ 
+    class Notification {
+        
+        /**
+         * Send the given notification to the given notifiable entities.
+         *
+         * @param \Illuminate\Support\Collection|array|mixed $notifiables
+         * @param mixed $notification
+         * @return void 
+         * @static 
+         */ 
+        public static function send($notifiables, $notification)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        $instance->send($notifiables, $notification);
+        }
+        
+        /**
+         * Send the given notification immediately.
+         *
+         * @param \Illuminate\Support\Collection|array|mixed $notifiables
+         * @param mixed $notification
+         * @param array|null $channels
+         * @return void 
+         * @static 
+         */ 
+        public static function sendNow($notifiables, $notification, $channels = null)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        $instance->sendNow($notifiables, $notification, $channels);
+        }
+        
+        /**
+         * Get a channel instance.
+         *
+         * @param string|null $name
+         * @return mixed 
+         * @static 
+         */ 
+        public static function channel($name = null)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->channel($name);
+        }
+        
+        /**
+         * Get the default channel driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Get the default channel driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function deliversVia()
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->deliversVia();
+        }
+        
+        /**
+         * Set the default channel driver name.
+         *
+         * @param string $channel
+         * @return void 
+         * @static 
+         */ 
+        public static function deliverVia($channel)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        $instance->deliverVia($channel);
+        }
+        
+        /**
+         * Get a driver instance.
+         *
+         * @param string $driver
+         * @return mixed 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->driver($driver);
+        }
+        
+        /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Notifications\ChannelManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+        
+        /**
+         * Get all of the created "drivers".
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDrivers()
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->getDrivers();
+        }
+        
+        /**
+         * Assert if a notification was sent based on a truth-test callback.
+         *
+         * @param mixed $notifiable
+         * @param string $notification
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertSentTo($notifiable, $notification, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertSentTo($notifiable, $notification, $callback);
+        }
+        
+        /**
+         * Assert if a notification was sent a number of times.
+         *
+         * @param mixed $notifiable
+         * @param string $notification
+         * @param int $times
+         * @return void 
+         * @static 
+         */ 
+        public static function assertSentToTimes($notifiable, $notification, $times = 1)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertSentToTimes($notifiable, $notification, $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 
+         * @static 
+         */ 
+        public static function assertNotSentTo($notifiable, $notification, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertNotSentTo($notifiable, $notification, $callback);
+        }
+        
+        /**
+         * Assert that no notifications were sent.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingSent()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertNothingSent();
+        }
+        
+        /**
+         * Assert the total amount of times a notification was sent.
+         *
+         * @param int $expectedCount
+         * @param string $notification
+         * @return void 
+         * @static 
+         */ 
+        public static function assertTimesSent($expectedCount, $notification)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertTimesSent($expectedCount, $notification);
+        }
+        
+        /**
+         * Get all of the notifications matching a truth-test callback.
+         *
+         * @param mixed $notifiable
+         * @param string $notification
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function sent($notifiable, $notification, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        return $instance->sent($notifiable, $notification, $callback);
+        }
+        
+        /**
+         * Determine if there are more notifications left to inspect.
+         *
+         * @param mixed $notifiable
+         * @param string $notification
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasSent($notifiable, $notification)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        return $instance->hasSent($notifiable, $notification);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @method static string sendResetLink(array $credentials)
+     * @method static mixed reset(array $credentials, \Closure $callback)
+     * @method static void validator(\Closure $callback)
+     * @method static bool validateNewPassword(array $credentials)
+     * @see \Illuminate\Auth\Passwords\PasswordBroker
+     */ 
+    class Password {
+        
+        /**
+         * Attempt to get the broker from the local cache.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Contracts\Auth\PasswordBroker 
+         * @static 
+         */ 
+        public static function broker($name = null)
+        {
+                        /** @var \Illuminate\Auth\Passwords\PasswordBrokerManager $instance */
+                        return $instance->broker($name);
+        }
+        
+        /**
+         * Get the default password broker name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Auth\Passwords\PasswordBrokerManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Set the default password broker name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Auth\Passwords\PasswordBrokerManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Queue\QueueManager
+     * @see \Illuminate\Queue\Queue
+     */ 
+    class Queue {
+        
+        /**
+         * Register an event listener for the before job event.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function before($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->before($callback);
+        }
+        
+        /**
+         * Register an event listener for the after job event.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function after($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->after($callback);
+        }
+        
+        /**
+         * Register an event listener for the exception occurred job event.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function exceptionOccurred($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->exceptionOccurred($callback);
+        }
+        
+        /**
+         * Register an event listener for the daemon queue loop.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function looping($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->looping($callback);
+        }
+        
+        /**
+         * Register an event listener for the failed job event.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function failing($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->failing($callback);
+        }
+        
+        /**
+         * Register an event listener for the daemon queue stopping.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function stopping($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->stopping($callback);
+        }
+        
+        /**
+         * Determine if the driver is connected.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function connected($name = null)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->connected($name);
+        }
+        
+        /**
+         * Resolve a queue connection instance.
+         *
+         * @param string $name
+         * @return \Illuminate\Contracts\Queue\Queue 
+         * @static 
+         */ 
+        public static function connection($name = null)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->connection($name);
+        }
+        
+        /**
+         * Add a queue connection resolver.
+         *
+         * @param string $driver
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function extend($driver, $resolver)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->extend($driver, $resolver);
+        }
+        
+        /**
+         * Add a queue connection resolver.
+         *
+         * @param string $driver
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function addConnector($driver, $resolver)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->addConnector($driver, $resolver);
+        }
+        
+        /**
+         * Get the name of the default queue connection.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Set the name of the default queue connection.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+        
+        /**
+         * Get the full name for the given connection.
+         *
+         * @param string $connection
+         * @return string 
+         * @static 
+         */ 
+        public static function getName($connection = null)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->getName($connection);
+        }
+        
+        /**
+         * Determine if the application is in maintenance mode.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDownForMaintenance()
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->isDownForMaintenance();
+        }
+        
+        /**
+         * Assert if a job was pushed based on a truth-test callback.
+         *
+         * @param string $job
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertPushed($job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertPushed($job, $callback);
+        }
+        
+        /**
+         * Assert if a job was pushed based on a truth-test callback.
+         *
+         * @param string $queue
+         * @param string $job
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertPushedOn($queue, $job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertPushedOn($queue, $job, $callback);
+        }
+        
+        /**
+         * Assert if a job was pushed with chained jobs based on a truth-test callback.
+         *
+         * @param string $job
+         * @param array $expectedChain
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertPushedWithChain($job, $expectedChain = array(), $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertPushedWithChain($job, $expectedChain, $callback);
+        }
+        
+        /**
+         * Determine if a job was pushed based on a truth-test callback.
+         *
+         * @param string $job
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotPushed($job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertNotPushed($job, $callback);
+        }
+        
+        /**
+         * Assert that no jobs were pushed.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingPushed()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertNothingPushed();
+        }
+        
+        /**
+         * Get all of the jobs matching a truth-test callback.
+         *
+         * @param string $job
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function pushed($job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pushed($job, $callback);
+        }
+        
+        /**
+         * Determine if there are any stored jobs for a given class.
+         *
+         * @param string $job
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasPushed($job)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->hasPushed($job);
+        }
+        
+        /**
+         * Get the size of the queue.
+         *
+         * @param string $queue
+         * @return int 
+         * @static 
+         */ 
+        public static function size($queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->size($queue);
+        }
+        
+        /**
+         * Push a new job onto the queue.
+         *
+         * @param string $job
+         * @param mixed $data
+         * @param string $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function push($job, $data = '', $queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->push($job, $data, $queue);
+        }
+        
+        /**
+         * Push a raw payload onto the queue.
+         *
+         * @param string $payload
+         * @param string $queue
+         * @param array $options
+         * @return mixed 
+         * @static 
+         */ 
+        public static function pushRaw($payload, $queue = null, $options = array())
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pushRaw($payload, $queue, $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 
+         * @static 
+         */ 
+        public static function later($delay, $job, $data = '', $queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->later($delay, $job, $data, $queue);
+        }
+        
+        /**
+         * Push a new job onto the queue.
+         *
+         * @param string $queue
+         * @param string $job
+         * @param mixed $data
+         * @return mixed 
+         * @static 
+         */ 
+        public static function pushOn($queue, $job, $data = '')
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pushOn($queue, $job, $data);
+        }
+        
+        /**
+         * 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 
+         * @static 
+         */ 
+        public static function laterOn($queue, $delay, $job, $data = '')
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->laterOn($queue, $delay, $job, $data);
+        }
+        
+        /**
+         * Pop the next job off of the queue.
+         *
+         * @param string $queue
+         * @return \Illuminate\Contracts\Queue\Job|null 
+         * @static 
+         */ 
+        public static function pop($queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pop($queue);
+        }
+        
+        /**
+         * Push an array of jobs onto the queue.
+         *
+         * @param array $jobs
+         * @param mixed $data
+         * @param string $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function bulk($jobs, $data = '', $queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->bulk($jobs, $data, $queue);
+        }
+        
+        /**
+         * Get the connection name for the queue.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getConnectionName()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->getConnectionName();
+        }
+        
+        /**
+         * Set the connection name for the queue.
+         *
+         * @param string $name
+         * @return \Illuminate\Support\Testing\Fakes\QueueFake 
+         * @static 
+         */ 
+        public static function setConnectionName($name)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->setConnectionName($name);
+        }
+        
+        /**
+         * Release a reserved job back onto the queue.
+         *
+         * @param string $queue
+         * @param \Illuminate\Queue\Jobs\DatabaseJobRecord $job
+         * @param int $delay
+         * @return mixed 
+         * @static 
+         */ 
+        public static function release($queue, $job, $delay)
+        {
+                        /** @var \Illuminate\Queue\DatabaseQueue $instance */
+                        return $instance->release($queue, $job, $delay);
+        }
+        
+        /**
+         * Delete a reserved job from the queue.
+         *
+         * @param string $queue
+         * @param string $id
+         * @return void 
+         * @throws \Exception|\Throwable
+         * @static 
+         */ 
+        public static function deleteReserved($queue, $id)
+        {
+                        /** @var \Illuminate\Queue\DatabaseQueue $instance */
+                        $instance->deleteReserved($queue, $id);
+        }
+        
+        /**
+         * Get the queue or return the default.
+         *
+         * @param string|null $queue
+         * @return string 
+         * @static 
+         */ 
+        public static function getQueue($queue)
+        {
+                        /** @var \Illuminate\Queue\DatabaseQueue $instance */
+                        return $instance->getQueue($queue);
+        }
+        
+        /**
+         * Get the underlying database instance.
+         *
+         * @return \Illuminate\Database\Connection 
+         * @static 
+         */ 
+        public static function getDatabase()
+        {
+                        /** @var \Illuminate\Queue\DatabaseQueue $instance */
+                        return $instance->getDatabase();
+        }
+        
+        /**
+         * Get the expiration timestamp for an object-based queue handler.
+         *
+         * @param mixed $job
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getJobExpiration($job)
+        {
+            //Method inherited from \Illuminate\Queue\Queue            
+                        /** @var \Illuminate\Queue\DatabaseQueue $instance */
+                        return $instance->getJobExpiration($job);
+        }
+        
+        /**
+         * Set the IoC container instance.
+         *
+         * @param \Illuminate\Container\Container $container
+         * @return void 
+         * @static 
+         */ 
+        public static function setContainer($container)
+        {
+            //Method inherited from \Illuminate\Queue\Queue            
+                        /** @var \Illuminate\Queue\DatabaseQueue $instance */
+                        $instance->setContainer($container);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Routing\Redirector
+     */ 
+    class Redirect {
+        
+        /**
+         * Create a new redirect response to the "home" route.
+         *
+         * @param int $status
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function home($status = 302)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->home($status);
+        }
+        
+        /**
+         * Create a new redirect response to the previous location.
+         *
+         * @param int $status
+         * @param array $headers
+         * @param mixed $fallback
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function back($status = 302, $headers = array(), $fallback = false)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->back($status, $headers, $fallback);
+        }
+        
+        /**
+         * Create a new redirect response to the current URI.
+         *
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function refresh($status = 302, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->refresh($status, $headers);
+        }
+        
+        /**
+         * Create a new redirect response, while putting the current URL in the session.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @param bool $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function guest($path, $status = 302, $headers = array(), $secure = null)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->guest($path, $status, $headers, $secure);
+        }
+        
+        /**
+         * Create a new redirect response to the previously intended location.
+         *
+         * @param string $default
+         * @param int $status
+         * @param array $headers
+         * @param bool $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function intended($default = '/', $status = 302, $headers = array(), $secure = null)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->intended($default, $status, $headers, $secure);
+        }
+        
+        /**
+         * Create a new redirect response to the given path.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @param bool $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function to($path, $status = 302, $headers = array(), $secure = null)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->to($path, $status, $headers, $secure);
+        }
+        
+        /**
+         * Create a new redirect response to an external URL (no validation).
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function away($path, $status = 302, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->away($path, $status, $headers);
+        }
+        
+        /**
+         * Create a new redirect response to the given HTTPS path.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function secure($path, $status = 302, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->secure($path, $status, $headers);
+        }
+        
+        /**
+         * Create a new redirect response to a named route.
+         *
+         * @param string $route
+         * @param mixed $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function route($route, $parameters = array(), $status = 302, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->route($route, $parameters, $status, $headers);
+        }
+        
+        /**
+         * Create a new redirect response to a controller action.
+         *
+         * @param string $action
+         * @param mixed $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function action($action, $parameters = array(), $status = 302, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->action($action, $parameters, $status, $headers);
+        }
+        
+        /**
+         * Get the URL generator instance.
+         *
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function getUrlGenerator()
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->getUrlGenerator();
+        }
+        
+        /**
+         * Set the active session store.
+         *
+         * @param \Illuminate\Session\Store $session
+         * @return void 
+         * @static 
+         */ 
+        public static function setSession($session)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        $instance->setSession($session);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Routing\Redirector::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Routing\Redirector::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Routing\Redirector::hasMacro($name);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Redis\RedisManager
+     * @see \Illuminate\Contracts\Redis\Factory
+     */ 
+    class Redis {
+        
+        /**
+         * Get a Redis connection by name.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Redis\Connections\Connection 
+         * @static 
+         */ 
+        public static function connection($name = null)
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        return $instance->connection($name);
+        }
+        
+        /**
+         * Resolve the given connection by name.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Redis\Connections\Connection 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function resolve($name = null)
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        return $instance->resolve($name);
+        }
+        
+        /**
+         * Return all of the created connections.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function connections()
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        return $instance->connections();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Http\Request
+     */ 
+    class Request {
+        
+        /**
+         * Create a new Illuminate HTTP request from server variables.
+         *
+         * @return static 
+         * @static 
+         */ 
+        public static function capture()
+        {
+                        return \Illuminate\Http\Request::capture();
+        }
+        
+        /**
+         * Return the Request instance.
+         *
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function instance()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->instance();
+        }
+        
+        /**
+         * Get the request method.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function method()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->method();
+        }
+        
+        /**
+         * Get the root URL for the application.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function root()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->root();
+        }
+        
+        /**
+         * Get the URL (no query string) for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function url()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->url();
+        }
+        
+        /**
+         * Get the full URL for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function fullUrl()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->fullUrl();
+        }
+        
+        /**
+         * Get the full URL for the request with the added query string parameters.
+         *
+         * @param array $query
+         * @return string 
+         * @static 
+         */ 
+        public static function fullUrlWithQuery($query)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->fullUrlWithQuery($query);
+        }
+        
+        /**
+         * Get the current path info for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function path()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->path();
+        }
+        
+        /**
+         * Get the current decoded path info for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function decodedPath()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->decodedPath();
+        }
+        
+        /**
+         * Get a segment from the URI (1 based index).
+         *
+         * @param int $index
+         * @param string|null $default
+         * @return string|null 
+         * @static 
+         */ 
+        public static function segment($index, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->segment($index, $default);
+        }
+        
+        /**
+         * Get all of the segments for the request path.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function segments()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->segments();
+        }
+        
+        /**
+         * Determine if the current request URI matches a pattern.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function is($patterns = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->is($patterns);
+        }
+        
+        /**
+         * Determine if the route name matches a given pattern.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function routeIs($patterns = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->routeIs($patterns);
+        }
+        
+        /**
+         * Determine if the current request URL and query string matches a pattern.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function fullUrlIs($patterns = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->fullUrlIs($patterns);
+        }
+        
+        /**
+         * Determine if the request is the result of an AJAX call.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function ajax()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->ajax();
+        }
+        
+        /**
+         * Determine if the request is the result of an PJAX call.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function pjax()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->pjax();
+        }
+        
+        /**
+         * Determine if the request is over HTTPS.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function secure()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->secure();
+        }
+        
+        /**
+         * Get the client IP address.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function ip()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->ip();
+        }
+        
+        /**
+         * Get the client IP addresses.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function ips()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->ips();
+        }
+        
+        /**
+         * Get the client user agent.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function userAgent()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->userAgent();
+        }
+        
+        /**
+         * Merge new input into the current request's input array.
+         *
+         * @param array $input
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function merge($input)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->merge($input);
+        }
+        
+        /**
+         * Replace the input for the current request.
+         *
+         * @param array $input
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function replace($input)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->replace($input);
+        }
+        
+        /**
+         * This method belongs to Symfony HttpFoundation and is not usually needed when using Laravel.
+         * 
+         * Instead, you may use the "input" method.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function get($key, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->get($key, $default);
+        }
+        
+        /**
+         * Get the JSON payload for the request.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return \Symfony\Component\HttpFoundation\ParameterBag|mixed 
+         * @static 
+         */ 
+        public static function json($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->json($key, $default);
+        }
+        
+        /**
+         * Create a new request instance from the given Laravel request.
+         *
+         * @param \Illuminate\Http\Request $from
+         * @param \Illuminate\Http\Request|null $to
+         * @return static 
+         * @static 
+         */ 
+        public static function createFrom($from, $to = null)
+        {
+                        return \Illuminate\Http\Request::createFrom($from, $to);
+        }
+        
+        /**
+         * Create an Illuminate request from a Symfony instance.
+         *
+         * @param \Symfony\Component\HttpFoundation\Request $request
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function createFromBase($request)
+        {
+                        return \Illuminate\Http\Request::createFromBase($request);
+        }
+        
+        /**
+         * Clones a request and overrides some of its parameters.
+         *
+         * @param array $query The GET parameters
+         * @param array $request The POST parameters
+         * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+         * @param array $cookies The COOKIE parameters
+         * @param array $files The FILES parameters
+         * @param array $server The SERVER parameters
+         * @return static 
+         * @static 
+         */ 
+        public static function duplicate($query = null, $request = null, $attributes = null, $cookies = null, $files = null, $server = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->duplicate($query, $request, $attributes, $cookies, $files, $server);
+        }
+        
+        /**
+         * Get the session associated with the request.
+         *
+         * @return \Illuminate\Session\Store 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function session()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->session();
+        }
+        
+        /**
+         * Get the session associated with the request.
+         *
+         * @return \Illuminate\Session\Store|null 
+         * @static 
+         */ 
+        public static function getSession()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getSession();
+        }
+        
+        /**
+         * Set the session instance on the request.
+         *
+         * @param \Illuminate\Contracts\Session\Session $session
+         * @return void 
+         * @static 
+         */ 
+        public static function setLaravelSession($session)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->setLaravelSession($session);
+        }
+        
+        /**
+         * Get the user making the request.
+         *
+         * @param string|null $guard
+         * @return mixed 
+         * @static 
+         */ 
+        public static function user($guard = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->user($guard);
+        }
+        
+        /**
+         * Get the route handling the request.
+         *
+         * @param string|null $param
+         * @return \Illuminate\Routing\Route|object|string 
+         * @static 
+         */ 
+        public static function route($param = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->route($param);
+        }
+        
+        /**
+         * Get a unique fingerprint for the request / route / IP address.
+         *
+         * @return string 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function fingerprint()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->fingerprint();
+        }
+        
+        /**
+         * Set the JSON payload for the request.
+         *
+         * @param \Symfony\Component\HttpFoundation\ParameterBag $json
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function setJson($json)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setJson($json);
+        }
+        
+        /**
+         * Get the user resolver callback.
+         *
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function getUserResolver()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUserResolver();
+        }
+        
+        /**
+         * Set the user resolver callback.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function setUserResolver($callback)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setUserResolver($callback);
+        }
+        
+        /**
+         * Get the route resolver callback.
+         *
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function getRouteResolver()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRouteResolver();
+        }
+        
+        /**
+         * Set the route resolver callback.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function setRouteResolver($callback)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setRouteResolver($callback);
+        }
+        
+        /**
+         * Get all of the input and files for the request.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function toArray()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->toArray();
+        }
+        
+        /**
+         * Determine if the given offset exists.
+         *
+         * @param string $offset
+         * @return bool 
+         * @static 
+         */ 
+        public static function offsetExists($offset)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->offsetExists($offset);
+        }
+        
+        /**
+         * Get the value at the given offset.
+         *
+         * @param string $offset
+         * @return mixed 
+         * @static 
+         */ 
+        public static function offsetGet($offset)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->offsetGet($offset);
+        }
+        
+        /**
+         * Set the value at the given offset.
+         *
+         * @param string $offset
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetSet($offset, $value)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->offsetSet($offset, $value);
+        }
+        
+        /**
+         * Remove the value at the given offset.
+         *
+         * @param string $offset
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetUnset($offset)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->offsetUnset($offset);
+        }
+        
+        /**
+         * Sets the parameters for this request.
+         * 
+         * This method also re-initializes all properties.
+         *
+         * @param array $query The GET parameters
+         * @param array $request The POST parameters
+         * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+         * @param array $cookies The COOKIE parameters
+         * @param array $files The FILES parameters
+         * @param array $server The SERVER parameters
+         * @param string|resource|null $content The raw body data
+         * @static 
+         */ 
+        public static function initialize($query = array(), $request = array(), $attributes = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
+        }
+        
+        /**
+         * Creates a new request with values from PHP's super globals.
+         *
+         * @return static 
+         * @static 
+         */ 
+        public static function createFromGlobals()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::createFromGlobals();
+        }
+        
+        /**
+         * Creates a Request based on a given URI and configuration.
+         * 
+         * The information contained in the URI always take precedence
+         * over the other information (server and parameters).
+         *
+         * @param string $uri The URI
+         * @param string $method The HTTP method
+         * @param array $parameters The query (GET) or request (POST) parameters
+         * @param array $cookies The request cookies ($_COOKIE)
+         * @param array $files The request files ($_FILES)
+         * @param array $server The server parameters ($_SERVER)
+         * @param string|resource|null $content The raw body data
+         * @return static 
+         * @static 
+         */ 
+        public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::create($uri, $method, $parameters, $cookies, $files, $server, $content);
+        }
+        
+        /**
+         * Sets a callable able to create a Request instance.
+         * 
+         * This is mainly useful when you need to override the Request class
+         * to keep BC with an existing system. It should not be used for any
+         * other purpose.
+         *
+         * @param callable|null $callable A PHP callable
+         * @static 
+         */ 
+        public static function setFactory($callable)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::setFactory($callable);
+        }
+        
+        /**
+         * Overrides the PHP global variables according to this request instance.
+         * 
+         * It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE.
+         * $_FILES is never overridden, see rfc1867
+         *
+         * @static 
+         */ 
+        public static function overrideGlobals()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->overrideGlobals();
+        }
+        
+        /**
+         * Sets a list of trusted proxies.
+         * 
+         * You should only list the reverse proxies that you manage directly.
+         *
+         * @param array $proxies A list of trusted proxies
+         * @param int $trustedHeaderSet A bit field of Request::HEADER_*, to set which headers to trust from your proxies
+         * @throws \InvalidArgumentException When $trustedHeaderSet is invalid
+         * @static 
+         */ 
+        public static function setTrustedProxies($proxies, $trustedHeaderSet)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::setTrustedProxies($proxies, $trustedHeaderSet);
+        }
+        
+        /**
+         * Gets the list of trusted proxies.
+         *
+         * @return array An array of trusted proxies
+         * @static 
+         */ 
+        public static function getTrustedProxies()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::getTrustedProxies();
+        }
+        
+        /**
+         * Gets the set of trusted headers from trusted proxies.
+         *
+         * @return int A bit field of Request::HEADER_* that defines which headers are trusted from your proxies
+         * @static 
+         */ 
+        public static function getTrustedHeaderSet()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::getTrustedHeaderSet();
+        }
+        
+        /**
+         * Sets a list of trusted host patterns.
+         * 
+         * You should only list the hosts you manage using regexs.
+         *
+         * @param array $hostPatterns A list of trusted host patterns
+         * @static 
+         */ 
+        public static function setTrustedHosts($hostPatterns)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::setTrustedHosts($hostPatterns);
+        }
+        
+        /**
+         * Gets the list of trusted host patterns.
+         *
+         * @return array An array of trusted host patterns
+         * @static 
+         */ 
+        public static function getTrustedHosts()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::getTrustedHosts();
+        }
+        
+        /**
+         * Normalizes a query string.
+         * 
+         * It builds a normalized query string, where keys/value pairs are alphabetized,
+         * have consistent escaping and unneeded delimiters are removed.
+         *
+         * @param string $qs Query string
+         * @return string A normalized query string for the Request
+         * @static 
+         */ 
+        public static function normalizeQueryString($qs)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::normalizeQueryString($qs);
+        }
+        
+        /**
+         * Enables support for the _method request parameter to determine the intended HTTP method.
+         * 
+         * Be warned that enabling this feature might lead to CSRF issues in your code.
+         * Check that you are using CSRF tokens when required.
+         * If the HTTP method parameter override is enabled, an html-form with method "POST" can be altered
+         * and used to send a "PUT" or "DELETE" request via the _method request parameter.
+         * If these methods are not protected against CSRF, this presents a possible vulnerability.
+         * 
+         * The HTTP method can only be overridden when the real HTTP method is POST.
+         *
+         * @static 
+         */ 
+        public static function enableHttpMethodParameterOverride()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::enableHttpMethodParameterOverride();
+        }
+        
+        /**
+         * Checks whether support for the _method request parameter is enabled.
+         *
+         * @return bool True when the _method request parameter is enabled, false otherwise
+         * @static 
+         */ 
+        public static function getHttpMethodParameterOverride()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::getHttpMethodParameterOverride();
+        }
+        
+        /**
+         * Whether the request contains a Session which was started in one of the
+         * previous requests.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasPreviousSession()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasPreviousSession();
+        }
+        
+        /**
+         * Whether the request contains a Session object.
+         * 
+         * This method does not give any information about the state of the session object,
+         * like whether the session is started or not. It is just a way to check if this Request
+         * is associated with a Session instance.
+         *
+         * @return bool true when the Request contains a Session object, false otherwise
+         * @static 
+         */ 
+        public static function hasSession()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasSession();
+        }
+        
+        /**
+         * Sets the Session.
+         *
+         * @param \Symfony\Component\HttpFoundation\SessionInterface $session The Session
+         * @static 
+         */ 
+        public static function setSession($session)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setSession($session);
+        }
+        
+        /**
+         * 
+         *
+         * @internal 
+         * @static 
+         */ 
+        public static function setSessionFactory($factory)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setSessionFactory($factory);
+        }
+        
+        /**
+         * Returns the client IP addresses.
+         * 
+         * In the returned array the most trusted IP address is first, and the
+         * least trusted one last. The "real" client IP address is the last one,
+         * but this is also the least trusted one. Trusted proxies are stripped.
+         * 
+         * Use this method carefully; you should use getClientIp() instead.
+         *
+         * @return array The client IP addresses
+         * @see getClientIp()
+         * @static 
+         */ 
+        public static function getClientIps()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getClientIps();
+        }
+        
+        /**
+         * Returns the client IP address.
+         * 
+         * This method can read the client IP address from the "X-Forwarded-For" header
+         * when trusted proxies were set via "setTrustedProxies()". The "X-Forwarded-For"
+         * header value is a comma+space separated list of IP addresses, the left-most
+         * being the original client, and each successive proxy that passed the request
+         * adding the IP address where it received the request from.
+         *
+         * @return string|null The client IP address
+         * @see getClientIps()
+         * @see http://en.wikipedia.org/wiki/X-Forwarded-For
+         * @static 
+         */ 
+        public static function getClientIp()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getClientIp();
+        }
+        
+        /**
+         * Returns current script name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getScriptName()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getScriptName();
+        }
+        
+        /**
+         * Returns the path being requested relative to the executed script.
+         * 
+         * The path info always starts with a /.
+         * 
+         * Suppose this request is instantiated from /mysite on localhost:
+         * 
+         *  * http://localhost/mysite              returns an empty string
+         *  * http://localhost/mysite/about        returns '/about'
+         *  * http://localhost/mysite/enco%20ded   returns '/enco%20ded'
+         *  * http://localhost/mysite/about?var=1  returns '/about'
+         *
+         * @return string The raw path (i.e. not urldecoded)
+         * @static 
+         */ 
+        public static function getPathInfo()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPathInfo();
+        }
+        
+        /**
+         * Returns the root path from which this request is executed.
+         * 
+         * Suppose that an index.php file instantiates this request object:
+         * 
+         *  * http://localhost/index.php         returns an empty string
+         *  * http://localhost/index.php/page    returns an empty string
+         *  * http://localhost/web/index.php     returns '/web'
+         *  * http://localhost/we%20b/index.php  returns '/we%20b'
+         *
+         * @return string The raw path (i.e. not urldecoded)
+         * @static 
+         */ 
+        public static function getBasePath()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getBasePath();
+        }
+        
+        /**
+         * Returns the root URL from which this request is executed.
+         * 
+         * The base URL never ends with a /.
+         * 
+         * This is similar to getBasePath(), except that it also includes the
+         * script filename (e.g. index.php) if one exists.
+         *
+         * @return string The raw URL (i.e. not urldecoded)
+         * @static 
+         */ 
+        public static function getBaseUrl()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getBaseUrl();
+        }
+        
+        /**
+         * Gets the request's scheme.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getScheme()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getScheme();
+        }
+        
+        /**
+         * Returns the port on which the request is made.
+         * 
+         * This method can read the client port from the "X-Forwarded-Port" header
+         * when trusted proxies were set via "setTrustedProxies()".
+         * 
+         * The "X-Forwarded-Port" header must contain the client port.
+         *
+         * @return int|string can be a string if fetched from the server bag
+         * @static 
+         */ 
+        public static function getPort()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPort();
+        }
+        
+        /**
+         * Returns the user.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function getUser()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUser();
+        }
+        
+        /**
+         * Returns the password.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function getPassword()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPassword();
+        }
+        
+        /**
+         * Gets the user info.
+         *
+         * @return string A user name and, optionally, scheme-specific information about how to gain authorization to access the server
+         * @static 
+         */ 
+        public static function getUserInfo()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUserInfo();
+        }
+        
+        /**
+         * Returns the HTTP host being requested.
+         * 
+         * The port name will be appended to the host if it's non-standard.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getHttpHost()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getHttpHost();
+        }
+        
+        /**
+         * Returns the requested URI (path and query string).
+         *
+         * @return string The raw URI (i.e. not URI decoded)
+         * @static 
+         */ 
+        public static function getRequestUri()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRequestUri();
+        }
+        
+        /**
+         * Gets the scheme and HTTP host.
+         * 
+         * If the URL was called with basic authentication, the user
+         * and the password are not added to the generated string.
+         *
+         * @return string The scheme and HTTP host
+         * @static 
+         */ 
+        public static function getSchemeAndHttpHost()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getSchemeAndHttpHost();
+        }
+        
+        /**
+         * Generates a normalized URI (URL) for the Request.
+         *
+         * @return string A normalized URI (URL) for the Request
+         * @see getQueryString()
+         * @static 
+         */ 
+        public static function getUri()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUri();
+        }
+        
+        /**
+         * Generates a normalized URI for the given path.
+         *
+         * @param string $path A path to use instead of the current one
+         * @return string The normalized URI for the path
+         * @static 
+         */ 
+        public static function getUriForPath($path)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUriForPath($path);
+        }
+        
+        /**
+         * Returns the path as relative reference from the current Request path.
+         * 
+         * Only the URIs path component (no schema, host etc.) is relevant and must be given.
+         * Both paths must be absolute and not contain relative parts.
+         * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
+         * Furthermore, they can be used to reduce the link size in documents.
+         * 
+         * Example target paths, given a base path of "/a/b/c/d":
+         * - "/a/b/c/d"     -> ""
+         * - "/a/b/c/"      -> "./"
+         * - "/a/b/"        -> "../"
+         * - "/a/b/c/other" -> "other"
+         * - "/a/x/y"       -> "../../x/y"
+         *
+         * @param string $path The target path
+         * @return string The relative target path
+         * @static 
+         */ 
+        public static function getRelativeUriForPath($path)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRelativeUriForPath($path);
+        }
+        
+        /**
+         * Generates the normalized query string for the Request.
+         * 
+         * It builds a normalized query string, where keys/value pairs are alphabetized
+         * and have consistent escaping.
+         *
+         * @return string|null A normalized query string for the Request
+         * @static 
+         */ 
+        public static function getQueryString()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getQueryString();
+        }
+        
+        /**
+         * Checks whether the request is secure or not.
+         * 
+         * This method can read the client protocol from the "X-Forwarded-Proto" header
+         * when trusted proxies were set via "setTrustedProxies()".
+         * 
+         * The "X-Forwarded-Proto" header must contain the protocol: "https" or "http".
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isSecure()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isSecure();
+        }
+        
+        /**
+         * Returns the host name.
+         * 
+         * This method can read the client host name from the "X-Forwarded-Host" header
+         * when trusted proxies were set via "setTrustedProxies()".
+         * 
+         * The "X-Forwarded-Host" header must contain the client host name.
+         *
+         * @return string 
+         * @throws SuspiciousOperationException when the host name is invalid or not trusted
+         * @static 
+         */ 
+        public static function getHost()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getHost();
+        }
+        
+        /**
+         * Sets the request method.
+         *
+         * @param string $method
+         * @static 
+         */ 
+        public static function setMethod($method)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setMethod($method);
+        }
+        
+        /**
+         * Gets the request "intended" method.
+         * 
+         * If the X-HTTP-Method-Override header is set, and if the method is a POST,
+         * then it is used to determine the "real" intended HTTP method.
+         * 
+         * The _method request parameter can also be used to determine the HTTP method,
+         * but only if enableHttpMethodParameterOverride() has been called.
+         * 
+         * The method is always an uppercased string.
+         *
+         * @return string The request method
+         * @see getRealMethod()
+         * @static 
+         */ 
+        public static function getMethod()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getMethod();
+        }
+        
+        /**
+         * Gets the "real" request method.
+         *
+         * @return string The request method
+         * @see getMethod()
+         * @static 
+         */ 
+        public static function getRealMethod()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRealMethod();
+        }
+        
+        /**
+         * Gets the mime type associated with the format.
+         *
+         * @param string $format The format
+         * @return string|null The associated mime type (null if not found)
+         * @static 
+         */ 
+        public static function getMimeType($format)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getMimeType($format);
+        }
+        
+        /**
+         * Gets the mime types associated with the format.
+         *
+         * @param string $format The format
+         * @return array The associated mime types
+         * @static 
+         */ 
+        public static function getMimeTypes($format)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        return \Illuminate\Http\Request::getMimeTypes($format);
+        }
+        
+        /**
+         * Gets the format associated with the mime type.
+         *
+         * @param string $mimeType The associated mime type
+         * @return string|null The format (null if not found)
+         * @static 
+         */ 
+        public static function getFormat($mimeType)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getFormat($mimeType);
+        }
+        
+        /**
+         * Associates a format with mime types.
+         *
+         * @param string $format The format
+         * @param string|array $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type)
+         * @static 
+         */ 
+        public static function setFormat($format, $mimeTypes)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setFormat($format, $mimeTypes);
+        }
+        
+        /**
+         * Gets the request format.
+         * 
+         * Here is the process to determine the format:
+         * 
+         *  * format defined by the user (with setRequestFormat())
+         *  * _format request attribute
+         *  * $default
+         *
+         * @param string|null $default The default format
+         * @return string|null The request format
+         * @static 
+         */ 
+        public static function getRequestFormat($default = 'html')
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRequestFormat($default);
+        }
+        
+        /**
+         * Sets the request format.
+         *
+         * @param string $format The request format
+         * @static 
+         */ 
+        public static function setRequestFormat($format)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setRequestFormat($format);
+        }
+        
+        /**
+         * Gets the format associated with the request.
+         *
+         * @return string|null The format (null if no content type is present)
+         * @static 
+         */ 
+        public static function getContentType()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getContentType();
+        }
+        
+        /**
+         * Sets the default locale.
+         *
+         * @param string $locale
+         * @static 
+         */ 
+        public static function setDefaultLocale($locale)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setDefaultLocale($locale);
+        }
+        
+        /**
+         * Get the default locale.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultLocale()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getDefaultLocale();
+        }
+        
+        /**
+         * Sets the locale.
+         *
+         * @param string $locale
+         * @static 
+         */ 
+        public static function setLocale($locale)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setLocale($locale);
+        }
+        
+        /**
+         * Get the locale.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getLocale()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getLocale();
+        }
+        
+        /**
+         * Checks if the request method is of specified type.
+         *
+         * @param string $method Uppercase request method (GET, POST etc)
+         * @return bool 
+         * @static 
+         */ 
+        public static function isMethod($method)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isMethod($method);
+        }
+        
+        /**
+         * Checks whether or not the method is safe.
+         *
+         * @see https://tools.ietf.org/html/rfc7231#section-4.2.1
+         * @param bool $andCacheable Adds the additional condition that the method should be cacheable. True by default.
+         * @return bool 
+         * @static 
+         */ 
+        public static function isMethodSafe()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isMethodSafe();
+        }
+        
+        /**
+         * Checks whether or not the method is idempotent.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isMethodIdempotent()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isMethodIdempotent();
+        }
+        
+        /**
+         * Checks whether the method is cacheable or not.
+         *
+         * @see https://tools.ietf.org/html/rfc7231#section-4.2.3
+         * @return bool True for GET and HEAD, false otherwise
+         * @static 
+         */ 
+        public static function isMethodCacheable()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isMethodCacheable();
+        }
+        
+        /**
+         * Returns the protocol version.
+         * 
+         * If the application is behind a proxy, the protocol version used in the
+         * requests between the client and the proxy and between the proxy and the
+         * server might be different. This returns the former (from the "Via" header)
+         * if the proxy is trusted (see "setTrustedProxies()"), otherwise it returns
+         * the latter (from the "SERVER_PROTOCOL" server parameter).
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getProtocolVersion()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getProtocolVersion();
+        }
+        
+        /**
+         * Returns the request body content.
+         *
+         * @param bool $asResource If true, a resource will be returned
+         * @return string|resource The request body content or a resource to read the body stream
+         * @throws \LogicException
+         * @static 
+         */ 
+        public static function getContent($asResource = false)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getContent($asResource);
+        }
+        
+        /**
+         * Gets the Etags.
+         *
+         * @return array The entity tags
+         * @static 
+         */ 
+        public static function getETags()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getETags();
+        }
+        
+        /**
+         * 
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isNoCache()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isNoCache();
+        }
+        
+        /**
+         * Returns the preferred language.
+         *
+         * @param array $locales An array of ordered available locales
+         * @return string|null The preferred locale
+         * @static 
+         */ 
+        public static function getPreferredLanguage($locales = null)
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPreferredLanguage($locales);
+        }
+        
+        /**
+         * Gets a list of languages acceptable by the client browser.
+         *
+         * @return array Languages ordered in the user browser preferences
+         * @static 
+         */ 
+        public static function getLanguages()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getLanguages();
+        }
+        
+        /**
+         * Gets a list of charsets acceptable by the client browser.
+         *
+         * @return array List of charsets in preferable order
+         * @static 
+         */ 
+        public static function getCharsets()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getCharsets();
+        }
+        
+        /**
+         * Gets a list of encodings acceptable by the client browser.
+         *
+         * @return array List of encodings in preferable order
+         * @static 
+         */ 
+        public static function getEncodings()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getEncodings();
+        }
+        
+        /**
+         * Gets a list of content types acceptable by the client browser.
+         *
+         * @return array List of content types in preferable order
+         * @static 
+         */ 
+        public static function getAcceptableContentTypes()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getAcceptableContentTypes();
+        }
+        
+        /**
+         * Returns true if the request is a XMLHttpRequest.
+         * 
+         * It works if your JavaScript library sets an X-Requested-With HTTP header.
+         * It is known to work with common JavaScript frameworks:
+         *
+         * @see http://en.wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript
+         * @return bool true if the request is an XMLHttpRequest, false otherwise
+         * @static 
+         */ 
+        public static function isXmlHttpRequest()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isXmlHttpRequest();
+        }
+        
+        /**
+         * Indicates whether this request originated from a trusted proxy.
+         * 
+         * This can be useful to determine whether or not to trust the
+         * contents of a proxy-specific header.
+         *
+         * @return bool true if the request came from a trusted proxy, false otherwise
+         * @static 
+         */ 
+        public static function isFromTrustedProxy()
+        {
+            //Method inherited from \Symfony\Component\HttpFoundation\Request            
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isFromTrustedProxy();
+        }
+        
+        /**
+         * Determine if the given content types match.
+         *
+         * @param string $actual
+         * @param string $type
+         * @return bool 
+         * @static 
+         */ 
+        public static function matchesType($actual, $type)
+        {
+                        return \Illuminate\Http\Request::matchesType($actual, $type);
+        }
+        
+        /**
+         * Determine if the request is sending JSON.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isJson()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isJson();
+        }
+        
+        /**
+         * Determine if the current request probably expects a JSON response.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function expectsJson()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->expectsJson();
+        }
+        
+        /**
+         * Determine if the current request is asking for JSON.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function wantsJson()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->wantsJson();
+        }
+        
+        /**
+         * Determines whether the current requests accepts a given content type.
+         *
+         * @param string|array $contentTypes
+         * @return bool 
+         * @static 
+         */ 
+        public static function accepts($contentTypes)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->accepts($contentTypes);
+        }
+        
+        /**
+         * Return the most suitable content type from the given array based on content negotiation.
+         *
+         * @param string|array $contentTypes
+         * @return string|null 
+         * @static 
+         */ 
+        public static function prefers($contentTypes)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->prefers($contentTypes);
+        }
+        
+        /**
+         * Determine if the current request accepts any content type.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function acceptsAnyContentType()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->acceptsAnyContentType();
+        }
+        
+        /**
+         * Determines whether a request accepts JSON.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function acceptsJson()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->acceptsJson();
+        }
+        
+        /**
+         * Determines whether a request accepts HTML.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function acceptsHtml()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->acceptsHtml();
+        }
+        
+        /**
+         * Get the data format expected in the response.
+         *
+         * @param string $default
+         * @return string 
+         * @static 
+         */ 
+        public static function format($default = 'html')
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->format($default);
+        }
+        
+        /**
+         * Retrieve an old input item.
+         *
+         * @param string $key
+         * @param string|array|null $default
+         * @return string|array 
+         * @static 
+         */ 
+        public static function old($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->old($key, $default);
+        }
+        
+        /**
+         * Flash the input for the current request to the session.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flash()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->flash();
+        }
+        
+        /**
+         * Flash only some of the input to the session.
+         *
+         * @param array|mixed $keys
+         * @return void 
+         * @static 
+         */ 
+        public static function flashOnly($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->flashOnly($keys);
+        }
+        
+        /**
+         * Flash only some of the input to the session.
+         *
+         * @param array|mixed $keys
+         * @return void 
+         * @static 
+         */ 
+        public static function flashExcept($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->flashExcept($keys);
+        }
+        
+        /**
+         * Flush all of the old input from the session.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flush()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->flush();
+        }
+        
+        /**
+         * Retrieve a server variable from the request.
+         *
+         * @param string $key
+         * @param string|array|null $default
+         * @return string|array 
+         * @static 
+         */ 
+        public static function server($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->server($key, $default);
+        }
+        
+        /**
+         * Determine if a header is set on the request.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasHeader($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasHeader($key);
+        }
+        
+        /**
+         * Retrieve a header from the request.
+         *
+         * @param string $key
+         * @param string|array|null $default
+         * @return string|array 
+         * @static 
+         */ 
+        public static function header($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->header($key, $default);
+        }
+        
+        /**
+         * Get the bearer token from the request headers.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function bearerToken()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->bearerToken();
+        }
+        
+        /**
+         * Determine if the request contains a given input item key.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->exists($key);
+        }
+        
+        /**
+         * Determine if the request contains a given input item key.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->has($key);
+        }
+        
+        /**
+         * Determine if the request contains any of the given inputs.
+         *
+         * @param string|array $keys
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasAny($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasAny($keys);
+        }
+        
+        /**
+         * Determine if the request contains a non-empty value for an input item.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function filled($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->filled($key);
+        }
+        
+        /**
+         * Determine if the request contains a non-empty value for any of the given inputs.
+         *
+         * @param string|array $keys
+         * @return bool 
+         * @static 
+         */ 
+        public static function anyFilled($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->anyFilled($keys);
+        }
+        
+        /**
+         * Get the keys for all of the input and files.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function keys()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->keys();
+        }
+        
+        /**
+         * Get all of the input and files for the request.
+         *
+         * @param array|mixed $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function all($keys = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->all($keys);
+        }
+        
+        /**
+         * Retrieve an input item from the request.
+         *
+         * @param string|null $key
+         * @param string|array|null $default
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function input($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->input($key, $default);
+        }
+        
+        /**
+         * Get a subset containing the provided keys with values from the input data.
+         *
+         * @param array|mixed $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function only($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->only($keys);
+        }
+        
+        /**
+         * Get all of the input except for a specified array of items.
+         *
+         * @param array|mixed $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function except($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->except($keys);
+        }
+        
+        /**
+         * Retrieve a query string item from the request.
+         *
+         * @param string $key
+         * @param string|array|null $default
+         * @return string|array 
+         * @static 
+         */ 
+        public static function query($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->query($key, $default);
+        }
+        
+        /**
+         * Retrieve a request payload item from the request.
+         *
+         * @param string $key
+         * @param string|array|null $default
+         * @return string|array 
+         * @static 
+         */ 
+        public static function post($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->post($key, $default);
+        }
+        
+        /**
+         * Determine if a cookie is set on the request.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasCookie($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasCookie($key);
+        }
+        
+        /**
+         * Retrieve a cookie from the request.
+         *
+         * @param string $key
+         * @param string|array|null $default
+         * @return string|array 
+         * @static 
+         */ 
+        public static function cookie($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->cookie($key, $default);
+        }
+        
+        /**
+         * Get an array of all of the files on the request.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function allFiles()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->allFiles();
+        }
+        
+        /**
+         * Determine if the uploaded data contains a file.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasFile($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasFile($key);
+        }
+        
+        /**
+         * Retrieve a file from the request.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return \Illuminate\Http\UploadedFile|array|null 
+         * @static 
+         */ 
+        public static function file($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->file($key, $default);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Http\Request::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Http\Request::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Http\Request::hasMacro($name);
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function validate($rules, $params = null)
+        {
+                        return \Illuminate\Http\Request::validate($rules, $params);
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function hasValidSignature()
+        {
+                        return \Illuminate\Http\Request::hasValidSignature();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Routing\ResponseFactory
+     */ 
+    class Response {
+        
+        /**
+         * Return a new response from the application.
+         *
+         * @param string $content
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\Response 
+         * @static 
+         */ 
+        public static function make($content = '', $status = 200, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->make($content, $status, $headers);
+        }
+        
+        /**
+         * Return a new view response from the application.
+         *
+         * @param string $view
+         * @param array $data
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\Response 
+         * @static 
+         */ 
+        public static function view($view, $data = array(), $status = 200, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->view($view, $data, $status, $headers);
+        }
+        
+        /**
+         * Return a new JSON response from the application.
+         *
+         * @param mixed $data
+         * @param int $status
+         * @param array $headers
+         * @param int $options
+         * @return \Illuminate\Http\JsonResponse 
+         * @static 
+         */ 
+        public static function json($data = array(), $status = 200, $headers = array(), $options = 0)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->json($data, $status, $headers, $options);
+        }
+        
+        /**
+         * Return a new JSONP response from the application.
+         *
+         * @param string $callback
+         * @param mixed $data
+         * @param int $status
+         * @param array $headers
+         * @param int $options
+         * @return \Illuminate\Http\JsonResponse 
+         * @static 
+         */ 
+        public static function jsonp($callback, $data = array(), $status = 200, $headers = array(), $options = 0)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->jsonp($callback, $data, $status, $headers, $options);
+        }
+        
+        /**
+         * Return a new streamed response from the application.
+         *
+         * @param \Closure $callback
+         * @param int $status
+         * @param array $headers
+         * @return \Symfony\Component\HttpFoundation\StreamedResponse 
+         * @static 
+         */ 
+        public static function stream($callback, $status = 200, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->stream($callback, $status, $headers);
+        }
+        
+        /**
+         * Return a new streamed response as a file download from the application.
+         *
+         * @param \Closure $callback
+         * @param string|null $name
+         * @param array $headers
+         * @param string|null $disposition
+         * @return \Symfony\Component\HttpFoundation\StreamedResponse 
+         * @static 
+         */ 
+        public static function streamDownload($callback, $name = null, $headers = array(), $disposition = 'attachment')
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->streamDownload($callback, $name, $headers, $disposition);
+        }
+        
+        /**
+         * Create a new file download response.
+         *
+         * @param \SplFileInfo|string $file
+         * @param string|null $name
+         * @param array $headers
+         * @param string|null $disposition
+         * @return \Symfony\Component\HttpFoundation\BinaryFileResponse 
+         * @static 
+         */ 
+        public static function download($file, $name = null, $headers = array(), $disposition = 'attachment')
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->download($file, $name, $headers, $disposition);
+        }
+        
+        /**
+         * Return the raw contents of a binary file.
+         *
+         * @param \SplFileInfo|string $file
+         * @param array $headers
+         * @return \Symfony\Component\HttpFoundation\BinaryFileResponse 
+         * @static 
+         */ 
+        public static function file($file, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->file($file, $headers);
+        }
+        
+        /**
+         * Create a new redirect response to the given path.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectTo($path, $status = 302, $headers = array(), $secure = null)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectTo($path, $status, $headers, $secure);
+        }
+        
+        /**
+         * Create a new redirect response to a named route.
+         *
+         * @param string $route
+         * @param array $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectToRoute($route, $parameters = array(), $status = 302, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectToRoute($route, $parameters, $status, $headers);
+        }
+        
+        /**
+         * Create a new redirect response to a controller action.
+         *
+         * @param string $action
+         * @param array $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectToAction($action, $parameters = array(), $status = 302, $headers = array())
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectToAction($action, $parameters, $status, $headers);
+        }
+        
+        /**
+         * Create a new redirect response, while putting the current URL in the session.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectGuest($path, $status = 302, $headers = array(), $secure = null)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectGuest($path, $status, $headers, $secure);
+        }
+        
+        /**
+         * Create a new redirect response to the previously intended location.
+         *
+         * @param string $default
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectToIntended($default = '/', $status = 302, $headers = array(), $secure = null)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectToIntended($default, $status, $headers, $secure);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Routing\ResponseFactory::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Routing\ResponseFactory::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Routing\ResponseFactory::hasMacro($name);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @method static \Illuminate\Routing\RouteRegistrar prefix(string  $prefix)
+     * @method static \Illuminate\Routing\RouteRegistrar where(array  $where)
+     * @method static \Illuminate\Routing\RouteRegistrar middleware(array|string|null $middleware)
+     * @method static \Illuminate\Routing\RouteRegistrar as(string $value)
+     * @method static \Illuminate\Routing\RouteRegistrar domain(string $value)
+     * @method static \Illuminate\Routing\RouteRegistrar name(string $value)
+     * @method static \Illuminate\Routing\RouteRegistrar namespace(string $value)
+     * @see \Illuminate\Routing\Router
+     */ 
+    class Route {
+        
+        /**
+         * Register a new GET route with the router.
+         *
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function get($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->get($uri, $action);
+        }
+        
+        /**
+         * Register a new POST route with the router.
+         *
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function post($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->post($uri, $action);
+        }
+        
+        /**
+         * Register a new PUT route with the router.
+         *
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function put($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->put($uri, $action);
+        }
+        
+        /**
+         * Register a new PATCH route with the router.
+         *
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function patch($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->patch($uri, $action);
+        }
+        
+        /**
+         * Register a new DELETE route with the router.
+         *
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function delete($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->delete($uri, $action);
+        }
+        
+        /**
+         * Register a new OPTIONS route with the router.
+         *
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function options($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->options($uri, $action);
+        }
+        
+        /**
+         * Register a new route responding to all verbs.
+         *
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function any($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->any($uri, $action);
+        }
+        
+        /**
+         * Register a new Fallback route with the router.
+         *
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function fallback($action)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->fallback($action);
+        }
+        
+        /**
+         * Create a redirect from one URI to another.
+         *
+         * @param string $uri
+         * @param string $destination
+         * @param int $status
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function redirect($uri, $destination, $status = 301)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->redirect($uri, $destination, $status);
+        }
+        
+        /**
+         * Register a new route that returns a view.
+         *
+         * @param string $uri
+         * @param string $view
+         * @param array $data
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function view($uri, $view, $data = array())
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->view($uri, $view, $data);
+        }
+        
+        /**
+         * Register a new route with the given verbs.
+         *
+         * @param array|string $methods
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function match($methods, $uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->match($methods, $uri, $action);
+        }
+        
+        /**
+         * Register an array of resource controllers.
+         *
+         * @param array $resources
+         * @return void 
+         * @static 
+         */ 
+        public static function resources($resources)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->resources($resources);
+        }
+        
+        /**
+         * Route a resource to a controller.
+         *
+         * @param string $name
+         * @param string $controller
+         * @param array $options
+         * @return \Illuminate\Routing\PendingResourceRegistration 
+         * @static 
+         */ 
+        public static function resource($name, $controller, $options = array())
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->resource($name, $controller, $options);
+        }
+        
+        /**
+         * Register an array of API resource controllers.
+         *
+         * @param array $resources
+         * @return void 
+         * @static 
+         */ 
+        public static function apiResources($resources)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->apiResources($resources);
+        }
+        
+        /**
+         * Route an API resource to a controller.
+         *
+         * @param string $name
+         * @param string $controller
+         * @param array $options
+         * @return \Illuminate\Routing\PendingResourceRegistration 
+         * @static 
+         */ 
+        public static function apiResource($name, $controller, $options = array())
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->apiResource($name, $controller, $options);
+        }
+        
+        /**
+         * Create a route group with shared attributes.
+         *
+         * @param array $attributes
+         * @param \Closure|string $routes
+         * @return void 
+         * @static 
+         */ 
+        public static function group($attributes, $routes)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->group($attributes, $routes);
+        }
+        
+        /**
+         * Merge the given array with the last group stack.
+         *
+         * @param array $new
+         * @return array 
+         * @static 
+         */ 
+        public static function mergeWithLastGroup($new)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->mergeWithLastGroup($new);
+        }
+        
+        /**
+         * Get the prefix from the last group on the stack.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getLastGroupPrefix()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getLastGroupPrefix();
+        }
+        
+        /**
+         * Add a route to the underlying route collection.
+         *
+         * @param array|string $methods
+         * @param string $uri
+         * @param \Closure|array|string|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function addRoute($methods, $uri, $action)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->addRoute($methods, $uri, $action);
+        }
+        
+        /**
+         * Return the response returned by the given route.
+         *
+         * @param string $name
+         * @return mixed 
+         * @static 
+         */ 
+        public static function respondWithRoute($name)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->respondWithRoute($name);
+        }
+        
+        /**
+         * Dispatch the request to the application.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse 
+         * @static 
+         */ 
+        public static function dispatch($request)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->dispatch($request);
+        }
+        
+        /**
+         * Dispatch the request to a route and return the response.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return mixed 
+         * @static 
+         */ 
+        public static function dispatchToRoute($request)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->dispatchToRoute($request);
+        }
+        
+        /**
+         * Gather the middleware for the given route with resolved class names.
+         *
+         * @param \Illuminate\Routing\Route $route
+         * @return array 
+         * @static 
+         */ 
+        public static function gatherRouteMiddleware($route)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->gatherRouteMiddleware($route);
+        }
+        
+        /**
+         * Create a response instance from the given value.
+         *
+         * @param \Symfony\Component\HttpFoundation\Request $request
+         * @param mixed $response
+         * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse 
+         * @static 
+         */ 
+        public static function prepareResponse($request, $response)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->prepareResponse($request, $response);
+        }
+        
+        /**
+         * Static version of prepareResponse.
+         *
+         * @param \Symfony\Component\HttpFoundation\Request $request
+         * @param mixed $response
+         * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse 
+         * @static 
+         */ 
+        public static function toResponse($request, $response)
+        {
+                        return \Illuminate\Routing\Router::toResponse($request, $response);
+        }
+        
+        /**
+         * Substitute the route bindings onto the route.
+         *
+         * @param \Illuminate\Routing\Route $route
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function substituteBindings($route)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->substituteBindings($route);
+        }
+        
+        /**
+         * Substitute the implicit Eloquent model bindings for the route.
+         *
+         * @param \Illuminate\Routing\Route $route
+         * @return void 
+         * @static 
+         */ 
+        public static function substituteImplicitBindings($route)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->substituteImplicitBindings($route);
+        }
+        
+        /**
+         * Register a route matched event listener.
+         *
+         * @param string|callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function matched($callback)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->matched($callback);
+        }
+        
+        /**
+         * Get all of the defined middleware short-hand names.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getMiddleware()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getMiddleware();
+        }
+        
+        /**
+         * Register a short-hand name for a middleware.
+         *
+         * @param string $name
+         * @param string $class
+         * @return \Illuminate\Routing\Router 
+         * @static 
+         */ 
+        public static function aliasMiddleware($name, $class)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->aliasMiddleware($name, $class);
+        }
+        
+        /**
+         * Check if a middlewareGroup with the given name exists.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMiddlewareGroup($name)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->hasMiddlewareGroup($name);
+        }
+        
+        /**
+         * Get all of the defined middleware groups.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getMiddlewareGroups()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getMiddlewareGroups();
+        }
+        
+        /**
+         * Register a group of middleware.
+         *
+         * @param string $name
+         * @param array $middleware
+         * @return \Illuminate\Routing\Router 
+         * @static 
+         */ 
+        public static function middlewareGroup($name, $middleware)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->middlewareGroup($name, $middleware);
+        }
+        
+        /**
+         * Add a middleware to the beginning of a middleware group.
+         * 
+         * If the middleware is already in the group, it will not be added again.
+         *
+         * @param string $group
+         * @param string $middleware
+         * @return \Illuminate\Routing\Router 
+         * @static 
+         */ 
+        public static function prependMiddlewareToGroup($group, $middleware)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->prependMiddlewareToGroup($group, $middleware);
+        }
+        
+        /**
+         * Add a middleware to the end of a middleware group.
+         * 
+         * If the middleware is already in the group, it will not be added again.
+         *
+         * @param string $group
+         * @param string $middleware
+         * @return \Illuminate\Routing\Router 
+         * @static 
+         */ 
+        public static function pushMiddlewareToGroup($group, $middleware)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->pushMiddlewareToGroup($group, $middleware);
+        }
+        
+        /**
+         * Add a new route parameter binder.
+         *
+         * @param string $key
+         * @param string|callable $binder
+         * @return void 
+         * @static 
+         */ 
+        public static function bind($key, $binder)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->bind($key, $binder);
+        }
+        
+        /**
+         * Register a model binder for a wildcard.
+         *
+         * @param string $key
+         * @param string $class
+         * @param \Closure|null $callback
+         * @return void 
+         * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+         * @static 
+         */ 
+        public static function model($key, $class, $callback = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->model($key, $class, $callback);
+        }
+        
+        /**
+         * Get the binding callback for a given binding.
+         *
+         * @param string $key
+         * @return \Closure|null 
+         * @static 
+         */ 
+        public static function getBindingCallback($key)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getBindingCallback($key);
+        }
+        
+        /**
+         * Get the global "where" patterns.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getPatterns()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getPatterns();
+        }
+        
+        /**
+         * Set a global where pattern on all routes.
+         *
+         * @param string $key
+         * @param string $pattern
+         * @return void 
+         * @static 
+         */ 
+        public static function pattern($key, $pattern)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->pattern($key, $pattern);
+        }
+        
+        /**
+         * Set a group of global where patterns on all routes.
+         *
+         * @param array $patterns
+         * @return void 
+         * @static 
+         */ 
+        public static function patterns($patterns)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->patterns($patterns);
+        }
+        
+        /**
+         * Determine if the router currently has a group stack.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasGroupStack()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->hasGroupStack();
+        }
+        
+        /**
+         * Get the current group stack for the router.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getGroupStack()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getGroupStack();
+        }
+        
+        /**
+         * Get a route parameter for the current route.
+         *
+         * @param string $key
+         * @param string $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function input($key, $default = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->input($key, $default);
+        }
+        
+        /**
+         * Get the request currently being dispatched.
+         *
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function getCurrentRequest()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getCurrentRequest();
+        }
+        
+        /**
+         * Get the currently dispatched route instance.
+         *
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function getCurrentRoute()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getCurrentRoute();
+        }
+        
+        /**
+         * Get the currently dispatched route instance.
+         *
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function current()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->current();
+        }
+        
+        /**
+         * Check if a route with the given name exists.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($name)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->has($name);
+        }
+        
+        /**
+         * Get the current route name.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function currentRouteName()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->currentRouteName();
+        }
+        
+        /**
+         * Alias for the "currentRouteNamed" method.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function is($patterns = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->is($patterns);
+        }
+        
+        /**
+         * Determine if the current route matches a pattern.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function currentRouteNamed($patterns = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->currentRouteNamed($patterns);
+        }
+        
+        /**
+         * Get the current route action.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function currentRouteAction()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->currentRouteAction();
+        }
+        
+        /**
+         * Alias for the "currentRouteUses" method.
+         *
+         * @param array $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function uses($patterns = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->uses($patterns);
+        }
+        
+        /**
+         * Determine if the current route action matches a given action.
+         *
+         * @param string $action
+         * @return bool 
+         * @static 
+         */ 
+        public static function currentRouteUses($action)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->currentRouteUses($action);
+        }
+        
+        /**
+         * Register the typical authentication routes for an application.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function auth()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->auth();
+        }
+        
+        /**
+         * Set the unmapped global resource parameters to singular.
+         *
+         * @param bool $singular
+         * @return void 
+         * @static 
+         */ 
+        public static function singularResourceParameters($singular = true)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->singularResourceParameters($singular);
+        }
+        
+        /**
+         * Set the global resource parameter mapping.
+         *
+         * @param array $parameters
+         * @return void 
+         * @static 
+         */ 
+        public static function resourceParameters($parameters = array())
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->resourceParameters($parameters);
+        }
+        
+        /**
+         * Get or set the verbs used in the resource URIs.
+         *
+         * @param array $verbs
+         * @return array|null 
+         * @static 
+         */ 
+        public static function resourceVerbs($verbs = array())
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->resourceVerbs($verbs);
+        }
+        
+        /**
+         * Get the underlying route collection.
+         *
+         * @return \Illuminate\Routing\RouteCollection 
+         * @static 
+         */ 
+        public static function getRoutes()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getRoutes();
+        }
+        
+        /**
+         * Set the route collection instance.
+         *
+         * @param \Illuminate\Routing\RouteCollection $routes
+         * @return void 
+         * @static 
+         */ 
+        public static function setRoutes($routes)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->setRoutes($routes);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Routing\Router::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Routing\Router::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Routing\Router::hasMacro($name);
+        }
+        
+        /**
+         * Dynamically handle calls to the class.
+         *
+         * @param string $method
+         * @param array $parameters
+         * @return mixed 
+         * @throws \BadMethodCallException
+         * @static 
+         */ 
+        public static function macroCall($method, $parameters)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->macroCall($method, $parameters);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Database\Schema\Builder
+     */ 
+    class Schema {
+        
+        /**
+         * Determine if the given table exists.
+         *
+         * @param string $table
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasTable($table)
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->hasTable($table);
+        }
+        
+        /**
+         * Get the column listing for a given table.
+         *
+         * @param string $table
+         * @return array 
+         * @static 
+         */ 
+        public static function getColumnListing($table)
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->getColumnListing($table);
+        }
+        
+        /**
+         * Drop all tables from the database.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function dropAllTables()
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->dropAllTables();
+        }
+        
+        /**
+         * Drop all views from the database.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function dropAllViews()
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->dropAllViews();
+        }
+        
+        /**
+         * Set the default string length for migrations.
+         *
+         * @param int $length
+         * @return void 
+         * @static 
+         */ 
+        public static function defaultStringLength($length)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        \Illuminate\Database\Schema\MySqlBuilder::defaultStringLength($length);
+        }
+        
+        /**
+         * Determine if the given table has a given column.
+         *
+         * @param string $table
+         * @param string $column
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasColumn($table, $column)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->hasColumn($table, $column);
+        }
+        
+        /**
+         * Determine if the given table has given columns.
+         *
+         * @param string $table
+         * @param array $columns
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasColumns($table, $columns)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->hasColumns($table, $columns);
+        }
+        
+        /**
+         * Get the data type for the given column name.
+         *
+         * @param string $table
+         * @param string $column
+         * @return string 
+         * @static 
+         */ 
+        public static function getColumnType($table, $column)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->getColumnType($table, $column);
+        }
+        
+        /**
+         * Modify a table on the schema.
+         *
+         * @param string $table
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function table($table, $callback)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->table($table, $callback);
+        }
+        
+        /**
+         * Create a new table on the schema.
+         *
+         * @param string $table
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function create($table, $callback)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->create($table, $callback);
+        }
+        
+        /**
+         * Drop a table from the schema.
+         *
+         * @param string $table
+         * @return void 
+         * @static 
+         */ 
+        public static function drop($table)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->drop($table);
+        }
+        
+        /**
+         * Drop a table from the schema if it exists.
+         *
+         * @param string $table
+         * @return void 
+         * @static 
+         */ 
+        public static function dropIfExists($table)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->dropIfExists($table);
+        }
+        
+        /**
+         * Rename a table on the schema.
+         *
+         * @param string $from
+         * @param string $to
+         * @return void 
+         * @static 
+         */ 
+        public static function rename($from, $to)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->rename($from, $to);
+        }
+        
+        /**
+         * Enable foreign key constraints.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function enableForeignKeyConstraints()
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->enableForeignKeyConstraints();
+        }
+        
+        /**
+         * Disable foreign key constraints.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function disableForeignKeyConstraints()
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->disableForeignKeyConstraints();
+        }
+        
+        /**
+         * Get the database connection instance.
+         *
+         * @return \Illuminate\Database\Connection 
+         * @static 
+         */ 
+        public static function getConnection()
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->getConnection();
+        }
+        
+        /**
+         * Set the database connection instance.
+         *
+         * @param \Illuminate\Database\Connection $connection
+         * @return \Illuminate\Database\Schema\MySqlBuilder 
+         * @static 
+         */ 
+        public static function setConnection($connection)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->setConnection($connection);
+        }
+        
+        /**
+         * Set the Schema Blueprint resolver callback.
+         *
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function blueprintResolver($resolver)
+        {
+            //Method inherited from \Illuminate\Database\Schema\Builder            
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->blueprintResolver($resolver);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Session\SessionManager
+     * @see \Illuminate\Session\Store
+     */ 
+    class Session {
+        
+        /**
+         * Get the session configuration.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getSessionConfig()
+        {
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->getSessionConfig();
+        }
+        
+        /**
+         * Get the default session driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Set the default session driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+        
+        /**
+         * Get a driver instance.
+         *
+         * @param string $driver
+         * @return mixed 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->driver($driver);
+        }
+        
+        /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Session\SessionManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+        
+        /**
+         * Get all of the created "drivers".
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDrivers()
+        {
+            //Method inherited from \Illuminate\Support\Manager            
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->getDrivers();
+        }
+        
+        /**
+         * Start the session, reading the data from a handler.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function start()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->start();
+        }
+        
+        /**
+         * Save the session data to storage.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function save()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->save();
+        }
+        
+        /**
+         * Age the flash data for the session.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function ageFlashData()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->ageFlashData();
+        }
+        
+        /**
+         * Get all of the session data.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function all()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->all();
+        }
+        
+        /**
+         * Checks if a key exists.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($key)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->exists($key);
+        }
+        
+        /**
+         * Checks if a key is present and not null.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->has($key);
+        }
+        
+        /**
+         * Get an item from the session.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function get($key, $default = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->get($key, $default);
+        }
+        
+        /**
+         * Get the value of a given key and then forget it.
+         *
+         * @param string $key
+         * @param string $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function pull($key, $default = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->pull($key, $default);
+        }
+        
+        /**
+         * Determine if the session contains old input.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasOldInput($key = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->hasOldInput($key);
+        }
+        
+        /**
+         * Get the requested item from the flashed input array.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getOldInput($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->getOldInput($key, $default);
+        }
+        
+        /**
+         * Replace the given session attributes entirely.
+         *
+         * @param array $attributes
+         * @return void 
+         * @static 
+         */ 
+        public static function replace($attributes)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->replace($attributes);
+        }
+        
+        /**
+         * Put a key / value pair or array of key / value pairs in the session.
+         *
+         * @param string|array $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function put($key, $value = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->put($key, $value);
+        }
+        
+        /**
+         * Get an item from the session, or store the default value.
+         *
+         * @param string $key
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function remember($key, $callback)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->remember($key, $callback);
+        }
+        
+        /**
+         * Push a value onto a session array.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function push($key, $value)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->push($key, $value);
+        }
+        
+        /**
+         * Increment the value of an item in the session.
+         *
+         * @param string $key
+         * @param int $amount
+         * @return mixed 
+         * @static 
+         */ 
+        public static function increment($key, $amount = 1)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->increment($key, $amount);
+        }
+        
+        /**
+         * Decrement the value of an item in the session.
+         *
+         * @param string $key
+         * @param int $amount
+         * @return int 
+         * @static 
+         */ 
+        public static function decrement($key, $amount = 1)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->decrement($key, $amount);
+        }
+        
+        /**
+         * Flash a key / value pair to the session.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function flash($key, $value = true)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->flash($key, $value);
+        }
+        
+        /**
+         * Flash a key / value pair to the session for immediate use.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function now($key, $value)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->now($key, $value);
+        }
+        
+        /**
+         * Reflash all of the session flash data.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function reflash()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->reflash();
+        }
+        
+        /**
+         * Reflash a subset of the current flash data.
+         *
+         * @param array|mixed $keys
+         * @return void 
+         * @static 
+         */ 
+        public static function keep($keys = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->keep($keys);
+        }
+        
+        /**
+         * Flash an input array to the session.
+         *
+         * @param array $value
+         * @return void 
+         * @static 
+         */ 
+        public static function flashInput($value)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->flashInput($value);
+        }
+        
+        /**
+         * Remove an item from the session, returning its value.
+         *
+         * @param string $key
+         * @return mixed 
+         * @static 
+         */ 
+        public static function remove($key)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->remove($key);
+        }
+        
+        /**
+         * Remove one or many items from the session.
+         *
+         * @param string|array $keys
+         * @return void 
+         * @static 
+         */ 
+        public static function forget($keys)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->forget($keys);
+        }
+        
+        /**
+         * Remove all of the items from the session.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flush()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->flush();
+        }
+        
+        /**
+         * Flush the session data and regenerate the ID.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function invalidate()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->invalidate();
+        }
+        
+        /**
+         * Generate a new session identifier.
+         *
+         * @param bool $destroy
+         * @return bool 
+         * @static 
+         */ 
+        public static function regenerate($destroy = false)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->regenerate($destroy);
+        }
+        
+        /**
+         * Generate a new session ID for the session.
+         *
+         * @param bool $destroy
+         * @return bool 
+         * @static 
+         */ 
+        public static function migrate($destroy = false)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->migrate($destroy);
+        }
+        
+        /**
+         * Determine if the session has been started.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isStarted()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->isStarted();
+        }
+        
+        /**
+         * Get the name of the session.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getName()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->getName();
+        }
+        
+        /**
+         * Set the name of the session.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setName($name)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setName($name);
+        }
+        
+        /**
+         * Get the current session ID.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getId()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->getId();
+        }
+        
+        /**
+         * Set the session ID.
+         *
+         * @param string $id
+         * @return void 
+         * @static 
+         */ 
+        public static function setId($id)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setId($id);
+        }
+        
+        /**
+         * Determine if this is a valid session ID.
+         *
+         * @param string $id
+         * @return bool 
+         * @static 
+         */ 
+        public static function isValidId($id)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->isValidId($id);
+        }
+        
+        /**
+         * Set the existence of the session on the handler if applicable.
+         *
+         * @param bool $value
+         * @return void 
+         * @static 
+         */ 
+        public static function setExists($value)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setExists($value);
+        }
+        
+        /**
+         * Get the CSRF token value.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function token()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->token();
+        }
+        
+        /**
+         * Regenerate the CSRF token value.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function regenerateToken()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->regenerateToken();
+        }
+        
+        /**
+         * Get the previous URL from the session.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function previousUrl()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->previousUrl();
+        }
+        
+        /**
+         * Set the "previous" URL in the session.
+         *
+         * @param string $url
+         * @return void 
+         * @static 
+         */ 
+        public static function setPreviousUrl($url)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setPreviousUrl($url);
+        }
+        
+        /**
+         * Get the underlying session handler implementation.
+         *
+         * @return \SessionHandlerInterface 
+         * @static 
+         */ 
+        public static function getHandler()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->getHandler();
+        }
+        
+        /**
+         * Determine if the session handler needs a request.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function handlerNeedsRequest()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->handlerNeedsRequest();
+        }
+        
+        /**
+         * Set the request on the handler instance.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return void 
+         * @static 
+         */ 
+        public static function setRequestOnHandler($request)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setRequestOnHandler($request);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Filesystem\FilesystemManager
+     */ 
+    class Storage {
+        
+        /**
+         * Get a filesystem instance.
+         *
+         * @param string $name
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function drive($name = null)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->drive($name);
+        }
+        
+        /**
+         * Get a filesystem instance.
+         *
+         * @param string $name
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function disk($name = null)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->disk($name);
+        }
+        
+        /**
+         * Get a default cloud filesystem instance.
+         *
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function cloud()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->cloud();
+        }
+        
+        /**
+         * Create an instance of the local driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function createLocalDriver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createLocalDriver($config);
+        }
+        
+        /**
+         * Create an instance of the ftp driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function createFtpDriver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createFtpDriver($config);
+        }
+        
+        /**
+         * Create an instance of the sftp driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function createSftpDriver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createSftpDriver($config);
+        }
+        
+        /**
+         * Create an instance of the Amazon S3 driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Contracts\Filesystem\Cloud 
+         * @static 
+         */ 
+        public static function createS3Driver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createS3Driver($config);
+        }
+        
+        /**
+         * Create an instance of the Rackspace driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Contracts\Filesystem\Cloud 
+         * @static 
+         */ 
+        public static function createRackspaceDriver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createRackspaceDriver($config);
+        }
+        
+        /**
+         * Set the given disk instance.
+         *
+         * @param string $name
+         * @param mixed $disk
+         * @return \Illuminate\Filesystem\FilesystemManager 
+         * @static 
+         */ 
+        public static function set($name, $disk)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->set($name, $disk);
+        }
+        
+        /**
+         * Get the default driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+        
+        /**
+         * Get the default cloud driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultCloudDriver()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->getDefaultCloudDriver();
+        }
+        
+        /**
+         * Unset the given disk instances.
+         *
+         * @param array|string $disk
+         * @return \Illuminate\Filesystem\FilesystemManager 
+         * @static 
+         */ 
+        public static function forgetDisk($disk)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->forgetDisk($disk);
+        }
+        
+        /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Filesystem\FilesystemManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+        
+        /**
+         * Assert that the given file exists.
+         *
+         * @param string $path
+         * @return void 
+         * @static 
+         */ 
+        public static function assertExists($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        $instance->assertExists($path);
+        }
+        
+        /**
+         * Assert that the given file does not exist.
+         *
+         * @param string $path
+         * @return void 
+         * @static 
+         */ 
+        public static function assertMissing($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        $instance->assertMissing($path);
+        }
+        
+        /**
+         * Determine if a file exists.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->exists($path);
+        }
+        
+        /**
+         * Get the full path for the file at the given "short" path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function path($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->path($path);
+        }
+        
+        /**
+         * Get the contents of a file.
+         *
+         * @param string $path
+         * @return string 
+         * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+         * @static 
+         */ 
+        public static function get($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->get($path);
+        }
+        
+        /**
+         * 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 
+         * @static 
+         */ 
+        public static function response($path, $name = null, $headers = array(), $disposition = 'inline')
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->response($path, $name, $headers, $disposition);
+        }
+        
+        /**
+         * 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 
+         * @static 
+         */ 
+        public static function download($path, $name = null, $headers = array())
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->download($path, $name, $headers);
+        }
+        
+        /**
+         * Write the contents of a file.
+         *
+         * @param string $path
+         * @param string|resource $contents
+         * @param mixed $options
+         * @return bool 
+         * @static 
+         */ 
+        public static function put($path, $contents, $options = array())
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->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 
+         * @static 
+         */ 
+        public static function putFile($path, $file, $options = array())
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->putFile($path, $file, $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 
+         * @static 
+         */ 
+        public static function putFileAs($path, $file, $name, $options = array())
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->putFileAs($path, $file, $name, $options);
+        }
+        
+        /**
+         * Get the visibility for the given path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function getVisibility($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->getVisibility($path);
+        }
+        
+        /**
+         * Set the visibility for the given path.
+         *
+         * @param string $path
+         * @param string $visibility
+         * @return void 
+         * @static 
+         */ 
+        public static function setVisibility($path, $visibility)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        $instance->setVisibility($path, $visibility);
+        }
+        
+        /**
+         * Prepend to a file.
+         *
+         * @param string $path
+         * @param string $data
+         * @param string $separator
+         * @return int 
+         * @static 
+         */ 
+        public static function prepend($path, $data, $separator = '')
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->prepend($path, $data, $separator);
+        }
+        
+        /**
+         * Append to a file.
+         *
+         * @param string $path
+         * @param string $data
+         * @param string $separator
+         * @return int 
+         * @static 
+         */ 
+        public static function append($path, $data, $separator = '')
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->append($path, $data, $separator);
+        }
+        
+        /**
+         * Delete the file at a given path.
+         *
+         * @param string|array $paths
+         * @return bool 
+         * @static 
+         */ 
+        public static function delete($paths)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->delete($paths);
+        }
+        
+        /**
+         * Copy a file to a new location.
+         *
+         * @param string $from
+         * @param string $to
+         * @return bool 
+         * @static 
+         */ 
+        public static function copy($from, $to)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->copy($from, $to);
+        }
+        
+        /**
+         * Move a file to a new location.
+         *
+         * @param string $from
+         * @param string $to
+         * @return bool 
+         * @static 
+         */ 
+        public static function move($from, $to)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->move($from, $to);
+        }
+        
+        /**
+         * Get the file size of a given file.
+         *
+         * @param string $path
+         * @return int 
+         * @static 
+         */ 
+        public static function size($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->size($path);
+        }
+        
+        /**
+         * Get the mime-type of a given file.
+         *
+         * @param string $path
+         * @return string|false 
+         * @static 
+         */ 
+        public static function mimeType($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->mimeType($path);
+        }
+        
+        /**
+         * Get the file's last modification time.
+         *
+         * @param string $path
+         * @return int 
+         * @static 
+         */ 
+        public static function lastModified($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->lastModified($path);
+        }
+        
+        /**
+         * Get the URL for the file at the given path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function url($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->url($path);
+        }
+        
+        /**
+         * Get a temporary URL for the file at the given path.
+         *
+         * @param string $path
+         * @param \DateTimeInterface $expiration
+         * @param array $options
+         * @return string 
+         * @static 
+         */ 
+        public static function temporaryUrl($path, $expiration, $options = array())
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->temporaryUrl($path, $expiration, $options);
+        }
+        
+        /**
+         * 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 
+         * @static 
+         */ 
+        public static function getAwsTemporaryUrl($adapter, $path, $expiration, $options)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->getAwsTemporaryUrl($adapter, $path, $expiration, $options);
+        }
+        
+        /**
+         * 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 
+         * @static 
+         */ 
+        public static function getRackspaceTemporaryUrl($adapter, $path, $expiration, $options)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->getRackspaceTemporaryUrl($adapter, $path, $expiration, $options);
+        }
+        
+        /**
+         * Get an array of all files in a directory.
+         *
+         * @param string|null $directory
+         * @param bool $recursive
+         * @return array 
+         * @static 
+         */ 
+        public static function files($directory = null, $recursive = false)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->files($directory, $recursive);
+        }
+        
+        /**
+         * Get all of the files from the given directory (recursive).
+         *
+         * @param string|null $directory
+         * @return array 
+         * @static 
+         */ 
+        public static function allFiles($directory = null)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->allFiles($directory);
+        }
+        
+        /**
+         * Get all of the directories within a given directory.
+         *
+         * @param string|null $directory
+         * @param bool $recursive
+         * @return array 
+         * @static 
+         */ 
+        public static function directories($directory = null, $recursive = false)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->directories($directory, $recursive);
+        }
+        
+        /**
+         * Get all (recursive) of the directories within a given directory.
+         *
+         * @param string|null $directory
+         * @return array 
+         * @static 
+         */ 
+        public static function allDirectories($directory = null)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->allDirectories($directory);
+        }
+        
+        /**
+         * Create a directory.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function makeDirectory($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->makeDirectory($path);
+        }
+        
+        /**
+         * Recursively delete a directory.
+         *
+         * @param string $directory
+         * @return bool 
+         * @static 
+         */ 
+        public static function deleteDirectory($directory)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->deleteDirectory($directory);
+        }
+        
+        /**
+         * Flush the Flysystem cache.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushCache()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        $instance->flushCache();
+        }
+        
+        /**
+         * Get the Flysystem driver.
+         *
+         * @return \League\Flysystem\FilesystemInterface 
+         * @static 
+         */ 
+        public static function getDriver()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->getDriver();
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Routing\UrlGenerator
+     */ 
+    class URL {
+        
+        /**
+         * Get the full URL for the current request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function full()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->full();
+        }
+        
+        /**
+         * Get the current URL for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function current()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->current();
+        }
+        
+        /**
+         * Get the URL for the previous request.
+         *
+         * @param mixed $fallback
+         * @return string 
+         * @static 
+         */ 
+        public static function previous($fallback = false)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->previous($fallback);
+        }
+        
+        /**
+         * Generate an absolute URL to the given path.
+         *
+         * @param string $path
+         * @param mixed $extra
+         * @param bool|null $secure
+         * @return string 
+         * @static 
+         */ 
+        public static function to($path, $extra = array(), $secure = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->to($path, $extra, $secure);
+        }
+        
+        /**
+         * Generate a secure, absolute URL to the given path.
+         *
+         * @param string $path
+         * @param array $parameters
+         * @return string 
+         * @static 
+         */ 
+        public static function secure($path, $parameters = array())
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->secure($path, $parameters);
+        }
+        
+        /**
+         * Generate the URL to an application asset.
+         *
+         * @param string $path
+         * @param bool|null $secure
+         * @return string 
+         * @static 
+         */ 
+        public static function asset($path, $secure = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->asset($path, $secure);
+        }
+        
+        /**
+         * Generate the URL to a secure asset.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function secureAsset($path)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->secureAsset($path);
+        }
+        
+        /**
+         * Generate the URL to an asset from a custom root domain such as CDN, etc.
+         *
+         * @param string $root
+         * @param string $path
+         * @param bool|null $secure
+         * @return string 
+         * @static 
+         */ 
+        public static function assetFrom($root, $path, $secure = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->assetFrom($root, $path, $secure);
+        }
+        
+        /**
+         * Get the default scheme for a raw URL.
+         *
+         * @param bool|null $secure
+         * @return string 
+         * @static 
+         */ 
+        public static function formatScheme($secure)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatScheme($secure);
+        }
+        
+        /**
+         * Create a signed route URL for a named route.
+         *
+         * @param string $name
+         * @param array $parameters
+         * @param \DateTimeInterface|int $expiration
+         * @return string 
+         * @static 
+         */ 
+        public static function signedRoute($name, $parameters = array(), $expiration = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->signedRoute($name, $parameters, $expiration);
+        }
+        
+        /**
+         * Create a temporary signed route URL for a named route.
+         *
+         * @param string $name
+         * @param \DateTimeInterface|int $expiration
+         * @param array $parameters
+         * @return string 
+         * @static 
+         */ 
+        public static function temporarySignedRoute($name, $expiration, $parameters = array())
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->temporarySignedRoute($name, $expiration, $parameters);
+        }
+        
+        /**
+         * Determine if the given request has a valid signature.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasValidSignature($request)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->hasValidSignature($request);
+        }
+        
+        /**
+         * Get the URL to a named route.
+         *
+         * @param string $name
+         * @param mixed $parameters
+         * @param bool $absolute
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function route($name, $parameters = array(), $absolute = true)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->route($name, $parameters, $absolute);
+        }
+        
+        /**
+         * Get the URL to a controller action.
+         *
+         * @param string $action
+         * @param mixed $parameters
+         * @param bool $absolute
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function action($action, $parameters = array(), $absolute = true)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->action($action, $parameters, $absolute);
+        }
+        
+        /**
+         * Format the array of URL parameters.
+         *
+         * @param mixed|array $parameters
+         * @return array 
+         * @static 
+         */ 
+        public static function formatParameters($parameters)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatParameters($parameters);
+        }
+        
+        /**
+         * Get the base URL for the request.
+         *
+         * @param string $scheme
+         * @param string $root
+         * @return string 
+         * @static 
+         */ 
+        public static function formatRoot($scheme, $root = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatRoot($scheme, $root);
+        }
+        
+        /**
+         * Format the given URL segments into a single URL.
+         *
+         * @param string $root
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function format($root, $path)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->format($root, $path);
+        }
+        
+        /**
+         * Determine if the given path is a valid URL.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function isValidUrl($path)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->isValidUrl($path);
+        }
+        
+        /**
+         * Set the default named parameters used by the URL generator.
+         *
+         * @param array $defaults
+         * @return void 
+         * @static 
+         */ 
+        public static function defaults($defaults)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        $instance->defaults($defaults);
+        }
+        
+        /**
+         * Get the default named parameters used by the URL generator.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDefaultParameters()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->getDefaultParameters();
+        }
+        
+        /**
+         * Force the scheme for URLs.
+         *
+         * @param string $schema
+         * @return void 
+         * @static 
+         */ 
+        public static function forceScheme($schema)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        $instance->forceScheme($schema);
+        }
+        
+        /**
+         * Set the forced root URL.
+         *
+         * @param string $root
+         * @return void 
+         * @static 
+         */ 
+        public static function forceRootUrl($root)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        $instance->forceRootUrl($root);
+        }
+        
+        /**
+         * Set a callback to be used to format the host of generated URLs.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function formatHostUsing($callback)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatHostUsing($callback);
+        }
+        
+        /**
+         * Set a callback to be used to format the path of generated URLs.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function formatPathUsing($callback)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatPathUsing($callback);
+        }
+        
+        /**
+         * Get the path formatter being used by the URL generator.
+         *
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function pathFormatter()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->pathFormatter();
+        }
+        
+        /**
+         * Get the request instance.
+         *
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function getRequest()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->getRequest();
+        }
+        
+        /**
+         * Set the current request instance.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return void 
+         * @static 
+         */ 
+        public static function setRequest($request)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        $instance->setRequest($request);
+        }
+        
+        /**
+         * Set the route collection.
+         *
+         * @param \Illuminate\Routing\RouteCollection $routes
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function setRoutes($routes)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->setRoutes($routes);
+        }
+        
+        /**
+         * Set the session resolver for the generator.
+         *
+         * @param callable $sessionResolver
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function setSessionResolver($sessionResolver)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->setSessionResolver($sessionResolver);
+        }
+        
+        /**
+         * Set the encryption key resolver.
+         *
+         * @param callable $keyResolver
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function setKeyResolver($keyResolver)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->setKeyResolver($keyResolver);
+        }
+        
+        /**
+         * Set the root controller namespace.
+         *
+         * @param string $rootNamespace
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function setRootControllerNamespace($rootNamespace)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->setRootControllerNamespace($rootNamespace);
+        }
+        
+        /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Routing\UrlGenerator::macro($name, $macro);
+        }
+        
+        /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin)
+        {
+                        \Illuminate\Routing\UrlGenerator::mixin($mixin);
+        }
+        
+        /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Routing\UrlGenerator::hasMacro($name);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\Validation\Factory
+     */ 
+    class Validator {
+        
+        /**
+         * Create a new Validator instance.
+         *
+         * @param array $data
+         * @param array $rules
+         * @param array $messages
+         * @param array $customAttributes
+         * @return \Illuminate\Validation\Validator 
+         * @static 
+         */ 
+        public static function make($data, $rules, $messages = array(), $customAttributes = array())
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        return $instance->make($data, $rules, $messages, $customAttributes);
+        }
+        
+        /**
+         * Validate the given data against the provided rules.
+         *
+         * @param array $data
+         * @param array $rules
+         * @param array $messages
+         * @param array $customAttributes
+         * @return array 
+         * @throws \Illuminate\Validation\ValidationException
+         * @static 
+         */ 
+        public static function validate($data, $rules, $messages = array(), $customAttributes = array())
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        return $instance->validate($data, $rules, $messages, $customAttributes);
+        }
+        
+        /**
+         * Register a custom validator extension.
+         *
+         * @param string $rule
+         * @param \Closure|string $extension
+         * @param string $message
+         * @return void 
+         * @static 
+         */ 
+        public static function extend($rule, $extension, $message = null)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->extend($rule, $extension, $message);
+        }
+        
+        /**
+         * Register a custom implicit validator extension.
+         *
+         * @param string $rule
+         * @param \Closure|string $extension
+         * @param string $message
+         * @return void 
+         * @static 
+         */ 
+        public static function extendImplicit($rule, $extension, $message = null)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->extendImplicit($rule, $extension, $message);
+        }
+        
+        /**
+         * Register a custom dependent validator extension.
+         *
+         * @param string $rule
+         * @param \Closure|string $extension
+         * @param string $message
+         * @return void 
+         * @static 
+         */ 
+        public static function extendDependent($rule, $extension, $message = null)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->extendDependent($rule, $extension, $message);
+        }
+        
+        /**
+         * Register a custom validator message replacer.
+         *
+         * @param string $rule
+         * @param \Closure|string $replacer
+         * @return void 
+         * @static 
+         */ 
+        public static function replacer($rule, $replacer)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->replacer($rule, $replacer);
+        }
+        
+        /**
+         * Set the Validator instance resolver.
+         *
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function resolver($resolver)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->resolver($resolver);
+        }
+        
+        /**
+         * Get the Translator implementation.
+         *
+         * @return \Illuminate\Contracts\Translation\Translator 
+         * @static 
+         */ 
+        public static function getTranslator()
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        return $instance->getTranslator();
+        }
+        
+        /**
+         * Get the Presence Verifier implementation.
+         *
+         * @return \Illuminate\Validation\PresenceVerifierInterface 
+         * @static 
+         */ 
+        public static function getPresenceVerifier()
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        return $instance->getPresenceVerifier();
+        }
+        
+        /**
+         * Set the Presence Verifier implementation.
+         *
+         * @param \Illuminate\Validation\PresenceVerifierInterface $presenceVerifier
+         * @return void 
+         * @static 
+         */ 
+        public static function setPresenceVerifier($presenceVerifier)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->setPresenceVerifier($presenceVerifier);
+        }
+         
+    }
+
+    /**
+     * 
+     *
+     * @see \Illuminate\View\Factory
+     */ 
+    class View {
+        
+        /**
+         * Get the evaluated view contents for the given view.
+         *
+         * @param string $path
+         * @param array $data
+         * @param array $mergeData
+         * @return \Illuminate\Contracts\View\View 
+         * @static 
+         */ 
+        public static function file($path, $data = array(), $mergeData = array())
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->file($path, $data, $mergeData);
+        }
+        
+        /**
+         * Get the evaluated view contents for the given view.
+         *
+         * @param string $view
+         * @param array $data
+         * @param array $mergeData
+         * @return \Illuminate\Contracts\View\View 
+         * @static 
+         */ 
+        public static function make($view, $data = array(), $mergeData = array())
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->make($view, $data, $mergeData);
+        }
+        
+        /**
+         * 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 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function first($views, $data = array(), $mergeData = array())
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->first($views, $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 
+         * @static 
+         */ 
+        public static function renderWhen($condition, $view, $data = array(), $mergeData = array())
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->renderWhen($condition, $view, $data, $mergeData);
+        }
+        
+        /**
+         * Get the rendered contents of a partial from a loop.
+         *
+         * @param string $view
+         * @param array $data
+         * @param string $iterator
+         * @param string $empty
+         * @return string 
+         * @static 
+         */ 
+        public static function renderEach($view, $data, $iterator, $empty = 'raw|')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->renderEach($view, $data, $iterator, $empty);
+        }
+        
+        /**
+         * Determine if a given view exists.
+         *
+         * @param string $view
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($view)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->exists($view);
+        }
+        
+        /**
+         * Get the appropriate view engine for the given path.
+         *
+         * @param string $path
+         * @return \Illuminate\Contracts\View\Engine 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function getEngineFromPath($path)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getEngineFromPath($path);
+        }
+        
+        /**
+         * Add a piece of shared data to the environment.
+         *
+         * @param array|string $key
+         * @param mixed $value
+         * @return mixed 
+         * @static 
+         */ 
+        public static function share($key, $value = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->share($key, $value);
+        }
+        
+        /**
+         * Increment the rendering counter.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function incrementRender()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->incrementRender();
+        }
+        
+        /**
+         * Decrement the rendering counter.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function decrementRender()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->decrementRender();
+        }
+        
+        /**
+         * Check if there are no active render operations.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function doneRendering()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->doneRendering();
+        }
+        
+        /**
+         * Add a location to the array of view locations.
+         *
+         * @param string $location
+         * @return void 
+         * @static 
+         */ 
+        public static function addLocation($location)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->addLocation($location);
+        }
+        
+        /**
+         * Add a new namespace to the loader.
+         *
+         * @param string $namespace
+         * @param string|array $hints
+         * @return \Illuminate\View\Factory 
+         * @static 
+         */ 
+        public static function addNamespace($namespace, $hints)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->addNamespace($namespace, $hints);
+        }
+        
+        /**
+         * Prepend a new namespace to the loader.
+         *
+         * @param string $namespace
+         * @param string|array $hints
+         * @return \Illuminate\View\Factory 
+         * @static 
+         */ 
+        public static function prependNamespace($namespace, $hints)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->prependNamespace($namespace, $hints);
+        }
+        
+        /**
+         * Replace the namespace hints for the given namespace.
+         *
+         * @param string $namespace
+         * @param string|array $hints
+         * @return \Illuminate\View\Factory 
+         * @static 
+         */ 
+        public static function replaceNamespace($namespace, $hints)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->replaceNamespace($namespace, $hints);
+        }
+        
+        /**
+         * Register a valid view extension and its engine.
+         *
+         * @param string $extension
+         * @param string $engine
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function addExtension($extension, $engine, $resolver = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->addExtension($extension, $engine, $resolver);
+        }
+        
+        /**
+         * Flush all of the factory state like sections and stacks.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushState()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushState();
+        }
+        
+        /**
+         * Flush all of the section contents if done rendering.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushStateIfDoneRendering()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushStateIfDoneRendering();
+        }
+        
+        /**
+         * Get the extension to engine bindings.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getExtensions()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getExtensions();
+        }
+        
+        /**
+         * Get the engine resolver instance.
+         *
+         * @return \Illuminate\View\Engines\EngineResolver 
+         * @static 
+         */ 
+        public static function getEngineResolver()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getEngineResolver();
+        }
+        
+        /**
+         * Get the view finder instance.
+         *
+         * @return \Illuminate\View\ViewFinderInterface 
+         * @static 
+         */ 
+        public static function getFinder()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getFinder();
+        }
+        
+        /**
+         * Set the view finder instance.
+         *
+         * @param \Illuminate\View\ViewFinderInterface $finder
+         * @return void 
+         * @static 
+         */ 
+        public static function setFinder($finder)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->setFinder($finder);
+        }
+        
+        /**
+         * Flush the cache of views located by the finder.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushFinderCache()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushFinderCache();
+        }
+        
+        /**
+         * Get the event dispatcher instance.
+         *
+         * @return \Illuminate\Contracts\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function getDispatcher()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getDispatcher();
+        }
+        
+        /**
+         * Set the event dispatcher instance.
+         *
+         * @param \Illuminate\Contracts\Events\Dispatcher $events
+         * @return void 
+         * @static 
+         */ 
+        public static function setDispatcher($events)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->setDispatcher($events);
+        }
+        
+        /**
+         * Get the IoC container instance.
+         *
+         * @return \Illuminate\Contracts\Container\Container 
+         * @static 
+         */ 
+        public static function getContainer()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getContainer();
+        }
+        
+        /**
+         * Set the IoC container instance.
+         *
+         * @param \Illuminate\Contracts\Container\Container $container
+         * @return void 
+         * @static 
+         */ 
+        public static function setContainer($container)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->setContainer($container);
+        }
+        
+        /**
+         * Get an item from the shared data.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function shared($key, $default = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->shared($key, $default);
+        }
+        
+        /**
+         * Get all of the shared data for the environment.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getShared()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getShared();
+        }
+        
+        /**
+         * Start a component rendering process.
+         *
+         * @param string $name
+         * @param array $data
+         * @return void 
+         * @static 
+         */ 
+        public static function startComponent($name, $data = array())
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startComponent($name, $data);
+        }
+        
+        /**
+         * Render the current component.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function renderComponent()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->renderComponent();
+        }
+        
+        /**
+         * Start the slot rendering process.
+         *
+         * @param string $name
+         * @param string|null $content
+         * @return void 
+         * @static 
+         */ 
+        public static function slot($name, $content = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->slot($name, $content);
+        }
+        
+        /**
+         * Save the slot content for rendering.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function endSlot()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->endSlot();
+        }
+        
+        /**
+         * Register a view creator event.
+         *
+         * @param array|string $views
+         * @param \Closure|string $callback
+         * @return array 
+         * @static 
+         */ 
+        public static function creator($views, $callback)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->creator($views, $callback);
+        }
+        
+        /**
+         * Register multiple view composers via an array.
+         *
+         * @param array $composers
+         * @return array 
+         * @static 
+         */ 
+        public static function composers($composers)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->composers($composers);
+        }
+        
+        /**
+         * Register a view composer event.
+         *
+         * @param array|string $views
+         * @param \Closure|string $callback
+         * @return array 
+         * @static 
+         */ 
+        public static function composer($views, $callback)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->composer($views, $callback);
+        }
+        
+        /**
+         * Call the composer for a given view.
+         *
+         * @param \Illuminate\Contracts\View\View $view
+         * @return void 
+         * @static 
+         */ 
+        public static function callComposer($view)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->callComposer($view);
+        }
+        
+        /**
+         * Call the creator for a given view.
+         *
+         * @param \Illuminate\Contracts\View\View $view
+         * @return void 
+         * @static 
+         */ 
+        public static function callCreator($view)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->callCreator($view);
+        }
+        
+        /**
+         * Start injecting content into a section.
+         *
+         * @param string $section
+         * @param string|null $content
+         * @return void 
+         * @static 
+         */ 
+        public static function startSection($section, $content = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startSection($section, $content);
+        }
+        
+        /**
+         * Inject inline content into a section.
+         *
+         * @param string $section
+         * @param string $content
+         * @return void 
+         * @static 
+         */ 
+        public static function inject($section, $content)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->inject($section, $content);
+        }
+        
+        /**
+         * Stop injecting content into a section and return its contents.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function yieldSection()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->yieldSection();
+        }
+        
+        /**
+         * Stop injecting content into a section.
+         *
+         * @param bool $overwrite
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function stopSection($overwrite = false)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->stopSection($overwrite);
+        }
+        
+        /**
+         * Stop injecting content into a section and append it.
+         *
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function appendSection()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->appendSection();
+        }
+        
+        /**
+         * Get the string contents of a section.
+         *
+         * @param string $section
+         * @param string $default
+         * @return string 
+         * @static 
+         */ 
+        public static function yieldContent($section, $default = '')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->yieldContent($section, $default);
+        }
+        
+        /**
+         * Get the parent placeholder for the current request.
+         *
+         * @param string $section
+         * @return string 
+         * @static 
+         */ 
+        public static function parentPlaceholder($section = '')
+        {
+                        return \Illuminate\View\Factory::parentPlaceholder($section);
+        }
+        
+        /**
+         * Check if section exists.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasSection($name)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->hasSection($name);
+        }
+        
+        /**
+         * Get the contents of a section.
+         *
+         * @param string $name
+         * @param string $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getSection($name, $default = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getSection($name, $default);
+        }
+        
+        /**
+         * Get the entire array of sections.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getSections()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getSections();
+        }
+        
+        /**
+         * Flush all of the sections.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushSections()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushSections();
+        }
+        
+        /**
+         * Add new loop to the stack.
+         *
+         * @param \Countable|array $data
+         * @return void 
+         * @static 
+         */ 
+        public static function addLoop($data)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->addLoop($data);
+        }
+        
+        /**
+         * Increment the top loop's indices.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function incrementLoopIndices()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->incrementLoopIndices();
+        }
+        
+        /**
+         * Pop a loop from the top of the loop stack.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function popLoop()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->popLoop();
+        }
+        
+        /**
+         * Get an instance of the last loop in the stack.
+         *
+         * @return \stdClass|null 
+         * @static 
+         */ 
+        public static function getLastLoop()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getLastLoop();
+        }
+        
+        /**
+         * Get the entire loop stack.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getLoopStack()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getLoopStack();
+        }
+        
+        /**
+         * Start injecting content into a push section.
+         *
+         * @param string $section
+         * @param string $content
+         * @return void 
+         * @static 
+         */ 
+        public static function startPush($section, $content = '')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startPush($section, $content);
+        }
+        
+        /**
+         * Stop injecting content into a push section.
+         *
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function stopPush()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->stopPush();
+        }
+        
+        /**
+         * Start prepending content into a push section.
+         *
+         * @param string $section
+         * @param string $content
+         * @return void 
+         * @static 
+         */ 
+        public static function startPrepend($section, $content = '')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startPrepend($section, $content);
+        }
+        
+        /**
+         * Stop prepending content into a push section.
+         *
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function stopPrepend()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->stopPrepend();
+        }
+        
+        /**
+         * Get the string contents of a push section.
+         *
+         * @param string $section
+         * @param string $default
+         * @return string 
+         * @static 
+         */ 
+        public static function yieldPushContent($section, $default = '')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->yieldPushContent($section, $default);
+        }
+        
+        /**
+         * Flush all of the stacks.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushStacks()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushStacks();
+        }
+        
+        /**
+         * Start a translation block.
+         *
+         * @param array $replacements
+         * @return void 
+         * @static 
+         */ 
+        public static function startTranslation($replacements = array())
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startTranslation($replacements);
+        }
+        
+        /**
+         * Render the current translation.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function renderTranslation()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->renderTranslation();
+        }
+         
+    }
+ 
+}
+
+namespace Mews\Captcha\Facades { 
+
+    /**
+     * 
+     *
+     * @see \Mews\Captcha
+     */ 
+    class Captcha {
+        
+        /**
+         * Create captcha image
+         *
+         * @param string $config
+         * @param boolean $api
+         * @return \Mews\Captcha\ImageManager->response 
+         * @static 
+         */ 
+        public static function create($config = 'default', $api = false)
+        {
+                        /** @var \Mews\Captcha\Captcha $instance */
+                        return $instance->create($config, $api);
+        }
+        
+        /**
+         * Captcha check
+         *
+         * @param $value
+         * @return bool 
+         * @static 
+         */ 
+        public static function check($value)
+        {
+                        /** @var \Mews\Captcha\Captcha $instance */
+                        return $instance->check($value);
+        }
+        
+        /**
+         * Captcha check
+         *
+         * @param $value
+         * @return bool 
+         * @static 
+         */ 
+        public static function check_api($value, $key)
+        {
+                        /** @var \Mews\Captcha\Captcha $instance */
+                        return $instance->check_api($value, $key);
+        }
+        
+        /**
+         * Generate captcha image source
+         *
+         * @param null $config
+         * @return string 
+         * @static 
+         */ 
+        public static function src($config = null)
+        {
+                        /** @var \Mews\Captcha\Captcha $instance */
+                        return $instance->src($config);
+        }
+        
+        /**
+         * Generate captcha image html tag
+         *
+         * @param null $config
+         * @param array $attrs HTML attributes supplied to the image tag where key is the attribute
+         * and the value is the attribute value
+         * @return string 
+         * @static 
+         */ 
+        public static function img($config = null, $attrs = array())
+        {
+                        /** @var \Mews\Captcha\Captcha $instance */
+                        return $instance->img($config, $attrs);
+        }
+         
+    }
+ 
+}
+
+namespace Jenssegers\Agent\Facades { 
+
+    /**
+     * 
+     *
+     */ 
+    class Agent {
+        
+        /**
+         * Get all detection rules. These rules include the additional
+         * platforms and browsers and utilities.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDetectionRulesExtended()
+        {
+                        return \Jenssegers\Agent\Agent::getDetectionRulesExtended();
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getRules()
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getRules();
+        }
+        
+        /**
+         * 
+         *
+         * @return \Jenssegers\Agent\CrawlerDetect 
+         * @static 
+         */ 
+        public static function getCrawlerDetect()
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getCrawlerDetect();
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getBrowsers()
+        {
+                        return \Jenssegers\Agent\Agent::getBrowsers();
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getOperatingSystems()
+        {
+                        return \Jenssegers\Agent\Agent::getOperatingSystems();
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getPlatforms()
+        {
+                        return \Jenssegers\Agent\Agent::getPlatforms();
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getDesktopDevices()
+        {
+                        return \Jenssegers\Agent\Agent::getDesktopDevices();
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getProperties()
+        {
+                        return \Jenssegers\Agent\Agent::getProperties();
+        }
+        
+        /**
+         * Get accept languages.
+         *
+         * @param string $acceptLanguage
+         * @return array 
+         * @static 
+         */ 
+        public static function languages($acceptLanguage = null)
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->languages($acceptLanguage);
+        }
+        
+        /**
+         * Get the browser name.
+         *
+         * @param string|null $userAgent
+         * @return string 
+         * @static 
+         */ 
+        public static function browser($userAgent = null)
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->browser($userAgent);
+        }
+        
+        /**
+         * Get the platform name.
+         *
+         * @param string|null $userAgent
+         * @return string 
+         * @static 
+         */ 
+        public static function platform($userAgent = null)
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->platform($userAgent);
+        }
+        
+        /**
+         * Get the device name.
+         *
+         * @param string|null $userAgent
+         * @return string 
+         * @static 
+         */ 
+        public static function device($userAgent = null)
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->device($userAgent);
+        }
+        
+        /**
+         * Check if the device is a desktop computer.
+         *
+         * @param string|null $userAgent deprecated
+         * @param array $httpHeaders deprecated
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDesktop($userAgent = null, $httpHeaders = null)
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->isDesktop($userAgent, $httpHeaders);
+        }
+        
+        /**
+         * Check if the device is a mobile phone.
+         *
+         * @param string|null $userAgent deprecated
+         * @param array $httpHeaders deprecated
+         * @return bool 
+         * @static 
+         */ 
+        public static function isPhone($userAgent = null, $httpHeaders = null)
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->isPhone($userAgent, $httpHeaders);
+        }
+        
+        /**
+         * Get the robot name.
+         *
+         * @param string|null $userAgent
+         * @return string|bool 
+         * @static 
+         */ 
+        public static function robot($userAgent = null)
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->robot($userAgent);
+        }
+        
+        /**
+         * Check if device is a robot.
+         *
+         * @param string|null $userAgent
+         * @return bool 
+         * @static 
+         */ 
+        public static function isRobot($userAgent = null)
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->isRobot($userAgent);
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function version($propertyName, $type = 'text')
+        {
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->version($propertyName, $type);
+        }
+        
+        /**
+         * Get the current script version.
+         * 
+         * This is useful for the demo.php file,
+         * so people can check on what version they are testing
+         * for mobile devices.
+         *
+         * @return string The version number in semantic version format.
+         * @static 
+         */ 
+        public static function getScriptVersion()
+        {
+            //Method inherited from \Mobile_Detect            
+                        return \Jenssegers\Agent\Agent::getScriptVersion();
+        }
+        
+        /**
+         * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers.
+         *
+         * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract
+         *                           the headers. The default null is left for backwards compatibility.
+         * @static 
+         */ 
+        public static function setHttpHeaders($httpHeaders = null)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->setHttpHeaders($httpHeaders);
+        }
+        
+        /**
+         * Retrieves the HTTP headers.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getHttpHeaders()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getHttpHeaders();
+        }
+        
+        /**
+         * Retrieves a particular header. If it doesn't exist, no exception/error is caused.
+         * 
+         * Simply null is returned.
+         *
+         * @param string $header The name of the header to retrieve. Can be HTTP compliant such as
+         *                       "User-Agent" or "X-Device-User-Agent" or can be php-esque with the
+         *                       all-caps, HTTP_ prefixed, underscore seperated awesomeness.
+         * @return string|null The value of the header.
+         * @static 
+         */ 
+        public static function getHttpHeader($header)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getHttpHeader($header);
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getMobileHeaders()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getMobileHeaders();
+        }
+        
+        /**
+         * Get all possible HTTP headers that
+         * can contain the User-Agent string.
+         *
+         * @return array List of HTTP headers.
+         * @static 
+         */ 
+        public static function getUaHttpHeaders()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getUaHttpHeaders();
+        }
+        
+        /**
+         * Set CloudFront headers
+         * http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device
+         *
+         * @param array $cfHeaders List of HTTP headers
+         * @return boolean If there were CloudFront headers to be set
+         * @static 
+         */ 
+        public static function setCfHeaders($cfHeaders = null)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->setCfHeaders($cfHeaders);
+        }
+        
+        /**
+         * Retrieves the cloudfront headers.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getCfHeaders()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getCfHeaders();
+        }
+        
+        /**
+         * Set the User-Agent to be used.
+         *
+         * @param string $userAgent The user agent string to set.
+         * @return string|null 
+         * @static 
+         */ 
+        public static function setUserAgent($userAgent = null)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->setUserAgent($userAgent);
+        }
+        
+        /**
+         * Retrieve the User-Agent.
+         *
+         * @return string|null The user agent if it's set.
+         * @static 
+         */ 
+        public static function getUserAgent()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getUserAgent();
+        }
+        
+        /**
+         * Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or
+         * self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set.
+         *
+         * @deprecated since version 2.6.9
+         * @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default
+         *                     parameter is null which will default to self::DETECTION_TYPE_MOBILE.
+         * @static 
+         */ 
+        public static function setDetectionType($type = null)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->setDetectionType($type);
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getMatchingRegex()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getMatchingRegex();
+        }
+        
+        /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getMatchesArray()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getMatchesArray();
+        }
+        
+        /**
+         * Retrieve the list of known phone devices.
+         *
+         * @return array List of phone devices.
+         * @static 
+         */ 
+        public static function getPhoneDevices()
+        {
+            //Method inherited from \Mobile_Detect            
+                        return \Jenssegers\Agent\Agent::getPhoneDevices();
+        }
+        
+        /**
+         * Retrieve the list of known tablet devices.
+         *
+         * @return array List of tablet devices.
+         * @static 
+         */ 
+        public static function getTabletDevices()
+        {
+            //Method inherited from \Mobile_Detect            
+                        return \Jenssegers\Agent\Agent::getTabletDevices();
+        }
+        
+        /**
+         * Alias for getBrowsers() method.
+         *
+         * @return array List of user agents.
+         * @static 
+         */ 
+        public static function getUserAgents()
+        {
+            //Method inherited from \Mobile_Detect            
+                        return \Jenssegers\Agent\Agent::getUserAgents();
+        }
+        
+        /**
+         * Retrieve the list of known utilities.
+         *
+         * @return array List of utilities.
+         * @static 
+         */ 
+        public static function getUtilities()
+        {
+            //Method inherited from \Mobile_Detect            
+                        return \Jenssegers\Agent\Agent::getUtilities();
+        }
+        
+        /**
+         * Method gets the mobile detection rules. This method is used for the magic methods $detect->is*().
+         *
+         * @deprecated since version 2.6.9
+         * @return array All the rules (but not extended).
+         * @static 
+         */ 
+        public static function getMobileDetectionRules()
+        {
+            //Method inherited from \Mobile_Detect            
+                        return \Jenssegers\Agent\Agent::getMobileDetectionRules();
+        }
+        
+        /**
+         * Method gets the mobile detection rules + utilities.
+         * 
+         * The reason this is separate is because utilities rules
+         * don't necessary imply mobile. This method is used inside
+         * the new $detect->is('stuff') method.
+         *
+         * @deprecated since version 2.6.9
+         * @return array All the rules + extended.
+         * @static 
+         */ 
+        public static function getMobileDetectionRulesExtended()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->getMobileDetectionRulesExtended();
+        }
+        
+        /**
+         * Check the HTTP headers for signs of mobile.
+         * 
+         * This is the fastest mobile check possible; it's used
+         * inside isMobile() method.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function checkHttpHeadersForMobile()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->checkHttpHeadersForMobile();
+        }
+        
+        /**
+         * Check if the device is mobile.
+         * 
+         * Returns true if any type of mobile device detected, including special ones
+         *
+         * @param null $userAgent deprecated
+         * @param null $httpHeaders deprecated
+         * @return bool 
+         * @static 
+         */ 
+        public static function isMobile($userAgent = null, $httpHeaders = null)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->isMobile($userAgent, $httpHeaders);
+        }
+        
+        /**
+         * Check if the device is a tablet.
+         * 
+         * Return true if any type of tablet device is detected.
+         *
+         * @param string $userAgent deprecated
+         * @param array $httpHeaders deprecated
+         * @return bool 
+         * @static 
+         */ 
+        public static function isTablet($userAgent = null, $httpHeaders = null)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->isTablet($userAgent, $httpHeaders);
+        }
+        
+        /**
+         * This method checks for a certain property in the
+         * userAgent.
+         *
+         * @todo : The httpHeaders part is not yet used.
+         * @param string $key
+         * @param string $userAgent deprecated
+         * @param string $httpHeaders deprecated
+         * @return bool|int|null 
+         * @static 
+         */ 
+        public static function is($key, $userAgent = null, $httpHeaders = null)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->is($key, $userAgent, $httpHeaders);
+        }
+        
+        /**
+         * Some detection rules are relative (not standard),
+         * because of the diversity of devices, vendors and
+         * their conventions in representing the User-Agent or
+         * the HTTP headers.
+         * 
+         * This method will be used to check custom regexes against
+         * the User-Agent string.
+         *
+         * @param $regex
+         * @param string $userAgent
+         * @return bool 
+         * @todo : search in the HTTP headers too.
+         * @static 
+         */ 
+        public static function match($regex, $userAgent = null)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->match($regex, $userAgent);
+        }
+        
+        /**
+         * Prepare the version number.
+         *
+         * @todo Remove the error supression from str_replace() call.
+         * @param string $ver The string version, like "2.6.21.2152";
+         * @return float 
+         * @static 
+         */ 
+        public static function prepareVersionNo($ver)
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->prepareVersionNo($ver);
+        }
+        
+        /**
+         * Retrieve the mobile grading, using self::MOBILE_GRADE_* constants.
+         *
+         * @return string One of the self::MOBILE_GRADE_* constants.
+         * @static 
+         */ 
+        public static function mobileGrade()
+        {
+            //Method inherited from \Mobile_Detect            
+                        /** @var \Jenssegers\Agent\Agent $instance */
+                        return $instance->mobileGrade();
+        }
+         
+    }
+ 
+}
+
+namespace Mews\Purifier\Facades { 
+
+    /**
+     * 
+     *
+     * @see \Mews\Purifier
+     */ 
+    class Purifier {
+        
+        /**
+         * 
+         *
+         * @param $dirty
+         * @param null $config
+         * @return mixed 
+         * @static 
+         */ 
+        public static function clean($dirty, $config = null)
+        {
+                        /** @var \Mews\Purifier\Purifier $instance */
+                        return $instance->clean($dirty, $config);
+        }
+        
+        /**
+         * Get HTMLPurifier instance.
+         *
+         * @return \HTMLPurifier 
+         * @static 
+         */ 
+        public static function getInstance()
+        {
+                        /** @var \Mews\Purifier\Purifier $instance */
+                        return $instance->getInstance();
+        }
+         
+    }
+ 
+}
+
+namespace Misechow\Geetest { 
+
+    /**
+     * 
+     *
+     */ 
+    class Geetest {
+        
+        /**
+         * 
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getGeetestUrl()
+        {
+                        /** @var \Misechow\Geetest\GeetestLib $instance */
+                        return $instance->getGeetestUrl();
+        }
+        
+        /**
+         * 
+         *
+         * @param string $geetestUrl
+         * @return \Misechow\Geetest\GeetestLib 
+         * @static 
+         */ 
+        public static function setGeetestUrl($url)
+        {
+                        /** @var \Misechow\Geetest\GeetestLib $instance */
+                        return $instance->setGeetestUrl($url);
+        }
+        
+        /**
+         * Check Geetest server is running or not.
+         *
+         * @param null $user_id
+         * @return int 
+         * @static 
+         */ 
+        public static function preProcess($param, $new_captcha = 1)
+        {
+                        /** @var \Misechow\Geetest\GeetestLib $instance */
+                        return $instance->preProcess($param, $new_captcha);
+        }
+        
+        /**
+         * 
+         *
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getResponseStr()
+        {
+                        /** @var \Misechow\Geetest\GeetestLib $instance */
+                        return $instance->getResponseStr();
+        }
+        
+        /**
+         * 
+         *
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getResponse()
+        {
+                        /** @var \Misechow\Geetest\GeetestLib $instance */
+                        return $instance->getResponse();
+        }
+        
+        /**
+         * Get success validate result.
+         *
+         * @param $challenge
+         * @param $validate
+         * @param $seccode
+         * @param null $user_id
+         * @return int 
+         * @static 
+         */ 
+        public static function successValidate($challenge, $validate, $seccode, $param, $json_format = 1)
+        {
+                        /** @var \Misechow\Geetest\GeetestLib $instance */
+                        return $instance->successValidate($challenge, $validate, $seccode, $param, $json_format);
+        }
+        
+        /**
+         * Get fail result.
+         *
+         * @param $challenge
+         * @param $validate
+         * @param $seccode
+         * @return int 
+         * @static 
+         */ 
+        public static function failValidate($challenge, $validate, $seccode)
+        {
+                        /** @var \Misechow\Geetest\GeetestLib $instance */
+                        return $instance->failValidate($challenge, $validate, $seccode);
+        }
+        
+        /**
+         * 
+         *
+         * @param string $product
+         * @static 
+         */ 
+        public static function render($product = 'float', $captchaId = 'geetest-captcha')
+        {
+                        /** @var \Misechow\Geetest\GeetestLib $instance */
+                        return $instance->render($product, $captchaId);
+        }
+         
+    }
+ 
+}
+
+namespace Misechow\NoCaptcha\Facades { 
+
+    /**
+     * 
+     *
+     */ 
+    class NoCaptcha {
+        
+        /**
+         * Render HTML captcha.
+         *
+         * @param array $attributes
+         * @return string 
+         * @static 
+         */ 
+        public static function display($attributes = array())
+        {
+                        /** @var \Misechow\NoCaptcha\NoCaptcha $instance */
+                        return $instance->display($attributes);
+        }
+        
+        /**
+         * 
+         *
+         * @see display()
+         * @static 
+         */ 
+        public static function displayWidget($attributes = array())
+        {
+                        /** @var \Misechow\NoCaptcha\NoCaptcha $instance */
+                        return $instance->displayWidget($attributes);
+        }
+        
+        /**
+         * Display a Invisible reCAPTCHA by embedding a callback into a form submit button.
+         *
+         * @param string $formIdentifier the html ID of the form that should be submitted.
+         * @param string $text the text inside the form button
+         * @param array $attributes array of additional html elements
+         * @return string 
+         * @static 
+         */ 
+        public static function displaySubmit($formIdentifier, $text = 'submit', $attributes = array())
+        {
+                        /** @var \Misechow\NoCaptcha\NoCaptcha $instance */
+                        return $instance->displaySubmit($formIdentifier, $text, $attributes);
+        }
+        
+        /**
+         * Render js source
+         *
+         * @param null $lang
+         * @param bool $callback
+         * @param string $onLoadClass
+         * @return string 
+         * @static 
+         */ 
+        public static function renderJs($lang = null, $callback = false, $onLoadClass = 'onloadCallBack')
+        {
+                        /** @var \Misechow\NoCaptcha\NoCaptcha $instance */
+                        return $instance->renderJs($lang, $callback, $onLoadClass);
+        }
+        
+        /**
+         * Verify no-captcha response.
+         *
+         * @param string $response
+         * @param string $clientIp
+         * @return bool 
+         * @static 
+         */ 
+        public static function verifyResponse($response, $clientIp = null)
+        {
+                        /** @var \Misechow\NoCaptcha\NoCaptcha $instance */
+                        return $instance->verifyResponse($response, $clientIp);
+        }
+        
+        /**
+         * Verify no-captcha response by Symfony Request.
+         *
+         * @param \Request $request
+         * @return bool 
+         * @static 
+         */ 
+        public static function verifyRequest($request)
+        {
+                        /** @var \Misechow\NoCaptcha\NoCaptcha $instance */
+                        return $instance->verifyRequest($request);
+        }
+        
+        /**
+         * Get recaptcha js link.
+         *
+         * @param string $lang
+         * @param boolean $callback
+         * @param string $onLoadClass
+         * @return string 
+         * @static 
+         */ 
+        public static function getJsLink($lang = null, $callback = false, $onLoadClass = 'onloadCallBack')
+        {
+                        /** @var \Misechow\NoCaptcha\NoCaptcha $instance */
+                        return $instance->getJsLink($lang, $callback, $onLoadClass);
+        }
+         
+    }
+ 
+}
+
+namespace Tymon\JWTAuth\Facades { 
+
+    /**
+     * 
+     *
+     */ 
+    class JWTAuth {
+        
+        /**
+         * Attempt to authenticate the user and return the token.
+         *
+         * @param array $credentials
+         * @return false|string 
+         * @static 
+         */ 
+        public static function attempt($credentials)
+        {
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->attempt($credentials);
+        }
+        
+        /**
+         * Authenticate a user via a token.
+         *
+         * @return \Tymon\JWTAuth\Contracts\JWTSubject|false 
+         * @static 
+         */ 
+        public static function authenticate()
+        {
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->authenticate();
+        }
+        
+        /**
+         * Alias for authenticate().
+         *
+         * @return \Tymon\JWTAuth\Contracts\JWTSubject|false 
+         * @static 
+         */ 
+        public static function toUser()
+        {
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->toUser();
+        }
+        
+        /**
+         * Get the authenticated user.
+         *
+         * @return \Tymon\JWTAuth\Contracts\JWTSubject 
+         * @static 
+         */ 
+        public static function user()
+        {
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->user();
+        }
+        
+        /**
+         * Generate a token for a given subject.
+         *
+         * @param \Tymon\JWTAuth\Contracts\JWTSubject $subject
+         * @return string 
+         * @static 
+         */ 
+        public static function fromSubject($subject)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->fromSubject($subject);
+        }
+        
+        /**
+         * Alias to generate a token for a given user.
+         *
+         * @param \Tymon\JWTAuth\Contracts\JWTSubject $user
+         * @return string 
+         * @static 
+         */ 
+        public static function fromUser($user)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->fromUser($user);
+        }
+        
+        /**
+         * Refresh an expired token.
+         *
+         * @param bool $forceForever
+         * @param bool $resetClaims
+         * @return string 
+         * @static 
+         */ 
+        public static function refresh($forceForever = false, $resetClaims = false)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->refresh($forceForever, $resetClaims);
+        }
+        
+        /**
+         * Invalidate a token (add it to the blacklist).
+         *
+         * @param bool $forceForever
+         * @return \Tymon\JWTAuth\JWTAuth 
+         * @static 
+         */ 
+        public static function invalidate($forceForever = false)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->invalidate($forceForever);
+        }
+        
+        /**
+         * Alias to get the payload, and as a result checks that
+         * the token is valid i.e. not expired or blacklisted.
+         *
+         * @throws \Tymon\JWTAuth\Exceptions\JWTException
+         * @return \Tymon\JWTAuth\Payload 
+         * @static 
+         */ 
+        public static function checkOrFail()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->checkOrFail();
+        }
+        
+        /**
+         * Check that the token is valid.
+         *
+         * @param bool $getPayload
+         * @return \Tymon\JWTAuth\Payload|bool 
+         * @static 
+         */ 
+        public static function check($getPayload = false)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->check($getPayload);
+        }
+        
+        /**
+         * Get the token.
+         *
+         * @return \Tymon\JWTAuth\Token|null 
+         * @static 
+         */ 
+        public static function getToken()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->getToken();
+        }
+        
+        /**
+         * Parse the token from the request.
+         *
+         * @throws \Tymon\JWTAuth\Exceptions\JWTException
+         * @return \Tymon\JWTAuth\JWTAuth 
+         * @static 
+         */ 
+        public static function parseToken()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->parseToken();
+        }
+        
+        /**
+         * Get the raw Payload instance.
+         *
+         * @return \Tymon\JWTAuth\Payload 
+         * @static 
+         */ 
+        public static function getPayload()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->getPayload();
+        }
+        
+        /**
+         * Alias for getPayload().
+         *
+         * @return \Tymon\JWTAuth\Payload 
+         * @static 
+         */ 
+        public static function payload()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->payload();
+        }
+        
+        /**
+         * Convenience method to get a claim value.
+         *
+         * @param string $claim
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getClaim($claim)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->getClaim($claim);
+        }
+        
+        /**
+         * Create a Payload instance.
+         *
+         * @param \Tymon\JWTAuth\Contracts\JWTSubject $subject
+         * @return \Tymon\JWTAuth\Payload 
+         * @static 
+         */ 
+        public static function makePayload($subject)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->makePayload($subject);
+        }
+        
+        /**
+         * Check if the subject model matches the one saved in the token.
+         *
+         * @param string|object $model
+         * @return bool 
+         * @static 
+         */ 
+        public static function checkSubjectModel($model)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->checkSubjectModel($model);
+        }
+        
+        /**
+         * Set the token.
+         *
+         * @param \Tymon\JWTAuth\Token|string $token
+         * @return \Tymon\JWTAuth\JWTAuth 
+         * @static 
+         */ 
+        public static function setToken($token)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->setToken($token);
+        }
+        
+        /**
+         * Unset the current token.
+         *
+         * @return \Tymon\JWTAuth\JWTAuth 
+         * @static 
+         */ 
+        public static function unsetToken()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->unsetToken();
+        }
+        
+        /**
+         * Set the request instance.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return \Tymon\JWTAuth\JWTAuth 
+         * @static 
+         */ 
+        public static function setRequest($request)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->setRequest($request);
+        }
+        
+        /**
+         * Set whether the subject should be "locked".
+         *
+         * @param bool $lock
+         * @return \Tymon\JWTAuth\JWTAuth 
+         * @static 
+         */ 
+        public static function lockSubject($lock)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->lockSubject($lock);
+        }
+        
+        /**
+         * Get the Manager instance.
+         *
+         * @return \Tymon\JWTAuth\Manager 
+         * @static 
+         */ 
+        public static function manager()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->manager();
+        }
+        
+        /**
+         * Get the Parser instance.
+         *
+         * @return \Tymon\JWTAuth\Http\Parser\Parser 
+         * @static 
+         */ 
+        public static function parser()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->parser();
+        }
+        
+        /**
+         * Get the Payload Factory.
+         *
+         * @return \Tymon\JWTAuth\Factory 
+         * @static 
+         */ 
+        public static function factory()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->factory();
+        }
+        
+        /**
+         * Get the Blacklist.
+         *
+         * @return \Tymon\JWTAuth\Blacklist 
+         * @static 
+         */ 
+        public static function blacklist()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->blacklist();
+        }
+        
+        /**
+         * Set the custom claims.
+         *
+         * @param array $customClaims
+         * @return \Tymon\JWTAuth\JWTAuth 
+         * @static 
+         */ 
+        public static function customClaims($customClaims)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->customClaims($customClaims);
+        }
+        
+        /**
+         * Alias to set the custom claims.
+         *
+         * @param array $customClaims
+         * @return \Tymon\JWTAuth\JWTAuth 
+         * @static 
+         */ 
+        public static function claims($customClaims)
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->claims($customClaims);
+        }
+        
+        /**
+         * Get the custom claims.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getCustomClaims()
+        {
+            //Method inherited from \Tymon\JWTAuth\JWT            
+                        /** @var \Tymon\JWTAuth\JWTAuth $instance */
+                        return $instance->getCustomClaims();
+        }
+         
+    }
+ 
+}
+
+namespace Telegram\Bot\Laravel\Facades { 
+
+    /**
+     * Class Telegram.
+     *
+     */ 
+    class Telegram {
+        
+        /**
+         * Set the IoC Container.
+         *
+         * @param $container Container instance
+         * @return \Telegram\Bot\BotsManager 
+         * @static 
+         */ 
+        public static function setContainer($container)
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->setContainer($container);
+        }
+        
+        /**
+         * Get the configuration for a bot.
+         *
+         * @param string|null $name
+         * @throws \InvalidArgumentException
+         * @return array 
+         * @static 
+         */ 
+        public static function getBotConfig($name = null)
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->getBotConfig($name);
+        }
+        
+        /**
+         * Get a bot instance.
+         *
+         * @param string $name
+         * @return \Telegram\Bot\Api 
+         * @static 
+         */ 
+        public static function bot($name = null)
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->bot($name);
+        }
+        
+        /**
+         * Reconnect to the given bot.
+         *
+         * @param string $name
+         * @return \Telegram\Bot\Api 
+         * @static 
+         */ 
+        public static function reconnect($name = null)
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->reconnect($name);
+        }
+        
+        /**
+         * Disconnect from the given bot.
+         *
+         * @param string $name
+         * @return \Telegram\Bot\BotsManager 
+         * @static 
+         */ 
+        public static function disconnect($name = null)
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->disconnect($name);
+        }
+        
+        /**
+         * Get the specified configuration value for Telegram.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getConfig($key, $default = null)
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->getConfig($key, $default);
+        }
+        
+        /**
+         * Get the default bot name.
+         *
+         * @throws TelegramSDKException
+         * @return string|null 
+         * @static 
+         */ 
+        public static function getDefaultBotName()
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->getDefaultBotName();
+        }
+        
+        /**
+         * Set the default bot name.
+         *
+         * @param string $name
+         * @return \Telegram\Bot\BotsManager 
+         * @static 
+         */ 
+        public static function setDefaultBot($name)
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->setDefaultBot($name);
+        }
+        
+        /**
+         * Return all of the created bots.
+         *
+         * @return \Telegram\Bot\Api[] 
+         * @static 
+         */ 
+        public static function getBots()
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->getBots();
+        }
+        
+        /**
+         * Builds the list of commands for the given commands array.
+         *
+         * @param array $commands
+         * @return array An array of commands which includes global and bot specific commands.
+         * @static 
+         */ 
+        public static function parseBotCommands($commands)
+        {
+                        /** @var \Telegram\Bot\BotsManager $instance */
+                        return $instance->parseBotCommands($commands);
+        }
+         
+    }
+ 
+}
+
+namespace Intervention\Image\Facades { 
+
+    /**
+     * 
+     *
+     */ 
+    class Image {
+        
+        /**
+         * Overrides configuration settings
+         *
+         * @param array $config
+         * @return self 
+         * @static 
+         */ 
+        public static function configure($config = array())
+        {
+                        /** @var \Intervention\Image\ImageManager $instance */
+                        return $instance->configure($config);
+        }
+        
+        /**
+         * Initiates an Image instance from different input types
+         *
+         * @param mixed $data
+         * @return \Intervention\Image\Image 
+         * @static 
+         */ 
+        public static function make($data)
+        {
+                        /** @var \Intervention\Image\ImageManager $instance */
+                        return $instance->make($data);
+        }
+        
+        /**
+         * Creates an empty image canvas
+         *
+         * @param int $width
+         * @param int $height
+         * @param mixed $background
+         * @return \Intervention\Image\Image 
+         * @static 
+         */ 
+        public static function canvas($width, $height, $background = null)
+        {
+                        /** @var \Intervention\Image\ImageManager $instance */
+                        return $instance->canvas($width, $height, $background);
+        }
+        
+        /**
+         * Create new cached image and run callback
+         * (requires additional package intervention/imagecache)
+         *
+         * @param \Closure $callback
+         * @param int $lifetime
+         * @param boolean $returnObj
+         * @return \Image 
+         * @static 
+         */ 
+        public static function cache($callback, $lifetime = null, $returnObj = false)
+        {
+                        /** @var \Intervention\Image\ImageManager $instance */
+                        return $instance->cache($callback, $lifetime, $returnObj);
+        }
+         
+    }
+ 
+}
+
+
+namespace  { 
+
+    class App extends \Illuminate\Support\Facades\App {}
+
+    class Artisan extends \Illuminate\Support\Facades\Artisan {}
+
+    class Auth extends \Illuminate\Support\Facades\Auth {}
+
+    class Blade extends \Illuminate\Support\Facades\Blade {}
+
+    class Broadcast extends \Illuminate\Support\Facades\Broadcast {}
+
+    class Bus extends \Illuminate\Support\Facades\Bus {}
+
+    class Cache extends \Illuminate\Support\Facades\Cache {}
+
+    class Config extends \Illuminate\Support\Facades\Config {}
+
+    class Cookie extends \Illuminate\Support\Facades\Cookie {}
+
+    class Crypt extends \Illuminate\Support\Facades\Crypt {}
+
+    class DB extends \Illuminate\Support\Facades\DB {}
+
+    class Eloquent extends \Illuminate\Database\Eloquent\Model {         
+            /**
+             * Create and return an un-saved model instance.
+             *
+             * @param array $attributes
+             * @return \Illuminate\Database\Eloquent\Model 
+             * @static 
+             */ 
+            public static function make($attributes = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->make($attributes);
+            }
+         
+            /**
+             * Register a new global scope.
+             *
+             * @param string $identifier
+             * @param \Illuminate\Database\Eloquent\Scope|\Closure $scope
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function withGlobalScope($identifier, $scope)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withGlobalScope($identifier, $scope);
+            }
+         
+            /**
+             * Remove a registered global scope.
+             *
+             * @param \Illuminate\Database\Eloquent\Scope|string $scope
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function withoutGlobalScope($scope)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withoutGlobalScope($scope);
+            }
+         
+            /**
+             * Remove all or passed registered global scopes.
+             *
+             * @param array|null $scopes
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function withoutGlobalScopes($scopes = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withoutGlobalScopes($scopes);
+            }
+         
+            /**
+             * Get an array of global scopes that were removed from the query.
+             *
+             * @return array 
+             * @static 
+             */ 
+            public static function removedScopes()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->removedScopes();
+            }
+         
+            /**
+             * Add a where clause on the primary key to the query.
+             *
+             * @param mixed $id
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function whereKey($id)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereKey($id);
+            }
+         
+            /**
+             * Add a where clause on the primary key to the query.
+             *
+             * @param mixed $id
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function whereKeyNot($id)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereKeyNot($id);
+            }
+         
+            /**
+             * Add a basic where clause to the query.
+             *
+             * @param string|array|\Closure $column
+             * @param mixed $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function where($column, $operator = null, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->where($column, $operator, $value, $boolean);
+            }
+         
+            /**
+             * Add an "or where" clause to the query.
+             *
+             * @param \Closure|array|string $column
+             * @param mixed $operator
+             * @param mixed $value
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orWhere($column, $operator = null, $value = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orWhere($column, $operator, $value);
+            }
+         
+            /**
+             * Create a collection of models from plain arrays.
+             *
+             * @param array $items
+             * @return \Illuminate\Database\Eloquent\Collection 
+             * @static 
+             */ 
+            public static function hydrate($items)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->hydrate($items);
+            }
+         
+            /**
+             * Create a collection of models from a raw query.
+             *
+             * @param string $query
+             * @param array $bindings
+             * @return \Illuminate\Database\Eloquent\Collection 
+             * @static 
+             */ 
+            public static function fromQuery($query, $bindings = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->fromQuery($query, $bindings);
+            }
+         
+            /**
+             * Find a model by its primary key.
+             *
+             * @param mixed $id
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null 
+             * @static 
+             */ 
+            public static function find($id, $columns = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->find($id, $columns);
+            }
+         
+            /**
+             * Find multiple models by their primary keys.
+             *
+             * @param \Illuminate\Contracts\Support\Arrayable|array $ids
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Collection 
+             * @static 
+             */ 
+            public static function findMany($ids, $columns = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->findMany($ids, $columns);
+            }
+         
+            /**
+             * Find a model by its primary key or throw an exception.
+             *
+             * @param mixed $id
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static|static[] 
+             * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+             * @static 
+             */ 
+            public static function findOrFail($id, $columns = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->findOrFail($id, $columns);
+            }
+         
+            /**
+             * Find a model by its primary key or return fresh model instance.
+             *
+             * @param mixed $id
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model 
+             * @static 
+             */ 
+            public static function findOrNew($id, $columns = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->findOrNew($id, $columns);
+            }
+         
+            /**
+             * Get the first record matching the attributes or instantiate it.
+             *
+             * @param array $attributes
+             * @param array $values
+             * @return \Illuminate\Database\Eloquent\Model 
+             * @static 
+             */ 
+            public static function firstOrNew($attributes, $values = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstOrNew($attributes, $values);
+            }
+         
+            /**
+             * Get the first record matching the attributes or create it.
+             *
+             * @param array $attributes
+             * @param array $values
+             * @return \Illuminate\Database\Eloquent\Model 
+             * @static 
+             */ 
+            public static function firstOrCreate($attributes, $values = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstOrCreate($attributes, $values);
+            }
+         
+            /**
+             * Create or update a record matching the attributes, and fill it with values.
+             *
+             * @param array $attributes
+             * @param array $values
+             * @return \Illuminate\Database\Eloquent\Model 
+             * @static 
+             */ 
+            public static function updateOrCreate($attributes, $values = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->updateOrCreate($attributes, $values);
+            }
+         
+            /**
+             * Execute the query and get the first result or throw an exception.
+             *
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+             * @static 
+             */ 
+            public static function firstOrFail($columns = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstOrFail($columns);
+            }
+         
+            /**
+             * Execute the query and get the first result or call a callback.
+             *
+             * @param \Closure|array $columns
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Model|static|mixed 
+             * @static 
+             */ 
+            public static function firstOr($columns = array(), $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstOr($columns, $callback);
+            }
+         
+            /**
+             * Get a single column's value from the first result of a query.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function value($column)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->value($column);
+            }
+         
+            /**
+             * Execute the query as a "select" statement.
+             *
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Collection|static[] 
+             * @static 
+             */ 
+            public static function get($columns = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->get($columns);
+            }
+         
+            /**
+             * Get the hydrated models without eager loading.
+             *
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model[] 
+             * @static 
+             */ 
+            public static function getModels($columns = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getModels($columns);
+            }
+         
+            /**
+             * Eager load the relationships for the models.
+             *
+             * @param array $models
+             * @return array 
+             * @static 
+             */ 
+            public static function eagerLoadRelations($models)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->eagerLoadRelations($models);
+            }
+         
+            /**
+             * Get a generator for the given query.
+             *
+             * @return \Generator 
+             * @static 
+             */ 
+            public static function cursor()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->cursor();
+            }
+         
+            /**
+             * Chunk the results of a query by comparing numeric IDs.
+             *
+             * @param int $count
+             * @param callable $callback
+             * @param string|null $column
+             * @param string|null $alias
+             * @return bool 
+             * @static 
+             */ 
+            public static function chunkById($count, $callback, $column = null, $alias = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->chunkById($count, $callback, $column, $alias);
+            }
+         
+            /**
+             * Get an array with the values of a given column.
+             *
+             * @param string $column
+             * @param string|null $key
+             * @return \Illuminate\Support\Collection 
+             * @static 
+             */ 
+            public static function pluck($column, $key = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->pluck($column, $key);
+            }
+         
+            /**
+             * Paginate the given query.
+             *
+             * @param int $perPage
+             * @param array $columns
+             * @param string $pageName
+             * @param int|null $page
+             * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function paginate($perPage = null, $columns = array(), $pageName = 'page', $page = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->paginate($perPage, $columns, $pageName, $page);
+            }
+         
+            /**
+             * Paginate the given query into a simple paginator.
+             *
+             * @param int $perPage
+             * @param array $columns
+             * @param string $pageName
+             * @param int|null $page
+             * @return \Illuminate\Contracts\Pagination\Paginator 
+             * @static 
+             */ 
+            public static function simplePaginate($perPage = null, $columns = array(), $pageName = 'page', $page = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->simplePaginate($perPage, $columns, $pageName, $page);
+            }
+         
+            /**
+             * Save a new model and return the instance.
+             *
+             * @param array $attributes
+             * @return \Illuminate\Database\Eloquent\Model|$this 
+             * @static 
+             */ 
+            public static function create($attributes = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->create($attributes);
+            }
+         
+            /**
+             * Save a new model and return the instance. Allow mass-assignment.
+             *
+             * @param array $attributes
+             * @return \Illuminate\Database\Eloquent\Model|$this 
+             * @static 
+             */ 
+            public static function forceCreate($attributes)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->forceCreate($attributes);
+            }
+         
+            /**
+             * Register a replacement for the default delete function.
+             *
+             * @param \Closure $callback
+             * @return void 
+             * @static 
+             */ 
+            public static function onDelete($callback)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                $instance->onDelete($callback);
+            }
+         
+            /**
+             * Call the given local model scopes.
+             *
+             * @param array $scopes
+             * @return mixed 
+             * @static 
+             */ 
+            public static function scopes($scopes)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->scopes($scopes);
+            }
+         
+            /**
+             * Apply the scopes to the Eloquent builder instance and return it.
+             *
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function applyScopes()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->applyScopes();
+            }
+         
+            /**
+             * Prevent the specified relations from being eager loaded.
+             *
+             * @param mixed $relations
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function without($relations)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->without($relations);
+            }
+         
+            /**
+             * Create a new instance of the model being queried.
+             *
+             * @param array $attributes
+             * @return \Illuminate\Database\Eloquent\Model 
+             * @static 
+             */ 
+            public static function newModelInstance($attributes = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->newModelInstance($attributes);
+            }
+         
+            /**
+             * Get the underlying query builder instance.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function getQuery()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getQuery();
+            }
+         
+            /**
+             * Set the underlying query builder instance.
+             *
+             * @param \Illuminate\Database\Query\Builder $query
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function setQuery($query)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->setQuery($query);
+            }
+         
+            /**
+             * Get a base query builder instance.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function toBase()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->toBase();
+            }
+         
+            /**
+             * Get the relationships being eagerly loaded.
+             *
+             * @return array 
+             * @static 
+             */ 
+            public static function getEagerLoads()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getEagerLoads();
+            }
+         
+            /**
+             * Set the relationships being eagerly loaded.
+             *
+             * @param array $eagerLoad
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function setEagerLoads($eagerLoad)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->setEagerLoads($eagerLoad);
+            }
+         
+            /**
+             * Get the model instance being queried.
+             *
+             * @return \Illuminate\Database\Eloquent\Model 
+             * @static 
+             */ 
+            public static function getModel()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getModel();
+            }
+         
+            /**
+             * Set a model instance for the model being queried.
+             *
+             * @param \Illuminate\Database\Eloquent\Model $model
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function setModel($model)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->setModel($model);
+            }
+         
+            /**
+             * Get the given macro by name.
+             *
+             * @param string $name
+             * @return \Closure 
+             * @static 
+             */ 
+            public static function getMacro($name)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getMacro($name);
+            }
+         
+            /**
+             * Chunk the results of the query.
+             *
+             * @param int $count
+             * @param callable $callback
+             * @return bool 
+             * @static 
+             */ 
+            public static function chunk($count, $callback)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->chunk($count, $callback);
+            }
+         
+            /**
+             * Execute a callback over each item while chunking.
+             *
+             * @param callable $callback
+             * @param int $count
+             * @return bool 
+             * @static 
+             */ 
+            public static function each($callback, $count = 1000)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->each($callback, $count);
+            }
+         
+            /**
+             * Execute the query and get the first result.
+             *
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model|object|static|null 
+             * @static 
+             */ 
+            public static function first($columns = array())
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->first($columns);
+            }
+         
+            /**
+             * Apply the callback's query changes if the given "value" is true.
+             *
+             * @param mixed $value
+             * @param callable $callback
+             * @param callable $default
+             * @return mixed|$this 
+             * @static 
+             */ 
+            public static function when($value, $callback, $default = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->when($value, $callback, $default);
+            }
+         
+            /**
+             * Pass the query to a given callback.
+             *
+             * @param \Closure $callback
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function tap($callback)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->tap($callback);
+            }
+         
+            /**
+             * Apply the callback's query changes if the given "value" is false.
+             *
+             * @param mixed $value
+             * @param callable $callback
+             * @param callable $default
+             * @return mixed|$this 
+             * @static 
+             */ 
+            public static function unless($value, $callback, $default = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->unless($value, $callback, $default);
+            }
+         
+            /**
+             * Add a relationship count / exists condition to the query.
+             *
+             * @param string $relation
+             * @param string $operator
+             * @param int $count
+             * @param string $boolean
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function has($relation, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->has($relation, $operator, $count, $boolean, $callback);
+            }
+         
+            /**
+             * Add a relationship count / exists condition to the query with an "or".
+             *
+             * @param string $relation
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orHas($relation, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orHas($relation, $operator, $count);
+            }
+         
+            /**
+             * Add a relationship count / exists condition to the query.
+             *
+             * @param string $relation
+             * @param string $boolean
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function doesntHave($relation, $boolean = 'and', $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->doesntHave($relation, $boolean, $callback);
+            }
+         
+            /**
+             * Add a relationship count / exists condition to the query with an "or".
+             *
+             * @param string $relation
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orDoesntHave($relation)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orDoesntHave($relation);
+            }
+         
+            /**
+             * Add a relationship count / exists condition to the query with where clauses.
+             *
+             * @param string $relation
+             * @param \Closure|null $callback
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function whereHas($relation, $callback = null, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereHas($relation, $callback, $operator, $count);
+            }
+         
+            /**
+             * Add a relationship count / exists condition to the query with where clauses and an "or".
+             *
+             * @param string $relation
+             * @param \Closure $callback
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereHas($relation, $callback = null, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orWhereHas($relation, $callback, $operator, $count);
+            }
+         
+            /**
+             * Add a relationship count / exists condition to the query with where clauses.
+             *
+             * @param string $relation
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function whereDoesntHave($relation, $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereDoesntHave($relation, $callback);
+            }
+         
+            /**
+             * Add a relationship count / exists condition to the query with where clauses and an "or".
+             *
+             * @param string $relation
+             * @param \Closure $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereDoesntHave($relation, $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orWhereDoesntHave($relation, $callback);
+            }
+         
+            /**
+             * Add subselect queries to count the relations.
+             *
+             * @param mixed $relations
+             * @return \Illuminate\Database\Eloquent\Builder 
+             * @static 
+             */ 
+            public static function withCount($relations)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withCount($relations);
+            }
+         
+            /**
+             * Merge the where constraints from another query to the current query.
+             *
+             * @param \Illuminate\Database\Eloquent\Builder $from
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function mergeConstraintsFrom($from)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->mergeConstraintsFrom($from);
+            }
+         
+            /**
+             * Set the columns to be selected.
+             *
+             * @param array|mixed $columns
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function select($columns = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->select($columns);
+            }
+         
+            /**
+             * Add a subselect expression to the query.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function selectSub($query, $as)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->selectSub($query, $as);
+            }
+         
+            /**
+             * Add a new "raw" select expression to the query.
+             *
+             * @param string $expression
+             * @param array $bindings
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function selectRaw($expression, $bindings = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->selectRaw($expression, $bindings);
+            }
+         
+            /**
+             * Makes "from" fetch from a subquery.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function fromSub($query, $as)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->fromSub($query, $as);
+            }
+         
+            /**
+             * Add a raw from clause to the query.
+             *
+             * @param string $expression
+             * @param mixed $bindings
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function fromRaw($expression, $bindings = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->fromRaw($expression, $bindings);
+            }
+         
+            /**
+             * Add a new select column to the query.
+             *
+             * @param array|mixed $column
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function addSelect($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->addSelect($column);
+            }
+         
+            /**
+             * Force the query to only return distinct results.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function distinct()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->distinct();
+            }
+         
+            /**
+             * Set the table which the query is targeting.
+             *
+             * @param string $table
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function from($table)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->from($table);
+            }
+         
+            /**
+             * Add a join clause to the query.
+             *
+             * @param string $table
+             * @param string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @param string $type
+             * @param bool $where
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function join($table, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->join($table, $first, $operator, $second, $type, $where);
+            }
+         
+            /**
+             * Add a "join where" clause to the query.
+             *
+             * @param string $table
+             * @param string $first
+             * @param string $operator
+             * @param string $second
+             * @param string $type
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function joinWhere($table, $first, $operator, $second, $type = 'inner')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->joinWhere($table, $first, $operator, $second, $type);
+            }
+         
+            /**
+             * Add a subquery join clause to the query.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @param string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @param string $type
+             * @param bool $where
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function joinSub($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->joinSub($query, $as, $first, $operator, $second, $type, $where);
+            }
+         
+            /**
+             * Add a left join to the query.
+             *
+             * @param string $table
+             * @param string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function leftJoin($table, $first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->leftJoin($table, $first, $operator, $second);
+            }
+         
+            /**
+             * Add a "join where" clause to the query.
+             *
+             * @param string $table
+             * @param string $first
+             * @param string $operator
+             * @param string $second
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function leftJoinWhere($table, $first, $operator, $second)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->leftJoinWhere($table, $first, $operator, $second);
+            }
+         
+            /**
+             * Add a subquery left join to the query.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @param string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function leftJoinSub($query, $as, $first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->leftJoinSub($query, $as, $first, $operator, $second);
+            }
+         
+            /**
+             * Add a right join to the query.
+             *
+             * @param string $table
+             * @param string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function rightJoin($table, $first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->rightJoin($table, $first, $operator, $second);
+            }
+         
+            /**
+             * Add a "right join where" clause to the query.
+             *
+             * @param string $table
+             * @param string $first
+             * @param string $operator
+             * @param string $second
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function rightJoinWhere($table, $first, $operator, $second)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->rightJoinWhere($table, $first, $operator, $second);
+            }
+         
+            /**
+             * Add a subquery right join to the query.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @param string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function rightJoinSub($query, $as, $first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->rightJoinSub($query, $as, $first, $operator, $second);
+            }
+         
+            /**
+             * Add a "cross join" clause to the query.
+             *
+             * @param string $table
+             * @param string|null $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function crossJoin($table, $first = null, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->crossJoin($table, $first, $operator, $second);
+            }
+         
+            /**
+             * Merge an array of where clauses and bindings.
+             *
+             * @param array $wheres
+             * @param array $bindings
+             * @return void 
+             * @static 
+             */ 
+            public static function mergeWheres($wheres, $bindings)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                $instance->mergeWheres($wheres, $bindings);
+            }
+         
+            /**
+             * Prepare the value and operator for a where clause.
+             *
+             * @param string $value
+             * @param string $operator
+             * @param bool $useDefault
+             * @return array 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function prepareValueAndOperator($value, $operator, $useDefault = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->prepareValueAndOperator($value, $operator, $useDefault);
+            }
+         
+            /**
+             * Add a "where" clause comparing two columns to the query.
+             *
+             * @param string|array $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @param string|null $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereColumn($first, $operator = null, $second = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereColumn($first, $operator, $second, $boolean);
+            }
+         
+            /**
+             * Add an "or where" clause comparing two columns to the query.
+             *
+             * @param string|array $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereColumn($first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereColumn($first, $operator, $second);
+            }
+         
+            /**
+             * Add a raw where clause to the query.
+             *
+             * @param string $sql
+             * @param mixed $bindings
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereRaw($sql, $bindings = array(), $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereRaw($sql, $bindings, $boolean);
+            }
+         
+            /**
+             * Add a raw or where clause to the query.
+             *
+             * @param string $sql
+             * @param mixed $bindings
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereRaw($sql, $bindings = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereRaw($sql, $bindings);
+            }
+         
+            /**
+             * Add a "where in" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $values
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereIn($column, $values, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereIn($column, $values, $boolean, $not);
+            }
+         
+            /**
+             * Add an "or where in" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $values
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereIn($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereIn($column, $values);
+            }
+         
+            /**
+             * Add a "where not in" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $values
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereNotIn($column, $values, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotIn($column, $values, $boolean);
+            }
+         
+            /**
+             * Add an "or where not in" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $values
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereNotIn($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotIn($column, $values);
+            }
+         
+            /**
+             * Add a "where null" clause to the query.
+             *
+             * @param string $column
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereNull($column, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNull($column, $boolean, $not);
+            }
+         
+            /**
+             * Add an "or where null" clause to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereNull($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNull($column);
+            }
+         
+            /**
+             * Add a "where not null" clause to the query.
+             *
+             * @param string $column
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereNotNull($column, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotNull($column, $boolean);
+            }
+         
+            /**
+             * Add a where between statement to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereBetween($column, $values, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereBetween($column, $values, $boolean, $not);
+            }
+         
+            /**
+             * Add an or where between statement to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereBetween($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereBetween($column, $values);
+            }
+         
+            /**
+             * Add a where not between statement to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereNotBetween($column, $values, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotBetween($column, $values, $boolean);
+            }
+         
+            /**
+             * Add an or where not between statement to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereNotBetween($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotBetween($column, $values);
+            }
+         
+            /**
+             * Add an "or where not null" clause to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereNotNull($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotNull($column);
+            }
+         
+            /**
+             * Add a "where date" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereDate($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereDate($column, $operator, $value, $boolean);
+            }
+         
+            /**
+             * Add an "or where date" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereDate($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereDate($column, $operator, $value);
+            }
+         
+            /**
+             * Add a "where time" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereTime($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereTime($column, $operator, $value, $boolean);
+            }
+         
+            /**
+             * Add an "or where time" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereTime($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereTime($column, $operator, $value);
+            }
+         
+            /**
+             * Add a "where day" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereDay($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereDay($column, $operator, $value, $boolean);
+            }
+         
+            /**
+             * Add an "or where day" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereDay($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereDay($column, $operator, $value);
+            }
+         
+            /**
+             * Add a "where month" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereMonth($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereMonth($column, $operator, $value, $boolean);
+            }
+         
+            /**
+             * Add an "or where month" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereMonth($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereMonth($column, $operator, $value);
+            }
+         
+            /**
+             * Add a "where year" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereYear($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereYear($column, $operator, $value, $boolean);
+            }
+         
+            /**
+             * Add an "or where year" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereYear($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereYear($column, $operator, $value);
+            }
+         
+            /**
+             * Add a nested where statement to the query.
+             *
+             * @param \Closure $callback
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereNested($callback, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNested($callback, $boolean);
+            }
+         
+            /**
+             * Create a new query instance for nested where condition.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function forNestedWhere()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->forNestedWhere();
+            }
+         
+            /**
+             * Add another query builder as a nested where to the query builder.
+             *
+             * @param \Illuminate\Database\Query\Builder|static $query
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function addNestedWhereQuery($query, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->addNestedWhereQuery($query, $boolean);
+            }
+         
+            /**
+             * Add an exists clause to the query.
+             *
+             * @param \Closure $callback
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereExists($callback, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereExists($callback, $boolean, $not);
+            }
+         
+            /**
+             * Add an or exists clause to the query.
+             *
+             * @param \Closure $callback
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereExists($callback, $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereExists($callback, $not);
+            }
+         
+            /**
+             * Add a where not exists clause to the query.
+             *
+             * @param \Closure $callback
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function whereNotExists($callback, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotExists($callback, $boolean);
+            }
+         
+            /**
+             * Add a where not exists clause to the query.
+             *
+             * @param \Closure $callback
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereNotExists($callback)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotExists($callback);
+            }
+         
+            /**
+             * Add an exists clause to the query.
+             *
+             * @param \Illuminate\Database\Query\Builder $query
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function addWhereExistsQuery($query, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->addWhereExistsQuery($query, $boolean, $not);
+            }
+         
+            /**
+             * Adds a where condition using row values.
+             *
+             * @param array $columns
+             * @param string $operator
+             * @param array $values
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereRowValues($columns, $operator, $values, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereRowValues($columns, $operator, $values, $boolean);
+            }
+         
+            /**
+             * Adds a or where condition using row values.
+             *
+             * @param array $columns
+             * @param string $operator
+             * @param array $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereRowValues($columns, $operator, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereRowValues($columns, $operator, $values);
+            }
+         
+            /**
+             * Add a "where JSON contains" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $value
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereJsonContains($column, $value, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereJsonContains($column, $value, $boolean, $not);
+            }
+         
+            /**
+             * Add a "or where JSON contains" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereJsonContains($column, $value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereJsonContains($column, $value);
+            }
+         
+            /**
+             * Add a "where JSON not contains" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereJsonDoesntContain($column, $value, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereJsonDoesntContain($column, $value, $boolean);
+            }
+         
+            /**
+             * Add a "or where JSON not contains" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereJsonDoesntContain($column, $value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereJsonDoesntContain($column, $value);
+            }
+         
+            /**
+             * Handles dynamic "where" clauses to the query.
+             *
+             * @param string $method
+             * @param string $parameters
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function dynamicWhere($method, $parameters)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->dynamicWhere($method, $parameters);
+            }
+         
+            /**
+             * Add a "group by" clause to the query.
+             *
+             * @param array $groups
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function groupBy($groups = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->groupBy($groups);
+            }
+         
+            /**
+             * Add a "having" clause to the query.
+             *
+             * @param string $column
+             * @param string|null $operator
+             * @param string|null $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function having($column, $operator = null, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->having($column, $operator, $value, $boolean);
+            }
+         
+            /**
+             * Add a "or having" clause to the query.
+             *
+             * @param string $column
+             * @param string|null $operator
+             * @param string|null $value
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orHaving($column, $operator = null, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orHaving($column, $operator, $value);
+            }
+         
+            /**
+             * Add a raw having clause to the query.
+             *
+             * @param string $sql
+             * @param array $bindings
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function havingRaw($sql, $bindings = array(), $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->havingRaw($sql, $bindings, $boolean);
+            }
+         
+            /**
+             * Add a raw or having clause to the query.
+             *
+             * @param string $sql
+             * @param array $bindings
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function orHavingRaw($sql, $bindings = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orHavingRaw($sql, $bindings);
+            }
+         
+            /**
+             * Add an "order by" clause to the query.
+             *
+             * @param string $column
+             * @param string $direction
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orderBy($column, $direction = 'asc')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orderBy($column, $direction);
+            }
+         
+            /**
+             * Add a descending "order by" clause to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orderByDesc($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orderByDesc($column);
+            }
+         
+            /**
+             * Add an "order by" clause for a timestamp to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function latest($column = 'created_at')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->latest($column);
+            }
+         
+            /**
+             * Add an "order by" clause for a timestamp to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function oldest($column = 'created_at')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->oldest($column);
+            }
+         
+            /**
+             * Put the query's results in random order.
+             *
+             * @param string $seed
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function inRandomOrder($seed = '')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->inRandomOrder($seed);
+            }
+         
+            /**
+             * Add a raw "order by" clause to the query.
+             *
+             * @param string $sql
+             * @param array $bindings
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orderByRaw($sql, $bindings = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orderByRaw($sql, $bindings);
+            }
+         
+            /**
+             * Alias to set the "offset" value of the query.
+             *
+             * @param int $value
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function skip($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->skip($value);
+            }
+         
+            /**
+             * Set the "offset" value of the query.
+             *
+             * @param int $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function offset($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->offset($value);
+            }
+         
+            /**
+             * Alias to set the "limit" value of the query.
+             *
+             * @param int $value
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function take($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->take($value);
+            }
+         
+            /**
+             * Set the "limit" value of the query.
+             *
+             * @param int $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function limit($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->limit($value);
+            }
+         
+            /**
+             * Set the limit and offset for a given page.
+             *
+             * @param int $page
+             * @param int $perPage
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function forPage($page, $perPage = 15)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->forPage($page, $perPage);
+            }
+         
+            /**
+             * Constrain the query to the next "page" of results after a given ID.
+             *
+             * @param int $perPage
+             * @param int|null $lastId
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->forPageAfterId($perPage, $lastId, $column);
+            }
+         
+            /**
+             * Add a union statement to the query.
+             *
+             * @param \Illuminate\Database\Query\Builder|\Closure $query
+             * @param bool $all
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function union($query, $all = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->union($query, $all);
+            }
+         
+            /**
+             * Add a union all statement to the query.
+             *
+             * @param \Illuminate\Database\Query\Builder|\Closure $query
+             * @return \Illuminate\Database\Query\Builder|static 
+             * @static 
+             */ 
+            public static function unionAll($query)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->unionAll($query);
+            }
+         
+            /**
+             * Lock the selected rows in the table.
+             *
+             * @param string|bool $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function lock($value = true)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->lock($value);
+            }
+         
+            /**
+             * Lock the selected rows in the table for updating.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function lockForUpdate()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->lockForUpdate();
+            }
+         
+            /**
+             * Share lock the selected rows in the table.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function sharedLock()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->sharedLock();
+            }
+         
+            /**
+             * Get the SQL representation of the query.
+             *
+             * @return string 
+             * @static 
+             */ 
+            public static function toSql()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->toSql();
+            }
+         
+            /**
+             * Get the count of the total records for the paginator.
+             *
+             * @param array $columns
+             * @return int 
+             * @static 
+             */ 
+            public static function getCountForPagination($columns = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getCountForPagination($columns);
+            }
+         
+            /**
+             * Concatenate values of a given column as a string.
+             *
+             * @param string $column
+             * @param string $glue
+             * @return string 
+             * @static 
+             */ 
+            public static function implode($column, $glue = '')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->implode($column, $glue);
+            }
+         
+            /**
+             * Determine if any rows exist for the current query.
+             *
+             * @return bool 
+             * @static 
+             */ 
+            public static function exists()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->exists();
+            }
+         
+            /**
+             * Determine if no rows exist for the current query.
+             *
+             * @return bool 
+             * @static 
+             */ 
+            public static function doesntExist()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->doesntExist();
+            }
+         
+            /**
+             * Retrieve the "count" result of the query.
+             *
+             * @param string $columns
+             * @return int 
+             * @static 
+             */ 
+            public static function count($columns = '*')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->count($columns);
+            }
+         
+            /**
+             * Retrieve the minimum value of a given column.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function min($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->min($column);
+            }
+         
+            /**
+             * Retrieve the maximum value of a given column.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function max($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->max($column);
+            }
+         
+            /**
+             * Retrieve the sum of the values of a given column.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function sum($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->sum($column);
+            }
+         
+            /**
+             * Retrieve the average of the values of a given column.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function avg($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->avg($column);
+            }
+         
+            /**
+             * Alias for the "avg" method.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function average($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->average($column);
+            }
+         
+            /**
+             * Execute an aggregate function on the database.
+             *
+             * @param string $function
+             * @param array $columns
+             * @return mixed 
+             * @static 
+             */ 
+            public static function aggregate($function, $columns = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->aggregate($function, $columns);
+            }
+         
+            /**
+             * Execute a numeric aggregate function on the database.
+             *
+             * @param string $function
+             * @param array $columns
+             * @return float|int 
+             * @static 
+             */ 
+            public static function numericAggregate($function, $columns = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->numericAggregate($function, $columns);
+            }
+         
+            /**
+             * Insert a new record into the database.
+             *
+             * @param array $values
+             * @return bool 
+             * @static 
+             */ 
+            public static function insert($values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->insert($values);
+            }
+         
+            /**
+             * Insert a new record and get the value of the primary key.
+             *
+             * @param array $values
+             * @param string|null $sequence
+             * @return int 
+             * @static 
+             */ 
+            public static function insertGetId($values, $sequence = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->insertGetId($values, $sequence);
+            }
+         
+            /**
+             * Insert or update a record matching the attributes, and fill it with values.
+             *
+             * @param array $attributes
+             * @param array $values
+             * @return bool 
+             * @static 
+             */ 
+            public static function updateOrInsert($attributes, $values = array())
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->updateOrInsert($attributes, $values);
+            }
+         
+            /**
+             * Run a truncate statement on the table.
+             *
+             * @return void 
+             * @static 
+             */ 
+            public static function truncate()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                $instance->truncate();
+            }
+         
+            /**
+             * Create a raw database expression.
+             *
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Expression 
+             * @static 
+             */ 
+            public static function raw($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->raw($value);
+            }
+         
+            /**
+             * Get the current query value bindings in a flattened array.
+             *
+             * @return array 
+             * @static 
+             */ 
+            public static function getBindings()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getBindings();
+            }
+         
+            /**
+             * Get the raw array of bindings.
+             *
+             * @return array 
+             * @static 
+             */ 
+            public static function getRawBindings()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getRawBindings();
+            }
+         
+            /**
+             * Set the bindings on the query builder.
+             *
+             * @param array $bindings
+             * @param string $type
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function setBindings($bindings, $type = 'where')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->setBindings($bindings, $type);
+            }
+         
+            /**
+             * Add a binding to the query.
+             *
+             * @param mixed $value
+             * @param string $type
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function addBinding($value, $type = 'where')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->addBinding($value, $type);
+            }
+         
+            /**
+             * Merge an array of bindings into our bindings.
+             *
+             * @param \Illuminate\Database\Query\Builder $query
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function mergeBindings($query)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->mergeBindings($query);
+            }
+         
+            /**
+             * Get the database query processor instance.
+             *
+             * @return \Illuminate\Database\Query\Processors\Processor 
+             * @static 
+             */ 
+            public static function getProcessor()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getProcessor();
+            }
+         
+            /**
+             * Get the query grammar instance.
+             *
+             * @return \Illuminate\Database\Query\Grammars\Grammar 
+             * @static 
+             */ 
+            public static function getGrammar()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getGrammar();
+            }
+         
+            /**
+             * Use the write pdo for query.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function useWritePdo()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->useWritePdo();
+            }
+         
+            /**
+             * Clone the query without the given properties.
+             *
+             * @param array $properties
+             * @return static 
+             * @static 
+             */ 
+            public static function cloneWithout($properties)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->cloneWithout($properties);
+            }
+         
+            /**
+             * Clone the query without the given bindings.
+             *
+             * @param array $except
+             * @return static 
+             * @static 
+             */ 
+            public static function cloneWithoutBindings($except)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->cloneWithoutBindings($except);
+            }
+         
+            /**
+             * Register a custom macro.
+             *
+             * @param string $name
+             * @param object|callable $macro
+             * @return void 
+             * @static 
+             */ 
+            public static function macro($name, $macro)
+            {
+                                \Illuminate\Database\Query\Builder::macro($name, $macro);
+            }
+         
+            /**
+             * Mix another object into the class.
+             *
+             * @param object $mixin
+             * @return void 
+             * @throws \ReflectionException
+             * @static 
+             */ 
+            public static function mixin($mixin)
+            {
+                                \Illuminate\Database\Query\Builder::mixin($mixin);
+            }
+         
+            /**
+             * Checks if macro is registered.
+             *
+             * @param string $name
+             * @return bool 
+             * @static 
+             */ 
+            public static function hasMacro($name)
+            {
+                                return \Illuminate\Database\Query\Builder::hasMacro($name);
+            }
+         
+            /**
+             * Dynamically handle calls to the class.
+             *
+             * @param string $method
+             * @param array $parameters
+             * @return mixed 
+             * @throws \BadMethodCallException
+             * @static 
+             */ 
+            public static function macroCall($method, $parameters)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->macroCall($method, $parameters);
+            }
+        }
+
+    class Event extends \Illuminate\Support\Facades\Event {}
+
+    class File extends \Illuminate\Support\Facades\File {}
+
+    class Gate extends \Illuminate\Support\Facades\Gate {}
+
+    class Hash extends \Illuminate\Support\Facades\Hash {}
+
+    class Lang extends \Illuminate\Support\Facades\Lang {}
+
+    class Log extends \Illuminate\Support\Facades\Log {}
+
+    class Mail extends \Illuminate\Support\Facades\Mail {}
+
+    class Notification extends \Illuminate\Support\Facades\Notification {}
+
+    class Password extends \Illuminate\Support\Facades\Password {}
+
+    class Queue extends \Illuminate\Support\Facades\Queue {}
+
+    class Redirect extends \Illuminate\Support\Facades\Redirect {}
+
+    class Redis extends \Illuminate\Support\Facades\Redis {}
+
+    class Request extends \Illuminate\Support\Facades\Request {}
+
+    class Response extends \Illuminate\Support\Facades\Response {}
+
+    class Route extends \Illuminate\Support\Facades\Route {}
+
+    class Schema extends \Illuminate\Support\Facades\Schema {}
+
+    class Session extends \Illuminate\Support\Facades\Session {}
+
+    class Storage extends \Illuminate\Support\Facades\Storage {}
+
+    class URL extends \Illuminate\Support\Facades\URL {}
+
+    class Validator extends \Illuminate\Support\Facades\Validator {}
+
+    class View extends \Illuminate\Support\Facades\View {}
+
+    class Captcha extends \Mews\Captcha\Facades\Captcha {}
+
+    class Agent extends \Jenssegers\Agent\Facades\Agent {}
+
+    class Purifier extends \Mews\Purifier\Facades\Purifier {}
+
+    class Geetest extends \Misechow\Geetest\Geetest {}
+
+    class NoCaptcha extends \Misechow\NoCaptcha\Facades\NoCaptcha {}
+
+    class JWTAuth extends \Tymon\JWTAuth\Facades\JWTAuth {}
+
+    class Telegram extends \Telegram\Bot\Laravel\Facades\Telegram {}
+
+    class Image extends \Intervention\Image\Facades\Image {}
+ 
+}
+
+
+

+ 249 - 0
app/Components/AlipayNotify.php

@@ -0,0 +1,249 @@
+<?php
+
+namespace App\Components;
+
+/**
+ * Class AlipayNotify
+ *
+ * @author  wz812180
+ *
+ * @package App\Components
+ */
+class AlipayNotify
+{
+    private $https_verify_url = 'https://mapi.alipay.com/gateway.do?service=notify_verify&'; // HTTPS形式消息验证地址
+    private $http_verify_url = 'http://notify.alipay.com/trade/notify_query.do?'; // HTTP形式消息验证地址
+    private $sign_type = "MD5"; // 加密方式:MD5/RSA
+    private $partner = "";
+    private $md5_key = "";
+    private $private_key = "";
+    private $alipay_public_key = "";
+    private $transport = "http";
+
+    function __construct($sign_type, $partner, $md5_key, $private_key, $alipay_public_key, $transport)
+    {
+        $this->sign_type = $sign_type;
+        $this->partner = $partner;
+        $this->md5_key = $md5_key;
+        $this->private_key = $private_key;
+        $this->alipay_public_key = $alipay_public_key;
+        $this->transport = $transport;
+    }
+
+    /**
+     * 针对notify_url验证消息是否是支付宝发出的合法消息
+     *
+     * @return bool 验证结果
+     */
+    public function verifyNotify()
+    {
+        if (empty($_POST)) {
+            return false;
+        } else {
+            // 生成签名结果
+            $isSign = $this->getSignVeryfy($_POST, $_POST["sign"]);
+
+            $converted_res = ($isSign) ? 'true' : 'false';
+
+            // 获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)
+            $responseTxt = 'false';
+            if (!empty($_POST["notify_id"])) {
+                $responseTxt = $this->getResponse($_POST["notify_id"]);
+            }
+
+            // 验证
+            // $responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
+            // isSign的结果不是true,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
+            if (preg_match("/true$/i", $responseTxt) && $isSign) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * 获取返回时的签名验证结果
+     *
+     * @param array  $para_temp 通知返回来的参数数组
+     * @param string $sign      返回的签名结果
+     *
+     * @return bool 签名验证结果
+     */
+    function getSignVeryfy($para_temp, $sign)
+    {
+        // 除去待签名参数数组中的空值和签名参数
+        $para_filter = $this->paraFilter($para_temp);
+
+        // 对待签名参数数组排序
+        $para_sort = $this->argSort($para_filter);
+
+        // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
+        $prestr = $this->createLinkString($para_sort);
+
+        switch (strtoupper(trim($this->sign_type))) {
+            case "RSA" :
+                $isSgin = $this->rsaVerify($prestr, trim($this->alipay_public_key), $sign);
+                break;
+            case "MD5" :
+                $isSgin = $this->md5Verify($prestr, $sign, trim($this->md5_key));
+                break;
+            default :
+                $isSgin = false;
+        }
+
+        return $isSgin;
+    }
+
+    /**
+     * 获取远程服务器ATN结果,验证返回URL
+     *
+     * @param integer $notify_id 通知校验ID
+     *
+     * @return string 服务器ATN结果
+     * 验证结果集:
+     * invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空
+     * true 返回正确信息
+     * false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟
+     */
+    function getResponse($notify_id)
+    {
+        $transport = strtolower(trim($this->transport));
+        $partner = trim($this->partner);
+
+        $verify_url = $transport == 'https' ? $this->https_verify_url : $this->http_verify_url;
+        $verify_url = $verify_url . "partner=" . $partner . "&notify_id=" . $notify_id;
+        $responseTxt = $this->getHttpResponseGET($verify_url, base_path('ca/cacert_alipay.pem'));
+
+        return $responseTxt;
+    }
+
+    /**
+     * RSA验签
+     *
+     * @param string $data              待签名数据
+     * @param string $alipay_public_key 支付宝的公钥字符串
+     * @param string $sign              要校对的的签名结果
+     *
+     * @return bool
+     */
+    function rsaVerify($data, $alipay_public_key, $sign)
+    {
+        // 以下为了初始化私钥,保证在您填写私钥时不管是带格式还是不带格式都可以通过验证。
+        $alipay_public_key = str_replace("-----BEGIN PUBLIC KEY-----", "", $alipay_public_key);
+        $alipay_public_key = str_replace("-----END PUBLIC KEY-----", "", $alipay_public_key);
+        $alipay_public_key = str_replace("\n", "", $alipay_public_key);
+
+        $alipay_public_key = '-----BEGIN PUBLIC KEY-----' . PHP_EOL . wordwrap($alipay_public_key, 64, "\n", true) . PHP_EOL . '-----END PUBLIC KEY-----';
+        $res = openssl_get_publickey($alipay_public_key);
+        if (!$res) {
+            \Log::error("支付宝公钥格式不正确");
+            exit();
+        }
+
+        $result = (bool)openssl_verify($data, base64_decode($sign), $res);
+        openssl_free_key($res);
+
+        return $result;
+    }
+
+    /**
+     * 验证签名
+     *
+     * @param string $prestr 需要签名的字符串pre-sign
+     * @param string $sign   签名结果
+     * @param string $key    私钥
+     *
+     * @return bool
+     */
+    function md5Verify($prestr, $sign, $key)
+    {
+        $mysgin = md5($prestr . $key);
+
+        return $mysgin == $sign ? true : false;
+    }
+
+    /**
+     * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
+     *
+     * @param array $para 需要拼接的数组
+     *
+     * @return string
+     */
+    function createLinkString($para)
+    {
+        $arg = "";
+        while (list ($key, $val) = each($para)) {
+            $arg .= $key . "=" . $val . "&";
+        }
+
+        // 去掉最后一个&字符
+        $arg = substr($arg, 0, count($arg) - 2);
+
+        // 如果存在转义字符,那么去掉转义
+        if (get_magic_quotes_gpc()) {
+            $arg = stripslashes($arg);
+        }
+
+        return $arg;
+    }
+
+    /**
+     * 远程获取数据,GET模式
+     * 注意:文件夹中cacert.pem是SSL证书请保证其路径有效,目前默认路径是:getcwd().'\\cacert.pem'
+     *
+     * @param string $url        指定URL完整路径地址
+     * @param string $cacert_url 指定当前工作目录绝对路径
+     *
+     * @return mixed
+     */
+    function getHttpResponseGET($url, $cacert_url)
+    {
+        $curl = curl_init($url);
+        curl_setopt($curl, CURLOPT_HEADER, 0); // 过滤HTTP头
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 显示输出结果
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); // SSL证书认证
+        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 严格认证
+        curl_setopt($curl, CURLOPT_CAINFO, $cacert_url); // 证书地址
+        $responseText = curl_exec($curl);
+        //var_dump( curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容
+        curl_close($curl);
+
+        return $responseText;
+    }
+
+    /**
+     * 除去数组中的空值和签名参数
+     *
+     * @param array $para 签名参数组
+     *
+     * @return array 去掉空值与签名参数后的新签名参数组
+     */
+    function paraFilter($para)
+    {
+        $para_filter = [];
+        while (list ($key, $val) = each($para)) {
+            if ($key == "sign" || $key == "sign_type" || $val == "") continue;
+            else    $para_filter[$key] = $para[$key];
+        }
+
+        return $para_filter;
+    }
+
+    /**
+     * 对数组排序
+     *
+     * @param array $para 排序前的数组
+     *
+     * @return array 排序后的数组
+     */
+    function argSort($para)
+    {
+        ksort($para);
+        reset($para);
+
+        return $para;
+    }
+}
+
+?>

+ 267 - 0
app/Components/AlipaySubmit.php

@@ -0,0 +1,267 @@
+<?php
+
+namespace App\Components;
+
+use \DOMDocument;
+
+/**
+ * Class AlipaySubmit
+ *
+ * @author  wz812180
+ *
+ * @package App\Components
+ */
+class AlipaySubmit
+{
+    var $alipay_gateway_new = 'https://mapi.alipay.com/gateway.do?'; // 支付宝网关地址(新)
+    var $sign_type = "MD5"; // 加密方式:MD5/RSA
+    var $partner = "";
+    var $md5_key = "";
+    var $private_key = "";
+
+    function __construct($sign_type, $partner, $md5_key, $private_key)
+    {
+        $this->sign_type = $sign_type;
+        $this->partner = $partner;
+        $this->md5_key = $md5_key;
+        $this->private_key = $private_key;
+    }
+
+    /**
+     * 生成签名结果
+     *
+     * @param array $para_sort 已排序要签名的数组
+     *
+     * @return string
+     */
+    function buildRequestMysign($para_sort)
+    {
+        // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
+        $prestr = $this->createLinkString($para_sort);
+
+        switch (strtoupper(trim($this->sign_type))) {
+            case "MD5" :
+                $mysign = $this->md5Sign($prestr, $this->md5_key);
+                break;
+            case "RSA" :
+                $mysign = $this->rsaSign($prestr, $this->private_key);
+                break;
+            default :
+                $mysign = "";
+        }
+
+        return $mysign;
+    }
+
+    /**
+     * 生成要请求给支付宝的参数数组
+     *
+     * @param array $para_temp 请求前的参数数组
+     *
+     * @return array
+     */
+    function buildRequestPara($para_temp)
+    {
+        // 除去待签名参数数组中的空值和签名参数
+        $para_filter = $this->paraFilter($para_temp);
+
+        // 对待签名参数数组排序
+        $para_sort = $this->argSort($para_filter);
+
+        // 生成签名结果
+        $mysign = $this->buildRequestMysign($para_sort);
+
+        // 签名结果与签名方式加入请求提交参数组中
+        $para_sort['sign'] = $mysign;
+        $para_sort['sign_type'] = strtoupper(trim($this->sign_type));
+
+        return $para_sort;
+    }
+
+    /**
+     * 生成要请求给支付宝的参数数组
+     *
+     * @param array $para_temp 请求前的参数数组
+     *
+     * @return string
+     */
+    function buildRequestParaToString($para_temp)
+    {
+        // 待请求参数数组
+        $para = $this->buildRequestPara($para_temp);
+
+        // 把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码
+        $request_data = $this->createLinkStringUrlEncode($para);
+
+        return $request_data;
+    }
+
+    /**
+     * 建立请求,以表单HTML形式构造(默认)
+     *
+     * @param array  $para_temp   请求参数数组
+     * @param string $method      提交方式。两个值可选:post、get
+     * @param string $button_name 确认按钮显示文字
+     *
+     * @return string
+     */
+    public function buildRequestForm($para_temp, $method, $button_name)
+    {
+        // 待请求参数数组
+        $para = $this->buildRequestPara($para_temp);
+
+        $sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='" . $this->alipay_gateway_new . "_input_charset=utf-8' method='" . $method . "'>";
+        while (list ($key, $val) = each($para)) {
+            $sHtml .= "<input type='hidden' name='" . $key . "' value='" . $val . "'/>";
+        }
+
+        // submit按钮控件请不要含有name属性
+        $sHtml = $sHtml . "<input type='submit'  value='" . $button_name . "' style='display:none;'></form>";
+        $sHtml = $sHtml . "<script>document.forms['alipaysubmit'].submit();</script>";
+
+        return $sHtml;
+    }
+
+    /**
+     * 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数
+     *
+     * @return string
+     */
+    function query_timestamp()
+    {
+        $url = $this->alipay_gateway_new . "service=query_timestamp&partner=" . trim(strtolower($this->partner)) . "&_input_charset=utf-8";
+
+        $doc = new DOMDocument();
+        $doc->load($url);
+        $itemEncrypt_key = $doc->getElementsByTagName("encrypt_key");
+        $encrypt_key = $itemEncrypt_key->item(0)->nodeValue;
+
+        return $encrypt_key;
+    }
+
+    /**
+     * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
+     *
+     * @param array $para
+     *
+     * @return bool|string
+     */
+    function createLinkString($para)
+    {
+        $arg = "";
+        while (list ($key, $val) = each($para)) {
+            $arg .= $key . "=" . $val . "&";
+        }
+
+        // 去掉最后一个&字符
+        $arg = substr($arg, 0, count($arg) - 2);
+
+        // 如果存在转义字符,那么去掉转义
+        if (get_magic_quotes_gpc()) {
+            $arg = stripslashes($arg);
+        }
+
+        return $arg;
+    }
+
+    /**
+     * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码
+     *
+     * @param array $para 需要拼接的数组
+     *
+     * @return bool|string
+     */
+    function createLinkStringUrlEncode($para)
+    {
+        $arg = "";
+        while (list ($key, $val) = each($para)) {
+            $arg .= $key . "=" . urlencode($val) . "&";
+        }
+
+        // 去掉最后一个&字符
+        $arg = substr($arg, 0, count($arg) - 2);
+
+        // 如果存在转义字符,那么去掉转义
+        if (get_magic_quotes_gpc()) {
+            $arg = stripslashes($arg);
+        }
+
+        return $arg;
+    }
+
+    /**
+     * RSA签名
+     *
+     * @param string $data        待签名数据
+     * @param string $private_key 商户私钥字符串
+     *
+     * @return string
+     */
+    function rsaSign($data, $private_key)
+    {
+        //以下为了初始化私钥,保证在您填写私钥时不管是带格式还是不带格式都可以通过验证。
+        $private_key = str_replace("-----BEGIN RSA PRIVATE KEY-----", "", $private_key);
+        $private_key = str_replace("-----END RSA PRIVATE KEY-----", "", $private_key);
+        $private_key = str_replace("\n", "", $private_key);
+        $private_key = "-----BEGIN RSA PRIVATE KEY-----" . PHP_EOL . wordwrap($private_key, 64, "\n", true) . PHP_EOL . "-----END RSA PRIVATE KEY-----";
+
+        $res = openssl_get_privatekey($private_key);
+        if (!$res) {
+            \Log::error("私钥格式不正确");
+            exit();
+        }
+
+        openssl_sign($data, $sign, $res);
+        openssl_free_key($res);
+
+        $sign = base64_encode($sign); // base64编码
+
+        return $sign;
+    }
+
+    /**
+     * 签名字符串
+     *
+     * @param string $prestr 需要签名的字符串
+     * @param string $key    私钥
+     *
+     * @return string
+     */
+    function md5Sign($prestr, $key)
+    {
+        return md5($prestr . $key);
+    }
+
+    /**
+     * 除去数组中的空值和签名参数
+     *
+     * @param array $para 签名参数组
+     *
+     * @return array
+     */
+    function paraFilter($para)
+    {
+        $para_filter = [];
+        while (list ($key, $val) = each($para)) {
+            if ($key == "sign" || $key == "sign_type" || $val == "") continue;
+            else    $para_filter[$key] = $para[$key];
+        }
+
+        return $para_filter;
+    }
+
+    /**
+     * 对数组排序
+     *
+     * @param array $para 排序前的数组
+     *
+     * @return mixed
+     */
+    function argSort($para)
+    {
+        ksort($para);
+        reset($para);
+
+        return $para;
+    }
+}

+ 36 - 0
app/Components/CaptchaVerify.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Components;
+
+/**
+ * Class CaptchaVerify 验证码
+ *
+ * @package App\Components
+ */
+Class CaptchaVerify
+{
+    /**
+     * 从后台获取 Geetest_id 和 Geetest_key
+     */
+    public static function geetestCaptchaGetConfig()
+    {
+        return [
+            "geetest_id"  => Helpers::systemConfig()["geetest_id"],
+            "geetest_key" => Helpers::systemConfig()["geetest_key"]
+        ];
+    }
+
+    /**
+     * 从后台获取 google_captcha_sitekey 和 google_captcha_secret
+     */
+    public static function googleCaptchaGetConfig()
+    {
+        return [
+            "sitekey" => Helpers::systemConfig()["google_captcha_sitekey"],
+            "secret"  => Helpers::systemConfig()["google_captcha_secret"],
+            "options" => []
+        ];
+    }
+}
+
+?>

+ 64 - 0
app/Components/Curl.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace App\Components;
+
+class Curl
+{
+    /**
+     * @param string $url  请求地址
+     * @param array  $data 数据,如果有数据则用POST请求
+     *
+     * @return mixed
+     */
+    public static function send($url, $data = [])
+    {
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 3);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($ch, CURLOPT_URL, $url);
+
+        if ($data) {
+            curl_setopt($ch, CURLOPT_POST, 1);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        }
+
+        $res = curl_exec($ch);
+        curl_close($ch);
+
+        return $res;
+    }
+
+    /**
+     * POST JSON数据
+     *
+     * @param string $url    请求地址
+     * @param string $data   JSON数据
+     * @param string $secret 通信密钥
+     *
+     * @return mixed
+     */
+    public static function sendJson($url, $data, $secret)
+    {
+        $header = [
+            'Content-Type: application/json; charset=utf-8',
+            'Content-Length: ' . strlen($data),
+            'Secret: ' . $secret
+        ];
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_POST, true);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 3);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
+        $res = curl_exec($ch);
+        curl_close($ch);
+
+        return json_decode($res);
+    }
+}

+ 192 - 0
app/Components/Helpers.php

@@ -0,0 +1,192 @@
+<?php
+
+namespace App\Components;
+
+use App\Http\Models\Config;
+use App\Http\Models\CouponLog;
+use App\Http\Models\EmailLog;
+use App\Http\Models\Level;
+use App\Http\Models\SsConfig;
+use App\Http\Models\User;
+use App\Http\Models\UserSubscribe;
+use App\Http\Models\UserTrafficModifyLog;
+
+class Helpers
+{
+    // 不生成的端口
+    private static $denyPorts = [
+        1068, 1109, 1434, 3127, 3128,
+        3129, 3130, 3332, 4444, 5554,
+        6669, 8080, 8081, 8082, 8181,
+        8282, 9996, 17185, 24554, 35601,
+        60177, 60179
+    ];
+
+    // 获取系统配置
+    public static function systemConfig()
+    {
+        $config = Config::query()->get();
+        $data = [];
+        foreach ($config as $vo) {
+            $data[$vo->name] = $vo->value;
+        }
+
+        return $data;
+    }
+
+    // 获取默认加密方式
+    public static function getDefaultMethod()
+    {
+        $config = SsConfig::default()->type(1)->first();
+
+        return $config ? $config->name : 'aes-256-cfb';
+    }
+
+    // 获取默认协议
+    public static function getDefaultProtocol()
+    {
+        $config = SsConfig::default()->type(2)->first();
+
+        return $config ? $config->name : 'origin';
+    }
+
+    // 获取默认混淆
+    public static function getDefaultObfs()
+    {
+        $config = SsConfig::default()->type(3)->first();
+
+        return $config ? $config->name : 'plain';
+    }
+
+    // 获取一个随机端口
+    public static function getRandPort()
+    {
+        $config = self::systemConfig();
+        $port = mt_rand($config['min_port'], $config['max_port']);
+
+        $exists_port = User::query()->pluck('port')->toArray();
+        if (in_array($port, $exists_port) || in_array($port, self::$denyPorts)) {
+            $port = self::getRandPort();
+        }
+
+        return $port;
+    }
+
+    // 获取一个端口
+    public static function getOnlyPort()
+    {
+        $config = self::systemConfig();
+        $port = $config['min_port'];
+
+        $exists_port = User::query()->where('port', '>=', $config['min_port'])->pluck('port')->toArray();
+        while (in_array($port, $exists_port) || in_array($port, self::$denyPorts)) {
+            $port = $port + 1;
+        }
+
+        return $port;
+    }
+
+    // 加密方式
+    public static function methodList()
+    {
+        return SsConfig::type(1)->get();
+    }
+
+    // 协议
+    public static function protocolList()
+    {
+        return SsConfig::type(2)->get();
+    }
+
+    // 混淆
+    public static function obfsList()
+    {
+        return SsConfig::type(3)->get();
+    }
+
+    // 等级
+    public static function levelList()
+    {
+        return Level::query()->get()->sortBy('level');
+    }
+
+    // 生成用户的订阅码
+    public static function makeSubscribeCode()
+    {
+        $code = makeRandStr(5);
+        if (UserSubscribe::query()->where('code', $code)->exists()) {
+            $code = self::makeSubscribeCode();
+        }
+
+        return $code;
+    }
+
+    /**
+     * 添加邮件投递日志
+     *
+     * @param string $address 收信地址
+     * @param string $title   标题
+     * @param string $content 内容
+     * @param int    $status  投递状态
+     * @param string $error   投递失败时记录的异常信息
+     *
+     * @return int
+     */
+    public static function addEmailLog($address, $title, $content, $status = 1, $error = '')
+    {
+        $log = new EmailLog();
+        $log->type = 1;
+        $log->address = $address;
+        $log->title = $title;
+        $log->content = $content;
+        $log->status = $status;
+        $log->error = $error;
+        $log->save();
+
+        return $log->id;
+    }
+
+    /**
+     * 添加优惠券操作日志
+     *
+     * @param int    $couponId 优惠券ID
+     * @param int    $goodsId  商品ID
+     * @param int    $orderId  订单ID
+     * @param string $desc     备注
+     *
+     * @return int
+     */
+    public static function addCouponLog($couponId, $goodsId, $orderId, $desc = '')
+    {
+        $log = new CouponLog();
+        $log->coupon_id = $couponId;
+        $log->goods_id = $goodsId;
+        $log->order_id = $orderId;
+        $log->desc = $desc;
+
+        return $log->save();
+    }
+
+    /**
+     * 记录流量变动日志
+     *
+     * @param int    $userId 用户ID
+     * @param string $oid    订单ID
+     * @param int    $before 记录前的值
+     * @param int    $after  记录后的值
+     * @param string $desc   描述
+     *
+     * @return int
+     */
+    public static function addUserTrafficModifyLog($userId, $oid, $before, $after, $desc = '')
+    {
+        $log = new UserTrafficModifyLog();
+        $log->user_id = $userId;
+        $log->order_id = $oid;
+        $log->before = $before;
+        $log->after = $after;
+        $log->desc = $desc;
+
+        return $log->save();
+    }
+}

+ 25 - 0
app/Components/IPIP.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Components;
+
+use ipip\db\City;
+
+class IPIP
+{
+    /**
+     * 查询IP地址的详细信息
+     *
+     * @param string $ip IPv4
+     *
+     * @return array|null
+     */
+    public static function ip($ip)
+    {
+        $filePath = public_path('ipip.ipdb');
+
+        $loc = new City($filePath);
+        $result = $loc->findMap($ip, 'CN');
+
+        return $result;
+    }
+}

+ 105 - 0
app/Components/Namesilo.php

@@ -0,0 +1,105 @@
+<?php
+
+namespace App\Components;
+
+use LSS\XML2Array;
+use Log;
+
+class Namesilo
+{
+    protected static $host;
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$host = 'https://www.namesilo.com/api/';
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 列出账号下所有域名
+    public function listDomains()
+    {
+        return $this->send('listDomains');
+    }
+
+    // 列出指定域名的所有DNS记录
+    public function dnsListRecords($domain)
+    {
+        $query = [
+            'domain' => $domain
+        ];
+
+        return $this->send('dnsListRecords', $query);
+    }
+
+    // 为指定域名添加DNS记录
+    public function dnsAddRecord($domain, $host, $value, $type = 'A', $ttl = 7207)
+    {
+        $query = [
+            'domain'  => $domain,
+            'rrtype'  => $type,
+            'rrhost'  => $host,
+            'rrvalue' => $value,
+            'rrttl'   => $ttl
+        ];
+
+        return $this->send('dnsAddRecord', $query);
+    }
+
+    // 更新DNS记录
+    public function dnsUpdateRecord($domain, $id, $host, $value, $ttl = 7207)
+    {
+        $query = [
+            'domain'  => $domain,
+            'rrid'    => $id,
+            'rrhost'  => $host,
+            'rrvalue' => $value,
+            'rrttl'   => $ttl
+        ];
+
+        return $this->send('dnsUpdateRecord', $query);
+    }
+
+    // 删除DNS记录
+    public function dnsDeleteRecord($domain, $id)
+    {
+        $data = [
+            'domain' => $domain,
+            'rrid'   => $id
+        ];
+
+        return $this->send('dnsDeleteRecord', $data);
+    }
+
+    // 发送请求
+    private function send($operation, $data = [])
+    {
+        $params = [
+            'version' => 1,
+            'type'    => 'xml',
+            'key'     => self::$systemConfig['namesilo_key']
+        ];
+        $query = array_merge($params, $data);
+
+        $content = '请求操作:[' . $operation . '] --- 请求数据:[' . http_build_query($query) . ']';
+
+        try {
+            $result = Curl::send(self::$host . $operation . '?' . http_build_query($query));
+            $result = XML2Array::createArray($result);
+
+            // 出错
+            if (empty($result['namesilo']) || $result['namesilo']['reply']['code'] != 300 || $result['namesilo']['reply']['detail'] != 'success') {
+                Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], '[Namesilo API] - [' . $operation . ']', $content, 0, $result['namesilo']['reply']['detail']);
+            } else {
+                Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], '[Namesilo API] - [' . $operation . ']', $content, 1, $result['namesilo']['reply']['detail']);
+            }
+
+            return $result['namesilo']['reply'];
+        } catch (\Exception $e) {
+            Log::error('CURL请求失败:' . $e->getMessage() . ' --- ' . $e->getLine());
+            Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], '[Namesilo API] - [' . $operation . ']', $content, 0, $e->getMessage());
+
+            return false;
+        }
+    }
+}

+ 22 - 0
app/Components/QQWry.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Components;
+
+use itbdw\Ip\IpLocation;
+
+class QQWry
+{
+    /**
+     * 查询IP地址的详细信息
+     *
+     * @param string $ip IPv4
+     *
+     * @return array
+     */
+    public static function ip($ip)
+    {
+        $filePath = public_path('qqwry.dat');
+
+        return IpLocation::getLocation($ip, $filePath);
+    }
+}

+ 61 - 0
app/Components/ServerChan.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace App\Components;
+
+use App\Http\Models\EmailLog;
+use Log;
+
+class ServerChan
+{
+    /**
+     * 推送消息
+     *
+     * @param string $title   消息标题
+     * @param string $content 消息内容
+     *
+     * @return mixed
+     */
+    public static function send($title, $content)
+    {
+        if (Helpers::systemConfig()['is_server_chan'] && Helpers::systemConfig()['server_chan_key']) {
+            try {
+                // TODO:一天仅可发送不超过500条
+                $url = 'https://sc.ftqq.com/' . Helpers::systemConfig()['server_chan_key'] . '.send?text=' . $title . '&desp=' . urlencode($content);
+                $response = Curl::send($url);
+                $result = json_decode($response);
+                if (!$result->errno) {
+                    self::addLog($title, $content);
+                } else {
+                    self::addLog($title, $content, 0, $result->errmsg);
+                }
+            } catch (\Exception $e) {
+                Log::error('ServerChan消息推送异常:' . $e);
+            }
+        } else {
+            Log::error('消息推送失败:未启用或未正确配置ServerChan');
+        }
+    }
+
+    /**
+     * 添加serverChan推送日志
+     *
+     * @param string $title   标题
+     * @param string $content 内容
+     * @param int    $status  投递状态
+     * @param string $error   投递失败时记录的异常信息
+     *
+     * @return int
+     */
+    private static function addLog($title, $content, $status = 1, $error = '')
+    {
+        $log = new EmailLog();
+        $log->type = 2;
+        $log->address = 'admin';
+        $log->title = $title;
+        $log->content = $content;
+        $log->status = $status;
+        $log->error = $error;
+
+        return $log->save();
+    }
+}

+ 59 - 0
app/Components/Sms.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Components;
+
+use Overtrue\EasySms\EasySms;
+
+/**
+ * 发送短信
+ *
+ * 参考文档:\vendor\overtrue\easy-sms\README.md
+ *
+ * Class Sms
+ *
+ * @package App\Components
+ */
+class Sms
+{
+    public static function send()
+    {
+
+        $config = [
+            // HTTP 请求的超时时间(秒)
+            'timeout'  => 5.0,
+
+            // 默认发送配置
+            'default'  => [
+                // 网关调用策略,默认:顺序调用
+                'strategy' => \Overtrue\EasySms\Strategies\OrderStrategy::class,
+
+                // 默认可用的发送网关
+                'gateways' => [
+                    'yunpian',
+                ],
+            ],
+
+            // 可用的网关配置
+            'gateways' => [
+                'errorlog' => [
+                    'file' => '/tmp/easy-sms.log',
+                ],
+                'yunpian'  => [
+                    'api_key' => '0c9c87c41aac355520d47d3c84e5a532',
+                ],
+            ],
+        ];
+
+        $easySms = new EasySms($config);
+
+        $result = $easySms->send(15960271718, [
+            'content'  => '您的验证码为: 6379',
+            'template' => '2189086',
+            'data'     => [
+                'code' => 6379
+            ],
+        ]);
+
+        return $result;
+    }
+}

+ 67 - 0
app/Components/TelegramBot.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace App\Components;
+
+use App\Http\Models\EmailLog;
+use Log;
+use Telegram\Bot\Api;
+
+/**
+ * Telegram操作类
+ *
+ * Class Telegram
+ *
+ * @package App\Components
+ */
+class TelegramBot
+{
+    public static function send($title, $content)
+    {
+        if (Helpers::systemConfig()['is_telegram']) {
+            $telegram = new Api(Helpers::systemConfig()['telegram_token']);
+            try {
+                $response = $telegram->sendMessage([
+                    'chat_id'    => Helpers::systemConfig()['telegram_chatid'],
+                    'text'       => $content,
+                    'parse_mode' => 'Markdown'
+                ]);
+
+                if ($response->getMessageId()) {
+                    self::addLog($title, $content);
+                } else {
+                    self::addLog($title, $content, 0, 'Telegram消息推送失败');
+                }
+            } catch (\Exception $e) {
+                Log::error('Telegram消息推送异常:' . $e);
+            }
+        } else {
+            Log::error('消息推送失败:未启用或未正确配置Telegram');
+        }
+    }
+
+    /**
+     * 添加Telegram推送日志
+     *
+     * @param string $title   标题
+     * @param string $content 内容
+     * @param int    $status  投递状态
+     * @param string $error   投递失败时记录的异常信息
+     *
+     * @return int
+     */
+    private static function addLog($title, $content, $status = 1, $error = '')
+    {
+        $code = Helpers::makeEmailLogCode();
+
+        $log = new EmailLog();
+        $log->type = 4;
+        $log->code = $code;
+        $log->address = 'admin';
+        $log->title = $title;
+        $log->content = $content;
+        $log->status = $status;
+        $log->error = $error;
+
+        return $log->save();
+    }
+}

+ 73 - 0
app/Components/Yzy.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace App\Components;
+
+use Cache;
+use Log;
+
+class Yzy
+{
+    protected static $systemConfig;
+    protected static $accessToken;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+        self::$accessToken = $this->getAccessToken();
+    }
+
+    // 获取accessToken
+    public function getAccessToken()
+    {
+        if (Cache::has('YZY_TOKEN')) {
+            $token = Cache::get('YZY_TOKEN');
+            if (!isset($token['error'])) {
+                return Cache::get('YZY_TOKEN')['access_token'];
+            }
+
+            Cache::forget('YZY_TOKEN');
+        }
+
+        $token = (new \Youzan\Open\Token(self::$systemConfig['youzan_client_id'], self::$systemConfig['youzan_client_secret']))->getToken('self', ['kdt_id' => self::$systemConfig['kdt_id']]);
+        if (isset($token['error'])) {
+            Log::info('获取有赞云支付access_token失败:' . $token['error_description']);
+
+            return '';
+        } else {
+            Cache::put('YZY_TOKEN', $token, 180);
+
+            return $token['access_token'];
+        }
+    }
+
+    // 生成收款二维码
+    public function createQrCode($goodsName, $price, $orderSn)
+    {
+        $client = new \Youzan\Open\Client(self::$accessToken);
+
+        $params = [
+            'qr_name'   => $goodsName, // 商品名
+            'qr_price'  => $price, // 单位分
+            'qr_source' => $orderSn, // 本地订单号
+            'qr_type'   => 'QR_TYPE_DYNAMIC'
+        ];
+
+        return $client->get('youzan.pay.qrcode.create', '3.0.0', $params);
+    }
+
+    // 通过tid获取交易信息
+    public function getTradeByTid($tid)
+    {
+        $client = new \Youzan\Open\Client(self::$accessToken);
+
+        return $client->post('youzan.trade.get', '4.0.0', ['tid' => $tid]);
+    }
+
+    // 通过二维码ID获取已支付的交易信息
+    public function getTradeByQrId($qr_id)
+    {
+        $client = new \Youzan\Open\Client(self::$accessToken);
+
+        return $client->post('youzan.trades.qr.get', '3.0.0', ['qr_id' => $qr_id, 'status' => 'TRADE_RECEIVED']);
+    }
+}

+ 209 - 0
app/Console/Commands/AutoCheckNodeTCP.php

@@ -0,0 +1,209 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use Illuminate\Console\Command;
+use App\Components\ServerChan;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeInfo;
+use App\Mail\nodeCrashWarning;
+use Cache;
+use Mail;
+use Log;
+
+class AutoCheckNodeTCP extends Command
+{
+    protected $signature = 'autoCheckNodeTCP';
+    protected $description = '自动检测节点是否被TCP阻断';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        if (self::$systemConfig['is_tcp_check']) {
+            if (!Cache::has('tcp_check_time')) {
+                $this->checkNodes();
+            } elseif (Cache::get('tcp_check_time') <= time()) {
+                $this->checkNodes();
+            } else {
+                Log::info('下次节点TCP阻断检测时间:' . date('Y-m-d H:i:s', Cache::get('tcp_check_time')));
+            }
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    // 监测节点状态
+    private function checkNodes()
+    {
+        $title = "节点异常警告";
+
+        $nodeList = SsNode::query()->where('is_transit', 0)->where('is_nat', 0)->where('status', 1)->where('is_tcp_check', 1)->get();
+        foreach ($nodeList as $node) {
+            $tcpCheck = $this->tcpCheck($node->ip);
+            if (false !== $tcpCheck) {
+                switch ($tcpCheck) {
+                    case 1:
+                        $text = '服务器宕机';
+                        break;
+                    case 2:
+                        $text = '海外不通';
+                        break;
+                    case 3:
+                        $text = 'TCP阻断';
+                        break;
+                    case 0:
+                    default:
+                        $text = '正常';
+                }
+
+                // 异常才发通知消息
+                if ($tcpCheck) {
+                    if (self::$systemConfig['tcp_check_warning_times']) {
+                        // 已通知次数
+                        $cacheKey = 'tcp_check_warning_times_' . $node->id;
+                        if (Cache::has($cacheKey)) {
+                            $times = Cache::get($cacheKey);
+                        } else {
+                            Cache::put($cacheKey, 1, 725); // 最多设置提醒12次,12*60=720分钟缓存时效,多5分钟防止异常
+                            $times = 1;
+                        }
+
+                        if ($times < self::$systemConfig['tcp_check_warning_times']) {
+                            Cache::increment($cacheKey);
+
+                            $this->notifyMaster($title, "节点**{$node->name}【{$node->ip}】**:**" . $text . "**", $node->name, $node->server);
+                        } elseif ($times >= self::$systemConfig['tcp_check_warning_times']) {
+                            Cache::forget($cacheKey);
+                            SsNode::query()->where('id', $node->id)->update(['status' => 0]);
+
+                            $this->notifyMaster($title, "节点**{$node->name}【{$node->ip}】**:**" . $text . "**,节点自动进入维护状态", $node->name, $node->server);
+                        }
+                    } else {
+                        $this->notifyMaster($title, "节点**{$node->name}【{$node->ip}】**:**" . $text . "**", $node->name, $node->server);
+                    }
+                }
+
+                Log::info("【TCP阻断检测】" . $node->name . ' - ' . $node->ip . ' - ' . $text);
+            }
+        }
+
+        // 随机生成下次检测时间
+        $nextCheckTime = time() + mt_rand(1800, 3600);
+        Cache::put('tcp_check_time', $nextCheckTime, 60);
+    }
+
+    /**
+     * 用ipcheck.need.sh进行TCP阻断检测
+     *
+     * @param string $ip 被检测的IP
+     *
+     * @return bool|int
+     */
+    private function tcpCheck($ip)
+    {
+        try {
+            $url = 'https://ipcheck.need.sh/api_v2.php?ip=' . $ip;
+            $ret = $this->curlRequest($url);
+            $ret = json_decode($ret);
+            if (!$ret || $ret->result != 'success') {
+                Log::warning("【TCP阻断检测】检测" . $ip . "时,接口返回异常");
+
+                return false;
+            }
+        } catch (\Exception $e) {
+            Log::warning("【TCP阻断检测】检测" . $ip . "时,接口请求超时");
+
+            return false;
+        }
+
+        if (!$ret->data->inside_gfw->tcp->alive && !$ret->data->outside_gfw->tcp->alive) {
+            return 1; // 服务器宕机或者检测接口挂了
+        } elseif ($ret->data->inside_gfw->tcp->alive && !$ret->data->outside_gfw->tcp->alive) {
+            return 2; // 国外访问异常
+        } elseif (!$ret->data->inside_gfw->tcp->alive && $ret->data->outside_gfw->tcp->alive) {
+            return 3; // 被墙
+        } else {
+            return 0; // 正常
+        }
+    }
+
+    /**
+     * 通知管理员
+     *
+     * @param string $title      消息标题
+     * @param string $content    消息内容
+     * @param string $nodeName   节点名称
+     * @param string $nodeServer 节点域名
+     *
+     * @throws \GuzzleHttp\Exception\GuzzleException
+     */
+    private function notifyMaster($title, $content, $nodeName, $nodeServer)
+    {
+        $this->notifyMasterByEmail($title, $content, $nodeName, $nodeServer);
+        ServerChan::send($title, $content);
+    }
+
+    /**
+     * 发邮件通知管理员
+     *
+     * @param string $title      消息标题
+     * @param string $content    消息内容
+     * @param string $nodeName   节点名称
+     * @param string $nodeServer 节点域名
+     */
+    private function notifyMasterByEmail($title, $content, $nodeName, $nodeServer)
+    {
+        if (self::$systemConfig['crash_warning_email']) {
+            $logId = Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $title, $content);
+            Mail::to(self::$systemConfig['crash_warning_email'])->send(new nodeCrashWarning($logId, $nodeName, $nodeServer));
+        }
+    }
+
+    /**
+     * 发起一个CURL请求
+     *
+     * @param string $url  请求地址
+     * @param array  $data POST数据,留空则为GET
+     *
+     * @return mixed
+     */
+    private function curlRequest($url, $data = [])
+    {
+        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($ch, CURLOPT_URL, $url);
+//        curl_setopt($ch, CURLOPT_HTTPHEADER, [
+//            'Accept: application/json', // 请求报头
+//            'Content-Type: application/json', // 实体报头
+//            'Content-Length: ' . strlen($data)
+//        ]);
+
+        // 如果data有数据,则用POST请求
+        if ($data) {
+            curl_setopt($ch, CURLOPT_POST, 1);
+            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        }
+
+        $result = curl_exec($ch);
+        curl_close($ch);
+
+        return $result;
+    }
+}

+ 84 - 0
app/Console/Commands/AutoClearLog.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use App\Http\Models\SsNodeIp;
+use App\Http\Models\SsNodeInfo;
+use App\Http\Models\SsNodeOnlineLog;
+use App\Http\Models\SsNodeTrafficHourly;
+use App\Http\Models\SsNodeTrafficDaily;
+use App\Http\Models\UserBanLog;
+use App\Http\Models\UserLoginLog;
+use App\Http\Models\UserSubscribeLog;
+use App\Http\Models\UserTrafficDaily;
+use App\Http\Models\UserTrafficLog;
+use App\Http\Models\UserTrafficHourly;
+use Illuminate\Console\Command;
+use Log;
+
+class AutoClearLog extends Command
+{
+    protected $signature = 'autoClearLog';
+    protected $description = '自动清除日志';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        // 清除日志
+        if (self::$systemConfig['is_clear_log']) {
+            $this->clearLog();
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    // 清除日志
+    private function clearLog()
+    {
+        // 自动清除30分钟以前的节点负载信息日志
+        SsNodeInfo::query()->where('log_time', '<=', strtotime("-30 minutes"))->delete();
+
+        // 自动清除1小时以前的节点在线用户数日志
+        SsNodeOnlineLog::query()->where('log_time', '<=', strtotime("-1 hour"))->delete();
+
+        // 自动清除3天以前的用户流量日志
+        UserTrafficLog::query()->where('log_time', '<=', strtotime("-3 days"))->delete();
+
+        // 自动清除3天以前的用户每小时流量数据日志
+        UserTrafficHourly::query()->where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 days')))->delete();
+
+        // 自动清除1个月以前的用户每天流量数据日志
+        UserTrafficDaily::query()->where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-1 month')))->delete();
+
+        // 自动清除2个月以前的节点每小时流量数据日志
+        SsNodeTrafficHourly::query()->where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-2 month')))->delete();
+
+        // 自动清除3个月以前的节点每天流量数据日志
+        SsNodeTrafficDaily::query()->where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-3 month')))->delete();
+
+        // 自动清除30天以前用户封禁日志
+        UserBanLog::query()->where('created_at', '<=', date('Y-m-d H:i:s', strtotime("-1 month")))->delete();
+
+        // 自动清除1天前用户连接IP
+        SsNodeIp::query()->where('created_at', '<=', strtotime("-1 day"))->delete();
+
+        // 自动清除3个月以前用户登陆日志
+        UserLoginLog::query()->where('created_at', '<=', date('Y-m-d H:i:s', strtotime("-3 month")))->delete();
+
+        // 自动清除1个月前的用户订阅记录
+        UserSubscribeLog::query()->where('request_time', '<=', date('Y-m-d H:i:s', strtotime("-1 month")))->delete();
+    }
+
+}

+ 125 - 0
app/Console/Commands/AutoDecGoodsTraffic.php

@@ -0,0 +1,125 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use Illuminate\Console\Command;
+use App\Http\Models\Order;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Http\Models\GoodsLabel;
+use Log;
+use DB;
+
+class AutoDecGoodsTraffic extends Command
+{
+    protected $signature = 'autoDecGoodsTraffic';
+    protected $description = '自动扣减用户到期商品的流量';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        // 扣减用户到期商品的流量
+        $this->decGoodsTraffic();
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    // 扣减用户到期商品的流量
+    private function decGoodsTraffic()
+    {
+        $orderList = Order::query()->with(['user', 'goods'])->where('status', 2)->where('is_expire', 0)->where('expire_at', '<', date('Y-m-d H:i:s'))->get();
+        if (!$orderList->isEmpty()) {
+            // 用户默认标签
+            $defaultLabels = [];
+            if (self::$systemConfig['initial_labels_for_user']) {
+                $defaultLabels = explode(',', self::$systemConfig['initial_labels_for_user']);
+            }
+
+            DB::beginTransaction();
+            try {
+                foreach ($orderList as $order) {
+                    // 先过期本订单
+                    Order::query()->where('oid', $order->oid)->update(['is_expire' => 1]);
+
+                    // 再检查该订单对应用户是否还有套餐(非流量包)存在
+                    $haveOrder = Order::query()
+                        ->with(['user', 'goods'])
+                        ->where('is_expire', 0)
+                        ->where('user_id', $order->user_id)
+                        ->whereHas('goods', function ($q) {
+                            $q->where('type', 2);
+                        })
+                        ->orderBy('oid', 'desc')
+                        ->first();
+                    if (!$haveOrder) {
+                        // 如果不存在有效套餐(非流量包),则清空用户重置日
+                        User::query()->where('id', $order->user_id)->update(['traffic_reset_day' => 0]);
+                    }
+
+                    if (empty($order->user) || empty($order->goods)) {
+                        continue;
+                    }
+
+                    if ($order->user->transfer_enable - $order->goods->traffic * 1048576 <= 0) {
+                        // 写入用户流量变动记录
+                        Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $order->user->transfer_enable, 0, '[定时任务]用户所购商品到期,扣减商品对应的流量(扣完并重置)');
+
+                        User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0, 'transfer_enable' => 0]);
+                    } else {
+                        // 写入用户流量变动记录
+                        Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $order->user->transfer_enable, ($order->user->transfer_enable - $order->goods->traffic * 1048576), '[定时任务]用户所购商品到期,扣减商品对应的流量(没扣完)');
+
+                        User::query()->where('id', $order->user_id)->decrement('transfer_enable', $order->goods->traffic * 1048576);
+
+                        // 处理已用流量
+                        if ($order->user->u + $order->user->d - $order->goods->traffic * 1048576 <= 0) {
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0]);
+                        } else {
+                            // 一般来说d的值远远大于u
+                            if ($order->user->d - $order->goods->traffic * 1048576 >= 0) {
+                                User::query()->where('id', $order->user_id)->decrement('d', $order->goods->traffic * 1048576);
+                            } else { // 如果d不够减,则减u,然后d置0
+                                User::query()->where('id', $order->user_id)->decrement('u', $order->goods->traffic * 1048576 - $order->user->d);
+                                User::query()->where('id', $order->user_id)->update(['d' => 0]);
+                            }
+                        }
+                    }
+
+                    // 删除该商品对应用户的所有标签
+                    UserLabel::query()->where('user_id', $order->user->id)->delete();
+
+                    // 取出用户的其他商品带有的标签
+                    $goodsIds = Order::query()->where('user_id', $order->user->id)->where('oid', '<>', $order->oid)->where('status', 2)->where('is_expire', 0)->groupBy('goods_id')->pluck('goods_id')->toArray();
+                    $goodsLabels = GoodsLabel::query()->whereIn('goods_id', $goodsIds)->groupBy('label_id')->pluck('label_id')->toArray();
+
+                    // 生成标签
+                    $labels = array_values(array_unique(array_merge($goodsLabels, $defaultLabels))); // 标签去重
+                    foreach ($labels as $vo) {
+                        $userLabel = new UserLabel();
+                        $userLabel->user_id = $order->user->id;
+                        $userLabel->label_id = $vo;
+                        $userLabel->save();
+                    }
+                }
+
+                DB::commit();
+            } catch (\Exception $e) {
+                \Log::error($this->description . ':' . $e);
+
+                DB::rollBack();
+            }
+        }
+    }
+}

+ 618 - 0
app/Console/Commands/AutoJob.php

@@ -0,0 +1,618 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use App\Components\ServerChan;
+use App\Components\Yzy;
+use App\Http\Models\Goods;
+use App\Http\Models\GoodsLabel;
+use App\Http\Models\ReferralLog;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeInfo;
+use App\Http\Models\SsNodeLabel;
+use App\Http\Models\Ticket;
+use App\Http\Models\UserBalanceLog;
+use App\Http\Models\VerifyCode;
+use App\Mail\sendUserInfo;
+use Illuminate\Console\Command;
+use App\Http\Models\Coupon;
+use App\Http\Models\Invite;
+use App\Http\Models\Order;
+use App\Http\Models\Payment;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Http\Models\UserBanLog;
+use App\Http\Models\UserSubscribe;
+use App\Http\Models\UserSubscribeLog;
+use App\Http\Models\UserTrafficHourly;
+use Log;
+use DB;
+use Mail;
+
+class AutoJob extends Command
+{
+    protected $signature = 'autoJob';
+    protected $description = '自动化任务';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    /*
+     * 警告:除非熟悉业务流程,否则不推荐更改以下执行顺序,随意变更以下顺序可能导致系统异常
+     */
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        // 注册验证码自动置无效
+        $this->expireVerifyCode();
+
+        // 优惠券到期自动置无效
+        $this->expireCoupon();
+
+        // 邀请码到期自动置无效
+        $this->expireInvite();
+
+        // 封禁访问异常的订阅链接
+        $this->blockSubscribe();
+
+        // 封禁账号
+        $this->blockUsers();
+
+        // 解封被封禁的账号
+        $this->unblockUsers();
+
+        // 端口回收与分配
+        $this->dispatchPort();
+
+        // 审计待支付的订单
+        $this->detectOrders();
+
+        // 关闭超时未支付订单
+        $this->closeOrders();
+
+        // 关闭超过72小时未处理的工单
+        $this->closeTickets();
+
+        // 检测节点是否离线
+        $this->checkNodeStatus();
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    // 注册验证码自动置无效
+    private function expireVerifyCode()
+    {
+        VerifyCode::query()->where('status', 0)->where('created_at', '<=', date('Y-m-d H:i:s', strtotime("-10 minutes")))->update(['status' => 2]);
+    }
+
+    // 优惠券到期自动置无效
+    private function expireCoupon()
+    {
+        $couponList = Coupon::query()->where('status', 0)->where('available_end', '<=', time())->get();
+        if (!$couponList->isEmpty()) {
+            foreach ($couponList as $coupon) {
+                Coupon::query()->where('id', $coupon->id)->update(['status' => 2]);
+            }
+        }
+    }
+
+    // 邀请码到期自动置无效
+    private function expireInvite()
+    {
+        $inviteList = Invite::query()->where('status', 0)->where('dateline', '<=', date('Y-m-d H:i:s'))->get();
+        if (!$inviteList->isEmpty()) {
+            foreach ($inviteList as $invite) {
+                Invite::query()->where('id', $invite->id)->update(['status' => 2]);
+            }
+        }
+    }
+
+    // 封禁访问异常的订阅链接
+    private function blockSubscribe()
+    {
+        if (self::$systemConfig['is_subscribe_ban']) {
+            $subscribeList = UserSubscribe::query()->where('status', 1)->get();
+            if (!$subscribeList->isEmpty()) {
+                foreach ($subscribeList as $subscribe) {
+                    // 24小时内不同IP的请求次数
+                    $request_times = UserSubscribeLog::query()->where('sid', $subscribe->id)->where('request_time', '>=', date("Y-m-d H:i:s", strtotime("-24 hours")))->distinct('request_ip')->count('request_ip');
+                    if ($request_times >= self::$systemConfig['subscribe_ban_times']) {
+                        UserSubscribe::query()->where('id', $subscribe->id)->update(['status' => 0, 'ban_time' => time(), 'ban_desc' => '存在异常,自动封禁']);
+
+                        // 记录封禁日志
+                        $this->addUserBanLog($subscribe->user_id, 0, '【完全封禁订阅】-订阅24小时内请求异常');
+                    }
+                }
+            }
+        }
+    }
+
+    // 封禁账号
+    private function blockUsers()
+    {
+        // 过期用户处理
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('expire_time', '<', date('Y-m-d'))->get();
+        if (!$userList->isEmpty()) {
+            foreach ($userList as $user) {
+                if (self::$systemConfig['is_ban_status']) {
+                    User::query()->where('id', $user->id)->update([
+                        'u'                 => 0,
+                        'd'                 => 0,
+                        'transfer_enable'   => 0,
+                        'enable'            => 0,
+                        'traffic_reset_day' => 0,
+                        'ban_time'          => 0,
+                        'status'            => -1
+                    ]);
+
+                    $this->addUserBanLog($user->id, 0, '【禁止登录,清空账户】-账号已过期');
+
+                    // 如果注册就有初始流量,则废除其名下邀请码
+                    if (self::$systemConfig['default_traffic']) {
+                        Invite::query()->where('uid', $user->id)->where('status', 0)->update(['status' => 2]);
+                    }
+
+                    // 写入用户流量变动记录
+                    Helpers::addUserTrafficModifyLog($user->id, 0, $user->transfer_enable, 0, '[定时任务]账号已过期(禁止登录,清空账户)');
+                } else {
+                    User::query()->where('id', $user->id)->update([
+                        'u'                 => 0,
+                        'd'                 => 0,
+                        'transfer_enable'   => 0,
+                        'enable'            => 0,
+                        'traffic_reset_day' => 0,
+                        'ban_time'          => 0
+                    ]);
+
+                    $this->addUserBanLog($user->id, 0, '【封禁代理,清空账户】-账号已过期');
+
+                    // 写入用户流量变动记录
+                    Helpers::addUserTrafficModifyLog($user->id, 0, $user->transfer_enable, 0, '[定时任务]账号已过期(封禁代理,清空账户)');
+                }
+
+                // 移除标签
+                UserLabel::query()->where('user_id', $user->id)->delete();
+            }
+        }
+
+        // 封禁1小时内流量异常账号
+        if (self::$systemConfig['is_traffic_ban']) {
+            $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('ban_time', 0)->get();
+            if (!$userList->isEmpty()) {
+                foreach ($userList as $user) {
+                    // 对管理员豁免
+                    if ($user->is_admin) {
+                        continue;
+                    }
+
+                    // 多往前取5分钟,防止数据统计任务执行时间过长导致没有数据
+                    $totalTraffic = UserTrafficHourly::query()->where('user_id', $user->id)->where('node_id', 0)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->sum('total');
+                    if ($totalTraffic >= (self::$systemConfig['traffic_ban_value'] * 1073741824)) {
+                        User::query()->where('id', $user->id)->update(['enable' => 0, 'ban_time' => strtotime(date('Y-m-d H:i:s', strtotime("+" . self::$systemConfig['traffic_ban_time'] . " minutes")))]);
+
+                        // 写入日志
+                        $this->addUserBanLog($user->id, self::$systemConfig['traffic_ban_time'], '【临时封禁代理】-1小时内流量异常');
+                    }
+                }
+            }
+        }
+
+        // 禁用流量超限用户
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('ban_time', 0)->whereRaw("u + d >= transfer_enable")->get();
+        if (!$userList->isEmpty()) {
+            foreach ($userList as $user) {
+                User::query()->where('id', $user->id)->update(['enable' => 0]);
+
+                // 写入日志
+                $this->addUserBanLog($user->id, 0, '【封禁代理】-流量已用完');
+            }
+        }
+    }
+
+    // 解封被临时封禁的账号
+    private function unblockUsers()
+    {
+        // 解封被临时封禁的账号
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 0)->where('ban_time', '>', 0)->get();
+        foreach ($userList as $user) {
+            if ($user->ban_time < time()) {
+                User::query()->where('id', $user->id)->update(['enable' => 1, 'ban_time' => 0]);
+
+                // 写入操作日志
+                $this->addUserBanLog($user->id, 0, '【自动解封】-临时封禁到期');
+            }
+        }
+
+        // 可用流量大于已用流量也解封(比如:邀请返利自动加了流量)
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 0)->where('ban_time', 0)->where('expire_time', '>=', date('Y-m-d'))->whereRaw("u + d < transfer_enable")->get();
+        if (!$userList->isEmpty()) {
+            foreach ($userList as $user) {
+                User::query()->where('id', $user->id)->update(['enable' => 1]);
+
+                // 写入操作日志
+                $this->addUserBanLog($user->id, 0, '【自动解封】-有流量解封');
+            }
+        }
+    }
+
+    // 端口回收与分配
+    private function dispatchPort()
+    {
+        if (self::$systemConfig['auto_release_port']) {
+            ## 自动分配端口
+            $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('port', 0)->get();
+            if (!$userList->isEmpty()) {
+                foreach ($userList as $user) {
+                    $port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+
+                    User::query()->where('id', $user->id)->update(['port' => $port]);
+                }
+            }
+
+            ## 被封禁的账号自动释放端口
+            $userList = User::query()->where('status', -1)->where('enable', 0)->get();
+            if (!$userList->isEmpty()) {
+                foreach ($userList as $user) {
+                    if ($user->port) {
+                        User::query()->where('id', $user->id)->update(['port' => 0]);
+                    }
+                }
+            }
+
+            ## 过期一个月的账户自动释放端口
+            $userList = User::query()->where('enable', 0)->get();
+            if (!$userList->isEmpty()) {
+                foreach ($userList as $user) {
+                    if ($user->port) {
+                        $overdueDays = floor((strtotime(date('Y-m-d H:i:s')) - strtotime($user->expire_time)) / 86400);
+                        if ($overdueDays > 30) {
+                            User::query()->where('id', $user->id)->update(['port' => 0]);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // 审计待支付的订单
+    private function detectOrders()
+    {
+        /*
+         * 因为订单在15分钟未支付则会被自动关闭
+         * 当有赞没有正常推送消息或者其他原因导致用户已付款但是订单不生效从而导致用户无法正常加流量、置状态
+         * 故需要每分钟请求一次未支付订单,审计一下其支付状态
+         */
+        $paymentList = Payment::query()->with(['order', 'user'])->where('status', 0)->where('qr_id', '>', 0)->get();
+        if (!$paymentList->isEmpty()) {
+            foreach ($paymentList as $payment) {
+                // 跳过order丢失的订单
+                if (!isset($payment->order)) {
+                    continue;
+                }
+
+                $yzy = new yzy();
+                $trade = $yzy->getTradeByQrId($payment->qr_id);
+                if ($trade['response']['total_results']) {
+                    // 再判断一遍当前要操作的订单的状态是否被改变了(可能请求延迟的时候已经回调处理完了)
+                    $payment = Payment::query()->where('id', $payment->id)->first();
+                    if ($payment->status != '0') {
+                        continue;
+                    }
+
+                    // 处理订单
+                    DB::beginTransaction();
+                    try {
+                        // 如果支付单中没有用户信息则创建一个用户
+                        if (!$payment->user_id) {
+                            // 生成一个可用端口
+                            $port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+
+                            $user = new User();
+                            $user->username = '自动生成-' . $payment->order->email;
+                            $user->password = md5(makeRandStr());
+                            $user->port = $port;
+                            $user->passwd = makeRandStr();
+                            $user->vmess_id = createGuid();
+                            $user->enable = 1;
+                            $user->method = Helpers::getDefaultMethod();
+                            $user->protocol = Helpers::getDefaultProtocol();
+                            $user->obfs = Helpers::getDefaultObfs();
+                            $user->usage = 1;
+                            $user->transfer_enable = 1; // 新创建的账号给1,防止定时任务执行时发现u + d >= transfer_enable被判为流量超限而封禁
+                            $user->enable_time = date('Y-m-d');
+                            $user->expire_time = date('Y-m-d', strtotime("+" . $payment->order->goods->days . " days"));
+                            $user->reg_ip = getClientIp();
+                            $user->referral_uid = 0;
+                            $user->traffic_reset_day = 0;
+                            $user->status = 1;
+                            $user->save();
+
+                            if ($user->id) {
+                                Order::query()->where('oid', $payment->oid)->update(['user_id' => $user->id]);
+                            }
+                        }
+
+                        // 更新支付单
+                        $payment->pay_way = $trade['response']['pay_type'] == 'WXPAY_BIGUNSIGN' ? 1 : 2; // 1-微信、2-支付宝
+                        $payment->status = 1;
+                        $payment->save();
+
+                        // 更新订单
+                        $order = Order::query()->with(['user'])->where('oid', $payment->oid)->first();
+                        $order->status = 2;
+                        $order->save();
+
+                        $goods = Goods::query()->where('id', $order->goods_id)->first();
+
+                        // 商品为流量或者套餐
+                        if ($goods->type <= 2) {
+                            // 如果买的是套餐,则先将之前购买的所有套餐置都无效,并扣掉之前所有套餐的流量,重置用户已用流量为0
+                            if ($goods->type == 2) {
+                                $existOrderList = Order::query()
+                                    ->with(['goods'])
+                                    ->whereHas('goods', function ($q) {
+                                        $q->where('type', 2);
+                                    })
+                                    ->where('user_id', $order->user_id)
+                                    ->where('oid', '<>', $order->oid)
+                                    ->where('is_expire', 0)
+                                    ->where('status', 2)
+                                    ->get();
+
+                                foreach ($existOrderList as $vo) {
+                                    Order::query()->where('oid', $vo->oid)->update(['is_expire' => 1]);
+
+                                    // 先判断,防止手动扣减过流量的用户流量被扣成负数
+                                    if ($order->user->transfer_enable - $vo->goods->traffic * 1048576 <= 0) {
+                                        // 写入用户流量变动记录
+                                        Helpers::addUserTrafficModifyLog($order->user_id, 0, $order->user->transfer_enable, 0, '[定时任务]审计待支付的订单(扣完)');
+
+                                        User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0, 'transfer_enable' => 0]);
+                                    } else {
+                                        // 写入用户流量变动记录
+                                        Helpers::addUserTrafficModifyLog($order->user_id, 0, $order->user->transfer_enable, ($order->user->transfer_enable - $vo->goods->traffic * 1048576), '[定时任务]审计待支付的订单');
+
+                                        User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0]);
+                                        User::query()->where('id', $order->user_id)->decrement('transfer_enable', $vo->goods->traffic * 1048576);
+                                    }
+                                }
+                            }
+
+                            // 计算账号过期时间
+                            if ($order->user->expire_time < date('Y-m-d', strtotime("+" . $goods->days . " days"))) {
+                                $expireTime = date('Y-m-d', strtotime("+" . $goods->days . " days"));
+                            } else {
+                                $expireTime = $order->user->expire_time;
+                            }
+
+                            // 把商品的流量加到账号上
+                            User::query()->where('id', $order->user_id)->increment('transfer_enable', $goods->traffic * 1048576);
+
+                            // 套餐就改流量重置日,流量包不改
+                            if ($goods->type == 2) {
+                                if (date('m') == 2 && date('d') == 29) {
+                                    $traffic_reset_day = 28;
+                                } else {
+                                    $traffic_reset_day = date('d') == 31 ? 30 : abs(date('d'));
+                                }
+
+                                User::query()->where('id', $order->user_id)->update(['traffic_reset_day' => $traffic_reset_day, 'expire_time' => $expireTime, 'enable' => 1]);
+                            } else {
+                                User::query()->where('id', $order->user_id)->update(['expire_time' => $expireTime, 'enable' => 1]);
+                            }
+
+                            // 写入用户标签
+                            if ($goods->label) {
+                                // 用户默认标签
+                                $defaultLabels = [];
+                                if (self::$systemConfig['initial_labels_for_user']) {
+                                    $defaultLabels = explode(',', self::$systemConfig['initial_labels_for_user']);
+                                }
+
+                                // 取出现有的标签
+                                $userLabels = UserLabel::query()->where('user_id', $order->user_id)->pluck('label_id')->toArray();
+                                $goodsLabels = GoodsLabel::query()->where('goods_id', $order->goods_id)->pluck('label_id')->toArray();
+
+                                // 标签去重
+                                $newUserLabels = array_values(array_unique(array_merge($userLabels, $goodsLabels, $defaultLabels)));
+
+                                // 删除用户所有标签
+                                UserLabel::query()->where('user_id', $order->user_id)->delete();
+
+                                // 生成标签
+                                foreach ($newUserLabels as $vo) {
+                                    $obj = new UserLabel();
+                                    $obj->user_id = $order->user_id;
+                                    $obj->label_id = $vo;
+                                    $obj->save();
+                                }
+                            }
+
+                            // 写入返利日志
+                            if ($order->user->referral_uid) {
+                                $this->addReferralLog($order->user_id, $order->user->referral_uid, $order->oid, $order->amount, $order->amount * self::$systemConfig['referral_percent']);
+                            }
+
+                            // 取消重复返利
+                            User::query()->where('id', $order->user_id)->update(['referral_uid' => 0]);
+
+                        } elseif ($goods->type == 3) { // 商品为在线充值
+                            User::query()->where('id', $order->user_id)->increment('balance', $goods->price * 100);
+
+                            // 余额变动记录日志
+                            $this->addUserBalanceLog($order->user_id, $order->oid, $order->user->balance, $order->user->balance + $goods->price, $goods->price, '用户在线充值');
+                        }
+
+                        // 自动提号机:如果order的email值不为空
+                        if ($order->email) {
+                            $title = '【' . self::$systemConfig['website_name'] . '】您的账号信息';
+                            $content = [
+                                'order_sn'      => $order->order_sn,
+                                'goods_name'    => $order->goods->name,
+                                'goods_traffic' => flowAutoShow($order->goods->traffic * 1048576),
+                                'port'          => $order->user->port,
+                                'passwd'        => $order->user->passwd,
+                                'method'        => $order->user->method,
+                                //'protocol'       => $order->user->protocol,
+                                //'protocol_param' => $order->user->protocol_param,
+                                //'obfs'           => $order->user->obfs,
+                                //'obfs_param'     => $order->user->obfs_param,
+                                'created_at'    => $order->created_at->toDateTimeString(),
+                                'expire_at'     => $order->expire_at
+                            ];
+
+                            // 获取可用节点列表
+                            $labels = UserLabel::query()->where('user_id', $order->user_id)->get()->pluck('label_id');
+                            $nodeIds = SsNodeLabel::query()->whereIn('label_id', $labels)->get()->pluck('node_id');
+                            $nodeList = SsNode::query()->whereIn('id', $nodeIds)->orderBy('sort', 'desc')->orderBy('id', 'desc')->get()->toArray();
+                            $content['serverList'] = $nodeList;
+
+                            $logId = Helpers::addEmailLog($order->email, $title, json_encode($content));
+                            Mail::to($order->email)->send(new sendUserInfo($logId, $content));
+                        }
+
+                        DB::commit();
+                    } catch (\Exception $e) {
+                        DB::rollBack();
+
+                        Log::info('【有赞云】审计订单时更新支付单和订单异常:' . $e);
+                    }
+                }
+            }
+        }
+    }
+
+    // 关闭超时未支付订单
+    private function closeOrders()
+    {
+        // 关闭超时未支付的有赞云订单(有赞云收款二维码超过30分钟自动关闭,关闭后无法再支付,所以我们限制15分钟内必须付款)
+        $paymentList = Payment::query()->with(['order', 'order.coupon'])->where('status', 0)->where('created_at', '<=', date("Y-m-d H:i:s", strtotime("-15 minutes")))->get();
+        if (!$paymentList->isEmpty()) {
+            DB::beginTransaction();
+            try {
+                foreach ($paymentList as $payment) {
+                    // 关闭支付单
+                    Payment::query()->where('id', $payment->id)->update(['status' => -1]);
+
+                    // 关闭订单
+                    Order::query()->where('oid', $payment->oid)->update(['status' => -1]);
+
+                    // 退回优惠券
+                    if ($payment->order->coupon_id) {
+                        Coupon::query()->where('id', $payment->order->coupon_id)->update(['status' => 0]);
+
+                        Helpers::addCouponLog($payment->order->coupon_id, $payment->order->goods_id, $payment->oid, '订单超时未支付,自动退回');
+                    }
+                }
+
+                DB::commit();
+            } catch (\Exception $e) {
+                Log::info('【异常】自动关闭超时未支付订单:' . $e);
+
+                DB::rollBack();
+            }
+        }
+    }
+
+    // 关闭超过72小时未处理的工单
+    private function closeTickets()
+    {
+        $ticketList = Ticket::query()->where('updated_at', '<=', date('Y-m-d H:i:s', strtotime("-72 hours")))->where('status', 1)->get();
+        foreach ($ticketList as $ticket) {
+            $ret = Ticket::query()->where('id', $ticket->id)->update(['status' => 2]);
+            if ($ret) {
+                ServerChan::send('工单关闭提醒', '工单:ID' . $ticket->id . '超过72小时未处理,系统已自动关闭');
+            }
+        }
+    }
+
+    // 检测节点是否离线
+    private function checkNodeStatus()
+    {
+        if (Helpers::systemConfig()['is_node_crash_warning']) {
+            $nodeList = SsNode::query()->where('is_transit', 0)->where('status', 1)->get();
+            foreach ($nodeList as $node) {
+                // 10分钟内无节点负载信息且TCP检测认为不是离线则认为是后端炸了
+                $nodeTTL = SsNodeInfo::query()->where('node_id', $node->id)->where('log_time', '>=', strtotime("-10 minutes"))->orderBy('id', 'desc')->first();
+                if (!$nodeTTL) {
+                    ServerChan::send('节点异常警告', "节点**{$node->name}【{$node->ip}】**异常:**心跳异常,可能离线了**");
+                }
+            }
+        }
+    }
+
+    /**
+     * 添加用户封禁日志
+     *
+     * @param int    $userId  用户ID
+     * @param int    $minutes 封禁时长,单位分钟
+     * @param string $desc    封禁理由
+     */
+    private function addUserBanLog($userId, $minutes, $desc)
+    {
+        $log = new UserBanLog();
+        $log->user_id = $userId;
+        $log->minutes = $minutes;
+        $log->desc = $desc;
+        $log->save();
+    }
+
+    /**
+     * 添加返利日志
+     *
+     * @param int $userId    用户ID
+     * @param int $refUserId 返利用户ID
+     * @param int $oid       订单ID
+     * @param int $amount    发生金额
+     * @param int $refAmount 返利金额
+     *
+     * @return int
+     */
+    public function addReferralLog($userId, $refUserId, $oid, $amount, $refAmount)
+    {
+        $log = new ReferralLog();
+        $log->user_id = $userId;
+        $log->ref_user_id = $refUserId;
+        $log->order_id = $oid;
+        $log->amount = $amount;
+        $log->ref_amount = $refAmount;
+        $log->status = 0;
+
+        return $log->save();
+    }
+
+    /**
+     * 记录余额操作日志
+     *
+     * @param int    $userId 用户ID
+     * @param string $oid    订单ID
+     * @param int    $before 记录前余额
+     * @param int    $after  记录后余额
+     * @param int    $amount 发生金额
+     * @param string $desc   描述
+     *
+     * @return int
+     */
+    public function addUserBalanceLog($userId, $oid, $before, $after, $amount, $desc = '')
+    {
+        $log = new UserBalanceLog();
+        $log->user_id = $userId;
+        $log->order_id = $oid;
+        $log->before = $before;
+        $log->after = $after;
+        $log->amount = $amount;
+        $log->desc = $desc;
+        $log->created_at = date('Y-m-d H:i:s');
+
+        return $log->save();
+    }
+}

+ 55 - 0
app/Console/Commands/AutoReportNode.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use App\Components\ServerChan;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeTrafficDaily;
+use Illuminate\Console\Command;
+use Log;
+
+class AutoReportNode extends Command
+{
+    protected $signature = 'autoReportNode';
+    protected $description = '自动报告节点昨日使用情况';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        if (self::$systemConfig['node_daily_report']) {
+            $nodeList = SsNode::query()->where('status', 1)->get();
+            if (!$nodeList->isEmpty()) {
+                $msg = "|节点|上行流量|下行流量|合计|\r\n| :------ | :------ | :------ |\r\n";
+                foreach ($nodeList as $node) {
+                    $log = SsNodeTrafficDaily::query()
+                        ->where('node_id', $node->id)
+                        ->where('created_at', '>=', date('Y-m-d 00:00:00', strtotime("-1 day")))
+                        ->where('created_at', '<=', date('Y-m-d 23:59:59', strtotime("-1 day")))
+                        ->first();
+
+                    if ($log) {
+                        $msg .= '|' . $node->name . '|' . flowAutoShow($log->u) . '|' . flowAutoShow($log->d) . '|' . $log->traffic . "\r\n";
+                    } else {
+                        $msg .= '|' . $node->name . '|' . flowAutoShow(0) . '|' . flowAutoShow(0) . "|0B\r\n";
+                    }
+                }
+
+                ServerChan::send('节点日报', $msg);
+            }
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+}

+ 80 - 0
app/Console/Commands/AutoResetUserTraffic.php

@@ -0,0 +1,80 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use Illuminate\Console\Command;
+use App\Http\Models\Order;
+use App\Http\Models\User;
+use Log;
+
+class AutoResetUserTraffic extends Command
+{
+    protected $signature = 'autoResetUserTraffic';
+    protected $description = '自动重置用户可用流量';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        // 重置用户流量
+        if (self::$systemConfig['reset_traffic']) {
+            $this->resetUserTraffic();
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    // 重置用户流量
+    private function resetUserTraffic()
+    {
+        $userList = User::query()->where('status', '>=', 0)->where('expire_time', '>=', date('Y-m-d'))->get();
+        if (!$userList->isEmpty()) {
+            foreach ($userList as $user) {
+                if (!$user->traffic_reset_day) {
+                    continue;
+                }
+
+                // 取出用户购买的有效套餐
+                $order = Order::query()
+                    ->with(['user', 'goods'])
+                    ->whereHas('goods', function ($q) {
+                        $q->where('type', 2);
+                    })
+                    ->where('user_id', $user->id)
+                    ->where('is_expire', 0)
+                    ->orderBy('oid', 'desc')
+                    ->first();
+
+                if (!$order) {
+                    continue;
+                }
+
+                $month = date('m');
+                $today = date('d');
+                $last_day= date('t');
+                $resetDay = $order->user->traffic_reset_day;
+                if ($resetDay == $today || ($today == $last_day && $resetDay > $last_day)) {
+                    // 跳过本月,防止异常重置
+                    if ($month == date('m', strtotime($order->expire_at))) {
+                        continue;
+                    } elseif ($month == date('m', strtotime($order->created_at))) {
+                        continue;
+                    }
+                    // 重置流量
+                    User::query()->where('id', $user->id)->update(['u' => 0, 'd' => 0,'transfer_enable' => $order->goods->traffic * 1048576]);
+                }
+            }
+        }
+    }
+}

+ 58 - 0
app/Console/Commands/AutoStatisticsNodeDailyTraffic.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeTrafficDaily;
+use App\Http\Models\UserTrafficLog;
+use Log;
+
+class AutoStatisticsNodeDailyTraffic extends Command
+{
+    protected $signature = 'autoStatisticsNodeDailyTraffic';
+    protected $description = '自动统计节点每日流量';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        $nodeList = SsNode::query()->where('status', 1)->orderBy('id', 'asc')->get();
+        foreach ($nodeList as $node) {
+            $this->statisticsByNode($node->id);
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    private function statisticsByNode($node_id)
+    {
+        $start_time = strtotime(date('Y-m-d 00:00:00', strtotime("-1 day")));
+        $end_time = strtotime(date('Y-m-d 23:59:59', strtotime("-1 day")));
+
+        $query = UserTrafficLog::query()->where('node_id', $node_id)->whereBetween('log_time', [$start_time, $end_time]);
+
+        $u = $query->sum('u');
+        $d = $query->sum('d');
+        $total = $u + $d;
+        $traffic = flowAutoShow($total);
+
+        if ($total) { // 有数据才记录
+            $obj = new SsNodeTrafficDaily();
+            $obj->node_id = $node_id;
+            $obj->u = $u;
+            $obj->d = $d;
+            $obj->total = $total;
+            $obj->traffic = $traffic;
+            $obj->save();
+        }
+    }
+}

+ 58 - 0
app/Console/Commands/AutoStatisticsNodeHourlyTraffic.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeTrafficHourly;
+use App\Http\Models\UserTrafficLog;
+use Log;
+
+class AutoStatisticsNodeHourlyTraffic extends Command
+{
+    protected $signature = 'autoStatisticsNodeHourlyTraffic';
+    protected $description = '自动统计节点每小时流量';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        $nodeList = SsNode::query()->where('status', 1)->orderBy('id', 'asc')->get();
+        foreach ($nodeList as $node) {
+            $this->statisticsByNode($node->id);
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    private function statisticsByNode($node_id)
+    {
+        $start_time = strtotime(date('Y-m-d H:i:s', strtotime("-1 hour")));
+        $end_time = time();
+
+        $query = UserTrafficLog::query()->where('node_id', $node_id)->whereBetween('log_time', [$start_time, $end_time]);
+
+        $u = $query->sum('u');
+        $d = $query->sum('d');
+        $total = $u + $d;
+        $traffic = flowAutoShow($total);
+
+        if ($total) { // 有数据才记录
+            $obj = new SsNodeTrafficHourly();
+            $obj->node_id = $node_id;
+            $obj->u = $u;
+            $obj->d = $d;
+            $obj->total = $total;
+            $obj->traffic = $traffic;
+            $obj->save();
+        }
+    }
+}

+ 71 - 0
app/Console/Commands/AutoStatisticsUserDailyTraffic.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Http\Models\SsNode;
+use App\Http\Models\User;
+use App\Http\Models\UserTrafficDaily;
+use App\Http\Models\UserTrafficLog;
+use Log;
+
+class AutoStatisticsUserDailyTraffic extends Command
+{
+    protected $signature = 'autoStatisticsUserDailyTraffic';
+    protected $description = '自动统计用户每日流量';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->get();
+        foreach ($userList as $user) {
+            // 统计一次所有节点的总和
+            $this->statisticsByNode($user->id);
+
+            // 统计每个节点产生的流量
+            $nodeList = SsNode::query()->where('status', 1)->orderBy('id', 'asc')->get();
+            foreach ($nodeList as $node) {
+                $this->statisticsByNode($user->id, $node->id);
+            }
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    private function statisticsByNode($user_id, $node_id = 0)
+    {
+        $start_time = strtotime(date('Y-m-d 00:00:00', strtotime("-1 day")));
+        $end_time = strtotime(date('Y-m-d 23:59:59', strtotime("-1 day")));
+
+        $query = UserTrafficLog::query()->where('user_id', $user_id)->whereBetween('log_time', [$start_time, $end_time]);
+
+        if ($node_id) {
+            $query->where('node_id', $node_id);
+        }
+
+        $u = $query->sum('u');
+        $d = $query->sum('d');
+        $total = $u + $d;
+        $traffic = flowAutoShow($total);
+
+        if ($total) { // 有数据才记录
+            $obj = new UserTrafficDaily();
+            $obj->user_id = $user_id;
+            $obj->node_id = $node_id;
+            $obj->u = $u;
+            $obj->d = $d;
+            $obj->total = $total;
+            $obj->traffic = $traffic;
+            $obj->save();
+        }
+    }
+}

+ 71 - 0
app/Console/Commands/AutoStatisticsUserHourlyTraffic.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Http\Models\SsNode;
+use App\Http\Models\User;
+use App\Http\Models\UserTrafficLog;
+use App\Http\Models\UserTrafficHourly;
+use Log;
+
+class AutoStatisticsUserHourlyTraffic extends Command
+{
+    protected $signature = 'autoStatisticsUserHourlyTraffic';
+    protected $description = '自动统计用户每小时流量';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->get();
+        foreach ($userList as $user) {
+            // 统计一次所有节点的总和
+            $this->statisticsByNode($user->id);
+
+            // 统计每个节点产生的流量
+            $nodeList = SsNode::query()->where('status', 1)->orderBy('id', 'asc')->get();
+            foreach ($nodeList as $node) {
+                $this->statisticsByNode($user->id, $node->id);
+            }
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    private function statisticsByNode($user_id, $node_id = 0)
+    {
+        $start_time = strtotime(date('Y-m-d H:i:s', strtotime("-1 hour")));
+        $end_time = time();
+
+        $query = UserTrafficLog::query()->where('user_id', $user_id)->whereBetween('log_time', [$start_time, $end_time]);
+
+        if ($node_id) {
+            $query->where('node_id', $node_id);
+        }
+
+        $u = $query->sum('u');
+        $d = $query->sum('d');
+        $total = $u + $d;
+        $traffic = flowAutoShow($total);
+
+        if ($total) { // 有数据才记录
+            $obj = new UserTrafficHourly();
+            $obj->user_id = $user_id;
+            $obj->node_id = $node_id;
+            $obj->u = $u;
+            $obj->d = $d;
+            $obj->total = $total;
+            $obj->traffic = $traffic;
+            $obj->save();
+        }
+    }
+}

+ 67 - 0
app/Console/Commands/UserExpireAutoWarning.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use Illuminate\Console\Command;
+use App\Http\Models\User;
+use App\Mail\userExpireWarning;
+use App\Mail\userExpireWarningToday;
+use Mail;
+use Log;
+
+class UserExpireAutoWarning extends Command
+{
+    protected $signature = 'userExpireAutoWarning';
+    protected $description = '用户临近到期自动发邮件提醒';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        // 用户临近到期自动发邮件提醒
+        if (self::$systemConfig['expire_warning']) {
+            $this->userExpireWarning();
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    private function userExpireWarning()
+    {
+        // 只取SSR没被禁用的用户,其他不用管
+        $userList = User::query()->where('enable', 1)->get();
+        foreach ($userList as $user) {
+            // 用户名不是邮箱的跳过
+            if (false === filter_var($user->username, FILTER_VALIDATE_EMAIL)) {
+                continue;
+            }
+
+            // 计算剩余可用时间
+            $lastCanUseDays = ceil(round(strtotime($user->expire_time) - strtotime(date('Y-m-d H:i:s'))) / 3600 / 24);
+            if ($lastCanUseDays == 0) {
+                $title = '账号过期提醒';
+                $content = '您的账号将于今天晚上【24:00】过期。';
+
+                $logId = Helpers::addEmailLog($user->username, $title, $content);
+                Mail::to($user->username)->send(new userExpireWarningToday($logId));
+            } elseif ($lastCanUseDays > 0 && $lastCanUseDays <= self::$systemConfig['expire_days']) {
+                $title = '账号过期提醒';
+                $content = '您的账号还剩' . $lastCanUseDays . '天即将过期。';
+
+                $logId = Helpers::addEmailLog($user->username, $title, $content);
+                Mail::to($user->username)->send(new userExpireWarning($logId, $lastCanUseDays));
+            }
+        }
+    }
+}

+ 59 - 0
app/Console/Commands/UserTrafficAbnormalAutoWarning.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use App\Components\ServerChan;
+use Illuminate\Console\Command;
+use App\Http\Models\User;
+use App\Http\Models\UserTrafficHourly;
+use Log;
+
+class UserTrafficAbnormalAutoWarning extends Command
+{
+    protected $signature = 'userTrafficAbnormalAutoWarning';
+    protected $description = '用户流量异常警告';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        // 用户流量异常警告
+        $this->userTrafficAbnormalWarning();
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    // 用户流量异常警告
+    private function userTrafficAbnormalWarning()
+    {
+        // 1小时内流量异常用户(多往前取5分钟,防止数据统计任务执行时间过长导致没有数据)
+        $userTotalTrafficList = UserTrafficHourly::query()->where('node_id', 0)->where('total', '>', 104857600)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->groupBy('user_id')->selectRaw("user_id, sum(total) as totalTraffic")->get(); // 只统计100M以上的记录,加快查询速度
+        if (!$userTotalTrafficList->isEmpty()) {
+            $title = "流量异常用户提醒";
+
+            foreach ($userTotalTrafficList as $vo) {
+                $user = User::query()->where('id', $vo->user_id)->first();
+
+                // 通过ServerChan发微信消息提醒管理员
+                if ($vo->totalTraffic > (self::$systemConfig['traffic_ban_value'] * 1073741824)) {
+                    $traffic = UserTrafficHourly::query()->where('node_id', 0)->where('user_id', $vo->user_id)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->selectRaw("user_id, sum(`u`) as totalU, sum(`d`) as totalD, sum(total) as totalTraffic")->first();
+
+                    $content = "用户**{$user->username}(ID:{$user->id})**,最近1小时**上行流量:" . flowAutoShow($traffic->totalU) . ",下行流量:" . flowAutoShow($traffic->totalD) . ",共计:" . flowAutoShow($traffic->totalTraffic) . "**。";
+
+                    ServerChan::send($title, $content);
+                }
+            }
+        }
+    }
+}

+ 59 - 0
app/Console/Commands/UserTrafficAutoWarning.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use Illuminate\Console\Command;
+use App\Http\Models\User;
+use App\Mail\userTrafficWarning;
+use Mail;
+use Log;
+
+class UserTrafficAutoWarning extends Command
+{
+    protected $signature = 'userTrafficAutoWarning';
+    protected $description = '用户流量超过警告阈值自动发邮件提醒';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        $jobStartTime = microtime(true);
+
+        // 用户流量超过警告阈值自动发邮件提醒
+        if (self::$systemConfig['traffic_warning']) {
+            $this->userTrafficWarning();
+        }
+
+        $jobEndTime = microtime(true);
+        $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
+
+        Log::info('执行定时任务【' . $this->description . '】,耗时' . $jobUsedTime . '秒');
+    }
+
+    // 用户流量超过警告阈值自动发邮件提醒
+    private function userTrafficWarning()
+    {
+        $userList = User::query()->where('status', '>=', 0)->where('enable', 1)->where('transfer_enable', '>', 0)->get();
+        foreach ($userList as $user) {
+            // 用户名不是邮箱的跳过
+            if (false === filter_var($user->username, FILTER_VALIDATE_EMAIL)) {
+                continue;
+            }
+
+            $usedPercent = round(($user->d + $user->u) / $user->transfer_enable, 2) * 100; // 已使用流量百分比
+            if ($usedPercent >= self::$systemConfig['traffic_warning_percent']) {
+                $title = '流量提醒';
+                $content = '流量已使用:' . $usedPercent . '%,请保持关注。';
+
+                $logId = Helpers::addEmailLog($user->username, $title, $content);
+                Mail::to($user->username)->send(new userTrafficWarning($logId, $usedPercent));
+            }
+        }
+    }
+}

+ 54 - 0
app/Console/Commands/upgradeUserLabels.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use Illuminate\Console\Command;
+
+class upgradeUserLabels extends Command
+{
+    protected $signature = 'upgradeUserLabels';
+    protected $description = '初始化用户默认标签';
+    protected static $systemConfig;
+
+    public function __construct()
+    {
+        parent::__construct();
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function handle()
+    {
+        if (empty(self::$systemConfig['initial_labels_for_user'])) {
+            \Log::info('初始化用户默认标签失败:系统未设置默认标签');
+            exit();
+        }
+
+        $userList = User::query()->where('status', '>=', 0)->get();
+        foreach ($userList as $user) {
+            // 跳过已经有标签的用户
+            $count = UserLabel::query()->where('user_id', $user->id)->count();
+            if ($count) {
+                continue;
+            }
+
+            // 给用户生成默认标签
+            $this->makeUserDefaultLabels($user->id);
+        }
+    }
+
+    // 生成用户默认标签
+    private function makeUserDefaultLabels($userId)
+    {
+        $labels = explode(',', self::$systemConfig['initial_labels_for_user']);
+
+        foreach ($labels as $vo) {
+            $userLabel = new UserLabel();
+            $userLabel->user_id = $userId;
+            $userLabel->label_id = $vo;
+            $userLabel->save();
+        }
+    }
+}

+ 33 - 0
app/Console/Commands/upgradeUserPassword.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Http\Models\User;
+use Illuminate\Console\Command;
+use Hash;
+use Log;
+
+class upgradeUserPassword extends Command
+{
+    protected $signature = 'upgradeUserPassword';
+    protected $description = '用户密码升级(MD5->HASH)';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        Log::info('----------------------------【升级用户登录密码】开始----------------------------');
+        
+        // 将用户的登录密码由原有的md5升级为hash,统一升级为与用户名相同的密码
+        $userList = User::query()->get();
+        foreach ($userList as $user) {
+            User::query()->where('id', $user->id)->update(['password' => Hash::make($user->username)]);
+            Log::info('----------------------------升级用户[' . $user->username . ']的登录密码----------------------------');
+        }
+
+        Log::info('----------------------------【升级用户登录密码】结束----------------------------');
+    }
+}

+ 36 - 0
app/Console/Commands/upgradeUserSpeedLimit.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Http\Models\User;
+use Illuminate\Console\Command;
+use Log;
+
+class upgradeUserSpeedLimit extends Command
+{
+    protected $signature = 'upgradeUserSpeedLimit';
+    protected $description = '升级用户限速字段,重置初始值';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        Log::info('----------------------------【重置用户限速字段】开始----------------------------');
+
+        $userList = User::query()->get();
+        foreach ($userList as $user) {
+            $data = [
+                'speed_limit_per_con'  => 10737418240,
+                'speed_limit_per_user' => 10737418240
+            ];
+
+            User::query()->where('id', $user->id)->update($data);
+            Log::info('---用户[ID:' . $user->id . ' - ' . $user->username . ']的限速字段值被重置为10G---');
+        }
+
+        Log::info('----------------------------【重置用户限速字段】结束----------------------------');
+    }
+}

+ 42 - 0
app/Console/Commands/upgradeUserSubscribe.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Components\Helpers;
+use App\Http\Models\User;
+use App\Http\Models\UserSubscribe;
+use Illuminate\Console\Command;
+use Log;
+
+class upgradeUserSubscribe extends Command
+{
+    protected $signature = 'upgradeUserSubscribe';
+    protected $description = '生成用户的订阅码';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        Log::info('----------------------------【生成用户订阅码】开始----------------------------');
+
+        $userList = User::query()->get();
+        foreach ($userList as $user) {
+            // 如果未生成过订阅码则生成一个
+            $subscribe = UserSubscribe::query()->where('user_id', $user->id)->first();
+            if (!$subscribe) {
+                $subscribe = new UserSubscribe();
+                $subscribe->user_id = $user->id;
+                $subscribe->code = Helpers::makeSubscribeCode();
+                $subscribe->times = 0;
+                $subscribe->save();
+
+                Log::info('---生成用户[ID:' . $user->id . ' - ' . $user->username . ']的订阅码---');
+            }
+        }
+
+        Log::info('----------------------------【生成用户订阅码】结束----------------------------');
+    }
+}

+ 32 - 0
app/Console/Commands/upgradeUserVmessId.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Http\Models\User;
+use Illuminate\Console\Command;
+
+class upgradeUserVmessId extends Command
+{
+    protected $signature = 'upgradeUserVmessId';
+    protected $description = '重新生成用户的vmess_id字段';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+        $userList = User::query()->get();
+        foreach ($userList as $user) {
+            if (!isset($user->vmess_id)) {
+                \Log::error("USER表缺失vmess_id字段,请先维护数据库字典");
+                break;
+            }
+
+            if (!$user->vmess_id) {
+                User::query()->where('id', $user->id)->update(['vmess_id' => createGuid()]);
+            }
+        }
+    }
+}

+ 71 - 0
app/Console/Kernel.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Console;
+
+use Illuminate\Console\Scheduling\Schedule;
+use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
+
+class Kernel extends ConsoleKernel
+{
+    /**
+     * The Artisan commands provided by your application.
+     *
+     * @var array
+     */
+    protected $commands = [
+        \App\Console\Commands\AutoJob::class,
+        \App\Console\Commands\AutoClearLog::class,
+        \App\Console\Commands\AutoDecGoodsTraffic::class,
+        \App\Console\Commands\AutoResetUserTraffic::class,
+        \App\Console\Commands\AutoCheckNodeTCP::class,
+        \App\Console\Commands\AutoStatisticsNodeDailyTraffic::class,
+        \App\Console\Commands\AutoStatisticsNodeHourlyTraffic::class,
+        \App\Console\Commands\AutoStatisticsUserDailyTraffic::class,
+        \App\Console\Commands\AutoStatisticsUserHourlyTraffic::class,
+        \App\Console\Commands\UserTrafficAbnormalAutoWarning::class,
+        \App\Console\Commands\UserExpireAutoWarning::class,
+        \App\Console\Commands\UserTrafficAutoWarning::class,
+        \App\Console\Commands\upgradeUserLabels::class,
+        \App\Console\Commands\upgradeUserPassword::class,
+        \App\Console\Commands\upgradeUserSpeedLimit::class,
+        \App\Console\Commands\upgradeUserSubscribe::class,
+        \App\Console\Commands\upgradeUserVmessId::class,
+        \App\Console\Commands\AutoReportNode::class,
+    ];
+
+    /**
+     * Define the application's command schedule.
+     *
+     * @param  \Illuminate\Console\Scheduling\Schedule $schedule
+     *
+     * @return void
+     */
+    protected function schedule(Schedule $schedule)
+    {
+        $schedule->command('autoJob')->everyMinute();
+        $schedule->command('autoClearLog')->everyThirtyMinutes();
+        $schedule->command('autoDecGoodsTraffic')->everyTenMinutes();
+        $schedule->command('autoResetUserTraffic')->daily();
+        $schedule->command('autoCheckNodeTCP')->everyMinute();
+        $schedule->command('autoStatisticsNodeDailyTraffic')->dailyAt('23:55');
+        $schedule->command('autoStatisticsNodeHourlyTraffic')->hourly();
+        $schedule->command('autoStatisticsUserDailyTraffic')->dailyAt('23:50');
+        $schedule->command('autoStatisticsUserHourlyTraffic')->hourly();
+        $schedule->command('userTrafficAbnormalAutoWarning')->hourly();
+        $schedule->command('userExpireAutoWarning')->dailyAt('20:00');
+        $schedule->command('userTrafficAutoWarning')->dailyAt('10:30');
+        $schedule->command('autoReportNode')->dailyAt('09:00');
+    }
+
+    /**
+     * Register the commands for the application.
+     *
+     * @return void
+     */
+    protected function commands()
+    {
+        $this->load(__DIR__.'/Commands');
+
+        require base_path('routes/console.php');
+    }
+}

+ 36 - 0
app/Events/Event.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace App\Events;
+
+use Illuminate\Broadcasting\Channel;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Broadcasting\PrivateChannel;
+use Illuminate\Broadcasting\PresenceChannel;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+
+class Event
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    /**
+     * Create a new event instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        //
+    }
+
+    /**
+     * Get the channels the event should broadcast on.
+     *
+     * @return \Illuminate\Broadcasting\Channel|array
+     */
+    public function broadcastOn()
+    {
+        return new PrivateChannel('channel-name');
+    }
+}

+ 171 - 0
app/Exceptions/Handler.php

@@ -0,0 +1,171 @@
+<?php
+
+namespace App\Exceptions;
+
+use ErrorException;
+use Exception;
+use Illuminate\Auth\AuthenticationException;
+use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
+use Illuminate\Session\TokenMismatchException;
+use InvalidArgumentException;
+use ReflectionException;
+use RuntimeException;
+use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
+use Tymon\JWTAuth\Exceptions\TokenExpiredException;
+use Tymon\JWTAuth\Exceptions\TokenInvalidException;
+
+class Handler extends ExceptionHandler
+{
+    /**
+     * A list of the exception types that are not reported.
+     *
+     * @var array
+     */
+    protected $dontReport = [
+        //
+    ];
+
+    /**
+     * A list of the inputs that are never flashed for validation exceptions.
+     *
+     * @var array
+     */
+    protected $dontFlash = [
+        'password',
+        'password_confirmation',
+    ];
+
+    /**
+     * Report or log an exception.
+     *
+     * @param Exception $exception
+     *
+     * @return mixed|void
+     * @throws Exception
+     */
+    public function report(Exception $exception)
+    {
+        // 记录异常来源
+        \Log::info('异常来源:' . get_class($exception));
+
+        // 调试模式下记录错误详情
+        if (config('app.debug')) {
+            \Log::info($exception);
+        }
+
+        parent::report($exception);
+    }
+
+    /**
+     * Render an exception into an HTTP response.
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Exception               $exception
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function render($request, Exception $exception)
+    {
+        // 调试模式下直接返回错误信息
+        if (config('app.debug')) {
+            return parent::render($request, $exception);
+        }
+
+        // 捕获未生成key异常
+        if ($exception instanceof RuntimeException) {
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => $exception->getMessage()]);
+            } else {
+                return response()->view('auth.error', ['message' => $exception->getMessage()]);
+            }
+        }
+
+        // 捕获访问异常
+        if ($exception instanceof NotFoundHttpException) {
+            \Log::info("异常请求:" . $request->fullUrl() . ",IP:" . getClientIp());
+
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => $exception->getMessage()]);
+            } else {
+                return response()->view('auth.error', ['message' => $exception->getMessage()]);
+            }
+        }
+
+        // 路由参数异常
+        if ($exception instanceof InvalidArgumentException) {
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => $exception->getMessage()]);
+            } else {
+                return response()->view('auth.error', ['message' => $exception->getMessage()]);
+            }
+        }
+
+        // 请求方式不允许异常
+        if ($exception instanceof MethodNotAllowedHttpException) {
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => $exception->getMessage()]);
+            } else {
+                return response()->view('auth.error', ['message' => $exception->getMessage()]);
+            }
+        }
+
+        // 捕获身份校验异常
+        if ($exception instanceof AuthenticationException) {
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => $exception->getMessage()]);
+            } else {
+                return response()->view('auth.error', ['message' => $exception->getMessage()]);
+            }
+        }
+
+        // 捕获CSRF异常
+        if ($exception instanceof TokenMismatchException) {
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => 'System Error, Please Refresh Page, Try One More Time']);
+            } else {
+                return response()->view('auth.error', ['message' => trans('error.RefreshPage')]);
+            }
+        }
+
+        // 捕获反射异常
+        if ($exception instanceof ReflectionException) {
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => 'System Error']);
+            } else {
+                return response()->view('auth.error', ['message' => trans('error.SystemError')]);
+            }
+        }
+
+        // 捕获系统错误异常
+        if ($exception instanceof ErrorException) {
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => 'System Error']);
+            } else {
+                return response()->view('auth.error', ['message' => trans('error.SystemError') . ', ' . trans('error.Visit') . '<a href="/logs" target="_blank">' . trans('error.log') . '</a>']);
+            }
+        }
+
+        // 未授权异常
+        if ($exception instanceof UnauthorizedHttpException) {
+            if ($request->expectsJson()) {
+                return response()->json(['status' => 'fail', 'data' => '', 'message' => $exception->getMessage()]);
+            } else {
+                return response()->view('auth.error', ['message' => $exception->getMessage()]);
+            }
+        }
+
+        // 客户端API:捕获认证过期异常
+        if ($exception instanceof TokenExpiredException) {
+            return response()->json(['status' => 'fail', 'data' => '', 'message' => $exception->getMessage()]);
+        }
+
+        // 客户端API:捕获认证不合法异常
+        if ($exception instanceof TokenInvalidException) {
+            return response()->json(['status' => 'fail', 'data' => '', 'message' => $exception->getMessage()]);
+        }
+
+        return parent::render($request, $exception);
+    }
+}

+ 2641 - 0
app/Http/Controllers/AdminController.php

@@ -0,0 +1,2641 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\Helpers;
+use App\Components\IPIP;
+use App\Components\QQWry;
+use App\Http\Models\Article;
+use App\Http\Models\Config;
+use App\Http\Models\Country;
+use App\Http\Models\EmailLog;
+use App\Http\Models\Invite;
+use App\Http\Models\Label;
+use App\Http\Models\Level;
+use App\Http\Models\Order;
+use App\Http\Models\ReferralApply;
+use App\Http\Models\ReferralLog;
+use App\Http\Models\SsConfig;
+use App\Http\Models\SsGroup;
+use App\Http\Models\SsGroupNode;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeInfo;
+use App\Http\Models\SsNodeIp;
+use App\Http\Models\SsNodeLabel;
+use App\Http\Models\SsNodeOnlineLog;
+use App\Http\Models\SsNodeTrafficDaily;
+use App\Http\Models\SsNodeTrafficHourly;
+use App\Http\Models\User;
+use App\Http\Models\UserBalanceLog;
+use App\Http\Models\UserBanLog;
+use App\Http\Models\UserLabel;
+use App\Http\Models\UserLoginLog;
+use App\Http\Models\UserSubscribe;
+use App\Http\Models\UserTrafficDaily;
+use App\Http\Models\UserTrafficHourly;
+use App\Http\Models\UserTrafficLog;
+use App\Http\Models\UserTrafficModifyLog;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
+use Illuminate\Http\Request;
+use Redirect;
+use Response;
+use Session;
+use Log;
+use DB;
+use Auth;
+use Hash;
+
+/**
+ * 管理员控制器
+ *
+ * Class AdminController
+ *
+ * @package App\Http\Controllers
+ */
+class AdminController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function index(Request $request)
+    {
+        $past = strtotime(date('Y-m-d', strtotime("-" . self::$systemConfig['expire_days'] . " days")));
+
+        $view['expireDays'] = self::$systemConfig['expire_days'];
+        $view['totalUserCount'] = User::query()->count(); // 总用户数
+        $view['enableUserCount'] = User::query()->where('enable', 1)->count(); // 有效用户数
+        $view['activeUserCount'] = User::query()->where('t', '>=', $past)->count(); // 活跃用户数
+        $view['unActiveUserCount'] = User::query()->where('t', '<=', $past)->where('enable', 1)->where('t', '>', 0)->count(); // 不活跃用户数
+        $view['onlineUserCount'] = User::query()->where('t', '>=', time() - 600)->count(); // 10分钟内在线用户数
+        $view['expireWarningUserCount'] = User::query()->where('expire_time', '>=', date('Y-m-d', strtotime("now")))->where('expire_time', '<=', date('Y-m-d', strtotime("+" . self::$systemConfig['expire_days'] . " days")))->count(); // 临近过期用户数
+        $view['largeTrafficUserCount'] = User::query()->whereRaw('(u + d) >= 107374182400')->whereIn('status', [0, 1])->count(); // 流量超过100G的用户
+
+        // 1小时内流量异常用户
+        $tempUsers = [];
+        $userTotalTrafficList = UserTrafficHourly::query()->where('node_id', 0)->where('total', '>', 104857600)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->groupBy('user_id')->selectRaw("user_id, sum(total) as totalTraffic")->get(); // 只统计100M以上的记录,加快速度
+        if (!$userTotalTrafficList->isEmpty()) {
+            foreach ($userTotalTrafficList as $vo) {
+                if ($vo->totalTraffic > (self::$systemConfig['traffic_ban_value'] * 1073741824)) {
+                    $tempUsers[] = $vo->user_id;
+                }
+            }
+        }
+        $view['flowAbnormalUserCount'] = User::query()->whereIn('id', $tempUsers)->count();
+
+
+        $view['nodeCount'] = SsNode::query()->count();
+        $view['unnormalNodeCount'] = SsNode::query()->where('status', 0)->count();
+
+        $flowCount = SsNodeTrafficDaily::query()->where('created_at', '>=', date('Y-m-d 00:00:00', strtotime("-30 days")))->sum('total');
+        $view['flowCount'] = flowAutoShow($flowCount);
+        $totalFlowCount = SsNodeTrafficDaily::query()->sum('total');
+        $view['totalFlowCount'] = flowAutoShow($totalFlowCount);
+
+        $view['totalBalance'] = User::query()->sum('balance') / 100;
+        $view['totalWaitRefAmount'] = ReferralLog::query()->whereIn('status', [0, 1])->sum('ref_amount') / 100;
+        $view['totalRefAmount'] = ReferralApply::query()->where('status', 2)->sum('amount') / 100;
+
+        $view['totalOrder'] = Order::query()->count();
+        $view['totalOnlinePayOrder'] = Order::query()->where('pay_way', 2)->count();
+        $view['totalSuccessOrder'] = Order::query()->where('status', 2)->count();
+        $view['todaySuccessOrder'] = Order::query()->where('status', 2)->where('created_at', '>=', date('Y-m-d 00:00:00'))->where('created_at', '<=', date('Y-m-d 23:59:59'))->count();
+
+        return Response::view('admin.index', $view);
+    }
+
+    // 用户列表
+    public function userList(Request $request)
+    {
+        $id = intval($request->get('id'));
+        $username = trim($request->get('username'));
+        $wechat = trim($request->get('wechat'));
+        $qq = trim($request->get('qq'));
+        $port = intval($request->get('port'));
+        $pay_way = intval($request->get('pay_way'));
+        $status = $request->get('status');
+        $enable = $request->get('enable');
+        $online = $request->get('online');
+        $unActive = $request->get('unActive');
+        $flowAbnormal = $request->get('flowAbnormal');
+        $expireWarning = $request->get('expireWarning');
+        $largeTraffic = $request->get('largeTraffic');
+
+        $query = User::query()->with(['subscribe']);
+        if (!empty($id)) {
+            $query->where('id', $id);
+        }
+
+        if (!empty($username)) {
+            $query->where('username', 'like', '%' . $username . '%');
+        }
+
+        if (!empty($wechat)) {
+            $query->where('wechat', 'like', '%' . $wechat . '%');
+        }
+
+        if (!empty($qq)) {
+            $query->where('qq', 'like', '%' . $qq . '%');
+        }
+
+        if ($port != '') {
+            $query->where('port', $port);
+        }
+
+        if ($pay_way != '') {
+            $query->where('pay_way', $pay_way);
+        }
+
+        if ($status != '') {
+            $query->where('status', intval($status));
+        }
+
+        if ($enable != '') {
+            $query->where('enable', intval($enable));
+        }
+
+        // 流量超过100G的
+        if ($largeTraffic) {
+            $query->whereIn('status', [0, 1])->whereRaw('(u + d) >= 107374182400');
+        }
+
+        // 临近过期提醒
+        if ($expireWarning) {
+            $query->where('expire_time', '>=', date('Y-m-d', strtotime("now")))->where('expire_time', '<=', date('Y-m-d', strtotime("+" . self::$systemConfig['expire_days'] . " days")));
+        }
+
+        // 当前在线
+        if ($online) {
+            $query->where('t', '>=', time() - 600);
+        }
+
+        // 不活跃用户
+        if ($unActive) {
+            $query->where('t', '>', 0)->where('t', '<=', strtotime(date('Y-m-d', strtotime("-" . self::$systemConfig['expire_days'] . " days"))))->where('enable', 1);
+        }
+
+        // 1小时内流量异常用户
+        if ($flowAbnormal) {
+            $tempUsers = [];
+            $userTotalTrafficList = UserTrafficHourly::query()->where('node_id', 0)->where('total', '>', 104857600)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->groupBy('user_id')->selectRaw("user_id, sum(total) as totalTraffic")->get(); // 只统计100M以上的记录,加快速度
+            if (!$userTotalTrafficList->isEmpty()) {
+                foreach ($userTotalTrafficList as $vo) {
+                    if ($vo->totalTraffic > (self::$systemConfig['traffic_ban_value'] * 1024 * 1024 * 1024)) {
+                        $tempUsers[] = $vo->user_id;
+                    }
+                }
+            }
+            $query->whereIn('id', $tempUsers);
+        }
+
+        $userList = $query->orderBy('id', 'desc')->paginate(15)->appends($request->except('page'));
+        foreach ($userList as &$user) {
+            $user->transfer_enable = flowAutoShow($user->transfer_enable);
+            $user->used_flow = flowAutoShow($user->u + $user->d);
+            if ($user->expire_time < date('Y-m-d', strtotime("now"))) {
+                $user->expireWarning = -1; // 已过期
+            } elseif ($user->expire_time == date('Y-m-d', strtotime("now"))) {
+                $user->expireWarning = 0; // 今天过期
+            } elseif ($user->expire_time > date('Y-m-d', strtotime("now")) && $user->expire_time <= date('Y-m-d', strtotime("+30 days"))) {
+                $user->expireWarning = 1; // 最近一个月过期
+            } else {
+                $user->expireWarning = 2; // 大于一个月过期
+            }
+
+            // 流量异常警告
+            $time = date('Y-m-d H:i:s', time() - 3900);
+            $totalTraffic = UserTrafficHourly::query()->where('user_id', $user->id)->where('node_id', 0)->where('created_at', '>=', $time)->sum('total');
+            $user->trafficWarning = $totalTraffic > (self::$systemConfig['traffic_ban_value'] * 1024 * 1024 * 1024) ? 1 : 0;
+
+            // 订阅地址
+            $user->link = (self::$systemConfig['subscribe_domain'] ? self::$systemConfig['subscribe_domain'] : self::$systemConfig['website_url']) . '/s/' . $user->subscribe->code;
+        }
+
+        $view['userList'] = $userList;
+
+        return Response::view('admin.userList', $view);
+    }
+
+    // 添加账号
+    public function addUser(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            // 校验username是否已存在
+            $exists = User::query()->where('username', $request->get('username'))->first();
+            if ($exists) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '用户名已存在,请重新输入']);
+            }
+
+            if (!$request->get('usage')) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '请至少选择一种用途']);
+            }
+
+            $user = new User();
+            $user->username = trim($request->get('username'));
+            $user->password = trim($request->get('password')) ? Hash::make(trim($request->get('password'))) : Hash::make(makeRandStr());
+            $user->port = $request->get('port');
+            $user->passwd = empty($request->get('passwd')) ? makeRandStr() : $request->get('passwd');
+            $user->vmess_id = $request->get('vmess_id') ? trim($request->get('vmess_id')) : createGuid();
+            $user->transfer_enable = toGB($request->get('transfer_enable', 0));
+            $user->enable = intval($request->get('enable', 0));
+            $user->method = $request->get('method');
+            $user->protocol = $request->get('protocol');
+            $user->protocol_param = $request->get('protocol_param') ? $request->get('protocol_param') : '';
+            $user->obfs = $request->get('obfs');
+            $user->obfs_param = $request->get('obfs_param') ? $request->get('obfs_param') : '';
+            $user->speed_limit_per_con = intval($request->get('speed_limit_per_con'));
+            $user->speed_limit_per_user = intval($request->get('speed_limit_per_user'));
+            $user->gender = intval($request->get('gender'));
+            $user->wechat = $request->get('wechat') ? $request->get('wechat') : '';
+            $user->qq = $request->get('qq') ? $request->get('qq') : '';
+            $user->usage = $request->get('usage');
+            $user->pay_way = $request->get('pay_way');
+            $user->balance = 0;
+            $user->enable_time = empty($request->get('enable_time')) ? date('Y-m-d') : $request->get('enable_time');
+            $user->expire_time = empty($request->get('expire_time')) ? date('Y-m-d', strtotime("+365 days")) : $request->get('expire_time');
+            $user->remark = str_replace("eval", "", str_replace("atob", "", $request->get('remark')));
+            $user->level = $request->get('level') ? $request->get('level') : 1;
+            $user->is_admin = 0;
+            $user->reg_ip = getClientIp();
+            $user->referral_uid = 0;
+            $user->traffic_reset_day = 0;
+            $user->status = $request->get('status') ? $request->get('status') : 1;
+            $user->save();
+
+            if ($user->id) {
+                // 生成订阅码
+                $subscribe = new UserSubscribe();
+                $subscribe->user_id = $user->id;
+                $subscribe->code = Helpers::makeSubscribeCode();
+                $subscribe->times = 0;
+                $subscribe->save();
+
+                // 生成用户标签
+                $this->makeUserLabels($user->id, $request->get('labels'));
+
+                // 写入用户流量变动记录
+                Helpers::addUserTrafficModifyLog($user->id, 0, 0, toGB($request->get('transfer_enable', 0)), '后台手动添加用户');
+
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '添加成功']);
+            } else {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '添加失败']);
+            }
+        } else {
+            // 生成一个可用端口
+            $view['last_port'] = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+            $view['method_list'] = Helpers::methodList();
+            $view['protocol_list'] = Helpers::protocolList();
+            $view['obfs_list'] = Helpers::obfsList();
+            $view['level_list'] = Helpers::levelList();
+            $view['label_list'] = Label::query()->orderBy('sort', 'desc')->orderBy('id', 'asc')->get();
+            $view['initial_labels'] = explode(",", Helpers::systemConfig()['initial_labels_for_user']);
+
+            return Response::view('admin.addUser', $view);
+        }
+    }
+
+    // 批量生成账号
+    public function batchAddUsers(Request $request)
+    {
+        DB::beginTransaction();
+        try {
+            for ($i = 0; $i < 5; $i++) {
+                // 生成一个可用端口
+                $port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+
+                $user = new User();
+                $user->username = '批量生成-' . makeRandStr();
+                $user->password = Hash::make(makeRandStr());
+                $user->port = $port;
+                $user->passwd = makeRandStr();
+                $user->vmess_id = createGuid();
+                $user->enable = 1;
+                $user->method = Helpers::getDefaultMethod();
+                $user->protocol = Helpers::getDefaultProtocol();
+                $user->protocol_param = '';
+                $user->obfs = Helpers::getDefaultObfs();
+                $user->obfs_param = '';
+                $user->usage = 1;
+                $user->transfer_enable = toGB(1024);
+                $user->enable_time = date('Y-m-d');
+                $user->expire_time = date('Y-m-d', strtotime("+365 days"));
+                $user->remark = '';
+                $user->reg_ip = getClientIp();
+                $user->referral_uid = 0;
+                $user->traffic_reset_day = 0;
+                $user->status = 1;
+                $user->save();
+
+                if ($user->id) {
+                    // 生成订阅码
+                    $subscribe = new UserSubscribe();
+                    $subscribe->user_id = $user->id;
+                    $subscribe->code = Helpers::makeSubscribeCode();
+                    $subscribe->times = 0;
+                    $subscribe->save();
+
+                    // 初始化默认标签
+                    if (!empty(self::$systemConfig['initial_labels_for_user'])) {
+                        $labels = explode(',', self::$systemConfig['initial_labels_for_user']);
+                        $this->makeUserLabels($user->id, $labels);
+                    }
+
+                    // 写入用户流量变动记录
+                    Helpers::addUserTrafficModifyLog($user->id, 0, 0, toGB(1024), '后台批量生成用户');
+                }
+            }
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '批量生成账号成功']);
+        } catch (\Exception $e) {
+            DB::rollBack();
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '批量生成账号失败:' . $e->getMessage()]);
+        }
+    }
+
+    // 编辑账号
+    public function editUser(Request $request)
+    {
+        $id = intval($request->get('id'));
+
+        if ($request->isMethod('POST')) {
+            $username = trim($request->get('username'));
+            $password = $request->get('password');
+            $port = intval($request->get('port'));
+            $passwd = $request->get('passwd');
+            $vmess_id = $request->get('vmess_id') ? trim($request->get('vmess_id')) : createGuid();
+            $transfer_enable = $request->get('transfer_enable');
+            $enable = intval($request->get('enable'));
+            $method = $request->get('method');
+            $protocol = $request->get('protocol');
+            $protocol_param = $request->get('protocol_param');
+            $obfs = $request->get('obfs');
+            $obfs_param = $request->get('obfs_param');
+            $speed_limit_per_con = intval($request->get('speed_limit_per_con'));
+            $speed_limit_per_user = intval($request->get('speed_limit_per_user'));
+            $gender = intval($request->get('gender'));
+            $wechat = $request->get('wechat');
+            $qq = $request->get('qq');
+            $usage = $request->get('usage');
+            $pay_way = $request->get('pay_way');
+            $status = $request->get('status');
+            $labels = $request->get('labels');
+            $enable_time = $request->get('enable_time');
+            $expire_time = $request->get('expire_time');
+            $remark = str_replace("eval", "", str_replace("atob", "", $request->get('remark')));
+            $level = $request->get('level');
+            $is_admin = $request->get('is_admin');
+
+            // 校验username是否已存在
+            $exists = User::query()->where('id', '<>', $id)->where('username', $username)->first();
+            if ($exists) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '用户名已存在,请重新输入']);
+            }
+
+            // 校验端口是否已存在
+            $exists = User::query()->where('id', '<>', $id)->where('port', '>', 0)->where('port', $port)->first();
+            if ($exists) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '端口已存在,请重新输入']);
+            }
+
+            // 禁止取消默认管理员
+            if ($id == 1 && $is_admin == 0) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '系统默认管理员不可取消']);
+            }
+
+            if (!$request->get('usage')) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '请至少选择一种用途']);
+            }
+
+            // 用户编辑前的信息
+            $user = User::query()->where('id', $id)->first();
+
+            DB::beginTransaction();
+            try {
+                $data = [
+                    'username'             => $username,
+                    'port'                 => $port,
+                    'passwd'               => $passwd,
+                    'vmess_id'             => $vmess_id,
+                    'transfer_enable'      => toGB($transfer_enable),
+                    'enable'               => $status < 0 ? 0 : $enable, // 如果禁止登陆则同时禁用代理
+                    'method'               => $method,
+                    'protocol'             => $protocol,
+                    'protocol_param'       => $protocol_param,
+                    'obfs'                 => $obfs,
+                    'obfs_param'           => $obfs_param,
+                    'speed_limit_per_con'  => $speed_limit_per_con,
+                    'speed_limit_per_user' => $speed_limit_per_user,
+                    'gender'               => $gender,
+                    'wechat'               => $wechat,
+                    'qq'                   => $qq,
+                    'usage'                => $usage,
+                    'pay_way'              => $pay_way,
+                    'status'               => $status,
+                    'enable_time'          => empty($enable_time) ? date('Y-m-d') : $enable_time,
+                    'expire_time'          => empty($expire_time) ? date('Y-m-d', strtotime("+365 days")) : $expire_time,
+                    'remark'               => $remark,
+                    'level'                => $level,
+                ];
+
+                // 只有admin才有权限操作管理员属性
+                if (Auth::user()->id == 1) {
+                    $data['is_admin'] = $is_admin;
+                }
+
+                if (!empty($password)) {
+                    if (!(env('APP_DEMO') && $id == 1)) { // 演示环境禁止修改管理员密码
+                        $data['password'] = Hash::make($password);
+                    }
+                }
+
+                User::query()->where('id', $id)->update($data);
+
+                // 重新生成用户标签
+                $this->makeUserLabels($id, $labels);
+
+                // 写入用户流量变动记录
+                if ($user->transfer_enable != toGB($transfer_enable)) {
+                    Helpers::addUserTrafficModifyLog($id, 0, $user->transfer_enable, toGB($transfer_enable), '后台手动编辑用户');
+                }
+
+                DB::commit();
+
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '编辑成功']);
+            } catch (\Exception $e) {
+                DB::rollBack();
+                Log::error('编辑用户信息异常:' . $e->getMessage());
+
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '编辑失败']);
+            }
+        } else {
+            $user = User::query()->with(['label', 'referral'])->where('id', $id)->first();
+            if ($user) {
+                $user->transfer_enable = flowToGB($user->transfer_enable);
+
+                // 处理标签
+                $label = [];
+                foreach ($user->label as $vo) {
+                    $label[] = $vo->label_id;
+                }
+                $user->labels = $label;
+
+                // 处理用途
+                $user->usage = explode(',', $user->usage);
+            }
+
+            $view['user'] = $user;
+            $view['method_list'] = Helpers::methodList();
+            $view['protocol_list'] = Helpers::protocolList();
+            $view['obfs_list'] = Helpers::obfsList();
+            $view['level_list'] = Helpers::levelList();
+            $view['label_list'] = Label::query()->orderBy('sort', 'desc')->orderBy('id', 'asc')->get();
+
+            return Response::view('admin.editUser', $view);
+        }
+    }
+
+    // 删除用户
+    public function delUser(Request $request)
+    {
+        $id = $request->get('id');
+
+        if ($id <= 1) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '系统管理员不可删除']);
+        }
+
+        DB::beginTransaction();
+        try {
+            User::query()->where('id', $id)->delete();
+            UserSubscribe::query()->where('user_id', $id)->delete();
+            UserBanLog::query()->where('user_id', $id)->delete();
+            UserLabel::query()->where('user_id', $id)->delete();
+            UserBalanceLog::query()->where('user_id', $id)->delete();
+            UserTrafficModifyLog::query()->where('user_id', $id)->delete();
+            UserLoginLog::query()->where('user_id', $id)->delete();
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+        } catch (\Exception $e) {
+            Log::error($e);
+            DB::rollBack();
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败']);
+        }
+    }
+
+    // 节点列表
+    public function nodeList(Request $request)
+    {
+        $status = $request->input('status');
+
+        $query = SsNode::query();
+
+        if ($status != '') {
+            $query->where('status', intval($status));
+        }
+
+        $nodeList = $query->orderBy('status', 'desc')->orderBy('id', 'asc')->paginate(15)->appends($request->except('page'));
+        foreach ($nodeList as &$node) {
+            // 在线人数
+            $online_log = SsNodeOnlineLog::query()->where('node_id', $node->id)->where('log_time', '>=', strtotime("-5 minutes"))->orderBy('id', 'desc')->first();
+            $node->online_users = empty($online_log) ? 0 : $online_log->online_user;
+
+            // 已产生流量
+            $totalTraffic = SsNodeTrafficDaily::query()->where('node_id', $node->id)->sum('total');
+            $node->transfer = flowAutoShow($totalTraffic);
+
+            // 负载(10分钟以内)
+            $node_info = SsNodeInfo::query()->where('node_id', $node->id)->where('log_time', '>=', strtotime("-10 minutes"))->orderBy('id', 'desc')->first();
+            $node->load = $node->is_transit ? '' : (empty($node_info) || empty($node_info->load) ? '离线' : $node_info->load);
+            $node->uptime = empty($node_info) ? 0 : seconds2time($node_info->uptime);
+        }
+
+        $view['nodeList'] = $nodeList;
+
+        return Response::view('admin.nodeList', $view);
+    }
+
+    // 添加节点
+    public function addNode(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            if ($request->get('ssh_port') <= 0 || $request->get('ssh_port') >= 65535) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '添加失败:SSH端口不合法']);
+            }
+
+            if (false === filter_var($request->get('ip'), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '添加失败:IPv4地址不合法']);
+            }
+
+            if ($request->get('ipv6') && false === filter_var($request->get('ipv6'), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '添加失败:IPv6地址不合法']);
+            }
+
+            if ($request->get('server')) {
+                $domain = $request->get('server');
+                $domain = explode('.', $domain);
+                $domainSuffix = end($domain); // 取得域名后缀
+
+                if (!in_array($domainSuffix, \config('domains'))) {
+                    return Response::json(['status' => 'fail', 'data' => '', 'message' => '绑定域名不合法']);
+                }
+            }
+
+            // TODO:判断是否已存在绑定了相同域名的节点,提示是否要强制替换,或者不提示之前强制将其他节点的绑定域名置为空,然后发起域名绑定请求,或者请求进入队列
+
+            DB::beginTransaction();
+            try {
+                $ssNode = new SsNode();
+                $ssNode->type = intval($request->get('type'));
+                $ssNode->name = $request->get('name');
+                $ssNode->group_id = $request->get('group_id') ? intval($request->get('group_id')) : 0;
+                $ssNode->country_code = $request->get('country_code') ? $request->get('country_code') : 'un';
+                $ssNode->server = $request->get('server') ? $request->get('server') : '';
+                $ssNode->ip = $request->get('ip');
+                $ssNode->ipv6 = $request->get('ipv6');
+                $ssNode->desc = $request->get('desc') ? $request->get('desc') : '';
+                $ssNode->method = $request->get('method');
+                $ssNode->protocol = $request->get('protocol');
+                $ssNode->protocol_param = $request->get('protocol_param') ? $request->get('protocol_param') : '';
+                $ssNode->obfs = $request->get('obfs') ? $request->get('obfs') : '';
+                $ssNode->obfs_param = $request->get('obfs_param') ? $request->get('obfs_param') : '';
+                $ssNode->traffic_rate = $request->get('traffic_rate') ? $request->get('traffic_rate') : 1;
+                $ssNode->bandwidth = $request->get('bandwidth') ? $request->get('bandwidth') : 1000;
+                $ssNode->traffic = $request->get('traffic') ? $request->get('traffic') : 1000;
+                $ssNode->monitor_url = $request->get('monitor_url') ? $request->get('monitor_url') : '';
+                $ssNode->is_subscribe = intval($request->get('is_subscribe'));
+                $ssNode->is_nat = intval($request->get('is_nat'));
+                $ssNode->is_transit = intval($request->get('is_transit'));
+                $ssNode->ssh_port = $request->get('ssh_port') ? intval($request->get('ssh_port')) : 22;
+                $ssNode->is_tcp_check = intval($request->get('is_tcp_check'));
+                $ssNode->compatible = intval($request->get('type')) == 2 ? 0 : (intval($request->get('is_nat')) ? 0 : intval($request->get('compatible')));
+                $ssNode->single = intval($request->get('single'));
+                $ssNode->single_force = intval($request->get('single')) ? intval($request->get('single_force')) : 0;
+                $ssNode->single_port = intval($request->get('single')) ? ($request->get('single_port') ? $request->get('single_port') : 443) : '';
+                $ssNode->single_passwd = intval($request->get('single')) ? ($request->get('single_passwd') ? $request->get('single_passwd') : 'password') : '';
+                $ssNode->single_method = intval($request->get('single')) ? $request->get('single_method') : '';
+                $ssNode->single_protocol = intval($request->get('single')) ? $request->get('single_protocol') : '';
+                $ssNode->single_obfs = intval($request->get('single')) ? $request->get('single_obfs') : '';
+                $ssNode->sort = $request->get('sort') ? intval($request->get('sort')) : 0;
+                $ssNode->status = $request->get('status') ? intval($request->get('status')) : 1;
+                $ssNode->v2_alter_id = $request->get('v2_alter_id') ? intval($request->get('v2_alter_id')) : 16;
+                $ssNode->v2_port = $request->get('v2_port') ? intval($request->get('v2_port')) : 10087;
+                $ssNode->v2_method = $request->get('v2_method') ? $request->get('v2_method') : 'aes-128-gcm';
+                $ssNode->v2_net = $request->get('v2_net') ? $request->get('v2_net') : 'tcp';
+                $ssNode->v2_type = $request->get('v2_type') ? $request->get('v2_type') : 'none';
+                $ssNode->v2_host = $request->get('v2_host') ? $request->get('v2_host') : '';
+                $ssNode->v2_path = $request->get('v2_path') ? $request->get('v2_path') : '';
+                $ssNode->v2_tls = $request->get('v2_tls') ? intval($request->get('v2_tls')) : 0;
+                $ssNode->v2_insider_port = $request->get('v2_insider_port') ? intval($request->get('v2_insider_port')) : 10550;
+                $ssNode->v2_outsider_port = $request->get('v2_outsider_port') ? intval($request->get('v2_outsider_port')) : 443;
+                $ssNode->save();
+
+                // 建立分组关联
+                if ($ssNode->id && $request->get('group_id', 0)) {
+                    $ssGroupNode = new SsGroupNode();
+                    $ssGroupNode->group_id = $request->get('group_id', 0);
+                    $ssGroupNode->node_id = $ssNode->id;
+                    $ssGroupNode->save();
+                }
+
+                // 生成节点标签
+                $labels = $request->get('labels');
+                if ($ssNode->id && !empty($labels)) {
+                    foreach ($labels as $label) {
+                        $ssNodeLabel = new SsNodeLabel();
+                        $ssNodeLabel->node_id = $ssNode->id;
+                        $ssNodeLabel->label_id = $label;
+                        $ssNodeLabel->save();
+                    }
+                }
+
+                DB::commit();
+
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '添加成功']);
+            } catch (\Exception $e) {
+                DB::rollBack();
+                Log::error('添加节点信息异常:' . $e->getMessage());
+
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '添加失败:' . $e->getMessage()]);
+            }
+        } else {
+            $view['method_list'] = Helpers::methodList();
+            $view['protocol_list'] = Helpers::protocolList();
+            $view['obfs_list'] = Helpers::obfsList();
+            $view['level_list'] = Helpers::levelList();
+            $view['group_list'] = SsGroup::query()->get();
+            $view['country_list'] = Country::query()->orderBy('country_code', 'asc')->get();
+            $view['label_list'] = Label::query()->orderBy('sort', 'desc')->orderBy('id', 'asc')->get();
+
+            return Response::view('admin.addNode', $view);
+        }
+    }
+
+    // 编辑节点
+    public function editNode(Request $request)
+    {
+        $id = $request->get('id');
+
+        if ($request->isMethod('POST')) {
+            if ($request->get('ssh_port') <= 0 || $request->get('ssh_port') >= 65535) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '编辑失败:SSH端口不合法']);
+            }
+
+            if (false === filter_var($request->get('ip'), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '编辑失败:IPv4地址不合法']);
+            }
+
+            if ($request->get('ipv6') && false === filter_var($request->get('ipv6'), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '编辑失败:IPv6地址不合法']);
+            }
+
+            if ($request->get('server')) {
+                $domain = $request->get('server');
+                $domain = explode('.', $domain);
+                $domainSuffix = end($domain); // 取得域名后缀
+
+                if (!in_array($domainSuffix, \config('domains'))) {
+                    return Response::json(['status' => 'fail', 'data' => '', 'message' => '绑定域名不合法']);
+                }
+            }
+
+            if ($request->get('v2_alter_id') <= 0 || $request->get('v2_alter_id') >= 65535) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '编辑失败:AlterId不合法']);
+            }
+
+            DB::beginTransaction();
+            try {
+                $data = [
+                    'type'             => intval($request->get('type')),
+                    'name'             => $request->get('name'),
+                    'group_id'         => $request->get('group_id') ? $request->get('group_id') : 0,
+                    'country_code'     => $request->get('country_code'),
+                    'server'           => $request->get('server'),
+                    'ip'               => $request->get('ip'),
+                    'ipv6'             => $request->get('ipv6'),
+                    'desc'             => $request->get('desc'),
+                    'method'           => $request->get('method'),
+                    'protocol'         => $request->get('protocol'),
+                    'protocol_param'   => $request->get('protocol_param'),
+                    'obfs'             => $request->get('obfs'),
+                    'obfs_param'       => $request->get('obfs_param'),
+                    'traffic_rate'     => $request->get('traffic_rate'),
+                    'bandwidth'        => $request->get('bandwidth') ? $request->get('bandwidth') : 1000,
+                    'traffic'          => $request->get('traffic') ? $request->get('traffic') : 1000,
+                    'monitor_url'      => $request->get('monitor_url') ? $request->get('monitor_url') : '',
+                    'is_subscribe'     => intval($request->get('is_subscribe')),
+                    'is_nat'           => intval($request->get('is_nat')),
+                    'is_transit'       => intval($request->get('is_transit')),
+                    'ssh_port'         => intval($request->get('ssh_port')),
+                    'is_tcp_check'     => intval($request->get('is_tcp_check')),
+                    'compatible'       => intval($request->get('type')) == 2 ? 0 : (intval($request->get('is_nat')) ? 0 : intval($request->get('compatible'))),
+                    'single'           => intval($request->get('single')),
+                    'single_force'     => intval($request->get('single')) ? intval($request->get('single_force')) : 0,
+                    'single_port'      => intval($request->get('single')) ? ($request->get('single_port') ? $request->get('single_port') : 443) : '',
+                    'single_passwd'    => intval($request->get('single')) ? ($request->get('single_passwd') ? $request->get('single_passwd') : 'password') : '',
+                    'single_method'    => intval($request->get('single')) ? $request->get('single_method') : '',
+                    'single_protocol'  => intval($request->get('single')) ? $request->get('single_protocol') : '',
+                    'single_obfs'      => intval($request->get('single')) ? $request->get('single_obfs') : '',
+                    'sort'             => intval($request->get('sort')),
+                    'status'           => intval($request->get('status')),
+                    'v2_alter_id'      => $request->get('v2_alter_id') ? intval($request->get('v2_alter_id')) : 16,
+                    'v2_port'          => $request->get('v2_port') ? intval($request->get('v2_port')) : 10087,
+                    'v2_method'        => $request->get('v2_method') ? $request->get('v2_method') : 'aes-128-gcm',
+                    'v2_net'           => $request->get('v2_net'),
+                    'v2_type'          => $request->get('v2_type'),
+                    'v2_host'          => $request->get('v2_host'),
+                    'v2_path'          => $request->get('v2_path'),
+                    'v2_tls'           => intval($request->get('v2_tls')),
+                    'v2_insider_port'  => intval($request->get('v2_insider_port', 10550)),
+                    'v2_outsider_port' => intval($request->get('v2_outsider_port', 443))
+                ];
+
+                SsNode::query()->where('id', $id)->update($data);
+
+                // 建立分组关联
+                if ($request->get('group_id')) {
+                    // 先删除该节点所有关联
+                    SsGroupNode::query()->where('node_id', $id)->delete();
+
+                    // 建立关联
+                    $ssGroupNode = new SsGroupNode();
+                    $ssGroupNode->group_id = $request->get('group_id');
+                    $ssGroupNode->node_id = $id;
+                    $ssGroupNode->save();
+                }
+
+                // 生成节点标签
+                $this->makeNodeLabels($id, $request->get('labels'));
+
+                // TODO:更新节点绑定的域名DNS(将节点IP更新到域名DNS 的A记录)
+
+                DB::commit();
+
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '编辑成功']);
+            } catch (\Exception $e) {
+                DB::rollBack();
+                Log::error('编辑节点信息异常:' . $e->getMessage());
+
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '编辑失败:' . $e->getMessage()]);
+            }
+        } else {
+            $node = SsNode::query()->with(['label'])->where('id', $id)->first();
+            if ($node) {
+                $labels = [];
+                foreach ($node->label as $vo) {
+                    $labels[] = $vo->label_id;
+                }
+                $node->labels = $labels;
+            }
+
+            $view['node'] = $node;
+            $view['method_list'] = Helpers::methodList();
+            $view['protocol_list'] = Helpers::protocolList();
+            $view['obfs_list'] = Helpers::obfsList();
+            $view['level_list'] = Helpers::levelList();
+            $view['group_list'] = SsGroup::query()->get();
+            $view['country_list'] = Country::query()->orderBy('country_code', 'asc')->get();
+            $view['label_list'] = Label::query()->orderBy('sort', 'desc')->orderBy('id', 'asc')->get();
+
+            return Response::view('admin.editNode', $view);
+        }
+    }
+
+    // 删除节点
+    public function delNode(Request $request)
+    {
+        $id = $request->get('id');
+
+        $node = SsNode::query()->where('id', $id)->first();
+        if (!$node) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '节点不存在,请重试']);
+        }
+
+        DB::beginTransaction();
+        try {
+            // 删除分组关联、节点标签、节点相关日志
+            SsNode::query()->where('id', $id)->delete();
+            SsGroupNode::query()->where('node_id', $id)->delete();
+            SsNodeLabel::query()->where('node_id', $id)->delete();
+            SsNodeInfo::query()->where('node_id', $id)->delete();
+            SsNodeOnlineLog::query()->where('node_id', $id)->delete();
+            SsNodeTrafficDaily::query()->where('node_id', $id)->delete();
+            SsNodeTrafficHourly::query()->where('node_id', $id)->delete();
+            UserTrafficDaily::query()->where('node_id', $id)->delete();
+            UserTrafficHourly::query()->where('node_id', $id)->delete();
+            UserTrafficLog::query()->where('node_id', $id)->delete();
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+        } catch (\Exception $e) {
+            DB::rollBack();
+            Log::error('删除节点信息异常:' . $e->getMessage());
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败:' . $e->getMessage()]);
+        }
+    }
+
+    // 节点流量监控
+    public function nodeMonitor(Request $request)
+    {
+        $node_id = $request->get('id');
+
+        $node = SsNode::query()->where('id', $node_id)->orderBy('sort', 'desc')->first();
+        if (!$node) {
+            Session::flash('errorMsg', '节点不存在,请重试');
+
+            return Redirect::back();
+        }
+
+        // 查看流量
+        $dailyData = [];
+        $hourlyData = [];
+
+        // 节点一个月内的流量
+        $nodeTrafficDaily = SsNodeTrafficDaily::query()->with(['info'])->where('node_id', $node->id)->where('created_at', '>=', date('Y-m', time()))->orderBy('created_at', 'asc')->pluck('total')->toArray();
+        $dailyTotal = date('d', time()) - 1;//今天不算,减一
+        $dailyCount = count($nodeTrafficDaily);
+        for ($x = 0; $x < ($dailyTotal - $dailyCount); $x++) {
+            $dailyData[$x] = 0;
+        }
+        for ($x = ($dailyTotal - $dailyCount); $x < $dailyTotal; $x++) {
+            $dailyData[$x] = round($nodeTrafficDaily[$x - ($dailyTotal - $dailyCount)] / (1024 * 1024 * 1024), 3);
+        }
+
+        // 节点一天内的流量
+        $nodeTrafficHourly = SsNodeTrafficHourly::query()->with(['info'])->where('node_id', $node->id)->where('created_at', '>=', date('Y-m-d', time()))->orderBy('created_at', 'asc')->pluck('total')->toArray();
+        $hourlyTotal = date('H', time());
+        $hourlyCount = count($nodeTrafficHourly);
+        for ($x = 0; $x < ($hourlyTotal - $hourlyCount); $x++) {
+            $hourlyData[$x] = 0;
+        }
+        for ($x = ($hourlyTotal - $hourlyCount); $x < $hourlyTotal; $x++) {
+            $hourlyData[$x] = round($nodeTrafficHourly[$x - ($hourlyTotal - $hourlyCount)] / (1024 * 1024 * 1024), 3);
+        }
+
+        $view['trafficDaily'] = [
+            'nodeName'  => $node->name,
+            'dailyData' => "'" . implode("','", $dailyData) . "'"
+        ];
+
+        $view['trafficHourly'] = [
+            'nodeName'   => $node->name,
+            'hourlyData' => "'" . implode("','", $hourlyData) . "'"
+        ];
+
+
+        // 本月天数数据
+        $monthDays = [];
+        for ($i = 1; $i <= date("d"); $i++) {
+            $monthDays[] = $i;
+        }
+        // 本日小时数据
+        $dayHours = [];
+        for ($i = 1; $i <= date("H"); $i++) {
+            $dayHours[] = $i;
+        }
+
+        $view['nodeName'] = $node->name;
+        $view['nodeServer'] = $node->server;
+        $view['monthDays'] = "'" . implode("','", $monthDays) . "'";
+        $view['dayHours'] = "'" . implode("','", $dayHours) . "'";
+
+        return Response::view('admin.nodeMonitor', $view);
+    }
+
+    // 文章列表
+    public function articleList(Request $request)
+    {
+        $view['list'] = Article::query()->orderBy('sort', 'desc')->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.articleList', $view);
+    }
+
+    // 添加文章
+    public function addArticle(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $article = new Article();
+            $article->title = $request->get('title');
+            $article->type = $request->get('type', 1);
+            $article->author = '管理员';
+            $article->summary = $request->get('summary');
+            // LOGO
+            if ($article->type == 4) {
+                $article->logo = $request->get('logo');
+            } else {
+                $logo = '';
+                if ($request->hasFile('logo')) {
+                    $file = $request->file('logo');
+                    $fileType = $file->getClientOriginalExtension();
+
+                    // 验证文件合法性
+                    if (!in_array($fileType, ['jpg', 'png', 'jpeg', 'bmp'])) {
+                        Session::flash('errorMsg', 'LOGO不合法');
+
+                        return Redirect::back()->withInput();
+                    }
+
+                    $logoName = date('YmdHis') . mt_rand(1000, 2000) . '.' . $fileType;
+                    $move = $file->move(base_path() . '/public/upload/image/', $logoName);
+                    $logo = $move ? '/upload/image/' . $logoName : '';
+                }
+            $article = new Article();
+            $article->title = $request->get('title');
+            $article->type = $request->get('type', 1);
+            $article->author = '管理员';
+            $article->summary = $request->get('summary');
+            $article->logo = $logo;
+            }			
+            $article->content = $request->get('content');
+            $article->sort = $request->get('sort', 0);
+            $article->save();
+
+            if ($article->id) {
+                Session::flash('successMsg', '添加成功');
+            } else {
+                Session::flash('errorMsg', '添加失败');
+            }
+
+            return Redirect::to('admin/articleList');
+        } else {
+            return Response::view('admin.addArticle');
+        }
+    }
+
+    // 编辑文章
+    public function editArticle(Request $request)
+    {
+        $id = $request->get('id');
+
+        if ($request->isMethod('POST')) {
+            $title = $request->get('title');
+            $type = $request->get('type');
+            $summary = $request->get('summary');
+            $content = $request->get('content');
+            $sort = $request->get('sort');
+
+            // 商品LOGO
+            if ($type == 4) {
+                $logo = $request->get('logo');
+            } else {
+                $logo = '';
+                if ($request->hasFile('logo')) {
+                    $file = $request->file('logo');
+                    $fileType = $file->getClientOriginalExtension();
+
+                    // 验证文件合法性
+                    if (!in_array($fileType, ['jpg', 'png', 'jpeg', 'bmp'])) {
+                        Session::flash('errorMsg', 'LOGO不合法');
+
+                        return Redirect::back()->withInput();
+                    }
+
+                    $logoName = date('YmdHis') . mt_rand(1000, 2000) . '.' . $fileType;
+                    $move = $file->move(base_path() . '/public/upload/image/', $logoName);
+                    $logo = $move ? '/upload/image/' . $logoName : '';
+                }
+            }
+
+            $data = [
+                'type'    => $type,
+                'title'   => $title,
+                'summary' => $summary,
+                'content' => $content,
+                'sort'    => $sort
+            ];
+
+            if ($logo) {
+                $data['logo'] = $logo;
+            }
+
+            $ret = Article::query()->where('id', $id)->update($data);
+            if ($ret) {
+                Session::flash('successMsg', '编辑成功');
+            } else {
+                Session::flash('errorMsg', '编辑失败');
+            }
+
+            return Redirect::to('admin/editArticle?id=' . $id);
+        } else {
+            $view['article'] = Article::query()->where('id', $id)->first();
+
+            return Response::view('admin.editArticle', $view);
+        }
+    }
+
+    // 删除文章
+    public function delArticle(Request $request)
+    {
+        $id = $request->get('id');
+
+        $ret = Article::query()->where('id', $id)->delete();
+        if ($ret) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败']);
+        }
+    }
+
+    // 节点分组列表
+    public function groupList(Request $request)
+    {
+        $view['groupList'] = SsGroup::query()->paginate(15)->appends($request->except('page'));
+
+        $levelList = Helpers::levelList();
+        $levelMap = [];
+        foreach ($levelList as $vo) {
+            $levelMap[$vo['level']] = $vo['level_name'];
+        }
+        $view['levelMap'] = $levelMap;
+
+        return Response::view('admin.groupList', $view);
+    }
+
+    // 添加节点分组
+    public function addGroup(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $ssGroup = new SsGroup();
+            $ssGroup->name = $request->get('name');
+            $ssGroup->level = $request->get('level');
+            $ssGroup->save();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '添加成功']);
+        } else {
+            $view['levelList'] = Helpers::levelList();
+
+            return Response::view('admin.addGroup', $view);
+        }
+    }
+
+    // 编辑节点分组
+    public function editGroup(Request $request)
+    {
+        $id = $request->get('id');
+
+        if ($request->isMethod('POST')) {
+            $name = $request->get('name');
+            $level = $request->get('level');
+
+            $data = [
+                'name'  => $name,
+                'level' => $level
+            ];
+
+            $ret = SsGroup::query()->where('id', $id)->update($data);
+            if ($ret) {
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '编辑成功']);
+            } else {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '编辑失败']);
+            }
+        } else {
+            $view['group'] = SsGroup::query()->where('id', $id)->first();
+            $view['levelList'] = Helpers::levelList();
+
+            return Response::view('admin.editGroup', $view);
+        }
+    }
+
+    // 删除节点分组
+    public function delGroup(Request $request)
+    {
+        $id = $request->get('id');
+
+        // 检查是否该分组下是否有节点
+        $ssGroupNodeCount = SsGroupNode::query()->where('group_id', $id)->count();
+        if ($ssGroupNodeCount) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败:该分组下有节点关联,请先解除关联']);
+        }
+
+        $ret = SsGroup::query()->where('id', $id)->delete();
+        if ($ret) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败']);
+        }
+    }
+
+    // 流量日志
+    public function trafficLog(Request $request)
+    {
+        $port = $request->get('port');
+        $user_id = $request->get('user_id');
+        $username = trim($request->get('username'));
+        $nodeId = intval($request->get('nodeId'));
+
+        $query = UserTrafficLog::query()->with(['user', 'node']);
+
+        if ($port) {
+            $query->whereHas('user', function ($q) use ($port) {
+                $q->where('port', $port);
+            });
+        }
+
+        if ($user_id) {
+            $query->where('user_id', intval($user_id));
+        }
+
+        if ($username) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        if ($nodeId) {
+            $query->where('node_id', $nodeId);
+        }
+
+        // 已使用流量
+        $view['totalTraffic'] = flowAutoShow($query->sum('u') + $query->sum('d'));
+
+        $list = $query->orderBy('id', 'desc')->paginate(20)->appends($request->except('page'));
+        foreach ($list as &$vo) {
+            $vo->u = flowAutoShow($vo->u);
+            $vo->d = flowAutoShow($vo->d);
+            $vo->log_time = date('Y-m-d H:i:s', $vo->log_time);
+        }
+
+        $view['list'] = $list;
+        $view['nodeList'] = SsNode::query()->where('status', 1)->orderBy('sort', 'desc')->orderBy('id', 'desc')->get();
+
+        return Response::view('admin.trafficLog', $view);
+    }
+
+    // SS(R)链接反解析
+    public function decompile(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $content = $request->get('content');
+
+            if (empty($content)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '请在左侧填入要反解析的SS(R)链接']);
+            }
+
+            // 反解析处理
+            $content = str_replace("\n", ",", $content);
+            $content = explode(',', $content);
+            $txt = '';
+            foreach ($content as $item) {
+                // 判断是SS还是SSR链接
+                $str = '';
+                if (false !== strpos($item, 'ssr://')) {
+                    $str = mb_substr($item, 6);
+                } elseif (false !== strpos($item, 'ss://')) {
+                    $str = mb_substr($item, 5);
+                }
+
+                $txt .= "\r\n" . base64url_decode($str);
+            }
+
+            // 生成转换好的JSON文件
+            file_put_contents(public_path('downloads/decompile.json'), $txt);
+
+            return Response::json(['status' => 'success', 'data' => $txt, 'message' => '反解析成功']);
+        } else {
+            return Response::view('admin.decompile');
+        }
+    }
+
+    // 格式转换(SS转SSR)
+    public function convert(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $method = $request->get('method');
+            $transfer_enable = $request->get('transfer_enable');
+            $protocol = $request->get('protocol');
+            $protocol_param = $request->get('protocol_param');
+            $obfs = $request->get('obfs');
+            $obfs_param = $request->get('obfs_param');
+            $content = $request->get('content');
+
+            if (empty($content)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '请在左侧填入要转换的内容']);
+            }
+
+            // 校验格式
+            $content = json_decode($content);
+            if (empty($content->port_password)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '转换失败:配置信息里缺少【port_password】字段,或者该字段为空']);
+            }
+
+            // 转换成SSR格式JSON
+            $data = [];
+            foreach ($content->port_password as $port => $passwd) {
+                $data[] = [
+                    'd'               => 0,
+                    'enable'          => 1,
+                    'method'          => $method,
+                    'obfs'            => $obfs,
+                    'obfs_param'      => empty($obfs_param) ? "" : $obfs_param,
+                    'passwd'          => $passwd,
+                    'port'            => $port,
+                    'protocol'        => $protocol,
+                    'protocol_param'  => empty($protocol_param) ? "" : $protocol_param,
+                    'transfer_enable' => toGB($transfer_enable),
+                    'u'               => 0,
+                    'user'            => date('Ymd') . '_IMPORT_' . $port,
+                ];
+            }
+
+            $json = json_encode($data);
+
+            // 生成转换好的JSON文件
+            file_put_contents(public_path('downloads/convert.json'), $json);
+
+            return Response::json(['status' => 'success', 'data' => $json, 'message' => '转换成功']);
+        } else {
+            // 加密方式、协议、混淆
+            $view['method_list'] = Helpers::methodList();
+            $view['protocol_list'] = Helpers::protocolList();
+            $view['obfs_list'] = Helpers::obfsList();
+
+            return Response::view('admin.convert', $view);
+        }
+    }
+
+    // 下载转换好的JSON文件
+    public function download(Request $request)
+    {
+        $type = $request->get('type');
+        if (empty($type)) {
+            exit('参数异常');
+        }
+
+        if ($type == '1') {
+            $filePath = public_path('downloads/convert.json');
+        } else {
+            $filePath = public_path('downloads/decompile.json');
+        }
+
+        if (!file_exists($filePath)) {
+            exit('文件不存在,请检查目录权限');
+        }
+
+        return Response::download($filePath);
+    }
+
+    // 数据导入
+    public function import(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            if (!$request->hasFile('uploadFile')) {
+                Session::flash('errorMsg', '请选择要上传的文件');
+
+                return Redirect::back();
+            }
+
+            $file = $request->file('uploadFile');
+
+            // 只能上传JSON文件
+            if ($file->getClientMimeType() != 'application/json' || $file->getClientOriginalExtension() != 'json') {
+                Session::flash('errorMsg', '只允许上传JSON文件');
+
+                return Redirect::back();
+            }
+
+            if (!$file->isValid()) {
+                Session::flash('errorMsg', '产生未知错误,请重新上传');
+
+                return Redirect::back();
+            }
+
+            $save_path = realpath(storage_path('uploads'));
+            $new_name = md5($file->getClientOriginalExtension()) . '.json';
+            $file->move($save_path, $new_name);
+
+            // 读取文件内容
+            $data = file_get_contents($save_path . '/' . $new_name);
+            $data = json_decode($data);
+            if (!$data) {
+                Session::flash('errorMsg', '内容格式解析异常,请上传符合SSR(R)配置规范的JSON文件');
+
+                return Redirect::back();
+            }
+
+            DB::beginTransaction();
+            try {
+                foreach ($data as $user) {
+                    $obj = new User();
+                    $obj->username = $user->user;
+                    $obj->password = Hash::make('123456');
+                    $obj->port = $user->port;
+                    $obj->passwd = $user->passwd;
+                    $obj->vmess_id = $user->vmess_id;
+                    $obj->transfer_enable = $user->transfer_enable;
+                    $obj->u = 0;
+                    $obj->d = 0;
+                    $obj->t = 0;
+                    $obj->enable = 1;
+                    $obj->method = $user->method;
+                    $obj->protocol = $user->protocol;
+                    $obj->protocol_param = $user->protocol_param;
+                    $obj->obfs = $user->obfs;
+                    $obj->obfs_param = $user->obfs_param;
+                    $obj->speed_limit_per_con = 204800;
+                    $obj->speed_limit_per_user = 204800;
+                    $obj->wechat = '';
+                    $obj->qq = '';
+                    $obj->usage = 1;
+                    $obj->pay_way = 3;
+                    $obj->balance = 0;
+                    $obj->enable_time = date('Y-m-d');
+                    $obj->expire_time = '2099-01-01';
+                    $obj->remark = '';
+                    $obj->is_admin = 0;
+                    $obj->reg_ip = getClientIp();
+                    $obj->created_at = date('Y-m-d H:i:s');
+                    $obj->updated_at = date('Y-m-d H:i:s');
+                    $obj->save();
+                }
+
+                DB::commit();
+            } catch (\Exception $e) {
+                DB::rollBack();
+
+                Session::flash('errorMsg', '出错了,可能是导入的配置中有端口已经存在了');
+
+                return Redirect::back();
+            }
+
+            Session::flash('successMsg', '导入成功');
+
+            return Redirect::back();
+        } else {
+            return Response::view('admin.import');
+        }
+    }
+
+    // 导出配置信息
+    public function export(Request $request)
+    {
+        $id = $request->get('id');
+
+        if (empty($id)) {
+            return Redirect::to('admin/userList');
+        }
+
+        $user = User::query()->where('id', $id)->first();
+        if (empty($user)) {
+            return Redirect::to('admin/userList');
+        }
+
+        $nodeList = SsNode::query()->where('status', 1)->orderBy('sort', 'desc')->orderBy('id', 'asc')->paginate(15)->appends($request->except('page'));
+        foreach ($nodeList as &$node) {
+            // 获取分组名称
+            $group = SsGroup::query()->where('id', $node->group_id)->first();
+
+            if ($node->type == 1) {
+                // 生成ssr scheme
+                $obfs_param = $user->obfs_param ? $user->obfs_param : $node->obfs_param;
+                $protocol_param = $node->single ? $user->port . ':' . $user->passwd : $user->protocol_param;
+
+                $ssr_str = ($node->server ? $node->server : $node->ip) . ':' . ($node->single ? $node->single_port : $user->port);
+                $ssr_str .= ':' . ($node->single ? $node->single_protocol : $user->protocol) . ':' . ($node->single ? $node->single_method : $user->method);
+                $ssr_str .= ':' . ($node->single ? $node->single_obfs : $user->obfs) . ':' . ($node->single ? base64url_encode($node->single_passwd) : base64url_encode($user->passwd));
+                $ssr_str .= '/?obfsparam=' . base64url_encode($obfs_param);
+                $ssr_str .= '&protoparam=' . ($node->single ? base64url_encode($user->port . ':' . $user->passwd) : base64url_encode($protocol_param));
+                $ssr_str .= '&remarks=' . base64url_encode($node->name);
+                $ssr_str .= '&group=' . base64url_encode(empty($group) ? '' : $group->name);
+                $ssr_str .= '&udpport=0';
+                $ssr_str .= '&uot=0';
+                $ssr_str = base64url_encode($ssr_str);
+                $ssr_scheme = 'ssr://' . $ssr_str;
+
+                // 生成ss scheme
+                $ss_str = $user->method . ':' . $user->passwd . '@';
+                $ss_str .= ($node->server ? $node->server : $node->ip) . ':' . $user->port;
+                $ss_str = base64url_encode($ss_str) . '#' . 'VPN';
+                $ss_scheme = 'ss://' . $ss_str;
+
+                // 生成配置信息
+                $txt = "服务器:" . ($node->server ? $node->server : $node->ip) . "\r\n";
+                if ($node->ipv6) {
+                    $txt .= "IPv6:" . $node->ipv6 . "\r\n";
+                }
+                $txt .= "远程端口:" . ($node->single ? $node->single_port : $user->port) . "\r\n";
+                $txt .= "密码:" . ($node->single ? $node->single_passwd : $user->passwd) . "\r\n";
+                $txt .= "加密方法:" . ($node->single ? $node->single_method : $user->method) . "\r\n";
+                $txt .= "路由:绕过局域网及中国大陆地址\r\n\r\n";
+                $txt .= "协议:" . ($node->single ? $node->single_protocol : $user->protocol) . "\r\n";
+                $txt .= "协议参数:" . ($node->single ? $user->port . ':' . $user->passwd : $user->protocol_param) . "\r\n";
+                $txt .= "混淆方式:" . ($node->single ? $node->single_obfs : $user->obfs) . "\r\n";
+                $txt .= "混淆参数:" . ($user->obfs_param ? $user->obfs_param : $node->obfs_param) . "\r\n";
+                $txt .= "本地端口:1080\r\n";
+
+                $node->txt = $txt;
+                $node->ssr_scheme = $ssr_scheme;
+                $node->ss_scheme = $node->compatible ? $ss_scheme : ''; // 节点兼容原版才显示
+            } else {
+                // 生成v2ray scheme
+                $v2_json = [
+                    "v"    => "2",
+                    "ps"   => $node->name,
+                    "add"  => $node->server ? $node->server : $node->ip,
+                    "port" => $node->v2_port,
+                    "id"   => $user->vmess_id,
+                    "aid"  => $node->v2_alter_id,
+                    "net"  => $node->v2_net,
+                    "type" => $node->v2_type,
+                    "host" => $node->v2_host,
+                    "path" => $node->v2_path,
+                    "tls"  => $node->v2_tls ? "tls" : ""
+                ];
+                $v2_scheme = 'vmess://' . base64url_encode(json_encode($v2_json, JSON_PRETTY_PRINT));
+
+                // 生成文本配置信息
+                $txt = "服务器:" . ($node->server ? $node->server : $node->ip) . "\r\n";
+                if ($node->ipv6) {
+                    $txt .= "IPv6:" . $node->ipv6 . "\r\n";
+                }
+                $txt .= "端口:" . $node->v2_port . "\r\n";
+                $txt .= "加密方式:" . $node->v2_method . "\r\n";
+                $txt .= "用户ID:" . $user->vmess_id . "\r\n";
+                $txt .= "额外ID:" . $node->v2_alter_id . "\r\n";
+                $txt .= "传输协议:" . $node->v2_net . "\r\n";
+                $txt .= "伪装类型:" . $node->v2_type . "\r\n";
+                $txt .= $node->v2_host ? "伪装域名:" . $node->v2_host . "\r\n" : "";
+                $txt .= $node->v2_path ? "路径:" . $node->v2_path . "\r\n" : "";
+                $txt .= $node->v2_tls == 1 ? "TLS:tls\r\n" : "";
+
+                $node->txt = $txt;
+                $node->v2_scheme = $v2_scheme;
+            }
+        }
+
+        $view['nodeList'] = $nodeList;
+        $view['user'] = $user;
+
+        return Response::view('admin.export', $view);
+    }
+
+    // 导出原版SS用户配置信息
+    public function exportSSJson(Request $request)
+    {
+        $userList = User::query()->where('port', '>', 0)->get();
+        $defaultMethod = Helpers::getDefaultMethod();
+
+        $json = '';
+        if (!$userList->isEmpty()) {
+            $tmp = [];
+            foreach ($userList as $key => $user) {
+                $tmp[] = '"' . $user->port . '":"' . $user->passwd . '"';
+            }
+
+            $userPassword = implode(",\n\t\t", $tmp);
+            $json = <<<EOF
+{
+	"server":"0.0.0.0",
+    "local_address":"127.0.0.1",
+    "local_port":1080,
+    "port_password":{
+        {$userPassword}
+    },
+    "timeout":300,
+    "method":"{$defaultMethod}",
+    "fast_open":false
+}
+EOF;
+        }
+
+        // 生成JSON文件
+        $fileName = makeRandStr('16') . '_shadowsocks.json';
+        $filePath = public_path('downloads/' . $fileName);
+        file_put_contents($filePath, $json);
+
+        if (!file_exists($filePath)) {
+            exit('文件生成失败,请检查目录权限');
+        }
+
+        return Response::download($filePath);
+    }
+
+    // 修改个人资料
+    public function profile(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $old_password = trim($request->get('old_password'));
+            $new_password = trim($request->get('new_password'));
+
+            if (!Hash::check($old_password, Auth::user()->password)) {
+                return Redirect::back()->withErrors('旧密码错误,请重新输入');
+            } elseif (Hash::check($new_password, Auth::user()->password)) {
+                return Redirect::back()->withErrors('新密码不可与旧密码一样,请重新输入');
+            }
+
+            $ret = User::uid()->update(['password' => Hash::make($new_password)]);
+            if (!$ret) {
+                return Redirect::back()->withErrors('修改失败');
+            } else {
+                return Redirect::back()->with('successMsg', '修改成功');
+            }
+        } else {
+            return Response::view('admin.profile');
+        }
+    }
+
+    // 用户流量监控
+    public function userMonitor(Request $request)
+    {
+        $id = $request->get('id');
+
+        if (empty($id)) {
+            return Redirect::to('admin/userList');
+        }
+
+        $user = User::query()->where('id', $id)->first();
+        if (empty($user)) {
+            return Redirect::to('admin/userList');
+        }
+
+        // 30天内的流量
+        $dailyData = [];
+        $hourlyData = [];
+        // 节点一个月内的流量
+        $userTrafficDaily = UserTrafficDaily::query()->where('user_id', $user->id)->where('node_id', 0)->where('created_at', '>=', date('Y-m', time()))->orderBy('created_at', 'asc')->pluck('total')->toArray();
+
+        $dailyTotal = date('d') - 1; // 今天不算,减一
+        $dailyCount = count($userTrafficDaily);
+        for ($x = 0; $x < $dailyTotal - $dailyCount; $x++) {
+            $dailyData[$x] = 0;
+        }
+        for ($x = $dailyTotal - $dailyCount; $x < $dailyTotal; $x++) {
+            $dailyData[$x] = round($userTrafficDaily[$x - ($dailyTotal - $dailyCount)] / (1024 * 1024 * 1024), 3);
+        }
+
+        // 节点一天内的流量
+        $userTrafficHourly = UserTrafficHourly::query()->where('user_id', $user->id)->where('node_id', 0)->where('created_at', '>=', date('Y-m-d', time()))->orderBy('created_at', 'asc')->pluck('total')->toArray();
+        $hourlyTotal = date('H');
+        $hourlyCount = count($userTrafficHourly);
+        for ($x = 0; $x < $hourlyTotal - $hourlyCount; $x++) {
+            $hourlyData[$x] = 0;
+        }
+        for ($x = ($hourlyTotal - $hourlyCount); $x < $hourlyTotal; $x++) {
+            $hourlyData[$x] = round($userTrafficHourly[$x - ($hourlyTotal - $hourlyCount)] / (1024 * 1024 * 1024), 3);
+        }
+
+        // 本月天数数据
+        $monthDays = [];
+        for ($i = 1; $i <= date("d"); $i++) {
+            $monthDays[] = $i;
+        }
+        // 本日小时数据
+        $dayHours = [];
+        for ($i = 1; $i <= date("H"); $i++) {
+            $dayHours[] = $i;
+        }
+
+        $view['trafficDaily'] = "'" . implode("','", $dailyData) . "'";
+        $view['trafficHourly'] = "'" . implode("','", $hourlyData) . "'";
+        $view['monthDays'] = "'" . implode("','", $monthDays) . "'";
+        $view['dayHours'] = "'" . implode("','", $dayHours) . "'";
+        $view['username'] = $user->username;
+        return Response::view('admin.userMonitor', $view);
+    }
+
+    // 生成端口
+    public function makePort(Request $request)
+    {
+        $new_port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+        echo $new_port;
+        exit;
+    }
+
+    // 加密方式、混淆、协议、等级、国家地区
+    public function config(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $name = $request->get('name');
+            $type = $request->get('type', 1); // 类型:1-加密方式(method)、2-协议(protocol)、3-混淆(obfs)
+            $is_default = $request->get('is_default', 0);
+            $sort = $request->get('sort', 0);
+
+            if (empty($name)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '配置名称不能为空']);
+            }
+
+            // 校验是否已存在
+            $config = SsConfig::type($type)->where('name', $name)->first();
+            if ($config) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '配置已经存在,请勿重复添加']);
+            }
+
+            $ssConfig = new SsConfig();
+            $ssConfig->name = $name;
+            $ssConfig->type = $type;
+            $ssConfig->is_default = $is_default;
+            $ssConfig->sort = $sort;
+            $ssConfig->save();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '添加成功']);
+        } else {
+            $view['method_list'] = SsConfig::type(1)->get();
+            $view['protocol_list'] = SsConfig::type(2)->get();
+            $view['obfs_list'] = SsConfig::type(3)->get();
+            $view['level_list'] = Helpers::levelList();
+            $view['country_list'] = Country::query()->get();
+
+            return Response::view('admin.config', $view);
+        }
+    }
+
+    // 删除配置
+    public function delConfig(Request $request)
+    {
+        $id = $request->get('id');
+
+        $ret = SsConfig::query()->where('id', $id)->delete();
+        if ($ret) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败']);
+        }
+    }
+
+    // 设置默认配置
+    public function setDefaultConfig(Request $request)
+    {
+        $id = $request->get('id');
+
+        if (empty($id)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '非法请求']);
+        }
+
+        $config = SsConfig::query()->where('id', $id)->first();
+        if (!$config) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '配置不存在']);
+        }
+
+        // 去除该配置所属类型的默认值
+        SsConfig::default()->type($config->type)->update(['is_default' => 0]);
+
+        // 将该ID对应记录值置为默认值
+        SsConfig::query()->where('id', $id)->update(['is_default' => 1]);
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+    }
+
+    // 设置系统扩展信息,例如客服、统计代码
+    public function setExtend(Request $request)
+    {
+        $websiteAnalytics = $request->get('website_analytics');
+        $websiteCustomerService = $request->get('website_customer_service');
+
+        DB::beginTransaction();
+        try {
+            // 首页LOGO
+            if ($request->hasFile('website_home_logo')) {
+                $file = $request->file('website_home_logo');
+                $fileType = $file->getClientOriginalExtension();
+
+                // 验证文件合法性
+                if (!in_array($fileType, ['jpg', 'png', 'jpeg', 'bmp'])) {
+                    Session::flash('errorMsg', 'LOGO不合法');
+
+                    return Redirect::back();
+                }
+
+                $logoName = date('YmdHis') . mt_rand(1000, 2000) . '.' . $fileType;
+                $move = $file->move(base_path() . '/public/upload/image/', $logoName);
+                $websiteHomeLogo = $move ? '/upload/image/' . $logoName : '';
+
+                Config::query()->where('name', 'website_home_logo')->update(['value' => $websiteHomeLogo]);
+            }
+
+            // 站内LOGO
+            if ($request->hasFile('website_logo')) {
+                $file = $request->file('website_logo');
+                $fileType = $file->getClientOriginalExtension();
+
+                // 验证文件合法性
+                if (!in_array($fileType, ['jpg', 'png', 'jpeg', 'bmp'])) {
+                    Session::flash('errorMsg', 'LOGO不合法');
+
+                    return Redirect::back();
+                }
+
+                $logoName = date('YmdHis') . mt_rand(1000, 2000) . '.' . $fileType;
+                $move = $file->move(base_path() . '/public/upload/image/', $logoName);
+                $websiteLogo = $move ? '/upload/image/' . $logoName : '';
+
+                Config::query()->where('name', 'website_logo')->update(['value' => $websiteLogo]);
+            }
+
+            Config::query()->where('name', 'website_analytics')->update(['value' => $websiteAnalytics]);
+            Config::query()->where('name', 'website_customer_service')->update(['value' => $websiteCustomerService]);
+
+            Session::flash('successMsg', '更新成功');
+
+            DB::commit();
+
+            return Redirect::back();
+        } catch (\Exception $e) {
+            DB::rollBack();
+
+            Session::flash('errorMsg', '更新失败');
+
+            return Redirect::back();
+        }
+    }
+
+    // 日志分析
+    public function analysis(Request $request)
+    {
+        $file = storage_path('app/ssserver.log');
+        if (!file_exists($file)) {
+            Session::flash('analysisErrorMsg', $file . ' 不存在,请先创建文件');
+
+            return Response::view('admin.analysis');
+        }
+
+        $logs = $this->tail($file, 10000);
+        if (false === $logs) {
+            $view['urlList'] = [];
+        } else {
+            $url = [];
+            foreach ($logs as $log) {
+                if (strpos($log, 'TCP connecting')) {
+                    continue;
+                }
+
+                preg_match('/TCP request (\w+\.){2}\w+/', $log, $tcp_matches);
+                if (!empty($tcp_matches)) {
+                    $url[] = str_replace('TCP request ', '[TCP] ', $tcp_matches[0]);
+                } else {
+                    preg_match('/UDP data to (25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)/', $log, $udp_matches);
+                    if (!empty($udp_matches)) {
+                        $url[] = str_replace('UDP data to ', '[UDP] ', $udp_matches[0]);
+                    }
+                }
+            }
+
+            $view['urlList'] = array_unique($url);
+        }
+
+        return Response::view('admin.analysis', $view);
+    }
+
+    // 添加等级
+    public function addLevel(Request $request)
+    {
+        $level = intval($request->get('level'));
+        $level_name = trim($request->get('level_name'));
+
+        if (empty($level)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '等级不能为空']);
+        }
+
+        if (empty($level_name)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '等级名称不能为空']);
+        }
+
+        $exists = Level::query()->where('level', $level)->first();
+        if ($exists) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该等级已存在,请勿重复添加']);
+        }
+
+        $obj = new Level();
+        $obj->level = $level;
+        $obj->level_name = $level_name;
+        $obj->save();
+
+        if ($obj->id) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '提交成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '操作失败']);
+        }
+    }
+
+    // 编辑等级
+    public function updateLevel(Request $request)
+    {
+        $id = $request->get('id');
+        $level = $request->get('level');
+        $level_name = $request->get('level_name');
+
+        if (!$id) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => 'ID不能为空']);
+        }
+
+        if (!$level) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '等级不能为空']);
+        }
+
+        if (!$level_name) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '等级名称不能为空']);
+        }
+
+        $le = Level::query()->where('id', $id)->first();
+        if (!$le) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '等级不存在']);
+        }
+
+        // 校验该等级下是否存在关联分组
+        $ssGroupCount = SsGroup::query()->where('level', $le->level)->count();
+        if ($ssGroupCount) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该等级下存在关联分组,请先取消关联']);
+        }
+
+        // 校验该等级下是否存在关联账号
+        $userCount = User::query()->where('level', $le->level)->count();
+        if ($userCount) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该等级下存在关联账号,请先取消关联']);
+        }
+
+        Level::query()->where('id', $id)->update(['level' => $level, 'level_name' => $level_name]);
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+    }
+
+    // 删除等级
+    public function delLevel(Request $request)
+    {
+        $id = $request->get('id');
+
+        if (empty($id)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => 'ID不能为空']);
+        }
+
+        $level = Level::query()->where('id', $id)->first();
+        if (empty($level)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '等级不存在']);
+        }
+
+        // 校验该等级下是否存在关联分组
+        $existGroups = SsGroup::query()->where('level', $level->level)->get();
+        if (!$existGroups->isEmpty()) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该等级下存在关联分组,请先取消关联']);
+        }
+
+        // 校验该等级下是否存在关联账号
+        $existUsers = User::query()->where('level', $level->level)->get();
+        if (!$existUsers->isEmpty()) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该等级下存在关联账号,请先取消关联']);
+        }
+
+        $ret = Level::query()->where('id', $id)->delete();
+        if ($ret) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '操作失败']);
+        }
+    }
+
+    // 添加国家/地区
+    public function addCountry(Request $request)
+    {
+        $country_name = $request->get('country_name');
+        $country_code = $request->get('country_code');
+
+        if (empty($country_name)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '国家/地区名称不能为空']);
+        }
+
+        if (empty($country_code)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '国家/地区代码不能为空']);
+        }
+
+        $exists = Country::query()->where('country_name', $country_name)->first();
+        if ($exists) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该国家/地区名称已存在,请勿重复添加']);
+        }
+
+        $obj = new Country();
+        $obj->country_name = $country_name;
+        $obj->country_code = $country_code;
+        $obj->save();
+
+        if ($obj->id) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '提交成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '操作失败']);
+        }
+    }
+
+    // 编辑国家/地区
+    public function updateCountry(Request $request)
+    {
+        $id = $request->get('id');
+        $country_name = $request->get('country_name');
+        $country_code = $request->get('country_code');
+
+        if (empty($id)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => 'ID不能为空']);
+        }
+
+        if (empty($country_name)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '国家/地区名称不能为空']);
+        }
+
+        if (empty($country_code)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '国家/地区代码不能为空']);
+        }
+
+        $country = Country::query()->where('id', $id)->first();
+        if (empty($country)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '国家/地区不存在']);
+        }
+
+        // 校验该国家/地区下是否存在关联节点
+        $existNode = SsNode::query()->where('country_code', $country->country_code)->get();
+        if (!$existNode->isEmpty()) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该国家/地区下存在关联节点,请先取消关联']);
+        }
+
+        $ret = Country::query()->where('id', $id)->update(['country_name' => $country_name, 'country_code' => $country_code]);
+        if ($ret) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '操作失败']);
+        }
+    }
+
+    // 删除国家/地区
+    public function delCountry(Request $request)
+    {
+        $id = $request->get('id');
+
+        if (empty($id)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => 'ID不能为空']);
+        }
+
+        $country = Country::query()->where('id', $id)->first();
+        if (empty($country)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '国家/地区不存在']);
+        }
+
+        // 校验该国家/地区下是否存在关联节点
+        $existNode = SsNode::query()->where('country_code', $country->country_code)->get();
+        if (!$existNode->isEmpty()) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该国家/地区下存在关联节点,请先取消关联']);
+        }
+
+        $ret = Country::query()->where('id', $id)->delete();
+        if ($ret) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '操作失败']);
+        }
+    }
+
+    // 系统设置
+    public function system(Request $request)
+    {
+        $view = Helpers::systemConfig();
+        $view['label_list'] = Label::query()->orderBy('sort', 'desc')->orderBy('id', 'asc')->get();
+
+        return Response::view('admin.system', $view);
+    }
+
+    // 设置某个配置项
+    public function setConfig(Request $request)
+    {
+        $name = trim($request->get('name'));
+        $value = trim($request->get('value'));
+
+        if (!$name) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '设置失败:请求参数异常']);
+        }
+
+        // 屏蔽异常配置
+        if (!array_key_exists($name, self::$systemConfig)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '设置失败:配置不存在']);
+        }
+
+        // 如果开启用户邮件重置密码,则先设置网站名称和网址
+        if (in_array($name, ['is_reset_password', 'is_active_register']) && $value == '1') {
+            $config = Config::query()->where('name', 'website_name')->first();
+            if ($config->value == '') {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '设置失败:启用该配置需要先设置【网站名称】']);
+            }
+
+            $config = Config::query()->where('name', 'website_url')->first();
+            if ($config->value == '') {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '设置失败:启用该配置需要先设置【网站地址】']);
+            }
+        }
+
+        // 演示环境禁止修改特定配置项
+        if (env('APP_DEMO')) {
+            $denyConfig = [
+                'website_url',
+                'min_rand_traffic',
+                'max_rand_traffic',
+                'push_bear_send_key',
+                'push_bear_qrcode',
+                'youzan_client_id',
+                'youzan_client_secret',
+                'kdt_id',
+                'is_forbid_china',
+                'alipay_partner',
+                'alipay_key',
+                'alipay_transport',
+                'alipay_sign_type',
+                'alipay_private_key',
+                'alipay_public_key',
+                'website_security_code'
+            ];
+
+            if (in_array($name, $denyConfig)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '演示环境禁止修改该配置']);
+            }
+        }
+
+        // 如果更改了有赞云任何一个配置,则删除有赞云的授权缓存,防止出现client_id错误
+        if (in_array($name, ['youzan_client_id', 'youzan_client_secret', 'kdt_id'])) {
+            \Cache::forget('YZY_TOKEN');
+        }
+
+        // 如果是返利比例,则需要除100
+        if (in_array($name, ['referral_percent'])) {
+            $value = intval($value) / 100;
+        }
+
+        // 用有赞云支付则不可用支付宝国际和支付宝当面付
+        if (in_array($name, ['is_youzan'])) {
+            $is_alipay = Config::query()->where('name', 'is_alipay')->first();
+            if ($is_alipay->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【支付宝国际支付】']);
+            }
+
+            $is_f2fpay = Config::query()->where('name', 'is_f2fpay')->first();
+            if ($is_f2fpay->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【支付宝当面付】']);
+            }
+        }
+
+        // 用支付国际则不可用有赞云支付和支付宝当面付
+        if (in_array($name, ['is_alipay'])) {
+            $is_youzan = Config::query()->where('name', 'is_youzan')->first();
+            if ($is_youzan->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【有赞云支付】']);
+            }
+
+            $is_f2fpay = Config::query()->where('name', 'is_f2fpay')->first();
+            if ($is_f2fpay->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【支付宝当面付】']);
+            }
+        }
+
+        // 用支付宝当面则不可用有赞云支付和支付宝国际
+        if (in_array($name, ['is_f2fpay'])) {
+            $is_youzan = Config::query()->where('name', 'is_youzan')->first();
+            if ($is_youzan->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【有赞云支付】']);
+            }
+
+            $is_alipay = Config::query()->where('name', 'is_alipay')->first();
+            if ($is_alipay->value) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '已经在使用【支付宝国际支付】']);
+            }
+        }
+
+        // 更新配置
+        Config::query()->where('name', $name)->update(['value' => $value]);
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+    }
+
+    // 邀请码列表
+    public function inviteList(Request $request)
+    {
+        $view['inviteList'] = Invite::query()->with(['generator', 'user'])->orderBy('status', 'asc')->orderBy('id', 'desc')->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.inviteList', $view);
+    }
+
+    // 生成邀请码
+    public function makeInvite(Request $request)
+    {
+        for ($i = 0; $i < 10; $i++) {
+            $obj = new Invite();
+            $obj->uid = 0;
+            $obj->fuid = 0;
+            $obj->code = strtoupper(substr(md5(microtime() . makeRandStr()), 8, 12));
+            $obj->status = 0;
+            $obj->dateline = date('Y-m-d H:i:s', strtotime("+" . self::$systemConfig['admin_invite_days'] . " days"));
+            $obj->save();
+        }
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '生成成功']);
+    }
+
+    // 导出邀请码
+    public function exportInvite(Request $request)
+    {
+        $inviteList = Invite::query()->where('status', 0)->orderBy('id', 'asc')->get();
+
+        $filename = '邀请码' . date('Ymd') . '.xlsx';
+
+        $spreadsheet = new Spreadsheet();
+        $spreadsheet->getProperties()->setCreator('SSRPanel')->setLastModifiedBy('SSRPanel')->setTitle('邀请码')->setSubject('邀请码')->setDescription('')->setKeywords('')->setCategory('');
+
+        $spreadsheet->setActiveSheetIndex(0);
+        $sheet = $spreadsheet->getActiveSheet();
+        $sheet->setTitle('邀请码');
+        $sheet->fromArray(['邀请码', '有效期'], null);
+
+        foreach ($inviteList as $k => $vo) {
+            $sheet->fromArray([$vo->code, $vo->dateline], null, 'A' . ($k + 2));
+        }
+
+        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); // 输出07Excel文件
+        //header('Content-Type:application/vnd.ms-excel'); // 输出Excel03版本文件
+        header('Content-Disposition: attachment;filename="' . $filename . '"');
+        header('Cache-Control: max-age=0');
+        $writer = new Xlsx($spreadsheet);
+        $writer->save('php://output');
+    }
+
+    // 提现申请列表
+    public function applyList(Request $request)
+    {
+        $username = $request->get('username');
+        $status = $request->get('status');
+
+        $query = ReferralApply::with('user');
+        if ($username) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        if ($status) {
+            $query->where('status', $status);
+        }
+
+        $view['applyList'] = $query->orderBy('id', 'desc')->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.applyList', $view);
+    }
+
+    // 提现申请详情
+    public function applyDetail(Request $request)
+    {
+        $id = $request->get('id');
+
+        $list = new \stdClass();
+        $apply = ReferralApply::query()->with(['user'])->where('id', $id)->first();
+        if ($apply && $apply->link_logs) {
+            $link_logs = explode(',', $apply->link_logs);
+            $list = ReferralLog::query()->with(['user', 'order.goods'])->whereIn('id', $link_logs)->paginate(15)->appends($request->except('page'));
+        }
+
+        $view['info'] = $apply;
+        $view['list'] = $list;
+
+        return Response::view('admin.applyDetail', $view);
+    }
+
+    // 订单列表
+    public function orderList(Request $request)
+    {
+        $username = trim($request->get('username'));
+        $is_coupon = $request->get('is_coupon');
+        $is_expire = $request->get('is_expire');
+        $pay_way = $request->get('pay_way');
+        $status = intval($request->get('status'));
+        $range_time = $request->get('range_time');
+        $sort = intval($request->get('sort')); // 0-按创建时间降序、1-按创建时间升序
+
+        $query = Order::query()->with(['user', 'goods', 'coupon']);
+
+        if ($username) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        if ($is_coupon != '') {
+            if ($is_coupon) {
+                $query->where('coupon_id', '<>', 0);
+            } else {
+                $query->where('coupon_id', 0);
+            }
+        }
+
+        if ($is_expire != '') {
+            $query->where('is_expire', $is_expire);
+        }
+
+        if ($pay_way != '') {
+            $query->where('pay_way', $pay_way);
+        }
+
+        if ($status != '') {
+            $query->where('status', $status);
+        }
+
+        if ($range_time) {
+            $range_time = explode('至', $range_time);
+            $query->where('created_at', '>=', trim($range_time['0']))->where('created_at', '<=', trim($range_time[1]));
+        }
+
+        if ($sort) {
+            $query->orderBy('oid', 'asc');
+        } else {
+            $query->orderBy('oid', 'desc');
+        }
+
+        $view['orderList'] = $query->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.orderList', $view);
+    }
+
+    // 设置提现申请状态
+    public function setApplyStatus(Request $request)
+    {
+        $id = $request->get('id');
+        $status = $request->get('status');
+
+        $ret = ReferralApply::query()->where('id', $id)->update(['status' => $status]);
+        if ($ret) {
+            // 审核申请的时候将关联的
+            $referralApply = ReferralApply::query()->where('id', $id)->first();
+            $log_ids = explode(',', $referralApply->link_logs);
+            if ($referralApply && $status == 1) {
+                ReferralLog::query()->whereIn('id', $log_ids)->update(['status' => 1]);
+            } elseif ($referralApply && $status == 2) {
+                ReferralLog::query()->whereIn('id', $log_ids)->update(['status' => 2]);
+            }
+        }
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+    }
+
+    // 重置用户流量
+    public function resetUserTraffic(Request $request)
+    {
+        $id = $request->get('id');
+
+        User::query()->where('id', $id)->update(['u' => 0, 'd' => 0]);
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+    }
+
+    // 操作用户余额
+    public function handleUserBalance(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $userId = $request->get('user_id');
+            $amount = $request->get('amount');
+
+            if (empty($userId) || empty($amount)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '充值异常']);
+            }
+
+            DB::beginTransaction();
+            try {
+                $user = User::query()->where('id', $userId)->first();
+
+                // 写入余额变动日志
+                $this->addUserBalanceLog($userId, 0, $user->balance, $user->balance + $amount, $amount, '后台手动充值');
+
+                // 加减余额
+                if ($amount < 0) {
+                    $user->decrement('balance', abs($amount) * 100);
+                } else {
+                    $user->increment('balance', abs($amount) * 100);
+                }
+
+                DB::commit();
+
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '充值成功']);
+            } catch (\Exception $e) {
+                DB::rollBack();
+
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '充值失败:' . $e->getMessage()]);
+            }
+        } else {
+            return Response::view('admin.handleUserBalance');
+        }
+    }
+
+    // 用户余额变动记录
+    public function userBalanceLogList(Request $request)
+    {
+        $username = trim($request->get('username'));
+
+        $query = UserBalanceLog::query()->with(['user'])->orderBy('id', 'desc');
+
+        if ($username) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        $view['list'] = $query->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.userBalanceLogList', $view);
+    }
+
+    // 用户封禁记录
+    public function userBanLogList(Request $request)
+    {
+        $username = trim($request->get('username'));
+
+        $query = UserBanLog::query()->with(['user'])->orderBy('id', 'desc');
+
+        if ($username) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        $view['list'] = $query->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.userBanLogList', $view);
+    }
+
+    // 用户流量变动记录
+    public function userTrafficLogList(Request $request)
+    {
+        $username = trim($request->get('username'));
+
+        $query = UserTrafficModifyLog::query()->with(['user', 'order', 'order.goods'])->orderBy('id', 'desc');
+
+        if ($username) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        $view['list'] = $query->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.userTrafficLogList', $view);
+    }
+
+    // 用户返利流水记录
+    public function userRebateList(Request $request)
+    {
+        $username = trim($request->get('username'));
+        $ref_username = trim($request->get('ref_username'));
+        $status = $request->get('status');
+
+        $query = ReferralLog::query()->with(['user', 'order'])->orderBy('status', 'asc')->orderBy('id', 'desc');
+
+        if ($username) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        if ($ref_username) {
+            $query->whereHas('ref_user', function ($q) use ($ref_username) {
+                $q->where('username', 'like', '%' . $ref_username . '%');
+            });
+        }
+
+        if ($status != '') {
+            $query->where('status', intval($status));
+        }
+
+        $view['list'] = $query->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.userRebateList', $view);
+    }
+
+    // 用户在线IP记录
+    public function userOnlineIPList(Request $request)
+    {
+        $username = trim($request->get('username'));
+        $port = intval($request->get('port'));
+        $wechat = trim($request->get('wechat'));
+        $qq = trim($request->get('qq'));
+
+        $query = User::query()->where('status', '>=', 0)->where('enable', 1);
+
+        if ($username) {
+            $query->where('username', 'like', '%' . $username . '%');
+        }
+
+        if (!empty($wechat)) {
+            $query->where('wechat', 'like', '%' . $wechat . '%');
+        }
+
+        if (!empty($qq)) {
+            $query->where('qq', 'like', '%' . $qq . '%');
+        }
+
+        if ($port) {
+            $query->where('port', $port);
+        }
+
+        $userList = $query->paginate(15)->appends($request->except('page'));
+        if (!$userList->isEmpty()) {
+            foreach ($userList as &$user) {
+                // 最近5条在线IP记录,如果后端设置为60秒上报一次,则为10分钟内的在线IP
+                $user->onlineIPList = SsNodeIp::query()->with(['node'])->where('type', 'tcp')->where('port', $user->port)->where('created_at', '>=', strtotime("-10 minutes"))->orderBy('id', 'desc')->limit(5)->get();
+            }
+        }
+
+        $view['userList'] = $userList;
+
+        return Response::view('admin.userOnlineIPList', $view);
+    }
+
+    // 转换成某个用户的身份
+    public function switchToUser(Request $request)
+    {
+        $id = $request->get('user_id');
+
+        $user = User::query()->find($id);
+        if (!$user) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => "用户不存在"]);
+        }
+
+        // 存储当前管理员ID,并将当前登录信息改成要切换的用户的身份信息
+        Session::put('admin', Auth::user()->id);
+        Auth::login($user);
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => "身份切换成功"]);
+    }
+
+    // 标签列表
+    public function labelList(Request $request)
+    {
+        $labelList = Label::query()->paginate(15)->appends($request->except('page'));
+        foreach ($labelList as $label) {
+            $label->userCount = UserLabel::query()->where('label_id', $label->id)->groupBy('label_id')->count();
+            $label->nodeCount = SsNodeLabel::query()->where('label_id', $label->id)->groupBy('label_id')->count();
+        }
+
+        $view['labelList'] = $labelList;
+
+        return Response::view('admin.labelList', $view);
+    }
+
+    // 添加标签
+    public function addLabel(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $name = $request->get('name');
+            $sort = $request->get('sort');
+
+            $label = new Label();
+            $label->name = $name;
+            $label->sort = $sort;
+            $label->save();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '添加成功']);
+        } else {
+            return Response::view('admin.addLabel');
+        }
+    }
+
+    // 编辑标签
+    public function editLabel(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $id = $request->get('id');
+            $name = $request->get('name');
+            $sort = $request->get('sort');
+
+            Label::query()->where('id', $id)->update(['name' => $name, 'sort' => $sort]);
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '添加成功']);
+        } else {
+            $id = $request->get('id');
+            $view['label'] = Label::query()->where('id', $id)->first();
+
+            return Response::view('admin.editLabel', $view);
+        }
+    }
+
+    // 删除标签
+    public function delLabel(Request $request)
+    {
+        $id = $request->get('id');
+
+        DB::beginTransaction();
+        try {
+            Label::query()->where('id', $id)->delete();
+            UserLabel::query()->where('label_id', $id)->delete(); // 删除用户关联
+            SsNodeLabel::query()->where('label_id', $id)->delete(); // 删除节点关联
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+        } catch (\Exception $e) {
+            DB::rollBack();
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败:' . $e->getMessage()]);
+        }
+    }
+
+    // 邮件发送日志列表
+    public function emailLog(Request $request)
+    {
+        $view['list'] = EmailLog::query()->orderBy('id', 'desc')->paginate(15)->appends($request->except('page'));
+
+        return Response::view('admin.emailLog', $view);
+    }
+
+    // 在线IP监控(实时)
+    public function onlineIPMonitor(Request $request)
+    {
+        $ip = trim($request->get('ip'));
+        $username = trim($request->get('username'));
+        $port = intval($request->get('port'));
+        $nodeId = intval($request->get('nodeId'));
+        $userId = intval($request->get('id'));
+
+        $query = SsNodeIp::query()->with(['node', 'user'])->where('type', 'tcp')->where('created_at', '>=', strtotime("-120 seconds"));
+
+        if ($ip) {
+            $query->where('ip', $ip);
+        }
+
+        if ($username) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        if ($port) {
+            $query->whereHas('user', function ($q) use ($port) {
+                $q->where('port', $port);
+            });
+        }
+
+        if ($nodeId) {
+            $query->whereHas('node', function ($q) use ($nodeId) {
+                $q->where('id', $nodeId);
+            });
+        }
+
+        if ($userId) {
+            $query->whereHas('user', function ($q) use ($userId) {
+                $q->where('id', $userId);
+            });
+        }
+
+        $list = $query->groupBy('port')->orderBy('id', 'desc')->paginate(20)->appends($request->except('page'));
+
+        foreach ($list as $vo) {
+            // 跳过上报多IP的
+            if (strpos($vo->ip, ',') !== false) {
+                continue;
+            }
+
+            $ipInfo = QQWry::ip($vo->ip);
+            if (isset($ipInfo['error'])) {
+                // 用IPIP的库再试一下
+                $ipip = IPIP::ip($vo->ip);
+                $ipInfo = [
+                    'country'  => $ipip['country_name'],
+                    'province' => $ipip['region_name'],
+                    'city'     => $ipip['city_name']
+                ];
+            }
+
+            $vo->ipInfo = $ipInfo['country'] . ' ' . $ipInfo['province'] . ' ' . $ipInfo['city'];
+        }
+
+        $view['list'] = $list;
+        $view['nodeList'] = SsNode::query()->where('status', 1)->orderBy('sort', 'desc')->orderBy('id', 'desc')->get();
+
+        return Response::view('admin.onlineIPMonitor', $view);
+    }
+
+    // 生成用户标签
+    private function makeUserLabels($userId, $labels)
+    {
+        // 先删除该用户所有的标签
+        UserLabel::query()->where('user_id', $userId)->delete();
+
+        if (!empty($labels) && is_array($labels)) {
+            foreach ($labels as $label) {
+                $userLabel = new UserLabel();
+                $userLabel->user_id = $userId;
+                $userLabel->label_id = $label;
+                $userLabel->save();
+            }
+        }
+    }
+
+    // 生成节点标签
+    private function makeNodeLabels($nodeId, $labels)
+    {
+        // 先删除所有该节点的标签
+        SsNodeLabel::query()->where('node_id', $nodeId)->delete();
+
+        if (!empty($labels) && is_array($labels)) {
+            foreach ($labels as $label) {
+                $ssNodeLabel = new SsNodeLabel();
+                $ssNodeLabel->node_id = $nodeId;
+                $ssNodeLabel->label_id = $label;
+                $ssNodeLabel->save();
+            }
+        }
+    }
+}

+ 279 - 0
app/Http/Controllers/Api/AlipayController.php

@@ -0,0 +1,279 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Components\AlipayNotify;
+use App\Components\Helpers;
+use App\Http\Controllers\Controller;
+use App\Http\Models\Goods;
+use App\Http\Models\GoodsLabel;
+use App\Http\Models\Order;
+use App\Http\Models\Payment;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeLabel;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Mail\sendUserInfo;
+use DB;
+use Hash;
+use Illuminate\Http\Request;
+use Log;
+use Mail;
+
+/**
+ * Class AlipayController
+ *
+ * @author  wz812180
+ *
+ * @package App\Http\Controllers\Api
+ */
+class AlipayController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 接收GET请求
+    public function index(Request $request)
+    {
+        \Log::info("【支付宝国际】回调接口[GET]:" . var_export($request->all(), true) . '[' . getClientIp() . ']');
+        exit("【支付宝国际】接口正常");
+    }
+
+    // 接收POST请求
+    public function store(Request $request)
+    {
+        \Log::info("【支付宝国际】回调接口[POST]:" . var_export($request->all(), true));
+
+        $result = "fail";
+        $alipayNotify = new AlipayNotify(self::$systemConfig['alipay_sign_type'], self::$systemConfig['alipay_partner'], self::$systemConfig['alipay_key'], self::$systemConfig['alipay_private_key'], self::$systemConfig['alipay_public_key'], self::$systemConfig['alipay_transport']);
+
+        // 验证支付宝交易
+        $verify_result = $alipayNotify->verifyNotify();
+        if ($verify_result) { // 验证成功
+            $result = "success";
+            if ($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {
+                // 商户订单号
+                $data = [];
+                $data['out_trade_no'] = $request->get('out_trade_no');
+                // 支付宝交易号
+                $data['trade_no'] = $request->get('trade_no');
+                // 交易状态
+                $data['trade_status'] = $request->get('trade_status');
+                // 交易金额(这里是按照结算货币汇率的金额,和rmb_fee不相等)
+                $data['total_fee'] = $request->get('total_fee');
+
+                $this->tradePaid($data);
+            } else {
+                Log::info('AliPay-POST:交易失败[' . getClientIp() . ']');
+            }
+        } else {
+            Log::info('AliPay-POST:验证失败[' . getClientIp() . ']');
+        }
+
+        // 返回验证结果
+        exit($result);
+    }
+
+    // 交易支付
+    private function tradePaid($msg)
+    {
+        Log::info('【支付宝国际】回调交易支付');
+
+        // 获取未完成状态的订单防止重复增加时间
+        $payment = Payment::query()->with(['order', 'order.goods'])->where('status', 0)->where('order_sn', $msg['out_trade_no'])->first();
+        if (!$payment) {
+            Log::info('【支付宝国际】回调订单不存在');
+            return;
+        }
+
+        // 处理订单
+        DB::beginTransaction();
+        try {
+            // 如果支付单中没有用户信息则创建一个用户
+            if (!$payment->user_id) {
+                // 生成一个可用端口
+                $port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+
+                $user = new User();
+                $user->username = '自动生成-' . $payment->order->email;
+                $user->password = Hash::make(makeRandStr());
+                $user->port = $port;
+                $user->passwd = makeRandStr();
+                $user->vmess_id = createGuid();
+                $user->enable = 1;
+                $user->method = Helpers::getDefaultMethod();
+                $user->protocol = Helpers::getDefaultProtocol();
+                $user->obfs = Helpers::getDefaultObfs();
+                $user->usage = 1;
+                $user->transfer_enable = 1; // 新创建的账号给1,防止定时任务执行时发现u + d >= transfer_enable被判为流量超限而封禁
+                $user->enable_time = date('Y-m-d');
+                $user->expire_time = date('Y-m-d', strtotime("+" . $payment->order->goods->days . " days"));
+                $user->reg_ip = getClientIp();
+                $user->referral_uid = 0;
+                $user->traffic_reset_day = 0;
+                $user->status = 1;
+                $user->save();
+
+                if ($user->id) {
+                    Order::query()->where('oid', $payment->oid)->update(['user_id' => $user->id]);
+                }
+            }
+
+            // 更新支付单
+            $payment->pay_way = 2; // 1-微信、2-支付宝
+            $payment->status = 1;
+            $payment->save();
+
+            // 更新订单
+            $order = Order::query()->with(['user'])->where('oid', $payment->oid)->first();
+            $order->status = 2;
+            $order->save();
+
+            $goods = Goods::query()->where('id', $order->goods_id)->first();
+
+            // 商品为流量或者套餐
+            if ($goods->type <= 2) {
+                // 如果买的是套餐,则先将之前购买的所有套餐置都无效,并扣掉之前所有套餐的流量,重置用户已用流量为0
+                if ($goods->type == 2) {
+                    $existOrderList = Order::query()
+                        ->with(['goods'])
+                        ->whereHas('goods', function ($q) {
+                            $q->where('type', 2);
+                        })
+                        ->where('user_id', $order->user_id)
+                        ->where('oid', '<>', $order->oid)
+                        ->where('is_expire', 0)
+                        ->where('status', 2)
+                        ->get();
+
+                    foreach ($existOrderList as $vo) {
+                        Order::query()->where('oid', $vo->oid)->update(['is_expire' => 1]);
+
+                        // 先判断,防止手动扣减过流量的用户流量被扣成负数
+                        if ($order->user->transfer_enable - $vo->goods->traffic * 1048576 <= 0) {
+                            // 写入用户流量变动记录
+                            Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, 0, 0, '[在线支付]用户购买套餐,先扣减之前套餐的流量(扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0, 'transfer_enable' => 0]);
+                        } else {
+                            // 写入用户流量变动记录
+                            $user = User::query()->where('id', $order->user_id)->first(); // 重新取出user信息
+                            Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $user->transfer_enable, ($user->transfer_enable - $vo->goods->traffic * 1048576), '[在线支付]用户购买套餐,先扣减之前套餐的流量(未扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0]);
+                            User::query()->where('id', $order->user_id)->decrement('transfer_enable', $vo->goods->traffic * 1048576);
+                        }
+                    }
+                }
+
+                // 写入用户流量变动记录
+                $user = User::query()->where('id', $order->user_id)->first(); // 重新取出user信息
+                Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $user->transfer_enable, ($user->transfer_enable + $goods->traffic * 1048576), '[在线支付]用户购买商品,加上流量');
+
+                // 把商品的流量加到账号上
+                User::query()->where('id', $order->user_id)->increment('transfer_enable', $goods->traffic * 1048576);
+
+                // 计算账号过期时间
+                if ($order->user->expire_time < date('Y-m-d', strtotime("+" . $goods->days . " days"))) {
+                    $expireTime = date('Y-m-d', strtotime("+" . $goods->days . " days"));
+                } else {
+                    $expireTime = $order->user->expire_time;
+                }
+
+                // 套餐就改流量重置日,流量包不改
+                if ($goods->type == 2) {
+                    if (date('m') == 2 && date('d') == 29) {
+                        $traffic_reset_day = 28;
+                    } else {
+                        $traffic_reset_day = date('d') == 31 ? 30 : abs(date('d'));
+                    }
+                    User::query()->where('id', $order->user_id)->update(['traffic_reset_day' => $traffic_reset_day, 'expire_time' => $expireTime, 'enable' => 1]);
+                } else {
+                    User::query()->where('id', $order->user_id)->update(['expire_time' => $expireTime, 'enable' => 1]);
+                }
+
+                // 写入用户标签
+                if ($goods->label) {
+                    // 用户默认标签
+                    $defaultLabels = [];
+                    if (self::$systemConfig['initial_labels_for_user']) {
+                        $defaultLabels = explode(',', self::$systemConfig['initial_labels_for_user']);
+                    }
+
+                    // 取出现有的标签
+                    $userLabels = UserLabel::query()->where('user_id', $order->user_id)->pluck('label_id')->toArray();
+                    $goodsLabels = GoodsLabel::query()->where('goods_id', $order->goods_id)->pluck('label_id')->toArray();
+
+                    // 标签去重
+                    $newUserLabels = array_values(array_unique(array_merge($userLabels, $goodsLabels, $defaultLabels)));
+
+                    // 删除用户所有标签
+                    UserLabel::query()->where('user_id', $order->user_id)->delete();
+
+                    // 生成标签
+                    foreach ($newUserLabels as $vo) {
+                        $obj = new UserLabel();
+                        $obj->user_id = $order->user_id;
+                        $obj->label_id = $vo;
+                        $obj->save();
+                    }
+                }
+
+                // 写入返利日志
+                if ($order->user->referral_uid) {
+                    $this->addReferralLog($order->user_id, $order->user->referral_uid, $order->oid, $order->amount, $order->amount * self::$systemConfig['referral_percent']);
+                }
+
+                // 取消重复返利
+                User::query()->where('id', $order->user_id)->update(['referral_uid' => 0]);
+            } elseif ($goods->type == 3) { // 商品为在线充值
+                User::query()->where('id', $order->user_id)->increment('balance', $goods->price * 100);
+
+                // 余额变动记录日志
+                $this->addUserBalanceLog($order->user_id, $order->oid, $order->user->balance, $order->user->balance + $goods->price, $goods->price, '用户在线充值');
+            }
+
+            // 自动提号机:如果order的email值不为空
+            if ($order->email) {
+                $title = '自动发送账号信息';
+                $content = [
+                    'order_sn'      => $order->order_sn,
+                    'goods_name'    => $order->goods->name,
+                    'goods_traffic' => flowAutoShow($order->goods->traffic * 1048576),
+                    'port'          => $order->user->port,
+                    'passwd'        => $order->user->passwd,
+                    'method'        => $order->user->method,
+                    //'protocol'       => $order->user->protocol,
+                    //'protocol_param' => $order->user->protocol_param,
+                    //'obfs'           => $order->user->obfs,
+                    //'obfs_param'     => $order->user->obfs_param,
+                    'created_at'    => $order->created_at->toDateTimeString(),
+                    'expire_at'     => $order->expire_at
+                ];
+
+                // 获取可用节点列表
+                $labels = UserLabel::query()->where('user_id', $order->user_id)->get()->pluck('label_id');
+                $nodeIds = SsNodeLabel::query()->whereIn('label_id', $labels)->get()->pluck('node_id');
+                $nodeList = SsNode::query()->whereIn('id', $nodeIds)->orderBy('sort', 'desc')->orderBy('id', 'desc')->get()->toArray();
+                $content['serverList'] = $nodeList;
+
+                $logId = Helpers::addEmailLog($order->email, $title, json_encode($content));
+                Mail::to($order->email)->send(new sendUserInfo($logId, $content));
+            }
+
+            DB::commit();
+        } catch (\Exception $e) {
+            DB::rollBack();
+            Log::info('【支付宝国际】回调更新支付单和订单异常:' . $e->getMessage());
+        }
+    }
+
+    public function show(Request $request)
+    {
+        exit('show');
+    }
+}

+ 299 - 0
app/Http/Controllers/Api/F2fpayController.php

@@ -0,0 +1,299 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Components\Helpers;
+use App\Http\Controllers\Controller;
+use App\Http\Models\Goods;
+use App\Http\Models\GoodsLabel;
+use App\Http\Models\Order;
+use App\Http\Models\Payment;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeLabel;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Mail\sendUserInfo;
+use DB;
+use Hash;
+use Illuminate\Http\Request;
+use Log;
+use Mail;
+use Payment\Client\Query;
+use Payment\Common\PayException;
+
+/**
+ * Class F2fpayController
+ *
+ * @author  heron
+ *
+ * @package App\Http\Controllers\Api
+ */
+class F2fpayController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 接收GET请求
+    public function index(Request $request)
+    {
+        \Log::info("【支付宝当面付】回调接口[GET]:" . var_export($request->all(), true) . '[' . getClientIp() . ']');
+        exit("【支付宝当面付】接口正常");
+    }
+
+    // 接收POST请求
+    public function store(Request $request)
+    {
+        \Log::info("【支付宝当面付】回调接口[POST]:" . var_export($request->all(), true));
+
+        $result = "fail";
+
+        try {
+            $verify_result = Query::run('ali_charge', [
+                'use_sandbox'     => false,
+                "partner"         => self::$systemConfig['f2fpay_app_id'],
+                'app_id'          => self::$systemConfig['f2fpay_app_id'],
+                'sign_type'       => 'RSA2',
+                'ali_public_key'  => self::$systemConfig['f2fpay_public_key'],
+                'rsa_private_key' => self::$systemConfig['f2fpay_private_key'],
+                'notify_url'      => self::$systemConfig['website_url'] . "/api/f2fpay", // 异步回调接口
+                'return_url'      => self::$systemConfig['website_url'],
+                'return_raw'      => false
+            ], [
+                'out_trade_no' => $request->get('out_trade_no'),
+                'trade_no'     => $request->get('trade_no'),
+            ]);
+
+            \Log::info("【支付宝当面付】回调验证查询:" . var_export($verify_result, true));
+        } catch (PayException $e) {
+            \Log::info("【支付宝当面付】回调验证查询出错:" . var_export($e->errorMessage(), true));
+            exit($result);
+        }
+
+        if ($verify_result['is_success'] == 'T') { // 验证成功
+            $result = "success";
+            if ($_POST['trade_status'] == 'TRADE_FINISHED' || $_POST['trade_status'] == 'TRADE_SUCCESS') {
+                // 商户订单号
+                $data = [];
+                $data['out_trade_no'] = $request->get('out_trade_no');
+                // 支付宝交易号
+                $data['trade_no'] = $request->get('trade_no');
+                // 交易状态
+                $data['trade_status'] = $request->get('trade_status');
+                // 交易金额(这里是按照结算货币汇率的金额,和rmb_fee不相等)
+                $data['total_amount'] = $request->get('total_amount');
+
+                $this->tradePaid($data);
+            } else {
+                Log::info('支付宝当面付-POST:交易失败[' . getClientIp() . ']');
+            }
+        } else {
+            Log::info('支付宝当面付-POST:验证失败[' . getClientIp() . ']');
+        }
+
+        // 返回验证结果
+        exit($result);
+    }
+
+    // 交易支付
+    private function tradePaid($msg)
+    {
+        Log::info('【支付宝当面付】回调交易支付');
+
+        // 获取未完成状态的订单防止重复增加时间
+        $payment = Payment::query()->with(['order', 'order.goods'])->where('status', 0)->where('order_sn', $msg['out_trade_no'])->first();
+        if (!$payment) {
+            Log::info('【支付宝当面付】回调订单不存在');
+            return;
+        }
+
+        // 处理订单
+        DB::beginTransaction();
+        try {
+            // 如果支付单中没有用户信息则创建一个用户
+            if (!$payment->user_id) {
+                // 生成一个可用端口
+                $port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+
+                $user = new User();
+                $user->username = '自动生成-' . $payment->order->email;
+                $user->password = Hash::make(makeRandStr());
+                $user->port = $port;
+                $user->passwd = makeRandStr();
+                $user->vmess_id = createGuid();
+                $user->enable = 1;
+                $user->method = Helpers::getDefaultMethod();
+                $user->protocol = Helpers::getDefaultProtocol();
+                $user->obfs = Helpers::getDefaultObfs();
+                $user->usage = 1;
+                $user->transfer_enable = 1; // 新创建的账号给1,防止定时任务执行时发现u + d >= transfer_enable被判为流量超限而封禁
+                $user->enable_time = date('Y-m-d');
+                $user->expire_time = date('Y-m-d', strtotime("+" . $payment->order->goods->days . " days"));
+                $user->reg_ip = getClientIp();
+                $user->referral_uid = 0;
+                $user->traffic_reset_day = 0;
+                $user->status = 1;
+                $user->save();
+
+                if ($user->id) {
+                    Order::query()->where('oid', $payment->oid)->update(['user_id' => $user->id]);
+                }
+            }
+
+            // 更新支付单
+            $payment->pay_way = 2; // 1-微信、2-支付宝
+            $payment->status = 1;
+            $payment->save();
+
+            // 更新订单
+            $order = Order::query()->with(['user'])->where('oid', $payment->oid)->first();
+            $order->status = 2;
+            $order->save();
+
+            $goods = Goods::query()->where('id', $order->goods_id)->first();
+
+            // 商品为流量或者套餐
+            if ($goods->type <= 2) {
+                // 如果买的是套餐,则先将之前购买的所有套餐置都无效,并扣掉之前所有套餐的流量,重置用户已用流量为0
+                if ($goods->type == 2) {
+                    $existOrderList = Order::query()
+                        ->with(['goods'])
+                        ->whereHas('goods', function ($q) {
+                            $q->where('type', 2);
+                        })
+                        ->where('user_id', $order->user_id)
+                        ->where('oid', '<>', $order->oid)
+                        ->where('is_expire', 0)
+                        ->where('status', 2)
+                        ->get();
+
+                    foreach ($existOrderList as $vo) {
+                        Order::query()->where('oid', $vo->oid)->update(['is_expire' => 1]);
+
+                        // 先判断,防止手动扣减过流量的用户流量被扣成负数
+                        if ($order->user->transfer_enable - $vo->goods->traffic * 1048576 <= 0) {
+                            // 写入用户流量变动记录
+                            Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, 0, 0, '[在线支付]用户购买套餐,先扣减之前套餐的流量(扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0, 'transfer_enable' => 0]);
+                        } else {
+                            // 写入用户流量变动记录
+                            $user = User::query()->where('id', $order->user_id)->first(); // 重新取出user信息
+                            Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $user->transfer_enable, ($user->transfer_enable - $vo->goods->traffic * 1048576), '[在线支付]用户购买套餐,先扣减之前套餐的流量(未扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0]);
+                            User::query()->where('id', $order->user_id)->decrement('transfer_enable', $vo->goods->traffic * 1048576);
+                        }
+                    }
+                }
+
+                // 写入用户流量变动记录
+                $user = User::query()->where('id', $order->user_id)->first(); // 重新取出user信息
+                Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $user->transfer_enable, ($user->transfer_enable + $goods->traffic * 1048576), '[在线支付]用户购买商品,加上流量');
+
+                // 把商品的流量加到账号上
+                User::query()->where('id', $order->user_id)->increment('transfer_enable', $goods->traffic * 1048576);
+
+                // 计算账号过期时间
+                if ($order->user->expire_time < date('Y-m-d', strtotime("+" . $goods->days . " days"))) {
+                    $expireTime = date('Y-m-d', strtotime("+" . $goods->days . " days"));
+                } else {
+                    $expireTime = $order->user->expire_time;
+                }
+
+                // 套餐就改流量重置日,流量包不改
+                if ($goods->type == 2) {
+                    if (date('m') == 2 && date('d') == 29) {
+                        $traffic_reset_day = 28;
+                    } else {
+                        $traffic_reset_day = date('d') == 31 ? 30 : abs(date('d'));
+                    }
+                    User::query()->where('id', $order->user_id)->update(['traffic_reset_day' => $traffic_reset_day, 'expire_time' => $expireTime, 'enable' => 1]);
+                } else {
+                    User::query()->where('id', $order->user_id)->update(['expire_time' => $expireTime, 'enable' => 1]);
+                }
+
+                // 写入用户标签
+                if ($goods->label) {
+                    // 用户默认标签
+                    $defaultLabels = [];
+                    if (self::$systemConfig['initial_labels_for_user']) {
+                        $defaultLabels = explode(',', self::$systemConfig['initial_labels_for_user']);
+                    }
+
+                    // 取出现有的标签
+                    $userLabels = UserLabel::query()->where('user_id', $order->user_id)->pluck('label_id')->toArray();
+                    $goodsLabels = GoodsLabel::query()->where('goods_id', $order->goods_id)->pluck('label_id')->toArray();
+
+                    // 标签去重
+                    $newUserLabels = array_values(array_unique(array_merge($userLabels, $goodsLabels, $defaultLabels)));
+
+                    // 删除用户所有标签
+                    UserLabel::query()->where('user_id', $order->user_id)->delete();
+
+                    // 生成标签
+                    foreach ($newUserLabels as $vo) {
+                        $obj = new UserLabel();
+                        $obj->user_id = $order->user_id;
+                        $obj->label_id = $vo;
+                        $obj->save();
+                    }
+                }
+
+                // 写入返利日志
+                if ($order->user->referral_uid) {
+                    $this->addReferralLog($order->user_id, $order->user->referral_uid, $order->oid, $order->amount, $order->amount * self::$systemConfig['referral_percent']);
+                }
+
+                // 取消重复返利
+                User::query()->where('id', $order->user_id)->update(['referral_uid' => 0]);
+            } elseif ($goods->type == 3) { // 商品为在线充值
+                User::query()->where('id', $order->user_id)->increment('balance', $goods->price * 100);
+
+                // 余额变动记录日志
+                $this->addUserBalanceLog($order->user_id, $order->oid, $order->user->balance, $order->user->balance + $goods->price, $goods->price, '用户在线充值');
+            }
+
+            // 自动提号机:如果order的email值不为空
+            if ($order->email) {
+                $title = '自动发送账号信息';
+                $content = [
+                    'order_sn'      => $order->order_sn,
+                    'goods_name'    => $order->goods->name,
+                    'goods_traffic' => flowAutoShow($order->goods->traffic * 1048576),
+                    'port'          => $order->user->port,
+                    'passwd'        => $order->user->passwd,
+                    'method'        => $order->user->method,
+                    //'protocol'       => $order->user->protocol,
+                    //'protocol_param' => $order->user->protocol_param,
+                    //'obfs'           => $order->user->obfs,
+                    //'obfs_param'     => $order->user->obfs_param,
+                    'created_at'    => $order->created_at->toDateTimeString(),
+                    'expire_at'     => $order->expire_at
+                ];
+
+                // 获取可用节点列表
+                $labels = UserLabel::query()->where('user_id', $order->user_id)->get()->pluck('label_id');
+                $nodeIds = SsNodeLabel::query()->whereIn('label_id', $labels)->get()->pluck('node_id');
+                $nodeList = SsNode::query()->whereIn('id', $nodeIds)->orderBy('sort', 'desc')->orderBy('id', 'desc')->get()->toArray();
+                $content['serverList'] = $nodeList;
+
+                $logId = Helpers::addEmailLog($order->email, $title, json_encode($content));
+                Mail::to($order->email)->send(new sendUserInfo($logId, $content));
+            }
+
+            DB::commit();
+        } catch (\Exception $e) {
+            DB::rollBack();
+            Log::info('【支付宝当面付】回调更新支付单和订单异常:' . $e->getMessage());
+        }
+    }
+
+    public function show(Request $request)
+    {
+        exit('show');
+    }
+}

+ 150 - 0
app/Http/Controllers/Api/LoginController.php

@@ -0,0 +1,150 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Components\Helpers;
+use App\Http\Controllers\Controller;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Http\Models\UserSubscribe;
+use App\Http\Models\UserSubscribeLog;
+use Cache;
+use DB;
+use Hash;
+use Illuminate\Http\Request;
+use Response;
+
+/**
+ * 登录接口
+ *
+ * Class LoginController
+ *
+ * @package App\Http\Controllers
+ */
+class LoginController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 登录返回订阅信息
+    public function login(Request $request)
+    {
+        $username = trim($request->get('username'));
+        $password = trim($request->get('password'));
+        $cacheKey = 'request_times_' . md5(getClientIp());
+
+        if (!$username || !$password) {
+            Cache::increment($cacheKey);
+
+            return Response::json(['status' => 'fail', 'data' => [], 'message' => '请输入用户名和密码']);
+        }
+
+        // 连续请求失败15次,则封IP一小时
+        if (Cache::has($cacheKey)) {
+            if (Cache::get($cacheKey) >= 15) {
+                return Response::json(['status' => 'fail', 'data' => [], 'message' => '请求失败超限,禁止访问1小时']);
+            }
+        } else {
+            Cache::put($cacheKey, 1, 60);
+        }
+
+        $user = User::query()->where('username', $username)->where('status', '>=', 0)->first();
+        if (!$user) {
+            Cache::increment($cacheKey);
+
+            return Response::json(['status' => 'fail', 'data' => [], 'message' => '账号不存在或已被禁用']);
+        } elseif (!Hash::check($password, $user->password)) {
+            return Response::json(['status' => 'fail', 'data' => [], 'message' => '用户名或密码错误']);
+        }
+
+        DB::beginTransaction();
+        try {
+            // 如果未生成过订阅链接则生成一个
+            $subscribe = UserSubscribe::query()->where('user_id', $user->id)->first();
+
+            // 更新订阅链接访问次数
+            $subscribe->increment('times', 1);
+
+            // 记录每次请求
+            $this->log($subscribe->id, getClientIp(), 'API访问');
+
+            // 订阅链接
+            $url = self::$systemConfig['subscribe_domain'] ? self::$systemConfig['subscribe_domain'] : self::$systemConfig['website_url'];
+
+            // 节点列表
+            $userLabelIds = UserLabel::query()->where('user_id', $user->id)->pluck('label_id');
+            if (empty($userLabelIds)) {
+                return Response::json(['status' => 'fail', 'message' => '', 'data' => []]);
+            }
+
+            $nodeList = DB::table('ss_node')
+                ->selectRaw('ss_node.*')
+                ->leftJoin('ss_node_label', 'ss_node.id', '=', 'ss_node_label.node_id')
+                ->whereIn('ss_node_label.label_id', $userLabelIds)
+                ->where('ss_node.status', 1)
+                ->groupBy('ss_node.id')
+                ->orderBy('ss_node.sort', 'desc')
+                ->orderBy('ss_node.id', 'asc')
+                ->get();
+
+            $c_nodes = collect();
+            foreach ($nodeList as $node) {
+                $temp_node = [
+                    'name'          => $node->name,
+                    'server'        => $node->server,
+                    'server_port'   => $user->port,
+                    'method'        => $user->method,
+                    'obfs'          => $user->obfs,
+                    'flags'         => $url . '/assets/images/country/' . $node->country_code . '.png',
+                    'obfsparam'     => '',
+                    'password'      => $user->passwd,
+                    'group'         => '',
+                    'protocol'      => $user->protocol,
+                    'protoparam'    => '',
+                    'protocolparam' => ''
+                ];
+                $c_nodes = $c_nodes->push($temp_node);
+            }
+
+            $data = [
+                'status'       => 1,
+                'class'        => 0,
+                'level'        => 2,
+                'expire_in'    => $user->expire_time,
+                'text'         => '',
+                'buy_link'     => '',
+                'money'        => '0.00',
+                'sspannelName' => 'ssrpanel',
+                'usedTraffic'  => flowAutoShow($user->u + $user->d),
+                'Traffic'      => flowAutoShow($user->transfer_enable),
+                'all'          => 1,
+                'residue'      => '',
+                'nodes'        => $c_nodes,
+                'link'         => $url . '/s/' . $subscribe->code
+            ];
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => $data, 'message' => '登录成功']);
+        } catch (\Exception $e) {
+            DB::rollBack();
+
+            return Response::json(['status' => 'success', 'data' => [], 'message' => '登录失败']);
+        }
+    }
+
+    // 写入订阅访问日志
+    private function log($subscribeId, $ip, $headers)
+    {
+        $log = new UserSubscribeLog();
+        $log->sid = $subscribeId;
+        $log->request_ip = $ip;
+        $log->request_time = date('Y-m-d H:i:s');
+        $log->request_header = $headers;
+        $log->save();
+    }
+}

+ 81 - 0
app/Http/Controllers/Api/PingController.php

@@ -0,0 +1,81 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use Illuminate\Http\Request;
+use Log;
+
+/**
+ * PING检测工具
+ *
+ * Class PingController
+ *
+ * @package App\Http\Controllers\Api
+ */
+class PingController extends Controller
+{
+    public function ping(Request $request)
+    {
+        $token = $request->input('token');
+        $host = $request->input('host');
+        $port = $request->input('port', 22);
+        $transport = $request->input('transport', 'tcp');
+        $timeout = $request->input('timeout', 0.5);
+
+        if (empty($host)) {
+            echo "<pre>";
+            echo "使用方法:";
+            echo "<br>";
+            echo "GET /api/ping?token=toke_value&host=www.baidu.com&port=80&transport=tcp&timeout=0.5";
+            echo "<br>";
+            echo "token:.env下加入API_TOKEN,其值就是token的值";
+            echo "<br>";
+            echo "host:检测地址,必传,可以是域名、IPv4、IPv6";
+            echo "<br>";
+            echo "port:检测端口,可不传,默认22";
+            echo "<br>";
+            echo "transport:检测协议,可不传,默认tcp,可以是tcp、udp";
+            echo "<br>";
+            echo "timeout:检测超时,单位秒,可不传,默认0.5秒,建议不超过3秒";
+            echo "<br>";
+            echo "成功返回:1,失败返回:0";
+            echo "</pre>";
+            exit();
+        }
+
+        // 验证TOKEN,防止滥用
+        if (env('API_TOKEN') != $token) {
+            return response()->json(['status' => 0, 'message' => 'token invalid']);
+        }
+
+        // 如果不是IPv4
+        if (false === filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
+            // 如果是IPv6
+            if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
+                $host = '[' . $host . ']';
+            }
+        }
+
+        try {
+            $host = gethostbyname($host); // 这里如果挂了,说明服务器的DNS解析不给力,必须换
+            $fp = stream_socket_client($transport . '://' . $host . ':' . $port, $errno, $errstr, $timeout);
+            if (!$fp) {
+                Log::info("$errstr ($errno)");
+                $ret = 0;
+                $message = 'port close';
+            } else {
+                $ret = 1;
+                $message = 'port open';
+            }
+
+            fclose($fp);
+
+            return response()->json(['status' => $ret, 'message' => $message]);
+        } catch (\Exception $e) {
+            Log::info($e);
+
+            return response()->json(['status' => 0, 'message' => 'port close']);
+        }
+    }
+}

+ 393 - 0
app/Http/Controllers/Api/YzyController.php

@@ -0,0 +1,393 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Components\Helpers;
+use App\Http\Controllers\Controller;
+use App\Http\Models\Goods;
+use App\Http\Models\GoodsLabel;
+use App\Http\Models\Order;
+use App\Http\Models\Payment;
+use App\Http\Models\PaymentCallback;
+use App\Http\Models\SsNode;
+use App\Http\Models\SsNodeLabel;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Mail\sendUserInfo;
+use DB;
+use Hash;
+use Illuminate\Http\Request;
+use Log;
+use Mail;
+
+/**
+ * 有赞云支付消息推送接收
+ *
+ * Class YzyController
+ *
+ * @package App\Http\Controllers
+ */
+class YzyController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 接收GET请求
+    public function index(Request $request)
+    {
+        \Log::info("【有赞云】回调接口[GET]:" . var_export($request->all(), true) . '[' . getClientIp() . ']');
+        exit("【有赞云】接口正常");
+    }
+
+    // 接收POST请求
+    public function store(Request $request)
+    {
+        \Log::info("【有赞云】回调接口[POST]:" . var_export($request->all(), true));
+
+        $json = file_get_contents('php://input');
+        $data = json_decode($json, true);
+        if (!$data) {
+            Log::info('YZY-POST:回调数据无法解析,可能是非法请求[' . getClientIp() . ']');
+            exit();
+        }
+
+        // 判断消息是否合法
+        $msg = $data['msg'];
+        $sign_string = self::$systemConfig['youzan_client_id'] . "" . $msg . "" . self::$systemConfig['youzan_client_secret'];
+        $sign = md5($sign_string);
+        if ($sign != $data['sign']) {
+            Log::info('本地签名:' . $sign_string . ' | 远程签名:' . $data['sign']);
+            Log::info('YZY-POST:回调数据签名错误,可能是非法请求[' . getClientIp() . ']');
+            exit();
+        } else {
+            // 返回请求成功标识给有赞
+            var_dump(["code" => 0, "msg" => "success"]);
+        }
+
+        // 容错
+        if (!isset($data['kdt_name'])) {
+            Log::info("【有赞云】回调数据解析错误,请检查有赞支付设置是否与有赞控制台中的信息保持一致。如果还出现此提示,请执行一遍php artisan cache:clear命令");
+            exit();
+        }
+
+        // 先写入回调日志
+        $this->callbackLog($data['client_id'], $data['id'], $data['kdt_id'], $data['kdt_name'], $data['mode'], $data['msg'], $data['sendCount'], $data['sign'], $data['status'], $data['test'], $data['type'], $data['version']);
+
+        // msg内容经过 urlencode 编码,进行解码
+        $msg = json_decode(urldecode($msg), true);
+
+        switch ($data['type']) {
+            case 'trade_TradePaid':
+                $this->tradePaid($msg);
+                break;
+            case 'trade_TradeCreate':
+                $this->tradeCreate($msg);
+                break;
+            case 'trade_TradeClose':
+                $this->tradeClose($msg);
+                break;
+            case 'trade_TradeSuccess':
+                $this->tradeSuccess($msg);
+                break;
+            case 'trade_TradePartlySellerShip':
+                $this->tradePartlySellerShip($msg);
+                break;
+            case 'trade_TradeSellerShip':
+                $this->tradeSellerShip($msg);
+                break;
+            case 'trade_TradeBuyerPay':
+                $this->tradeBuyerPay($msg);
+                break;
+            case 'trade_TradeMemoModified':
+                $this->tradeMemoModified($msg);
+                break;
+            default:
+                Log::info('【有赞云】回调无法识别,可能是没有启用[交易消息V3]接口,请到有赞云控制台启用消息推送服务');
+                exit();
+        }
+
+        exit();
+    }
+
+    // 交易支付
+    private function tradePaid($msg)
+    {
+        Log::info('【有赞云】回调交易支付');
+
+        $payment = Payment::query()->with(['order', 'order.goods'])->where('qr_id', $msg['qr_info']['qr_id'])->first();
+        if (!$payment) {
+            Log::info('【有赞云】回调订单不存在');
+            exit();
+        }
+
+        if ($payment->status != '0') {
+            Log::info('【有赞云】回调订单状态不正确');
+            exit();
+        }
+
+        // 处理订单
+        DB::beginTransaction();
+        try {
+            // 如果支付单中没有用户信息则创建一个用户
+            if (!$payment->user_id) {
+                // 生成一个可用端口
+                $port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+
+                $user = new User();
+                $user->username = '自动生成-' . $payment->order->email;
+                $user->password = Hash::make(makeRandStr());
+                $user->port = $port;
+                $user->passwd = makeRandStr();
+                $user->vmess_id = createGuid();
+                $user->enable = 1;
+                $user->method = Helpers::getDefaultMethod();
+                $user->protocol = Helpers::getDefaultProtocol();
+                $user->obfs = Helpers::getDefaultObfs();
+                $user->usage = 1;
+                $user->transfer_enable = 1; // 新创建的账号给1,防止定时任务执行时发现u + d >= transfer_enable被判为流量超限而封禁
+                $user->enable_time = date('Y-m-d');
+                $user->expire_time = date('Y-m-d', strtotime("+" . $payment->order->goods->days . " days"));
+                $user->reg_ip = getClientIp();
+                $user->referral_uid = 0;
+                $user->traffic_reset_day = 0;
+                $user->status = 1;
+                $user->save();
+
+                if ($user->id) {
+                    Order::query()->where('oid', $payment->oid)->update(['user_id' => $user->id]);
+                }
+            }
+
+            // 更新支付单
+            $payment->pay_way = $msg['full_order_info']['order_info']['pay_type_str'] == 'WEIXIN_DAIXIAO' ? 1 : 2; // 1-微信、2-支付宝
+            $payment->status = 1;
+            $payment->save();
+
+            // 更新订单
+            $order = Order::query()->with(['user'])->where('oid', $payment->oid)->first();
+            $order->status = 2;
+            $order->save();
+
+            $goods = Goods::query()->where('id', $order->goods_id)->first();
+
+            // 商品为流量或者套餐
+            if ($goods->type <= 2) {
+                // 如果买的是套餐,则先将之前购买的所有套餐置都无效,并扣掉之前所有套餐的流量,重置用户已用流量为0
+                if ($goods->type == 2) {
+                    $existOrderList = Order::query()
+                        ->with(['goods'])
+                        ->whereHas('goods', function ($q) {
+                            $q->where('type', 2);
+                        })
+                        ->where('user_id', $order->user_id)
+                        ->where('oid', '<>', $order->oid)
+                        ->where('is_expire', 0)
+                        ->where('status', 2)
+                        ->get();
+
+                    foreach ($existOrderList as $vo) {
+                        Order::query()->where('oid', $vo->oid)->update(['is_expire' => 1]);
+
+                        // 先判断,防止手动扣减过流量的用户流量被扣成负数
+                        if ($order->user->transfer_enable - $vo->goods->traffic * 1048576 <= 0) {
+                            // 写入用户流量变动记录
+                            Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, 0, 0, '[在线支付]用户购买套餐,先扣减之前套餐的流量(扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0, 'transfer_enable' => 0]);
+                        } else {
+                            // 写入用户流量变动记录
+                            $user = User::query()->where('id', $order->user_id)->first(); // 重新取出user信息
+                            Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $user->transfer_enable, ($user->transfer_enable - $vo->goods->traffic * 1048576), '[在线支付]用户购买套餐,先扣减之前套餐的流量(未扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0]);
+                            User::query()->where('id', $order->user_id)->decrement('transfer_enable', $vo->goods->traffic * 1048576);
+                        }
+                    }
+                }
+
+                // 写入用户流量变动记录
+                $user = User::query()->where('id', $order->user_id)->first(); // 重新取出user信息
+                Helpers::addUserTrafficModifyLog($order->user_id, $order->oid, $user->transfer_enable, ($user->transfer_enable + $goods->traffic * 1048576), '[在线支付]用户购买商品,加上流量');
+
+                // 计算账号过期时间
+                if ($order->user->expire_time < date('Y-m-d', strtotime("+" . $goods->days . " days"))) {
+                    $expireTime = date('Y-m-d', strtotime("+" . $goods->days . " days"));
+                } else {
+                    $expireTime = $order->user->expire_time;
+                }
+
+                // 把商品的流量加到账号上
+                User::query()->where('id', $order->user_id)->increment('transfer_enable', $goods->traffic * 1048576);
+
+                // 套餐就改流量重置日,流量包不改
+                if ($goods->type == 2) {
+                    if (date('m') == 2 && date('d') == 29) {
+                        $traffic_reset_day = 28;
+                    } else {
+                        $traffic_reset_day = date('d') == 31 ? 30 : abs(date('d'));
+                    }
+                    User::query()->where('id', $order->user_id)->update(['traffic_reset_day' => $traffic_reset_day, 'expire_time' => $expireTime, 'enable' => 1]);
+                } else {
+                    User::query()->where('id', $order->user_id)->update(['expire_time' => $expireTime, 'enable' => 1]);
+                }
+
+                // 写入用户标签
+                if ($goods->label) {
+                    // 用户默认标签
+                    $defaultLabels = [];
+                    if (self::$systemConfig['initial_labels_for_user']) {
+                        $defaultLabels = explode(',', self::$systemConfig['initial_labels_for_user']);
+                    }
+
+                    // 取出现有的标签
+                    $userLabels = UserLabel::query()->where('user_id', $order->user_id)->pluck('label_id')->toArray();
+                    $goodsLabels = GoodsLabel::query()->where('goods_id', $order->goods_id)->pluck('label_id')->toArray();
+
+                    // 标签去重
+                    $newUserLabels = array_values(array_unique(array_merge($userLabels, $goodsLabels, $defaultLabels)));
+
+                    // 删除用户所有标签
+                    UserLabel::query()->where('user_id', $order->user_id)->delete();
+
+                    // 生成标签
+                    foreach ($newUserLabels as $vo) {
+                        $obj = new UserLabel();
+                        $obj->user_id = $order->user_id;
+                        $obj->label_id = $vo;
+                        $obj->save();
+                    }
+                }
+
+                // 写入返利日志
+                if ($order->user->referral_uid) {
+                    $this->addReferralLog($order->user_id, $order->user->referral_uid, $order->oid, $order->amount, $order->amount * self::$systemConfig['referral_percent']);
+                }
+
+                // 取消重复返利
+                User::query()->where('id', $order->user_id)->update(['referral_uid' => 0]);
+            } elseif ($goods->type == 3) { // 商品为在线充值
+                User::query()->where('id', $order->user_id)->increment('balance', $goods->price * 100);
+
+                // 余额变动记录日志
+                $this->addUserBalanceLog($order->user_id, $order->oid, $order->user->balance, $order->user->balance + $goods->price, $goods->price, '用户在线充值');
+            }
+
+            // 自动提号机:如果order的email值不为空
+            if ($order->email) {
+                $title = '自动发送账号信息';
+                $content = [
+                    'order_sn'      => $order->order_sn,
+                    'goods_name'    => $order->goods->name,
+                    'goods_traffic' => flowAutoShow($order->goods->traffic * 1048576),
+                    'port'          => $order->user->port,
+                    'passwd'        => $order->user->passwd,
+                    'method'        => $order->user->method,
+                    //'protocol'       => $order->user->protocol,
+                    //'protocol_param' => $order->user->protocol_param,
+                    //'obfs'           => $order->user->obfs,
+                    //'obfs_param'     => $order->user->obfs_param,
+                    'created_at'    => $order->created_at->toDateTimeString(),
+                    'expire_at'     => $order->expire_at
+                ];
+
+                // 获取可用节点列表
+                $labels = UserLabel::query()->where('user_id', $order->user_id)->get()->pluck('label_id');
+                $nodeIds = SsNodeLabel::query()->whereIn('label_id', $labels)->get()->pluck('node_id');
+                $nodeList = SsNode::query()->whereIn('id', $nodeIds)->orderBy('sort', 'desc')->orderBy('id', 'desc')->get()->toArray();
+                $content['serverList'] = $nodeList;
+
+                $logId = Helpers::addEmailLog($order->email, $title, json_encode($content));
+                Mail::to($order->email)->send(new sendUserInfo($logId, $content));
+            }
+
+            DB::commit();
+        } catch (\Exception $e) {
+            DB::rollBack();
+
+            Log::info('【有赞云】回调更新支付单和订单异常:' . $e->getMessage());
+        }
+
+        exit();
+    }
+
+    // 创建交易
+    private function tradeCreate($msg)
+    {
+        Log::info('【有赞云】回调创建交易');
+        exit();
+    }
+
+    // 关闭交易(无视,系统自带15分钟自动关闭未支付订单的定时任务)
+    private function tradeClose($msg)
+    {
+        Log::info('【有赞云】回调关闭交易');
+
+        exit();
+    }
+
+    // 交易成功
+    private function tradeSuccess($msg)
+    {
+        Log::info('【有赞云】回调交易成功');
+
+        exit();
+    }
+
+    // 卖家部分发货
+    private function tradePartlySellerShip($msg)
+    {
+        Log::info('【有赞云】回调卖家部分发货');
+        exit();
+    }
+
+    // 卖家发货
+    private function tradeSellerShip($msg)
+    {
+        Log::info('【有赞云】回调卖家发货');
+        exit();
+    }
+
+    // 买家付款
+    private function tradeBuyerPay($msg)
+    {
+        Log::info('【有赞云】回调买家付款');
+        exit();
+    }
+
+    // 卖家修改交易备注
+    private function tradeMemoModified($msg)
+    {
+        Log::info('【有赞云】回调卖家修改交易备注');
+        exit();
+    }
+
+    public function show(Request $request)
+    {
+        exit('show');
+    }
+
+    // 写入回调请求日志
+    private function callbackLog($client_id, $yz_id, $kdt_id, $kdt_name, $mode, $msg, $sendCount, $sign, $status, $test, $type, $version)
+    {
+        $obj = new PaymentCallback();
+        $obj->client_id = $client_id;
+        $obj->yz_id = $yz_id;
+        $obj->kdt_id = $kdt_id;
+        $obj->kdt_name = $kdt_name;
+        $obj->mode = $mode;
+        $obj->msg = urldecode($msg);
+        $obj->sendCount = $sendCount;
+        $obj->sign = $sign;
+        $obj->status = $status;
+        $obj->test = $test;
+        $obj->type = $type;
+        $obj->version = $version;
+        $obj->save();
+
+        return $obj->id;
+    }
+}

+ 766 - 0
app/Http/Controllers/AuthController.php

@@ -0,0 +1,766 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\Helpers;
+use App\Components\IPIP;
+use App\Components\QQWry;
+use App\Components\CaptchaVerify;
+use App\Http\Models\Invite;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Http\Models\UserLoginLog;
+use App\Http\Models\UserSubscribe;
+use App\Http\Models\Verify;
+use App\Http\Models\VerifyCode;
+use App\Mail\activeUser;
+use App\Mail\resetPassword;
+use App\Mail\sendVerifyCode;
+use Auth;
+use Cache;
+use Captcha;
+use Hash;
+use Illuminate\Http\Request;
+use Log;
+use Mail;
+use Redirect;
+use Response;
+use Session;
+use Validator;
+
+/**
+ * 认证控制器
+ *
+ * Class AuthController
+ *
+ * @package App\Http\Controllers
+ */
+class AuthController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 登录
+    public function login(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $this->validate($request, [
+                'username' => 'required',
+                'password' => 'required'
+            ], [
+                'username.required' => trans('auth.email_null'),
+                'password.required' => trans('auth.password_null')
+            ]);
+
+            // 是否校验验证码
+            switch (self::$systemConfig['is_captcha']) {
+                case 1: // 默认图形验证码
+                    if (!Captcha::check($request->captcha)) {
+                        return Redirect::back()->withInput()->withErrors(trans('auth.captcha_error'));
+                    }
+                    break;
+                case 2: // Geetest
+                    $result = $this->validate($request, [
+                        'geetest_challenge' => 'required|geetest'
+                    ], [
+                        'geetest' => trans('auth.captcha_fail')
+                    ]);
+
+                    if (!$result) {
+                        return Redirect::back()->withInput()->withErrors(trans('auth.fail_captcha'));
+                    }
+                    break;
+                case 3: // Google reCAPTCHA
+                    $result = $this->validate($request, [
+                        'g-recaptcha-response' => 'required|NoCaptcha'
+                    ]);
+
+                    if (!$result) {
+                        return Redirect::back()->withInput()->withErrors(trans('auth.fail_captcha'));
+                    }
+                    break;
+                default: // 不启用验证码
+                    break;
+            }
+
+            // 验证账号并创建会话
+            if (!Auth::attempt(['username' => $request->username, 'password' => $request->password], $request->remember)) {
+                return Redirect::back()->withInput()->withErrors(trans('auth.login_error'));
+            }
+
+            // 校验普通用户账号状态
+            if (!Auth::user()->is_admin) {
+                if (Auth::user()->status < 0) {
+                    Auth::logout(); // 强制销毁会话,因为Auth::attempt的时候会产生会话
+
+                    return Redirect::back()->withInput()->withErrors(trans('auth.login_ban', ['email' => self::$systemConfig['admin_email']]));
+                }
+
+                if (Auth::user()->status == 0 && self::$systemConfig['is_active_register']) {
+                    Auth::logout(); // 强制销毁会话,因为Auth::attempt的时候会产生会话
+
+                    return Redirect::back()->withInput()->withErrors(trans('auth.active_tip') . '<a href="/activeUser?username=' . $request->username . '" target="_blank"><span style="color:#000">【' . trans('auth.active_account') . '】</span></a>');
+                }
+            }
+
+            // 写入登录日志
+            $this->addUserLoginLog(Auth::user()->id, getClientIp());
+
+            // 更新登录信息
+            User::uid()->update(['last_login' => time()]);
+
+            // 根据权限跳转
+            if (Auth::user()->is_admin) {
+                return Redirect::to('admin');
+            }
+
+            return Redirect::to('/');
+        } else {
+            if (Auth::check()) {
+                if (Auth::user()->is_admin) {
+                    return Redirect::to('admin');
+                }
+
+                return Redirect::to('/');
+            }
+
+            return Response::view('auth.login');
+        }
+    }
+
+    // 退出
+    public function logout(Request $request)
+    {
+        Auth::logout();
+
+        return Redirect::to('login');
+    }
+
+    // 注册
+    public function register(Request $request)
+    {
+        $cacheKey = 'register_times_' . md5(getClientIp()); // 注册限制缓存key
+
+        if ($request->isMethod('POST')) {
+            $this->validate($request, [
+                'username'   => 'required|email|unique:user',
+                'password'   => 'required|min:6',
+                'repassword' => 'required|same:password',
+            ], [
+                'username.required'   => trans('auth.email_null'),
+                'username.email'      => trans('auth.email_legitimate'),
+                'username.unique'     => trans('auth.email_exist'),
+                'password.required'   => trans('auth.password_null'),
+                'password.min'        => trans('auth.password_limit'),
+                'repassword.required' => trans('auth.retype_password'),
+                'repassword.same'     => trans('auth.password_same')
+            ]);
+
+            // 防止重复提交
+            if ($request->register_token != Session::get('register_token')) {
+                return Redirect::back()->withInput()->withErrors(trans('auth.repeat_request'));
+            } else {
+                Session::forget('register_token');
+            }
+
+            // 是否开启注册
+            if (!self::$systemConfig['is_register']) {
+                return Redirect::back()->withErrors(trans('auth.register_close'));
+            }
+
+            // 校验域名邮箱是否在敏感词中
+            $sensitiveWords = $this->sensitiveWords();
+            $usernameSuffix = explode('@', $request->username); // 提取邮箱后缀
+            if (in_array(strtolower($usernameSuffix[1]), $sensitiveWords)) {
+                return Redirect::back()->withInput()->withErrors(trans('auth.email_banned'));
+            }
+
+            // 如果需要邀请注册
+            if (self::$systemConfig['is_invite_register']) {
+                // 必须使用邀请码
+                if (self::$systemConfig['is_invite_register'] == 2 && !$request->code) {
+                    return Redirect::back()->withInput()->withErrors(trans('auth.code_null'));
+                }
+
+                // 校验邀请码合法性
+                if ($request->code) {
+                    $codeEnable = Invite::query()->where('code', $request->code)->where('status', 0)->first();
+                    if (!$codeEnable) {
+                        return Redirect::back()->withInput($request->except(['code']))->withErrors(trans('auth.code_error'));
+                    }
+                }
+            }
+
+            // 如果开启注册发送验证码
+            if (self::$systemConfig['is_verify_register']) {
+                if (!$request->verify_code) {
+                    return Redirect::back()->withInput($request->except(['verify_code']))->withErrors(trans('auth.captcha_null'));
+                } else {
+                    $verifyCode = VerifyCode::query()->where('username', $request->username)->where('code', $request->verify_code)->where('status', 0)->first();
+                    if (!$verifyCode) {
+                        return Redirect::back()->withInput($request->except(['verify_code']))->withErrors(trans('auth.captcha_overtime'));
+                    }
+
+                    $verifyCode->status = 1;
+                    $verifyCode->save();
+                }
+            } elseif (self::$systemConfig['is_captcha']) { // 是否校验验证码
+                switch (self::$systemConfig['is_captcha']) {
+                    case 1: // 默认图形验证码
+                        if (!Captcha::check($request->captcha)) {
+                            return Redirect::back()->withInput()->withErrors(trans('auth.captcha_error'));
+                        }
+                        break;
+                    case 2: // Geetest
+                        $result = $this->validate($request, [
+                            'geetest_challenge' => 'required|geetest'
+                        ], [
+                            'geetest' => trans('auth.captcha_fail')
+                        ]);
+
+                        if (!$result) {
+                            return Redirect::back()->withInput()->withErrors(trans('auth.captcha_fail'));
+                        }
+                        break;
+                    case 3: // Google reCAPTCHA
+                        $result = $this->validate($request, [
+                            'g-recaptcha-response' => 'required|NoCaptcha'
+                        ]);
+
+                        if (!$result) {
+                            return Redirect::back()->withInput()->withErrors(trans('auth.captcha_fail'));
+                        }
+                        break;
+                    default: // 不启用验证码
+                        break;
+                }
+            }
+
+            // 24小时内同IP注册限制
+            if (self::$systemConfig['register_ip_limit']) {
+                if (Cache::has($cacheKey)) {
+                    $registerTimes = Cache::get($cacheKey);
+                    if ($registerTimes >= self::$systemConfig['register_ip_limit']) {
+                        return Redirect::back()->withInput($request->except(['code']))->withErrors(trans('auth.register_anti'));
+                    }
+                }
+            }
+
+            // 获取可用端口
+            $port = self::$systemConfig['is_rand_port'] ? Helpers::getRandPort() : Helpers::getOnlyPort();
+            if ($port > self::$systemConfig['max_port']) {
+                return Redirect::back()->withInput()->withErrors(trans('auth.register_close'));
+            }
+
+            // 获取aff
+            $affArr = $this->getAff($request->code, intval($request->aff));
+            $referral_uid = $affArr['referral_uid'];
+
+            $transfer_enable = $referral_uid ? (self::$systemConfig['default_traffic'] + self::$systemConfig['referral_traffic']) * 1048576 : self::$systemConfig['default_traffic'] * 1048576;
+
+            // 创建新用户
+            $user = new User();
+            $user->username = $request->username;
+            $user->password = Hash::make($request->password);
+            $user->port = $port;
+            $user->passwd = makeRandStr();
+            $user->vmess_id = createGuid();
+            $user->transfer_enable = $transfer_enable;
+            $user->method = Helpers::getDefaultMethod();
+            $user->protocol = Helpers::getDefaultProtocol();
+            $user->obfs = Helpers::getDefaultObfs();
+            $user->enable_time = date('Y-m-d H:i:s');
+            $user->expire_time = date('Y-m-d H:i:s', strtotime("+" . self::$systemConfig['default_days'] . " days"));
+            $user->reg_ip = getClientIp();
+            $user->referral_uid = $referral_uid;
+            $user->save();
+
+            // 注册失败,抛出异常
+            if (!$user->id) {
+                return Redirect::back()->withInput()->withErrors(trans('auth.register_fail'));
+            }
+
+            // 生成订阅码
+            $subscribe = new UserSubscribe();
+            $subscribe->user_id = $user->id;
+            $subscribe->code = Helpers::makeSubscribeCode();
+            $subscribe->times = 0;
+            $subscribe->save();
+
+            // 注册次数+1
+            if (Cache::has($cacheKey)) {
+                Cache::increment($cacheKey);
+            } else {
+                Cache::put($cacheKey, 1, 1440); // 24小时
+            }
+
+            // 初始化默认标签
+            if (strlen(self::$systemConfig['initial_labels_for_user'])) {
+                $labels = explode(',', self::$systemConfig['initial_labels_for_user']);
+                foreach ($labels as $label) {
+                    $userLabel = new UserLabel();
+                    $userLabel->user_id = $user->id;
+                    $userLabel->label_id = $label;
+                    $userLabel->save();
+                }
+            }
+
+            // 更新邀请码
+            if (self::$systemConfig['is_invite_register'] && $affArr['code_id']) {
+                Invite::query()->where('id', $affArr['code_id'])->update(['fuid' => $user->id, 'status' => 1]);
+            }
+
+            // 清除邀请人Cookie
+            \Cookie::unqueue('register_aff');
+
+            if (self::$systemConfig['is_verify_register']) {
+                if ($referral_uid) {
+                    $transfer_enable = self::$systemConfig['referral_traffic'] * 1048576;
+
+                    User::query()->where('id', $referral_uid)->increment('transfer_enable', $transfer_enable);
+                    User::query()->where('id', $referral_uid)->update(['status' => 1, 'enable' => 1]);
+                }
+
+                User::query()->where('id', $user->id)->update(['status' => 1, 'enable' => 1]);
+
+                Session::flash('regSuccessMsg', trans('auth.register_success'));
+            } else {
+                // 发送激活邮件
+                if (self::$systemConfig['is_active_register']) {
+                    // 生成激活账号的地址
+                    $token = md5(self::$systemConfig['website_name'] . $request->username . microtime());
+                    $activeUserUrl = self::$systemConfig['website_url'] . '/active/' . $token;
+                    $this->addVerify($user->id, $token);
+
+                    $logId = Helpers::addEmailLog($request->username, '注册激活', '请求地址:' . $activeUserUrl);
+                    Mail::to($request->username)->send(new activeUser($logId, $activeUserUrl));
+
+                    Session::flash('regSuccessMsg', trans('auth.register_success_tip'));
+                } else {
+                    // 如果不需要激活,则直接给推荐人加流量
+                    if ($referral_uid) {
+                        $transfer_enable = self::$systemConfig['referral_traffic'] * 1048576;
+
+                        User::query()->where('id', $referral_uid)->increment('transfer_enable', $transfer_enable);
+                        User::query()->where('id', $referral_uid)->update(['status' => 1, 'enable' => 1]);
+                    }
+
+                    User::query()->where('id', $user->id)->update(['status' => 1, 'enable' => 1]);
+
+                    Session::flash('regSuccessMsg', trans('auth.register_success'));
+                }
+            }
+
+            return Redirect::to('login')->withInput();
+        } else {
+            Session::put('register_token', makeRandStr(16));
+
+            return Response::view('auth.register');
+        }
+    }
+
+    // 重设密码页
+    public function resetPassword(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            // 校验请求
+            $this->validate($request, [
+                'username' => 'required|email'
+            ], [
+                'username.required' => trans('auth.email_null'),
+                'username.email'    => trans('auth.email_legitimate')
+            ]);
+
+            // 是否开启重设密码
+            if (!self::$systemConfig['is_reset_password']) {
+                return Redirect::back()->withErrors(trans('auth.reset_password_close', ['email' => self::$systemConfig['admin_email']]));
+            }
+
+            // 查找账号
+            $user = User::query()->where('username', $request->username)->first();
+            if (!$user) {
+                return Redirect::back()->withErrors(trans('auth.email_notExist'));
+            }
+
+            // 24小时内重设密码次数限制
+            $resetTimes = 0;
+            if (Cache::has('resetPassword_' . md5($request->username))) {
+                $resetTimes = Cache::get('resetPassword_' . md5($request->username));
+                if ($resetTimes >= self::$systemConfig['reset_password_times']) {
+                    return Redirect::back()->withErrors(trans('auth.reset_password_limit', ['time' => self::$systemConfig['reset_password_times']]));
+                }
+            }
+
+            // 生成取回密码的地址
+            $token = md5(self::$systemConfig['website_name'] . $request->username . microtime());
+            $verify = new Verify();
+            $verify->type = 1;
+            $verify->user_id = $user->id;
+            $verify->token = $token;
+            $verify->status = 0;
+            $verify->save();
+
+            // 发送邮件
+            $resetPasswordUrl = self::$systemConfig['website_url'] . '/reset/' . $token;
+
+            $logId = Helpers::addEmailLog($request->username, '重置密码', '请求地址:' . $resetPasswordUrl);
+            Mail::to($request->username)->send(new resetPassword($logId, $resetPasswordUrl));
+
+            Cache::put('resetPassword_' . md5($request->username), $resetTimes + 1, 1440);
+
+            return Redirect::back()->with('successMsg', trans('auth.reset_password_success_tip'));
+        } else {
+            return Response::view('auth.resetPassword');
+        }
+    }
+
+    // 重设密码
+    public function reset(Request $request, $token)
+    {
+        if (!$token) {
+            return Redirect::to('login');
+        }
+
+        if ($request->isMethod('POST')) {
+            $this->validate($request, [
+                'password'   => 'required|min:6',
+                'repassword' => 'required|same:password'
+            ], [
+                'password.required'   => trans('auth.password_null'),
+                'password.min'        => trans('auth.password_limit'),
+                'repassword.required' => trans('auth.password_null'),
+                'repassword.min'      => trans('auth.password_limit'),
+                'repassword.same'     => trans('auth.password_same'),
+            ]);
+
+            // 校验账号
+            $verify = Verify::type(1)->with('user')->where('token', $token)->first();
+            if (!$verify) {
+                return Redirect::to('login');
+            } elseif ($verify->status == 1) {
+                return Redirect::back()->withErrors(trans('auth.overtime'));
+            } elseif ($verify->user->status < 0) {
+                return Redirect::back()->withErrors(trans('auth.email_banned'));
+            } elseif (Hash::check($request->password, $verify->user->password)) {
+                return Redirect::back()->withErrors(trans('auth.rest_password_same_fail'));
+            }
+
+            // 更新密码
+            $ret = User::query()->where('id', $verify->user_id)->update(['password' => Hash::make($request->password)]);
+            if (!$ret) {
+                return Redirect::back()->withErrors(trans('auth.rest_password_fail'));
+            }
+
+            // 置为已使用
+            $verify->status = 1;
+            $verify->save();
+
+            return Redirect::back()->with('successMsg', trans('auth.reset_password_new'));
+        } else {
+            $verify = Verify::type(1)->where('token', $token)->first();
+            if (!$verify) {
+                return Redirect::to('login');
+            } elseif (time() - strtotime($verify->created_at) >= 1800) {
+                // 置为已失效
+                $verify->status = 2;
+                $verify->save();
+            }
+
+            // 重新获取一遍verify
+            $view['verify'] = Verify::type(1)->where('token', $token)->first();
+
+            return Response::view('auth.reset', $view);
+        }
+    }
+
+    // 激活账号页
+    public function activeUser(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $this->validate($request, [
+                'username' => 'required|email|exists:user,username'
+            ], [
+                'username.required' => trans('auth.email_null'),
+                'username.email'    => trans('auth.email_legitimate'),
+                'username.exists'   => trans('auth.email_notExist')
+            ]);
+
+            // 是否开启账号激活
+            if (!self::$systemConfig['is_active_register']) {
+                return Redirect::back()->withInput()->withErrors(trans('auth.active_close', ['email' => self::$systemConfig['admin_email']]));
+            }
+
+            // 查找账号
+            $user = User::query()->where('username', $request->username)->first();
+            if ($user->status < 0) {
+                return Redirect::back()->withErrors(trans('auth.login_ban', ['email' => self::$systemConfig['admin_email']]));
+            } elseif ($user->status > 0) {
+                return Redirect::back()->withErrors(trans('auth.email_normal'));
+            }
+
+            // 24小时内激活次数限制
+            $activeTimes = 0;
+            if (Cache::has('activeUser_' . md5($request->username))) {
+                $activeTimes = Cache::get('activeUser_' . md5($request->username));
+                if ($activeTimes >= self::$systemConfig['active_times']) {
+                    return Redirect::back()->withErrors(trans('auth.active_limit', ['time' => self::$systemConfig['admin_email']]));
+                }
+            }
+
+            // 生成激活账号的地址
+            $token = md5(self::$systemConfig['website_name'] . $request->username . microtime());
+            $verify = new Verify();
+            $verify->type = 1;
+            $verify->user_id = $user->id;
+            $verify->token = $token;
+            $verify->status = 0;
+            $verify->save();
+
+            // 发送邮件
+            $activeUserUrl = self::$systemConfig['website_url'] . '/active/' . $token;
+
+            $logId = Helpers::addEmailLog($request->username, '激活账号', '请求地址:' . $activeUserUrl);
+            Mail::to($request->username)->send(new activeUser($logId, $activeUserUrl));
+
+            Cache::put('activeUser_' . md5($request->username), $activeTimes + 1, 1440);
+
+            return Redirect::back()->with('successMsg', trans('auth.register_success_tip'));
+        } else {
+            return Response::view('auth.activeUser');
+        }
+    }
+
+    // 激活账号
+    public function active(Request $request, $token)
+    {
+        if (!$token) {
+            return Redirect::to('login');
+        }
+
+        $verify = Verify::type(1)->with('user')->where('token', $token)->first();
+        if (!$verify) {
+            return Redirect::to('login');
+        } elseif (empty($verify->user)) {
+            Session::flash('errorMsg', trans('auth.overtime'));
+
+            return Response::view('auth.active');
+        } elseif ($verify->status > 0) {
+            Session::flash('errorMsg', trans('auth.overtime'));
+
+            return Response::view('auth.active');
+        } elseif ($verify->user->status != 0) {
+            Session::flash('errorMsg', trans('auth.email_normal'));
+
+            return Response::view('auth.active');
+        } elseif (time() - strtotime($verify->created_at) >= 1800) {
+            Session::flash('errorMsg', trans('auth.overtime'));
+
+            // 置为已失效
+            $verify->status = 2;
+            $verify->save();
+
+            return Response::view('auth.active');
+        }
+
+        // 更新账号状态
+        $ret = User::query()->where('id', $verify->user_id)->update(['status' => 1]);
+        if (!$ret) {
+            Session::flash('errorMsg', trans('auth.active_fail'));
+
+            return Redirect::back();
+        }
+
+        // 置为已使用
+        $verify->status = 1;
+        $verify->save();
+
+        // 账号激活后给邀请人送流量
+        if ($verify->user->referral_uid) {
+            $transfer_enable = self::$systemConfig['referral_traffic'] * 1048576;
+
+            User::query()->where('id', $verify->user->referral_uid)->increment('transfer_enable', $transfer_enable);
+            User::query()->where('id', $verify->user->referral_uid)->update(['enable' => 1]);
+        }
+
+        Session::flash('successMsg', trans('auth.active_success'));
+
+        return Response::view('auth.active');
+    }
+
+    // 发送注册验证码
+    public function sendCode(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'username' => 'required|email|unique:user'
+        ], [
+            'username.required' => trans('auth.email_null'),
+            'username.email'    => trans('auth.email_legitimate'),
+            'username.unique'   => trans('auth.email_exist')
+        ]);
+
+        if ($validator->fails()) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => $validator->getMessageBag()->first()]);
+        }
+
+        // 校验域名邮箱是否在敏感词中
+        $sensitiveWords = $this->sensitiveWords();
+        $usernameSuffix = explode('@', $request->username); // 提取邮箱后缀
+        if (in_array(strtolower($usernameSuffix[1]), $sensitiveWords)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => trans('auth.email_banned')]);
+        }
+
+        // 是否开启注册发送验证码
+        if (!self::$systemConfig['is_verify_register']) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => trans('auth.captcha_close')]);
+        }
+
+        // 防刷机制
+        if (Cache::has('send_verify_code_' . md5(getClientIP()))) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => trans('auth.register_anti')]);
+        }
+
+        // 发送邮件
+        $code = makeRandStr(6, true);
+        $logId = Helpers::addEmailLog($request->username, '发送注册验证码', '验证码:' . $code);
+        Mail::to($request->username)->send(new sendVerifyCode($logId, $code));
+
+        $this->addVerifyCode($request->username, $code);
+
+        Cache::put('send_verify_code_' . md5(getClientIP()), getClientIP(), 1);
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => trans('auth.captcha_send')]);
+    }
+
+    // 公开的邀请码列表
+    public function free(Request $request)
+    {
+        $view['inviteList'] = Invite::query()->where('uid', 0)->where('status', 0)->paginate();
+
+        return Response::view('auth.free', $view);
+    }
+
+    // 切换语言
+    public function switchLang(Request $request, $locale)
+    {
+        Session::put("locale", $locale);
+
+        return Redirect::back();
+    }
+
+    /**
+     * 添加用户登录日志
+     *
+     * @param string $userId 用户ID
+     * @param string $ip     IP地址
+     */
+    private function addUserLoginLog($userId, $ip)
+    {
+        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
+            Log::info('识别到IPv6,尝试解析:' . $ip);
+            $ipInfo = getIPv6($ip);
+        } else {
+            $ipInfo = QQWry::ip($ip); // 通过纯真IP库解析IPv4信息
+            if (isset($ipInfo['error'])) {
+                Log::info('无法识别IPv4,尝试使用IPIP的IP库解析:' . $ip);
+                $ipip = IPIP::ip($ip);
+                $ipInfo = [
+                    'country'  => $ipip['country_name'],
+                    'province' => $ipip['region_name'],
+                    'city'     => $ipip['city_name']
+                ];
+            } else {
+                // 判断纯真IP库获取的国家信息是否与IPIP的IP库获取的信息一致,不一致则用IPIP的(因为纯真IP库的非大陆IP准确率较低)
+                $ipip = IPIP::ip($ip);
+                if ($ipInfo['country'] != $ipip['country_name']) {
+                    $ipInfo['country'] = $ipip['country_name'];
+                    $ipInfo['province'] = $ipip['region_name'];
+                    $ipInfo['city'] = $ipip['city_name'];
+                }
+            }
+        }
+
+        if (empty($ipInfo) || empty($ipInfo['country'])) {
+            Log::warning("获取IP信息异常:" . $ip);
+        }
+
+        $log = new UserLoginLog();
+        $log->user_id = $userId;
+        $log->ip = $ip;
+        $log->country = $ipInfo['country'] ?? '';
+        $log->province = $ipInfo['province'] ?? '';
+        $log->city = $ipInfo['city'] ?? '';
+        $log->county = $ipInfo['county'] ?? '';
+        $log->isp = $ipInfo['isp'] ?? ($ipInfo['organization'] ?? '');
+        $log->area = $ipInfo['area'] ?? '';
+        $log->save();
+    }
+
+    /**
+     * 获取AFF
+     *
+     * @param string $code 邀请码
+     * @param int    $aff  URL中的aff参数
+     *
+     * @return array
+     */
+    private function getAff($code = '', $aff = '')
+    {
+        // 邀请人ID
+        $referral_uid = 0;
+
+        // 邀请码ID
+        $code_id = 0;
+
+        // 有邀请码先用邀请码,用谁的邀请码就给谁返利
+        if ($code) {
+            $inviteCode = Invite::query()->where('code', $code)->where('status', 0)->first();
+            if ($inviteCode) {
+                $referral_uid = $inviteCode->uid;
+                $code_id = $inviteCode->id;
+            }
+        }
+
+        // 没有用邀请码或者邀请码是管理员生成的,则检查cookie或者url链接
+        if (!$referral_uid) {
+            // 检查一下cookie里有没有aff
+            $cookieAff = \Request::hasCookie('register_aff') ? \Request::cookie('register_aff') : 0;
+            if ($cookieAff) {
+                $affUser = User::query()->where('id', $cookieAff)->exists();
+                $referral_uid = $affUser ? $cookieAff : 0;
+            } elseif ($aff) { // 如果cookie里没有aff,就再检查一下请求的url里有没有aff,因为有些人的浏览器会禁用了cookie,比如chrome开了隐私模式
+                $affUser = User::query()->where('id', $aff)->exists();
+                $referral_uid = $affUser ? $aff : 0;
+            }
+        }
+
+        return [
+            'referral_uid' => $referral_uid,
+            'code_id'      => $code_id
+        ];
+    }
+
+    // 写入生成激活账号验证记录
+    private function addVerify($userId, $token)
+    {
+        $verify = new Verify();
+        $verify->type = 1;
+        $verify->user_id = $userId;
+        $verify->token = $token;
+        $verify->status = 0;
+        $verify->save();
+    }
+
+    // 生成注册验证码
+    private function addVerifyCode($username, $code)
+    {
+        $verify = new VerifyCode();
+        $verify->username = $username;
+        $verify->code = $code;
+        $verify->status = 0;
+        $verify->save();
+    }
+}

+ 166 - 0
app/Http/Controllers/Controller.php

@@ -0,0 +1,166 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Models\ReferralLog;
+use App\Http\Models\SensitiveWords;
+use App\Http\Models\UserBalanceLog;
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
+use Illuminate\Foundation\Bus\DispatchesJobs;
+use Illuminate\Foundation\Validation\ValidatesRequests;
+use Illuminate\Routing\Controller as BaseController;
+
+class Controller extends BaseController
+{
+    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
+
+    // 生成随机密码
+    public function makePasswd()
+    {
+        exit(makeRandStr());
+    }
+
+    // 生成VmessId
+    public function makeVmessId()
+    {
+        exit(createGuid());
+    }
+
+    // 生成网站安全码
+    public function makeSecurityCode()
+    {
+        exit(strtolower(makeRandStr(8)));
+    }
+
+    // 类似Linux中的tail命令
+    public function tail($file, $n, $base = 5)
+    {
+        $fileLines = $this->countLine($file);
+        if ($fileLines < 15000) {
+            return false;
+        }
+
+        $fp = fopen($file, "r+");
+        assert($n > 0);
+        $pos = $n + 1;
+        $lines = [];
+        while (count($lines) <= $n) {
+            try {
+                fseek($fp, -$pos, SEEK_END);
+            } catch (\Exception $e) {
+                fseek(0);
+                break;
+            }
+
+            $pos *= $base;
+            while (!feof($fp)) {
+                array_unshift($lines, fgets($fp));
+            }
+        }
+
+        return array_slice($lines, 0, $n);
+    }
+
+    /**
+     * 计算文件行数
+     */
+    public function countLine($file)
+    {
+        $fp = fopen($file, "r");
+        $i = 0;
+        while (!feof($fp)) {
+            //每次读取2M
+            if ($data = fread($fp, 1024 * 1024 * 2)) {
+                //计算读取到的行数
+                $num = substr_count($data, "\n");
+                $i += $num;
+            }
+        }
+
+        fclose($fp);
+
+        return $i;
+    }
+
+    /**
+     * 记录余额操作日志
+     *
+     * @param int    $userId 用户ID
+     * @param string $oid    订单ID
+     * @param int    $before 记录前余额
+     * @param int    $after  记录后余额
+     * @param int    $amount 发生金额
+     * @param string $desc   描述
+     *
+     * @return int
+     */
+    public function addUserBalanceLog($userId, $oid, $before, $after, $amount, $desc = '')
+    {
+        $log = new UserBalanceLog();
+        $log->user_id = $userId;
+        $log->order_id = $oid;
+        $log->before = $before;
+        $log->after = $after;
+        $log->amount = $amount;
+        $log->desc = $desc;
+        $log->created_at = date('Y-m-d H:i:s');
+
+        return $log->save();
+    }
+
+    /**
+     * 添加返利日志
+     *
+     * @param int $userId    用户ID
+     * @param int $refUserId 返利用户ID
+     * @param int $oid       订单ID
+     * @param int $amount    发生金额
+     * @param int $refAmount 返利金额
+     *
+     * @return int
+     */
+    public function addReferralLog($userId, $refUserId, $oid, $amount, $refAmount)
+    {
+        $log = new ReferralLog();
+        $log->user_id = $userId;
+        $log->ref_user_id = $refUserId;
+        $log->order_id = $oid;
+        $log->amount = $amount;
+        $log->ref_amount = $refAmount;
+        $log->status = 0;
+
+        return $log->save();
+    }
+
+    // 获取敏感词
+    public function sensitiveWords()
+    {
+        return SensitiveWords::query()->get()->pluck('words')->toArray();
+    }
+
+    // 将Base64图片转换为本地图片并保存
+    function base64ImageSaver($base64_image_content)
+    {
+        // 匹配出图片的格式
+        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {
+            $type = $result[2];
+
+            $directory = date('Ymd');
+            $path = '/assets/images/qrcode/' . $directory . '/';
+            if (!file_exists(public_path($path))) { // 检查是否有该文件夹,如果没有就创建,并给予最高权限
+                mkdir(public_path($path), 0755, true);
+            }
+
+            $fileName = makeRandStr(18, true) . ".{$type}";
+            if (file_put_contents(public_path($path . $fileName), base64_decode(str_replace($result[1], '', $base64_image_content)))) {
+                chmod(public_path($path . $fileName), 0744);
+
+                return $path . $fileName;
+            } else {
+                return '';
+            }
+        } else {
+            return '';
+        }
+    }
+}

+ 182 - 0
app/Http/Controllers/CouponController.php

@@ -0,0 +1,182 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Models\Coupon;
+use DB;
+use Illuminate\Http\Request;
+use Log;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
+use Redirect;
+use Response;
+use Session;
+
+/**
+ * 优惠券控制器
+ *
+ * Class CouponController
+ *
+ * @package App\Http\Controllers
+ */
+class CouponController extends Controller
+{
+    // 优惠券列表
+    public function couponList(Request $request)
+    {
+        $view['couponList'] = Coupon::query()->orderBy('status', 'asc')->orderBy('id', 'desc')->paginate(10);
+
+        return Response::view('coupon.couponList', $view);
+    }
+
+    // 添加商品
+    public function addCoupon(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $this->validate($request, [
+                'name'            => 'required',
+                'type'            => 'required|integer|between:1,3',
+                'usage'           => 'required|integer|between:1,2',
+                'num'             => 'required|integer|min:1',
+                'amount'          => 'required_unless:type,2|numeric|min:0.01|nullable',
+                'discount'        => 'required_if:type,2|numeric|between:1,9.9|nullable',
+                'available_start' => 'required|date|before_or_equal:available_end',
+                'available_end'   => 'required|date|after_or_equal:available_start',
+            ], [
+                'name.required'                   => '请填入卡券名称',
+                'type.required'                   => '请选择卡券类型',
+                'type.integer'                    => '卡券类型不合法,请重选',
+                'type.between'                    => '卡券类型不合法,请重选',
+                'usage.required'                  => '请选择卡券用途',
+                'usage.integer'                   => '卡券用途不合法,请重选',
+                'usage.between'                   => '卡券用途不合法,请重选',
+                'num.required'                    => '请填写卡券数量',
+                'num.integer'                     => '卡券数量不合法',
+                'num.min'                         => '卡券数量不合法,最小1',
+                'amount.required_unless'          => '请填入卡券面值',
+                'amount.numeric'                  => '卡券金额不合法',
+                'amount.min'                      => '卡券金额不合法,最小0.01',
+                'discount.required_if'            => '请填入卡券折扣',
+                'discount.numeric'                => '卡券折扣不合法',
+                'discount.between'                => '卡券折扣不合法,有效范围:1 ~ 9.9',
+                'available_start.required'        => '请填入有效期',
+                'available_start.date'            => '有效期不合法',
+                'available_start.before_or_equal' => '有效期不合法',
+                'available_end.required'          => '请填入有效期',
+                'available_end.date'              => '有效期不合法',
+                'available_end.after_or_equal'    => '有效期不合法'
+            ]);
+
+            // 商品LOGO
+            $logo = '';
+            if ($request->hasFile('logo')) {
+                $file = $request->file('logo');
+                $fileType = $file->getClientOriginalExtension();
+
+                // 验证文件合法性
+                if (!in_array($fileType, ['jpg', 'png', 'jpeg', 'bmp'])) {
+                    return Redirect::back()->withInput()->withErrors('LOGO不合法');
+                }
+
+                $logoName = date('YmdHis') . mt_rand(1000, 2000) . '.' . $fileType;
+                $move = $file->move(base_path() . '/public/upload/image/', $logoName);
+                $logo = $move ? '/upload/image/' . $logoName : '';
+            }
+
+            DB::beginTransaction();
+            try {
+                for ($i = 0; $i < $request->num; $i++) {
+                    $obj = new Coupon();
+                    $obj->name = $request->name;
+                    $obj->sn = strtoupper(makeRandStr(7));
+                    $obj->logo = $logo;
+                    $obj->type = $request->type;
+                    $obj->usage = $request->usage;
+                    $obj->amount = empty($request->amount) ? 0 : $request->amount;
+                    $obj->discount = empty($request->discount) ? 0 : $request->discount;
+                    $obj->available_start = strtotime(date('Y-m-d 00:00:00', strtotime($request->available_start)));
+                    $obj->available_end = strtotime(date('Y-m-d 23:59:59', strtotime($request->available_end)));
+                    $obj->status = 0;
+                    $obj->save();
+                }
+
+                DB::commit();
+
+                return Redirect::back()->with('successMsg', '生成成功');
+            } catch (\Exception $e) {
+                DB::rollBack();
+
+                Log::error('生成优惠券失败:' . $e->getMessage());
+
+                return Redirect::back()->withInput()->withErrors('生成失败:' . $e->getMessage());
+            }
+        } else {
+            return Response::view('coupon.addCoupon');
+        }
+    }
+
+    // 删除优惠券
+    public function delCoupon(Request $request)
+    {
+        Coupon::query()->where('id', $request->input('id'))->delete();
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+    }
+
+    // 导出卡券
+    public function exportCoupon(Request $request)
+    {
+        $cashCouponList = Coupon::type(1)->where('status', 0)->get();
+        $discountCouponList = Coupon::type(2)->where('status', 0)->get();
+        $chargeCouponList = Coupon::type(3)->where('status', 0)->get();
+
+        $filename = '卡券' . date('Ymd') . '.xlsx';
+        $spreadsheet = new Spreadsheet();
+        $spreadsheet->getProperties()->setCreator('SSRPanel')->setLastModifiedBy('SSRPanel')->setTitle('邀请码')->setSubject('邀请码')->setDescription('')->setKeywords('')->setCategory('');
+
+        // 抵用券
+        $spreadsheet->setActiveSheetIndex(0);
+        $sheet = $spreadsheet->getActiveSheet();
+        $sheet->setTitle('抵用券');
+        $sheet->fromArray(['名称', '类型', '有效期', '券码', '面额(元)'], null);
+        foreach ($cashCouponList as $k => $vo) {
+            $usage = '仅限一次性使用';
+            $dateRange = date('Y-m-d', $vo->available_start) . ' ~ ' . date('Y-m-d', $vo->available_end);
+            $sheet->fromArray([$vo->name, $usage, $dateRange, $vo->sn, $vo->amount], null, 'A' . ($k + 2));
+        }
+
+        // 折扣券
+        $spreadsheet->createSheet(1);
+        $spreadsheet->setActiveSheetIndex(1);
+        $sheet = $spreadsheet->getActiveSheet();
+        $sheet->setTitle('折扣券');
+        $sheet->fromArray(['名称', '类型', '有效期', '券码', '折扣(折)'], null);
+        foreach ($discountCouponList as $k => $vo) {
+            $usage = $vo->usage == 1 ? '仅限一次性使用' : '可重复使用';
+            $dateRange = date('Y-m-d', $vo->available_start) . ' ~ ' . date('Y-m-d', $vo->available_end);
+            $sheet->fromArray([$vo->name, $usage, $dateRange, $vo->sn, $vo->discount], null, 'A' . ($k + 2));
+        }
+
+        // 充值券
+        $spreadsheet->createSheet(2);
+        $spreadsheet->setActiveSheetIndex(2);
+        $sheet = $spreadsheet->getActiveSheet();
+        $sheet->setTitle('充值券');
+        $sheet->fromArray(['名称', '类型', '有效期', '券码', '面额(元)'], null);
+        foreach ($chargeCouponList as $k => $vo) {
+            $usage = '仅限一次性使用';
+            $dateRange = date('Y-m-d', $vo->available_start) . ' ~ ' . date('Y-m-d', $vo->available_end);
+            $sheet->fromArray([$vo->name, $usage, $dateRange, $vo->sn, $vo->amount], null, 'A' . ($k + 2));
+        }
+
+        // 指针切换回第一个sheet
+        $spreadsheet->setActiveSheetIndex(0);
+
+        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); // 输出07Excel文件
+        //header('Content-Type:application/vnd.ms-excel'); // 输出Excel03版本文件
+        header('Content-Disposition: attachment;filename="' . $filename . '"');
+        header('Cache-Control: max-age=0');
+        $writer = new Xlsx($spreadsheet);
+        $writer->save('php://output');
+    }
+}

+ 107 - 0
app/Http/Controllers/MarketingController.php

@@ -0,0 +1,107 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\Helpers;
+use App\Http\Models\Marketing;
+use DB;
+use GuzzleHttp\Client;
+use Illuminate\Http\Request;
+use Log;
+use Response;
+
+/**
+ * 促销控制器
+ *
+ * Class MarketingController
+ *
+ * @package App\Http\Controllers
+ */
+class MarketingController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 邮件群发消息列表
+    public function emailList(Request $request)
+    {
+        $view['list'] = Marketing::query()->where('type', 1)->paginate(15);
+
+        return Response::view('marketing.emailList', $view);
+    }
+
+    // 消息通道群发列表
+    public function pushList(Request $request)
+    {
+        $status = $request->get('status');
+
+        $query = Marketing::query()->where('type', 2);
+
+        if ($status != '') {
+            $query->where('status', $status);
+        }
+
+        $view['list'] = $query->paginate(15);
+
+        return Response::view('marketing.pushList', $view);
+    }
+
+    // 添加推送消息
+    public function addPushMarketing(Request $request)
+    {
+        $title = trim($request->get('title'));
+        $content = $request->get('content');
+
+        if (!self::$systemConfig['is_push_bear']) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '推送失败:请先启用并配置PushBear']);
+        }
+
+        DB::beginTransaction();
+        try {
+            $client = new Client();
+            $response = $client->request('GET', 'https://pushbear.ftqq.com/sub', [
+                'query' => [
+                    'sendkey' => self::$systemConfig['push_bear_send_key'],
+                    'text'    => $title,
+                    'desp'    => $content
+                ]
+            ]);
+
+            $result = json_decode($response->getBody());
+            if ($result->code) { // 失败
+                $this->addMarketing(2, $title, $content, -1, $result->message);
+
+                throw new \Exception($result->message);
+            }
+
+            $this->addMarketing(2, $title, $content, 1);
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '推送成功']);
+        } catch (\Exception $e) {
+            Log::info('PushBear消息推送失败:' . $e->getMessage());
+
+            DB::rollBack();
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '推送失败:' . $e->getMessage()]);
+        }
+    }
+
+    private function addMarketing($type = 1, $title = '', $content = '', $status = 1, $error = '', $receiver = '')
+    {
+        $marketing = new Marketing();
+        $marketing->type = $type;
+        $marketing->receiver = $receiver;
+        $marketing->title = $title;
+        $marketing->content = $content;
+        $marketing->error = $error;
+        $marketing->status = $status;
+
+        return $marketing->save();
+    }
+}

+ 287 - 0
app/Http/Controllers/PaymentController.php

@@ -0,0 +1,287 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\AlipaySubmit;
+use App\Components\Helpers;
+use App\Components\Yzy;
+use App\Http\Models\Coupon;
+use App\Http\Models\Goods;
+use App\Http\Models\Order;
+use App\Http\Models\Payment;
+use App\Http\Models\PaymentCallback;
+use Auth;
+use DB;
+use Illuminate\Http\Request;
+use Log;
+use Payment\Client\Charge;
+use Response;
+use Validator;
+
+/**
+ * 支付控制器
+ *
+ * Class PaymentController
+ *
+ * @package App\Http\Controllers
+ */
+class PaymentController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 创建支付单
+    public function create(Request $request)
+    {
+        $goods_id = intval($request->get('goods_id'));
+        $coupon_sn = $request->get('coupon_sn');
+
+        $goods = Goods::query()->where('status', 1)->where('id', $goods_id)->first();
+        if (!$goods) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:商品或服务已下架']);
+        }
+
+        // 判断是否开启有赞云支付
+        if (!self::$systemConfig['is_youzan'] && !self::$systemConfig['is_alipay'] && !self::$systemConfig['is_f2fpay']) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:系统并未开启在线支付功能']);
+        }
+
+        // 判断是否存在同个商品的未支付订单
+        $existsOrder = Order::uid()->where('status', 0)->where('goods_id', $goods_id)->exists();
+        if ($existsOrder) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:尚有未支付的订单,请先去支付']);
+        }
+
+        // 限购控制
+        $strategy = self::$systemConfig['goods_purchase_limit_strategy'];
+        if ($strategy == 'all' || ($strategy == 'package' && $goods->type == 2) || ($strategy == 'free' && $goods->price == 0) || ($strategy == 'package&free' && ($goods->type == 2 || $goods->price == 0))) {
+            $noneExpireOrderExist = Order::uid()->where('status', '>=', 0)->where('is_expire', 0)->where('goods_id', $goods_id)->exists();
+            if ($noneExpireOrderExist) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:商品不可重复购买']);
+            }
+        }
+
+        // 单个商品限购
+        if ($goods->is_limit == 1) {
+            $noneExpireOrderExist = Order::uid()->where('status', '>=', 0)->where('goods_id', $goods_id)->exists();
+            if ($noneExpireOrderExist) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:此商品每人限购1次']);
+            }
+        }
+
+        // 使用优惠券
+        if ($coupon_sn) {
+            $coupon = Coupon::query()->where('status', 0)->whereIn('type', [1, 2])->where('sn', $coupon_sn)->first();
+            if (!$coupon) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:优惠券不存在']);
+            }
+
+            // 计算实际应支付总价
+            $amount = $coupon->type == 2 ? $goods->price * $coupon->discount / 10 : $goods->price - $coupon->amount;
+            $amount = $amount > 0 ? round($amount, 2) : 0; // 四舍五入保留2位小数,避免无法正常创建订单
+        } else {
+            $amount = $goods->price;
+        }
+
+        // 价格异常判断
+        if ($amount < 0) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:订单总价异常']);
+        } elseif ($amount == 0) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:订单总价为0,无需使用在线支付']);
+        }
+
+        // 验证账号是否存在有效期更长的套餐
+        if ($goods->type == 2) {
+            $existOrderList = Order::uid()
+                ->with(['goods'])
+                ->whereHas('goods', function ($q) {
+                    $q->where('type', 2);
+                })
+                ->where('is_expire', 0)
+                ->where('status', 2)
+                ->get();
+
+            foreach ($existOrderList as $vo) {
+                if ($vo->goods->days > $goods->days) {
+                    return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败:您已存在有效期更长的套餐,只能购买流量包']);
+                }
+            }
+        }
+
+        DB::beginTransaction();
+        try {
+            $orderSn = date('ymdHis') . mt_rand(100000, 999999);
+            $sn = makeRandStr(12);
+
+            // 支付方式
+            if (self::$systemConfig['is_youzan']) {
+                $pay_way = 2;
+            } elseif (self::$systemConfig['is_alipay']) {
+                $pay_way = 4;
+            } elseif (self::$systemConfig['is_f2fpay']) {
+                $pay_way = 5;
+            }
+
+            // 生成订单
+            $order = new Order();
+            $order->order_sn = $orderSn;
+            $order->user_id = Auth::user()->id;
+            $order->goods_id = $goods_id;
+            $order->coupon_id = !empty($coupon) ? $coupon->id : 0;
+            $order->origin_amount = $goods->price;
+            $order->amount = $amount;
+            $order->expire_at = date("Y-m-d H:i:s", strtotime("+" . $goods->days . " days"));
+            $order->is_expire = 0;
+            $order->pay_way = $pay_way;
+            $order->status = 0;
+            $order->save();
+
+            // 生成支付单
+            if (self::$systemConfig['is_youzan']) {
+                $yzy = new Yzy();
+                $result = $yzy->createQrCode($goods->name, $amount * 100, $orderSn);
+                if (isset($result['error_response'])) {
+                    Log::error('【有赞云】创建二维码失败:' . $result['error_response']['msg']);
+
+                    throw new \Exception($result['error_response']['msg']);
+                }
+            } elseif (self::$systemConfig['is_alipay']) {
+                $parameter = [
+                    "service"        => "create_forex_trade", // WAP:create_forex_trade_wap ,即时到帐:create_forex_trade
+                    "partner"        => self::$systemConfig['alipay_partner'],
+                    "notify_url"     => self::$systemConfig['website_url'] . "/api/alipay", // 异步回调接口
+                    "return_url"     => self::$systemConfig['website_url'],
+                    "out_trade_no"   => $orderSn,  // 订单号
+                    "subject"        => "Package", // 订单名称
+                    //"total_fee"      => $amount, // 金额
+                    "rmb_fee"        => $amount,   // 使用RMB标价,不再使用总金额
+                    "body"           => "",        // 商品描述,可为空
+                    "currency"       => self::$systemConfig['alipay_currency'], // 结算币种
+                    "product_code"   => "NEW_OVERSEAS_SELLER",
+                    "_input_charset" => "utf-8"
+                ];
+
+                // 建立请求
+                $alipaySubmit = new AlipaySubmit(self::$systemConfig['alipay_sign_type'], self::$systemConfig['alipay_partner'], self::$systemConfig['alipay_key'], self::$systemConfig['alipay_private_key']);
+                $result = $alipaySubmit->buildRequestForm($parameter, "post", "确认");
+            } elseif (self::$systemConfig['is_f2fpay']) {
+                // TODO:goods表里增加一个字段用于自定义商品付款时展示的商品名称,
+                // TODO:这里增加一个随机商品列表,根据goods的价格随机取值
+                $result = Charge::run("ali_qr", [
+                    'use_sandbox'     => false,
+                    "partner"         => self::$systemConfig['f2fpay_app_id'],
+                    'app_id'          => self::$systemConfig['f2fpay_app_id'],
+                    'sign_type'       => 'RSA2',
+                    'ali_public_key'  => self::$systemConfig['f2fpay_public_key'],
+                    'rsa_private_key' => self::$systemConfig['f2fpay_private_key'],
+                    'notify_url'      => self::$systemConfig['website_url'] . "/api/f2fpay", // 异步回调接口
+                    'return_url'      => self::$systemConfig['website_url'],
+                    'return_raw'      => false
+                ], [
+                    'body'     => '',
+                    'subject'  => self::$systemConfig['f2fpay_subject_name'],
+                    'order_no' => $orderSn,
+                    'amount'   => $amount,
+                ]);
+            }
+
+            $payment = new Payment();
+            $payment->sn = $sn;
+            $payment->user_id = Auth::user()->id;
+            $payment->oid = $order->oid;
+            $payment->order_sn = $orderSn;
+            $payment->pay_way = 1;
+            $payment->amount = $amount;
+            if (self::$systemConfig['is_youzan']) {
+                $payment->qr_id = $result['response']['qr_id'];
+                $payment->qr_url = $result['response']['qr_url'];
+                $payment->qr_code = $result['response']['qr_code'];
+                $payment->qr_local_url = $this->base64ImageSaver($result['response']['qr_code']);
+            } elseif (self::$systemConfig['is_alipay']) {
+                $payment->qr_code = $result;
+            } elseif (self::$systemConfig['is_f2fpay']) {
+                $payment->qr_code = $result;
+                $payment->qr_url = 'http://qr.topscan.com/api.php?text=' . $result . '&bg=ffffff&fg=000000&pt=1c73bd&m=10&w=400&el=1&inpt=1eabfc&logo=https://t.alipayobjects.com/tfscom/T1Z5XfXdxmXXXXXXXX.png';
+                $payment->qr_local_url = $payment->qr_url;
+            }
+            $payment->status = 0;
+            $payment->save();
+
+            // 优惠券置为已使用
+            if (!empty($coupon)) {
+                if ($coupon->usage == 1) {
+                    $coupon->status = 1;
+                    $coupon->save();
+                }
+
+                Helpers::addCouponLog($coupon->id, $goods_id, $order->oid, '在线支付使用');
+            }
+
+            DB::commit();
+
+            if (self::$systemConfig['is_alipay']) { // Alipay返回支付信息
+                return Response::json(['status' => 'success', 'data' => $result, 'message' => '创建订单成功,正在转到付款页面,请稍后']);
+            } else {
+                return Response::json(['status' => 'success', 'data' => $sn, 'message' => '创建订单成功,正在转到付款页面,请稍后']);
+            }
+        } catch (\Exception $e) {
+            DB::rollBack();
+
+            Log::error('创建支付订单失败:' . $e->getMessage());
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建订单失败:' . $e->getMessage()]);
+        }
+    }
+
+    // 支付单详情
+    public function detail(Request $request, $sn)
+    {
+        $view['payment'] = Payment::uid()->with(['order', 'order.goods'])->where('sn', $sn)->firstOrFail();
+
+        return Response::view('payment.detail', $view);
+    }
+
+    // 获取订单支付状态
+    public function getStatus(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'sn' => 'required|exists:payment,sn'
+        ], [
+            'sn.required' => '请求失败:缺少sn',
+            'sn.exists'   => '支付失败:支付单不存在'
+        ]);
+
+        if ($validator->fails()) {
+            return Response::json(['status' => 'error', 'data' => '', 'message' => $validator->getMessageBag()->first()]);
+        }
+
+        $payment = Payment::uid()->where('sn', $request->sn)->first();
+        if ($payment->status > 0) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '支付成功']);
+        } elseif ($payment->status < 0) {
+            return Response::json(['status' => 'error', 'data' => '', 'message' => '订单超时未支付,已自动关闭']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '等待支付']);
+        }
+    }
+
+    // 回调日志
+    public function callbackList(Request $request)
+    {
+        $status = $request->get('status', 0);
+
+        $query = PaymentCallback::query();
+
+        if ($status) {
+            $query->where('status', $status);
+        }
+
+        $view['list'] = $query->orderBy('id', 'desc')->paginate(10);
+
+        return Response::view('payment.callbackList', $view);
+    }
+}

+ 62 - 0
app/Http/Controllers/SensitiveWordsController.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Models\SensitiveWords;
+use Illuminate\Http\Request;
+use Response;
+use Validator;
+
+/**
+ * 敏感词管理控制器
+ *
+ * Class SensitiveWordsController
+ *
+ * @package App\Http\Controllers
+ */
+class SensitiveWordsController extends Controller
+{
+    // 敏感词列表
+    public function sensitiveWordsList(Request $request)
+    {
+        $view['list'] = SensitiveWords::query()->orderBy('id', 'desc')->paginate(15);
+
+        return Response::view('sensitiveWords.sensitiveWordsList', $view);
+    }
+
+    // 添加敏感词
+    public function addSensitiveWords(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'words' => 'required|unique:sensitive_words'
+        ], [
+            'words.required' => '添加失败:请填写敏感词',
+            'words.unique'   => '添加失败:敏感词已存在'
+        ]);
+
+        if ($validator->fails()) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => $validator->getMessageBag()->first()]);
+        }
+
+        $obj = new SensitiveWords();
+        $obj->words = strtolower($request->words);
+        $obj->save();
+        if ($obj->id) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '添加成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '添加失败']);
+        }
+    }
+
+    // 删除敏感词
+    public function delSensitiveWords(Request $request)
+    {
+        $result = SensitiveWords::query()->where('id', $request->id)->delete();
+        if ($result) {
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '删除失败']);
+        }
+    }
+
+}

+ 253 - 0
app/Http/Controllers/ShopController.php

@@ -0,0 +1,253 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Models\Goods;
+use App\Http\Models\GoodsLabel;
+use App\Http\Models\Label;
+use DB;
+use Illuminate\Http\Request;
+use Log;
+use Redirect;
+use Response;
+use Session;
+
+/**
+ * 商店控制器
+ *
+ * Class ShopController
+ *
+ * @package App\Http\Controllers
+ */
+class ShopController extends Controller
+{
+    // 商品列表
+    public function goodsList(Request $request)
+    {
+        $view['goodsList'] = Goods::query()->orderBy('id', 'desc')->paginate(10);
+
+        return Response::view('shop.goodsList', $view);
+    }
+
+    // 添加商品
+    public function addGoods(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $this->validate($request, [
+                'name'    => 'required',
+                'traffic' => 'required_unless:type,3|integer|min:1024|max:10240000|nullable',
+                'price'   => 'required|numeric|min:0',
+                'type'    => 'required',
+                'days'    => 'required|integer',
+            ], [
+                'name.required'           => '请填入名称',
+                'traffic.required_unless' => '请填入流量',
+                'traffic.integer'         => '内含流量必须是整数值',
+                'traffic.min'             => '内含流量不能低于1MB',
+                'traffic.max'             => '内含流量不能超过10TB',
+                'price.required'          => '请填入价格',
+                'price.numeric'           => '价格不合法',
+                'price.min'               => '价格最低0',
+                'type.required'           => '请选择类型',
+                'days.required'           => '请填入有效期',
+                'days.integer'            => '有效期不合法',
+            ]);
+
+            // 套餐必须有价格
+            if ($request->type == 2 && $request->price <= 0) {
+                return Redirect::back()->withInput()->withErrors('套餐价格必须大于0');
+            }
+
+            // 套餐有效天数必须大于30天
+            if ($request->type == 2 && $request->days < 30) {
+                return Redirect::back()->withInput()->withErrors('套餐有效天数必须不能少于30天');
+            }
+
+            // 商品LOGO
+            $logo = '';
+            if ($request->hasFile('logo')) {
+                $file = $request->file('logo');
+                $fileType = $file->getClientOriginalExtension();
+
+                // 验证文件合法性
+                if (!in_array($fileType, ['jpg', 'png', 'jpeg', 'bmp'])) {
+                    return Redirect::back()->withInput()->withErrors('LOGO不合法');
+                }
+
+                $logoName = date('YmdHis') . mt_rand(1000, 2000) . '.' . $fileType;
+                $move = $file->move(base_path() . '/public/upload/image/', $logoName);
+                $logo = $move ? '/upload/image/' . $logoName : '';
+            }
+
+            DB::beginTransaction();
+            try {
+                $goods = new Goods();
+                $goods->name = $request->name;
+                $goods->info = $request->$info;
+                $goods->desc = $request->desc;
+                $goods->logo = $logo;
+                $goods->traffic = $request->traffic;
+                $goods->price = round($request->price, 2);
+                $goods->type = $request->type;
+                $goods->days = $request->days;
+                $goods->color = $request->color;
+                $goods->sort = intval($request->sort);
+                $goods->is_hot = intval($request->is_hot);
+                $goods->is_limit = intval($request->is_limit);
+                $goods->status = $request->status;
+                $goods->save();
+
+                // 生成SKU
+                $goods->sku = 'S0000' . $goods->id;
+                $goods->save();
+
+                // 生成商品标签
+                $labels = $request->get('labels');
+                if (!empty($labels)) {
+                    foreach ($labels as $label) {
+                        $goodsLabel = new GoodsLabel();
+                        $goodsLabel->goods_id = $goods->id;
+                        $goodsLabel->label_id = $label;
+                        $goodsLabel->save();
+                    }
+                }
+
+                DB::commit();
+
+                return Redirect::back()->with('successMsg', '添加成功');
+            } catch (\Exception $e) {
+                DB::rollBack();
+                Log::info($e);
+
+                return Redirect::back()->withInput()->withErrors('添加失败');
+            }
+        } else {
+            $view['label_list'] = Label::query()->orderBy('sort', 'desc')->orderBy('id', 'asc')->get();
+
+            return Response::view('shop.addGoods', $view);
+        }
+    }
+
+    // 编辑商品
+    public function editGoods(Request $request)
+    {
+        $id = $request->get('id');
+
+        if ($request->isMethod('POST')) {
+            $name = $request->get('name');
+            $info = $request->get('info', '');
+            $desc = $request->get('desc');
+            $price = round($request->get('price'), 2);
+            $labels = $request->get('labels');
+            $color = trim($request->get('color', 0));
+            $sort = intval($request->get('sort', 0));
+            $is_hot = intval($request->get('is_hot', 0));
+            $is_limit = intval($request->get('is_limit', 0));
+            $status = $request->get('status');
+
+            $goods = Goods::query()->where('id', $id)->first();
+            if (!$goods) {
+                Session::flash('errorMsg', '商品不存在');
+
+                return Redirect::back();
+            }
+
+            if (empty($name)) {
+                Session::flash('errorMsg', '请填写完整');
+
+                return Redirect::back()->withInput();
+            }
+
+            // 套餐必须有价格
+            if ($goods->type == 2 && $price <= 0) {
+                Session::flash('errorMsg', '套餐价格必须大于0');
+
+                return Redirect::back()->withInput();
+            }
+
+            // 商品LOGO
+            $logo = '';
+            if ($request->hasFile('logo')) {
+                $file = $request->file('logo');
+                $fileType = $file->getClientOriginalExtension();
+
+                // 验证文件合法性
+                if (!in_array($fileType, ['jpg', 'png', 'jpeg', 'bmp'])) {
+                    Session::flash('errorMsg', 'LOGO不合法');
+
+                    return Redirect::back()->withInput();
+                }
+
+                $logoName = date('YmdHis') . mt_rand(1000, 2000) . '.' . $fileType;
+                $move = $file->move(base_path() . '/public/upload/image/', $logoName);
+                $logo = $move ? '/upload/image/' . $logoName : '';
+            }
+
+            DB::beginTransaction();
+            try {
+                $data = [
+                    'name'     => $name,
+                    'info'     => $info,
+                    'desc'     => $desc,
+                    'price'    => $price * 100,
+                    'sort'     => $sort,
+                    'color'    => $color,
+                    'is_hot'   => $is_hot,
+                    'is_limit' => $is_limit,
+                    'status'   => $status
+                ];
+
+                if ($logo) {
+                    $data['logo'] = $logo;
+                }
+
+                Goods::query()->where('id', $id)->update($data);
+
+                // 先删除该商品所有的标签
+                GoodsLabel::query()->where('goods_id', $id)->delete();
+
+                // 生成商品标签
+                if (!empty($labels)) {
+                    foreach ($labels as $label) {
+                        $goodsLabel = new GoodsLabel();
+                        $goodsLabel->goods_id = $id;
+                        $goodsLabel->label_id = $label;
+                        $goodsLabel->save();
+                    }
+                }
+
+                Session::flash('successMsg', '编辑成功');
+
+                DB::commit();
+            } catch (\Exception $e) {
+                Session::flash('errorMsg', '编辑失败');
+
+                DB::rollBack();
+            }
+
+            return Redirect::to('shop/editGoods?id=' . $id);
+        } else {
+            $goods = Goods::query()->with(['label'])->where('id', $id)->first();
+            if ($goods) {
+                $label = [];
+                foreach ($goods->label as $vo) {
+                    $label[] = $vo->label_id;
+                }
+                $goods->labels = $label;
+            }
+
+            $view['goods'] = $goods;
+            $view['label_list'] = Label::query()->orderBy('sort', 'desc')->orderBy('id', 'asc')->get();
+
+            return Response::view('shop.editGoods', $view);
+        }
+    }
+
+    // 删除商品
+    public function delGoods(Request $request)
+    {
+        Goods::query()->where('id', $request->input('id'))->delete();
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '删除成功']);
+    }
+}

+ 281 - 0
app/Http/Controllers/SubscribeController.php

@@ -0,0 +1,281 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\Helpers;
+use App\Http\Models\Device;
+use App\Http\Models\SsGroup;
+use App\Http\Models\SsNode;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Http\Models\UserSubscribe;
+use App\Http\Models\UserSubscribeLog;
+use Illuminate\Http\Request;
+use Redirect;
+use Response;
+
+/**
+ * 订阅控制器
+ *
+ * Class SubscribeController
+ *
+ * @package App\Http\Controllers
+ */
+class SubscribeController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 订阅码列表
+    public function subscribeList(Request $request)
+    {
+        $user_id = $request->input('user_id');
+        $username = $request->input('username');
+        $status = $request->input('status');
+
+        $query = UserSubscribe::with(['User']);
+
+        if (!empty($user_id)) {
+            $query->where('user_id', $user_id);
+        }
+
+        if (!empty($username)) {
+            $query->whereHas('user', function ($q) use ($username) {
+                $q->where('username', 'like', '%' . $username . '%');
+            });
+        }
+
+        if ($status != '') {
+            $query->where('status', intval($status));
+        }
+
+        $view['subscribeList'] = $query->orderBy('id', 'desc')->paginate(20)->appends($request->except('page'));
+
+        return Response::view('subscribe.subscribeList', $view);
+    }
+
+    // 订阅设备列表
+    public function deviceList(Request $request)
+    {
+        $type = $request->input('type');
+        $platform = $request->input('platform');
+        $name = trim($request->input('name'));
+        $status = $request->input('status');
+
+        $query = Device::query();
+
+        if (!empty($type)) {
+            $query->where('type', $type);
+        }
+
+        if ($platform != '') {
+            $query->where('platform', $platform);
+        }
+
+        if (!empty($name)) {
+            $query->where('name', 'like', '%' . $name . '%');
+        }
+
+        if ($status != '') {
+            $query->where('status', $status);
+        }
+
+        $view['deviceList'] = $query->paginate(20)->appends($request->except('page'));
+
+        return Response::view('subscribe.deviceList', $view);
+    }
+
+    // 设置用户的订阅的状态
+    public function setSubscribeStatus(Request $request)
+    {
+        $id = $request->get('id');
+        $status = $request->get('status', 0);
+
+        if (empty($id)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '操作异常']);
+        }
+
+        if ($status) {
+            UserSubscribe::query()->where('id', $id)->update(['status' => 1, 'ban_time' => 0, 'ban_desc' => '']);
+        } else {
+            UserSubscribe::query()->where('id', $id)->update(['status' => 0, 'ban_time' => time(), 'ban_desc' => '后台手动封禁']);
+        }
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+    }
+
+    // 设置设备是否允许订阅的状态
+    public function setDeviceStatus(Request $request)
+    {
+        $id = $request->input('id');
+        $status = $request->input('status', 0);
+
+        if (empty($id)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '操作异常']);
+        }
+
+        Device::query()->where('id', $id)->update(['status' => $status]);
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '操作成功']);
+    }
+
+    // 通过订阅码获取订阅信息
+    public function getSubscribeByCode(Request $request, $code)
+    {
+        // 校验合法性
+        $subscribe = UserSubscribe::query()->with('user')->where('status', 1)->where('code', $code)->first();
+        if (!$subscribe) {
+            exit($this->noneNode());
+        }
+
+        $user = User::query()->whereIn('status', [0, 1])->where('enable', 1)->where('id', $subscribe->user_id)->first();
+        if (!$user) {
+            exit($this->noneNode());
+        }
+
+        // 更新访问次数
+        $subscribe->increment('times', 1);
+
+        // 记录每次请求
+        $this->log($subscribe->id, getClientIp(), $request->headers);
+
+        // 获取这个账号可用节点
+        $userLabelIds = UserLabel::query()->where('user_id', $user->id)->pluck('label_id');
+        if (empty($userLabelIds)) {
+            exit($this->noneNode());
+        }
+
+        $query = SsNode::query()->selectRaw('ss_node.*')->leftjoin("ss_node_label", "ss_node.id", "=", "ss_node_label.node_id");
+
+        // 启用混合订阅时,加入V2Ray节点,未启用时仅下发SSR节点信息
+        if (!self::$systemConfig['mix_subscribe']) {
+            $query->where('ss_node.type', 1);
+        }
+
+        $nodeList = $query->where('ss_node.status', 1)->where('ss_node.is_subscribe', 1)->whereIn('ss_node_label.label_id', $userLabelIds)->groupBy('ss_node.id')->orderBy('ss_node.sort', 'desc')->orderBy('ss_node.id', 'asc')->get()->toArray();
+        if (empty($nodeList)) {
+            exit($this->noneNode());
+        }
+
+        // 打乱数组
+        if (self::$systemConfig['rand_subscribe']) {
+            shuffle($nodeList);
+        }
+
+        // 控制客户端最多获取节点数
+        $scheme = '';
+
+        // 展示到期时间和剩余流量
+        if (self::$systemConfig['is_custom_subscribe']) {
+            $scheme .= $this->expireDate($user);
+            $scheme .= $this->lastTraffic($user);
+        }
+
+        foreach ($nodeList as $key => $node) {
+            // 控制显示的节点数
+            if (self::$systemConfig['subscribe_max'] && $key >= self::$systemConfig['subscribe_max']) {
+                break;
+            }
+
+            // 获取分组名称
+            if ($node['type'] == 1) {
+                $group = SsGroup::query()->where('id', $node['group_id'])->first();
+
+                $obfs_param = $user->obfs_param ? $user->obfs_param : $node['obfs_param'];
+                $protocol_param = $node['single'] ? $user->port . ':' . $user->passwd : $user->protocol_param;
+
+                // 生成ssr scheme
+                $ssr_str = ($node['server'] ? $node['server'] : $node['ip']) . ':' . ($node['single'] ? $node['single_port'] : $user->port);
+                $ssr_str .= ':' . ($node['single'] ? $node['single_protocol'] : $user->protocol) . ':' . ($node['single'] ? $node['single_method'] : $user->method);
+                $ssr_str .= ':' . ($node['single'] ? $node['single_obfs'] : $user->obfs) . ':' . ($node['single'] ? base64url_encode($node['single_passwd']) : base64url_encode($user->passwd));
+                $ssr_str .= '/?obfsparam=' . base64url_encode($obfs_param);
+                $ssr_str .= '&protoparam=' . ($node['single'] ? base64url_encode($user->port . ':' . $user->passwd) : base64url_encode($protocol_param));
+                $ssr_str .= '&remarks=' . base64url_encode($node['name']);
+                $ssr_str .= '&group=' . base64url_encode(empty($group) ? Helpers::systemConfig()['website_name'] : $group->name);
+                $ssr_str .= '&udpport=0';
+                $ssr_str .= '&uot=0';
+                $ssr_str = base64url_encode($ssr_str);
+                $scheme .= 'ssr://' . $ssr_str . "\n";
+            } else {
+                // 生成v2ray scheme
+                $v2_json = [
+                    "v"    => "2",
+                    "ps"   => $node['name'],
+                    "add"  => $node['server'] ? $node['server'] : $node['ip'],
+                    "port" => $node['v2_port'],
+                    "id"   => $user->vmess_id,
+                    "aid"  => $node['v2_alter_id'],
+                    "net"  => $node['v2_net'],
+                    "type" => $node['v2_type'],
+                    "host" => $node['v2_host'],
+                    "path" => $node['v2_path'],
+                    "tls"  => $node['v2_tls'] ? "tls" : ""
+                ];
+
+                $scheme .= 'vmess://' . base64url_encode(json_encode($v2_json, JSON_PRETTY_PRINT)) . "\n";
+            }
+        }
+
+        // 适配Quantumult的自定义订阅头
+        if (self::$systemConfig['is_custom_subscribe']) {
+            $headers = [
+                'Content-type'          => 'application/octet-stream; charset=utf-8',
+                'Cache-Control'         => 'no-store, no-cache, must-revalidate',
+                'Subscription-Userinfo' => 'upload=' . $user->u . '; download=' . $user->d . '; total=' . $user->transfer_enable . '; expire=' . strtotime($user->expire_time)
+            ];
+
+            return Response::make(base64url_encode($scheme), 200, $headers);
+        } else {
+            return Response::make(base64url_encode($scheme));
+        }
+    }
+
+    // 写入订阅访问日志
+    private function log($subscribeId, $ip, $headers)
+    {
+        $log = new UserSubscribeLog();
+        $log->sid = $subscribeId;
+        $log->request_ip = $ip;
+        $log->request_time = date('Y-m-d H:i:s');
+        $log->request_header = $headers;
+        $log->save();
+    }
+
+    // 抛出无可用的节点信息,用于兼容防止客户端订阅失败
+    private function noneNode()
+    {
+        return base64url_encode('ssr://' . base64url_encode('0.0.0.0:1:origin:none:plain:' . base64url_encode('0000') . '/?obfsparam=&protoparam=&remarks=' . base64url_encode('无可用节点或账号被封禁或订阅被封禁') . '&group=' . base64url_encode('错误') . '&udpport=0&uot=0') . "\n");
+    }
+
+    /**
+     * 过期时间
+     *
+     * @param object $user
+     *
+     * @return string
+     */
+    private function expireDate($user)
+    {
+        $text = '到期时间:' . $user->expire_time;
+
+        return 'ssr://' . base64url_encode('0.0.0.1:1:origin:none:plain:' . base64url_encode('0000') . '/?obfsparam=&protoparam=&remarks=' . base64url_encode($text) . '&group=' . base64url_encode(Helpers::systemConfig()['website_name']) . '&udpport=0&uot=0') . "\n";
+    }
+
+    /**
+     * 剩余流量
+     *
+     * @param object $user
+     *
+     * @return string
+     */
+    private function lastTraffic($user)
+    {
+        $text = '剩余流量:' . flowAutoShow($user->transfer_enable - $user->u - $user->d);
+
+        return 'ssr://' . base64url_encode('0.0.0.2:1:origin:none:plain:' . base64url_encode('0000') . '/?obfsparam=&protoparam=&remarks=' . base64url_encode($text) . '&group=' . base64url_encode(Helpers::systemConfig()['website_name']) . '&udpport=0&uot=0') . "\n";
+    }
+}

+ 120 - 0
app/Http/Controllers/TicketController.php

@@ -0,0 +1,120 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\Helpers;
+use App\Components\ServerChan;
+use App\Http\Models\Ticket;
+use App\Http\Models\TicketReply;
+use App\Mail\closeTicket;
+use App\Mail\replyTicket;
+use Auth;
+use Illuminate\Http\Request;
+use Mail;
+use Response;
+
+/**
+ * 工单控制器
+ *
+ * Class TicketController
+ *
+ * @package App\Http\Controllers
+ */
+class TicketController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    // 工单列表
+    public function ticketList(Request $request)
+    {
+        $view['ticketList'] = Ticket::query()->orderBy('id', 'desc')->paginate(10);
+
+        return Response::view('ticket.ticketList', $view);
+    }
+
+    // 回复工单
+    public function replyTicket(Request $request)
+    {
+        $id = $request->input('id');
+
+        if ($request->isMethod('POST')) {
+            $content = clean($request->input('content'));
+            $content = str_replace("eval", "", str_replace("atob", "", $content));
+            $content = substr($content, 0, 300);
+
+            $obj = new TicketReply();
+            $obj->ticket_id = $id;
+            $obj->user_id = Auth::user()->id;
+            $obj->content = $content;
+            $obj->save();
+
+            if ($obj->id) {
+                // 将工单置为已回复
+                $ticket = Ticket::query()->with(['user'])->where('id', $id)->first();
+                $ticket->status = 1;
+                $ticket->save();
+
+
+                $title = "工单回复提醒";
+                $content = "标题:" . $ticket->title . "<br>管理员回复:" . $content;
+
+                // 发通知邮件
+                if (!Auth::user()->is_admin) {
+                    if (self::$systemConfig['crash_warning_email']) {
+                        $logId = Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $title, $content);
+                        Mail::to(self::$systemConfig['crash_warning_email'])->send(new replyTicket($logId, $title, $content));
+                    }
+                } else {
+                    $logId = Helpers::addEmailLog($ticket->user->username, $title, $content);
+                    Mail::to($ticket->user->username)->send(new replyTicket($logId, $title, $content));
+                }
+
+                // 通过ServerChan发微信消息提醒管理员
+                if (!Auth::user()->is_admin) {
+                    ServerChan::send($title, $content);
+                }
+
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '回复成功']);
+            } else {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '回复失败']);
+            }
+        } else {
+            $view['ticket'] = Ticket::query()->where('id', $id)->with('user')->first();
+            $view['replyList'] = TicketReply::query()->where('ticket_id', $id)->with('user')->orderBy('id', 'asc')->get();
+
+            return Response::view('ticket.replyTicket', $view);
+        }
+    }
+
+    // 关闭工单
+    public function closeTicket(Request $request)
+    {
+        $id = $request->input('id');
+
+        $ticket = Ticket::query()->with(['user'])->where('id', $id)->first();
+        if (!$ticket) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '关闭失败']);
+        }
+
+        $ticket->status = 2;
+        $ret = $ticket->save();
+        if (!$ret) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '关闭失败']);
+        }
+
+        $title = "工单关闭提醒";
+        $content = "工单【" . $ticket->title . "】已关闭";
+
+        // 发邮件通知用户
+        $logId = Helpers::addEmailLog($ticket->user->username, $title, $content);
+        Mail::to($ticket->user->username)->send(new closeTicket($logId, $title, $content));
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '关闭成功']);
+    }
+
+}

+ 953 - 0
app/Http/Controllers/UserController.php

@@ -0,0 +1,953 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Components\Helpers;
+use App\Components\ServerChan;
+use App\Http\Models\Article;
+use App\Http\Models\Coupon;
+use App\Http\Models\Goods;
+use App\Http\Models\GoodsLabel;
+use App\Http\Models\Invite;
+use App\Http\Models\Level;
+use App\Http\Models\Order;
+use App\Http\Models\ReferralApply;
+use App\Http\Models\ReferralLog;
+use App\Http\Models\SsGroup;
+use App\Http\Models\SsNodeInfo;
+use App\Http\Models\SsNodeLabel;
+use App\Http\Models\Ticket;
+use App\Http\Models\TicketReply;
+use App\Http\Models\User;
+use App\Http\Models\UserLabel;
+use App\Http\Models\UserLoginLog;
+use App\Http\Models\UserSubscribe;
+use App\Http\Models\UserTrafficDaily;
+use App\Http\Models\UserTrafficHourly;
+use App\Mail\newTicket;
+use App\Mail\replyTicket;
+use Auth;
+use Cache;
+use DB;
+use Exception;
+use Hash;
+use Illuminate\Http\Request;
+use Log;
+use Mail;
+use Redirect;
+use Response;
+use Session;
+use Validator;
+
+/**
+ * 用户控制器
+ *
+ * Class UserController
+ *
+ * @package App\Http\Controllers
+ */
+class UserController extends Controller
+{
+    protected static $systemConfig;
+
+    function __construct()
+    {
+        self::$systemConfig = Helpers::systemConfig();
+    }
+
+    public function index(Request $request)
+    {
+        $user = User::uid()->first();
+        $user->totalTransfer = flowAutoShow($user->transfer_enable);
+        $user->unusedTransfer = $user->transfer_enable - $user->u - $user->d > 0 ? $user->transfer_enable - $user->u - $user->d : 0;
+        $user->unusedPercent = $user->transfer_enable > 0 ? round($user->unusedTransfer / $user->transfer_enable, 2) : 0;
+        $user->unusedTransfer = flowAutoShow($user->unusedTransfer);
+        $user->levelName = Level::query()->where('level', $user['level'])->first()['level_name'];
+        $user->remainDays = date('Y-m-d') < $user->expire_time ? (strtotime($user->expire_time) - strtotime(date('Y-m-d'))) / 86400 : 0;
+        $user->resetDays = date('d') > $user->traffic_reset_day ? (strtotime($user->traffic_reset_day) - strtotime(date('Y-m-d'))) / 86400 : strtotime($user->traffic_reset_day);
+        $user_reset_day = $user->traffic_reset_day;
+        $last_day = date('t');
+        $today = date('d');
+        if ($user_reset_day > $today) {
+            $user->resetDays = $user_reset_day > $last_day ? $last_day - $today : $user_reset_day - $today;
+        } else {
+            $next_last_day = date('t', strtotime('next month'));
+            $user->resetDays = $user_reset_day > $next_last_day ? $last_day - $today + $next_last_day : $last_day - $today + $user_reset_day;
+        }
+        $view['info'] = $user->toArray();
+        $view['noticeList'] = Article::type(2)->orderBy('id', 'desc')->Paginate(1); // 公告
+        $view['userLoginLog'] = UserLoginLog::query()->where('user_id', Auth::user()->id)->orderBy('id', 'desc')->first(); // 近期登录日志
+        //流量异常判断
+        $hourlyTraffic = UserTrafficHourly::query()->where('user_id', $user->id)->where('node_id', 0)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900))->sum('total');
+        $view['isTrafficWarning'] = $hourlyTraffic < (self::$systemConfig['traffic_ban_value'] * 1073741824) ? 0 : 1;
+        //付费用户判断
+        $view['is_paying_user'] = Order::uid()->where('status', 2)->where('is_expire', 0)->where('origin_amount', '>', 0)->get()->isEmpty();
+
+
+        $dailyData = [];
+        $hourlyData = [];
+        // 节点一个月内的流量
+        $userTrafficDaily = UserTrafficDaily::query()->where('user_id', Auth::user()->id)->where('node_id', 0)->where('created_at', '>=', date('Y-m', time()))->orderBy('created_at', 'asc')->pluck('total')->toArray();
+
+        $dailyTotal = date('d') - 1; // 今天不算,减一
+        $dailyCount = count($userTrafficDaily);
+        for ($x = 0; $x < $dailyTotal - $dailyCount; $x++) {
+            $dailyData[$x] = 0;
+        }
+        for ($x = $dailyTotal - $dailyCount; $x < $dailyTotal; $x++) {
+            $dailyData[$x] = round($userTrafficDaily[$x - ($dailyTotal - $dailyCount)] / (1024 * 1024 * 1024), 3);
+        }
+
+        // 节点一天内的流量
+        $userTrafficHourly = UserTrafficHourly::query()->where('user_id', Auth::user()->id)->where('node_id', 0)->where('created_at', '>=', date('Y-m-d', time()))->orderBy('created_at', 'asc')->pluck('total')->toArray();
+        $hourlyTotal = date('H');
+        $hourlyCount = count($userTrafficHourly);
+        for ($x = 0; $x < $hourlyTotal - $hourlyCount; $x++) {
+            $hourlyData[$x] = 0;
+        }
+        for ($x = ($hourlyTotal - $hourlyCount); $x < $hourlyTotal; $x++) {
+            $hourlyData[$x] = round($userTrafficHourly[$x - ($hourlyTotal - $hourlyCount)] / (1024 * 1024 * 1024), 3);
+        }
+
+        // 本月天数数据
+        $monthDays = [];
+        for ($i = 1; $i <= date("d"); $i++) {
+            $monthDays[] = $i;
+        }
+        // 本日小时数据
+        $dayHours = [];
+        for ($i = 1; $i <= date("H"); $i++) {
+            $dayHours[] = $i;
+        }
+
+        $view['trafficDaily'] = "'" . implode("','", $dailyData) . "'";
+        $view['trafficHourly'] = "'" . implode("','", $hourlyData) . "'";
+        $view['monthDays'] = "'" . implode("','", $monthDays) . "'";
+        $view['dayHours'] = "'" . implode("','", $dayHours) . "'";
+        return Response::view('user.index', $view);
+    }
+
+    // 签到
+    public function checkIn(Request $request)
+    {
+        // 系统开启登录加积分功能才可以签到
+        if (!self::$systemConfig['is_checkin']) {
+            return Response::json(['status' => 'fail', 'message' => '系统未开启签到功能']);
+        }
+
+        // 已签到过,验证是否有效
+        if (Cache::has('userCheckIn_' . Auth::user()->id)) {
+            return Response::json(['status' => 'fail', 'message' => '已经签到过了,明天再来吧']);
+        }
+
+        $traffic = mt_rand(self::$systemConfig['min_rand_traffic'], self::$systemConfig['max_rand_traffic']);
+        $ret = User::uid()->increment('transfer_enable', $traffic * 1048576);
+        if (!$ret) {
+            return Response::json(['status' => 'fail', 'message' => '签到失败,系统异常']);
+        }
+
+        // 写入用户流量变动记录
+        Helpers::addUserTrafficModifyLog(Auth::user()->id, 0, Auth::user()->transfer_enable, Auth::user()->transfer_enable + $traffic * 1048576, '[签到]');
+
+        // 多久后可以再签到
+        $ttl = self::$systemConfig['traffic_limit_time'] ? self::$systemConfig['traffic_limit_time'] : 1440;
+        Cache::put('userCheckIn_' . Auth::user()->id, '1', $ttl);
+
+        return Response::json(['status' => 'success', 'message' => '签到成功,系统送您 ' . $traffic . 'M 流量']);
+    }
+
+    // 节点列表
+    public function nodeList(Request $request)
+    {
+    // 节点列表
+        $userLabelIds = UserLabel::uid()->pluck('label_id');
+        if (empty($userLabelIds)) {
+            $view['nodeList'] = [];
+            $view['allNodes'] = '';
+
+            return Response::view('user.nodeList', $view);
+        }
+
+        // 获取当前用户可用节点
+        $nodeList = DB::table('ss_node')
+            ->selectRaw('ss_node.*')
+            ->leftJoin('ss_node_label', 'ss_node.id', '=', 'ss_node_label.node_id')
+            ->whereIn('ss_node_label.label_id', $userLabelIds)
+            ->where('ss_node.status', 1)
+            ->groupBy('ss_node.id')
+            ->orderBy('ss_node.sort', 'desc')
+            ->orderBy('ss_node.id', 'asc')
+            ->get();
+
+        $allNodes = ''; // 全部节点SSR链接,用于一键复制所有节点
+        foreach ($nodeList as &$node) {
+            // 获取分组名称
+            $group = SsGroup::query()->where('id', $node->group_id)->first();
+
+            if ($node->type == 1) {
+                // 生成ssr scheme
+                $obfs_param = Auth::user()->obfs_param ? Auth::user()->obfs_param : $node->obfs_param;
+                $protocol_param = $node->single ? Auth::user()->port . ':' . Auth::user()->passwd : Auth::user()->protocol_param;
+
+                $ssr_str = ($node->server ? $node->server : $node->ip) . ':' . ($node->single ? $node->single_port : Auth::user()->port);
+                $ssr_str .= ':' . ($node->single ? $node->single_protocol : Auth::user()->protocol) . ':' . ($node->single ? $node->single_method : Auth::user()->method);
+                $ssr_str .= ':' . ($node->single ? $node->single_obfs : Auth::user()->obfs) . ':' . ($node->single ? base64url_encode($node->single_passwd) : base64url_encode(Auth::user()->passwd));
+                $ssr_str .= '/?obfsparam=' . base64url_encode($obfs_param);
+                $ssr_str .= '&protoparam=' . ($node->single ? base64url_encode(Auth::user()->port . ':' . Auth::user()->passwd) : base64url_encode($protocol_param));
+                $ssr_str .= '&remarks=' . base64url_encode($node->name);
+                $ssr_str .= '&group=' . base64url_encode(empty($group) ? '' : $group->name);
+                $ssr_str .= '&udpport=0';
+                $ssr_str .= '&uot=0';
+                $ssr_str = base64url_encode($ssr_str);
+                $ssr_scheme = 'ssr://' . $ssr_str;
+
+                // 生成ss scheme
+                $ss_str = Auth::user()->method . ':' . Auth::user()->passwd . '@';
+                $ss_str .= ($node->server ? $node->server : $node->ip) . ':' . Auth::user()->port;
+                $ss_str = base64url_encode($ss_str) . '#' . 'VPN';
+                $ss_scheme = 'ss://' . $ss_str;
+
+                // 生成文本配置信息
+                $txt = "服务器:" . ($node->server ? $node->server : $node->ip) . PHP_EOL;
+                if ($node->ipv6) {
+                    $txt .= "IPv6:" . $node->ipv6 . PHP_EOL;
+                }
+                $txt .= "远程端口:" . ($node->single ? $node->single_port : Auth::user()->port) . PHP_EOL;
+                $txt .= "密码:" . ($node->single ? $node->single_passwd : Auth::user()->passwd) . PHP_EOL;
+                $txt .= "加密方法:" . ($node->single ? $node->single_method : Auth::user()->method) . PHP_EOL;
+                $txt .= "路由:绕过局域网及中国大陆地址" . PHP_EOL . PHP_EOL;
+                $txt .= "协议:" . ($node->single ? $node->single_protocol : Auth::user()->protocol) . PHP_EOL;
+                $txt .= "协议参数:" . ($node->single ? Auth::user()->port . ':' . Auth::user()->passwd : Auth::user()->protocol_param) . PHP_EOL;
+                $txt .= "混淆方式:" . ($node->single ? $node->single_obfs : Auth::user()->obfs) . PHP_EOL;
+                $txt .= "混淆参数:" . (Auth::user()->obfs_param ? Auth::user()->obfs_param : $node->obfs_param) . PHP_EOL;
+                $txt .= "本地端口:1080" . PHP_EOL;
+
+                $node->txt = $txt;
+                $node->ssr_scheme = $ssr_scheme;
+                $node->ss_scheme = $node->compatible ? $ss_scheme : ''; // 节点兼容原版才显示
+
+                $allNodes .= $ssr_scheme . '|';
+            } else {
+                // 生成v2ray scheme
+                $v2_json = [
+                    "v"    => "2",
+                    "ps"   => $node->name,
+                    "add"  => $node->server ? $node->server : $node->ip,
+                    "port" => $node->v2_port,
+                    "id"   => Auth::user()->vmess_id,
+                    "aid"  => $node->v2_alter_id,
+                    "net"  => $node->v2_net,
+                    "type" => $node->v2_type,
+                    "host" => $node->v2_host,
+                    "path" => $node->v2_path,
+                    "tls"  => $node->v2_tls == 1 ? "tls" : ""
+                ];
+                $v2_scheme = 'vmess://' . base64url_encode(json_encode($v2_json, JSON_PRETTY_PRINT));
+
+                // 生成文本配置信息
+                $txt = "服务器:" . ($node->server ? $node->server : $node->ip) . PHP_EOL;
+                if ($node->ipv6) {
+                    $txt .= "IPv6:" . $node->ipv6 . PHP_EOL;
+                }
+                $txt .= "端口:" . $node->v2_port . PHP_EOL;
+                $txt .= "加密方式:" . $node->v2_method . PHP_EOL;
+                $txt .= "用户ID:" . Auth::user()->vmess_id . PHP_EOL;
+                $txt .= "额外ID:" . $node->v2_alter_id . PHP_EOL;
+                $txt .= "传输协议:" . $node->v2_net . PHP_EOL;
+                $txt .= "伪装类型:" . $node->v2_type . PHP_EOL;
+                $txt .= $node->v2_host ? "伪装域名:" . $node->v2_host . PHP_EOL : "";
+                $txt .= $node->v2_path ? "路径:" . $node->v2_path . PHP_EOL : "";
+                $txt .= $node->v2_tls ? "TLS:tls" . PHP_EOL : "";
+
+                $node->txt = $txt;
+                $node->v2_scheme = $v2_scheme;
+            }
+
+            // 节点在线状态
+            $nodeInfo = SsNodeInfo::query()->where('node_id', $node->id)->where('log_time', '>=', strtotime("-10 minutes"))->orderBy('id', 'desc')->first();
+            $node->online_status = empty($nodeInfo) || empty($nodeInfo->load) ? 0 : 1;
+
+            // 节点标签
+            $node->labels = SsNodeLabel::query()->with('labelInfo')->where('node_id', $node->id)->first();
+        }
+
+        $view['allNodes'] = rtrim($allNodes, "|");
+        $view['nodeList'] = $nodeList;
+
+        return Response::view('user.nodeList', $view);
+    }
+
+    // 公告详情
+    public function article(Request $request)
+    {
+        $view['info'] = Article::query()->findOrFail($request->id);
+
+        return Response::view('user.article', $view);
+    }
+
+    // 修改个人资料
+    public function profile(Request $request)
+    {
+        if ($request->isMethod('POST')) {
+            $old_password = trim($request->input('old_password'));
+            $new_password = trim($request->input('new_password'));
+            $wechat = $request->input('wechat');
+            $qq = $request->input('qq');
+            $passwd = trim($request->input('passwd'));
+
+            // 修改密码
+            if ($old_password && $new_password) {
+                if (!Hash::check($old_password, Auth::user()->password)) {
+                    return Redirect::to('profile#tab_1')->withErrors('旧密码错误,请重新输入');
+                } elseif (Hash::check($new_password, Auth::user()->password)) {
+                    return Redirect::to('profile#tab_1')->withErrors('新密码不可与旧密码一样,请重新输入');
+                }
+
+                // 演示环境禁止改管理员密码
+                if (env('APP_DEMO') && Auth::user()->id == 1) {
+                    return Redirect::to('profile#tab_1')->withErrors('演示环境禁止修改管理员密码');
+                }
+
+                $ret = User::uid()->update(['password' => Hash::make($new_password)]);
+                if (!$ret) {
+                    return Redirect::to('profile#tab_1')->withErrors('修改失败');
+                } else {
+                    return Redirect::to('profile#tab_1')->with('successMsg', '修改成功');
+                }
+            }
+
+            // 修改联系方式
+            if ($wechat || $qq) {
+                if (empty(clean($wechat)) && empty(clean($qq))) {
+                    return Redirect::to('profile#tab_2')->withErrors('修改失败');
+                }
+
+                $ret = User::uid()->update(['wechat' => $wechat, 'qq' => $qq]);
+                if (!$ret) {
+                    return Redirect::to('profile#tab_2')->withErrors('修改失败');
+                } else {
+                    return Redirect::to('profile#tab_2')->with('successMsg', '修改成功');
+                }
+            }
+
+            // 修改代理密码
+            if ($passwd) {
+                $ret = User::uid()->update(['passwd' => $passwd]);
+                if (!$ret) {
+                    return Redirect::to('profile#tab_3')->withErrors('修改失败');
+                } else {
+                    return Redirect::to('profile#tab_3')->with('successMsg', '修改成功');
+                }
+            }
+
+            return Redirect::to('profile#tab_1')->withErrors('非法请求');
+        } else {
+            return Response::view('user.profile');
+        }
+    }
+
+    // 商品列表
+    public function services(Request $request)
+    {
+        $user = User::uid()->first();
+        $view['user_balance'] = $user->balance;
+
+        // 余额充值商品,只取10个
+        $view['chargeGoodsList'] = Goods::type(3)->where('status', 1)->orderBy('price', 'asc')->orderBy('price', 'asc')->limit(10)->get();
+        $view['goodsList'] = Goods::query()->where('status', 1)->where('type', '<=', '2')->orderBy('type', 'desc')->orderBy('sort', 'desc')->paginate(10)->appends($request->except('page'));
+
+        return Response::view('user.services', $view);
+    }
+
+    // 工单
+    public function ticketList(Request $request)
+    {
+        $view['ticketList'] = Ticket::uid()->orderBy('id', 'desc')->paginate(10)->appends($request->except('page'));
+
+        return Response::view('user.ticketList', $view);
+    }
+
+    // 订单
+    public function invoices(Request $request)
+    {
+        $view['orderList'] = Order::uid()->with(['user', 'goods', 'coupon', 'payment'])->orderBy('oid', 'desc')->paginate(10)->appends($request->except('page'));
+
+        return Response::view('user.invoices', $view);
+    }
+
+    // 订单明细
+    public function invoiceDetail(Request $request, $sn)
+    {
+        $view['order'] = Order::uid()->with(['goods', 'coupon', 'payment'])->where('order_sn', $sn)->firstOrFail();
+
+        return Response::view('user.invoiceDetail', $view);
+    }
+
+    // 添加工单
+    public function addTicket(Request $request)
+    {
+        $title = $request->input('title');
+        $content = clean($request->input('content'));
+        $content = str_replace("eval", "", str_replace("atob", "", $content));
+
+        if (empty($title) || empty($content)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '请输入标题和内容']);
+        }
+
+        $obj = new Ticket();
+        $obj->user_id = Auth::user()->id;
+        $obj->title = $title;
+        $obj->content = $content;
+        $obj->status = 0;
+        $obj->save();
+
+        if ($obj->id) {
+            $emailTitle = "新工单提醒";
+            $content = "标题:【" . $title . "】<br>内容:" . $content;
+
+            // 发邮件通知管理员
+            if (self::$systemConfig['crash_warning_email']) {
+                $logId = Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $emailTitle, $content);
+                Mail::to(self::$systemConfig['crash_warning_email'])->send(new newTicket($logId, $emailTitle, $content));
+            }
+
+            ServerChan::send($emailTitle, $content);
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '提交成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '提交失败']);
+        }
+    }
+
+    // 回复工单
+    public function replyTicket(Request $request)
+    {
+        $id = intval($request->input('id'));
+
+        $ticket = Ticket::uid()->with('user')->where('id', $id)->firstOrFail();
+
+        if ($request->isMethod('POST')) {
+            $content = clean($request->input('content'));
+            $content = str_replace("eval", "", str_replace("atob", "", $content));
+            $content = substr($content, 0, 300);
+
+            if (empty($content)) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '回复内容不能为空']);
+            }
+
+            $obj = new TicketReply();
+            $obj->ticket_id = $id;
+            $obj->user_id = Auth::user()->id;
+            $obj->content = $content;
+            $obj->save();
+
+            if ($obj->id) {
+                // 重新打开工单
+                $ticket->status = 0;
+                $ticket->save();
+
+                $title = "工单回复提醒";
+                $content = "标题:【" . $ticket->title . "】<br>用户回复:" . $content;
+
+                // 发邮件通知管理员
+                if (self::$systemConfig['crash_warning_email']) {
+                    $logId = Helpers::addEmailLog(self::$systemConfig['crash_warning_email'], $title, $content);
+                    Mail::to(self::$systemConfig['crash_warning_email'])->send(new replyTicket($logId, $title, $content));
+                }
+
+                ServerChan::send($title, $content);
+
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '回复成功']);
+            } else {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '回复失败']);
+            }
+        } else {
+            $view['ticket'] = $ticket;
+            $view['replyList'] = TicketReply::query()->where('ticket_id', $id)->with('user')->orderBy('id', 'asc')->get();
+
+            return Response::view('user.replyTicket', $view);
+        }
+    }
+
+    // 关闭工单
+    public function closeTicket(Request $request)
+    {
+        $id = $request->input('id');
+
+        $ret = Ticket::uid()->where('id', $id)->update(['status' => 2]);
+        if ($ret) {
+            ServerChan::send('工单关闭提醒', '工单:ID' . $id . '用户已手动关闭');
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '关闭成功']);
+        } else {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '关闭失败']);
+        }
+    }
+
+    // 邀请码
+    public function invite(Request $request)
+    {
+        if (Order::uid()->where('status', 2)->where('is_expire', 0)->where('origin_amount', '>', 0)->get()->isEmpty()) {
+            return Response::view('auth.error', ['message' => '本功能对非付费用户禁用!请 <a class="btn btn-sm btn-danger" href="/">返回</a>']);
+        }
+        $view['inviteList'] = Invite::uid()->with(['generator', 'user'])->paginate(10); // 邀请码列表
+        $view['referral_traffic'] = flowAutoShow(self::$systemConfig['referral_traffic'] * 1048576);
+        $view['referral_percent'] = self::$systemConfig['referral_percent'];
+
+        return Response::view('user.invite', $view);
+    }
+
+    // 生成邀请码
+    public function makeInvite(Request $request)
+    {
+        if (!Auth::user()->invite_num) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '生成失败:邀请码数量不足']);
+        }
+
+        DB::beginTransaction();
+        try {
+            // 生成邀请码
+            $obj = new Invite();
+            $obj->uid = Auth::user()->id;
+            $obj->fuid = 0;
+            $obj->code = strtoupper(mb_substr(md5(microtime() . makeRandStr()), 8, 12));
+            $obj->status = 0;
+            $obj->dateline = date('Y-m-d H:i:s', strtotime("+" . self::$systemConfig['user_invite_days'] . " days"));
+            $obj->save();
+            // 扣减邀请码数
+            User::uid()->decrement('invite_num', 1);
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '生成成功']);
+        } catch (Exception $e) {
+            Log::info("用户生成邀请码异常:" . $e);
+            DB::rollBack();
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '生成失败:邀请码数量不足']);
+        }
+    }
+
+    // 使用优惠券
+    public function redeemCoupon(Request $request)
+    {
+        $coupon_sn = $request->input('coupon_sn');
+
+        if (empty($coupon_sn)) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '优惠券不能为空']);
+        }
+
+        $coupon = Coupon::query()->where('sn', $coupon_sn)->whereIn('type', [1, 2])->first();
+        if (!$coupon) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该优惠券不存在']);
+        } elseif ($coupon->status == 1) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该优惠券已使用,请换一个试试']);
+        } elseif ($coupon->status == 2) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该优惠券已失效,请换一个试试']);
+        } elseif ($coupon->available_end < time()) {
+            $coupon->status = 2;
+            $coupon->save();
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该优惠券已失效,请换一个试试']);
+        } elseif ($coupon->available_start > time()) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '该优惠券尚不可用,请换一个试试']);
+        }
+
+        $data = [
+            'type'     => $coupon->type,
+            'amount'   => $coupon->amount,
+            'discount' => $coupon->discount
+        ];
+
+        return Response::json(['status' => 'success', 'data' => $data, 'message' => '该优惠券有效']);
+    }
+
+    // 购买服务
+    public function buy(Request $request, $id)
+    {
+        $goods_id = intval($id);
+        $coupon_sn = $request->input('coupon_sn');
+        // 余额支付
+        if ($request->isMethod('POST')) {
+            $goods = Goods::query()->with(['label'])->where('status', 1)->where('id', $goods_id)->first();
+            if (!$goods) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败:商品或服务已下架']);
+            }
+
+            // 限购控制:all-所有商品限购, free-价格为0的商品限购, none-不限购(默认)
+            $strategy = self::$systemConfig['goods_purchase_limit_strategy'];
+            if ($strategy == 'all' || ($strategy == 'package' && $goods->type == 2) || ($strategy == 'free' && $goods->price == 0) || ($strategy == 'package&free' && ($goods->type == 2 || $goods->price == 0))) {
+                $noneExpireGoodExist = Order::uid()->where('status', '>=', 0)->where('is_expire', 0)->where('goods_id', $goods_id)->exists();
+                if ($noneExpireGoodExist) {
+                    return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败:商品不可重复购买']);
+                }
+            }
+
+            // 单个商品限购
+            if ($goods->is_limit == 1) {
+                $noneExpireOrderExist = Order::uid()->where('status', '>=', 0)->where('goods_id', $goods_id)->exists();
+                if ($noneExpireOrderExist) {
+                    return Response::json(['status' => 'fail', 'data' => '', 'message' => '创建支付单失败:此商品每人限购1次']);
+                }
+            }
+
+            // 使用优惠券
+            if (!empty($coupon_sn)) {
+                $coupon = Coupon::query()->where('status', 0)->whereIn('type', [1, 2])->where('sn', $coupon_sn)->first();
+                if (empty($coupon)) {
+                    return Response::json(['status' => 'fail', 'data' => '', 'message' => '优惠券不存在']);
+                }
+
+                // 计算实际应支付总价
+                $amount = $coupon->type == 2 ? $goods->price * $coupon->discount / 10 : $goods->price - $coupon->amount;
+                $amount = $amount > 0 ? $amount : 0;
+            } else {
+                $amount = $goods->price;
+            }
+
+            // 价格异常判断
+            if ($amount < 0) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败:订单总价异常']);
+            }
+
+            // 验证账号余额是否充足
+            $user = User::uid()->first();
+            if ($user->balance < $amount) {
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败:您的余额不足,请先充值']);
+            }
+
+            // 验证账号是否存在有效期更长的套餐
+            if ($goods->type == 2) {
+                $existOrderList = Order::uid()
+                    ->with(['goods'])
+                    ->whereHas('goods', function ($q) {
+                        $q->where('type', 2);
+                    })
+                    ->where('is_expire', 0)
+                    ->where('status', 2)
+                    ->get();
+
+                foreach ($existOrderList as $vo) {
+                    if ($vo->goods->days > $goods->days) {
+                        return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败:您已存在有效期更长的套餐,只能购买流量包']);
+                    }
+                }
+            }
+
+            DB::beginTransaction();
+            try {
+                // 生成订单
+                $order = new Order();
+                $order->order_sn = date('ymdHis') . mt_rand(100000, 999999);
+                $order->user_id = $user->id;
+                $order->goods_id = $goods_id;
+                $order->coupon_id = !empty($coupon) ? $coupon->id : 0;
+                $order->origin_amount = $goods->price;
+                $order->amount = $amount;
+                $order->expire_at = date("Y-m-d H:i:s", strtotime("+" . $goods->days . " days"));
+                $order->is_expire = 0;
+                $order->pay_way = 1;
+                $order->status = 2;
+                $order->save();
+
+                // 扣余额
+                User::query()->where('id', $user->id)->decrement('balance', $amount * 100);
+
+                // 记录余额操作日志
+                $this->addUserBalanceLog($user->id, $order->oid, $user->balance, $user->balance - $amount, -1 * $amount, '购买服务:' . $goods->name);
+
+                // 优惠券置为已使用
+                if (!empty($coupon)) {
+                    if ($coupon->usage == 1) {
+                        $coupon->status = 1;
+                        $coupon->save();
+                    }
+
+                    // 写入日志
+                    Helpers::addCouponLog($coupon->id, $goods_id, $order->oid, '余额支付订单使用');
+                }
+
+                // 如果买的是套餐,则先将之前购买的所有套餐置都无效,并扣掉之前所有套餐的流量,重置用户已用流量为0
+                if ($goods->type == 2) {
+                    $existOrderList = Order::query()
+                        ->with(['goods'])
+                        ->whereHas('goods', function ($q) {
+                            $q->where('type', 2);
+                        })
+                        ->where('user_id', $order->user_id)
+                        ->where('oid', '<>', $order->oid)
+                        ->where('is_expire', 0)
+                        ->where('status', 2)
+                        ->get();
+
+                    foreach ($existOrderList as $vo) {
+                        Order::query()->where('oid', $vo->oid)->update(['is_expire' => 1]);
+
+                        // 先判断,防止手动扣减过流量的用户流量被扣成负数
+                        if ($order->user->transfer_enable - $vo->goods->traffic * 1048576 <= 0) {
+                            // 写入用户流量变动记录
+                            Helpers::addUserTrafficModifyLog($user->id, $order->oid, 0, 0, '[余额支付]用户购买套餐,先扣减之前套餐的流量(扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0, 'transfer_enable' => 0]);
+                        } else {
+                            // 写入用户流量变动记录
+                            $user = User::query()->where('id', $user->id)->first(); // 重新取出user信息
+                            Helpers::addUserTrafficModifyLog($user->id, $order->oid, $user->transfer_enable, ($user->transfer_enable - $vo->goods->traffic * 1048576), '[余额支付]用户购买套餐,先扣减之前套餐的流量(未扣完)');
+
+                            User::query()->where('id', $order->user_id)->update(['u' => 0, 'd' => 0]);
+                            User::query()->where('id', $order->user_id)->decrement('transfer_enable', $vo->goods->traffic * 1048576);
+                        }
+                    }
+                }
+
+                // 写入用户流量变动记录
+                $user = User::query()->where('id', $user->id)->first(); // 重新取出user信息
+                Helpers::addUserTrafficModifyLog($user->id, $order->oid, $user->transfer_enable, ($user->transfer_enable + $goods->traffic * 1048576), '[余额支付]用户购买商品,加上流量');
+
+                // 把商品的流量加到账号上
+                User::query()->where('id', $user->id)->increment('transfer_enable', $goods->traffic * 1048576);
+
+                // 计算账号过期时间
+                if ($user->expire_time < date('Y-m-d', strtotime("+" . $goods->days . " days"))) {
+                    $expireTime = date('Y-m-d', strtotime("+" . $goods->days . " days"));
+                } else {
+                    $expireTime = $user->expire_time;
+                }
+
+                // 套餐就改流量重置日,流量包不改
+                if ($goods->type == 2) {
+                    $traffic_reset_day = date('d');
+                    User::query()->where('id', $order->user_id)->update(['traffic_reset_day' => $traffic_reset_day, 'expire_time' => $expireTime, 'enable' => 1]);
+                } else {
+                    User::query()->where('id', $order->user_id)->update(['expire_time' => $expireTime, 'enable' => 1]);
+                }
+
+                // 写入用户标签
+                if ($goods->label) {
+                    // 用户默认标签
+                    $defaultLabels = [];
+                    if (self::$systemConfig['initial_labels_for_user']) {
+                        $defaultLabels = explode(',', self::$systemConfig['initial_labels_for_user']);
+                    }
+
+                    // 取出现有的标签
+                    $userLabels = UserLabel::query()->where('user_id', $user->id)->pluck('label_id')->toArray();
+                    $goodsLabels = GoodsLabel::query()->where('goods_id', $goods_id)->pluck('label_id')->toArray();
+
+                    // 标签去重
+                    $newUserLabels = array_values(array_unique(array_merge($userLabels, $goodsLabels, $defaultLabels)));
+
+                    // 删除用户所有标签
+                    UserLabel::query()->where('user_id', $user->id)->delete();
+
+                    // 生成标签
+                    foreach ($newUserLabels as $vo) {
+                        $obj = new UserLabel();
+                        $obj->user_id = $user->id;
+                        $obj->label_id = $vo;
+                        $obj->save();
+                    }
+                }
+
+                // 写入返利日志
+                if ($user->referral_uid) {
+                    $this->addReferralLog($user->id, $user->referral_uid, $order->oid, $amount, $amount * self::$systemConfig['referral_percent']);
+                }
+
+                // 增加用户邀请码数量
+                if ($goods->invite_num) {
+                    User::uid()->increment('invite_num', $goods->invite_num);
+                }
+
+                // 取消重复返利
+                User::query()->where('id', $order->user_id)->update(['referral_uid' => 0]);
+
+                DB::commit();
+
+                return Response::json(['status' => 'success', 'data' => '', 'message' => '支付成功']);
+            } catch (\Exception $e) {
+                DB::rollBack();
+
+                Log::error('支付订单失败:' . $e->getMessage());
+
+                return Response::json(['status' => 'fail', 'data' => '', 'message' => '支付失败:' . $e->getMessage()]);
+            }
+        } else {
+            $goods = Goods::query()->where('id', $goods_id)->where('status', 1)->first();
+            if (empty($goods)) {
+                return Redirect::to('services');
+            }
+
+            $view['goods'] = $goods;
+
+            return Response::view('user.buy', $view);
+        }
+    }
+
+    // 推广返利
+    public function referral(Request $request)
+    {
+        if (Order::uid()->where('status', 2)->where('is_expire', 0)->where('origin_amount', '>', 0)->get()->isEmpty()) {
+            return Response::view('auth.error', ['message' => '本功能对非付费用户禁用!请 <a class="btn btn-sm btn-danger" href="/">返回</a>']);
+        }
+        $view['referral_traffic'] = flowAutoShow(self::$systemConfig['referral_traffic'] * 1048576);
+        $view['referral_percent'] = self::$systemConfig['referral_percent'];
+        $view['referral_money'] = self::$systemConfig['referral_money'];
+        $view['totalAmount'] = ReferralLog::uid()->sum('ref_amount') / 100;
+        $view['canAmount'] = ReferralLog::uid()->where('status', 0)->sum('ref_amount') / 100;
+        $view['link'] = self::$systemConfig['website_url'] . '/register?aff=' . Auth::user()->id;
+        $view['referralLogList'] = ReferralLog::uid()->with('user')->orderBy('id', 'desc')->paginate(10);
+        $view['referralApplyList'] = ReferralApply::uid()->with('user')->orderBy('id', 'desc')->paginate(10);
+        $view['referralUserList'] = User::query()->select(['username', 'created_at'])->where('referral_uid', Auth::user()->id)->orderBy('id', 'desc')->paginate(10);
+
+        return Response::view('user.referral', $view);
+    }
+
+    // 申请提现
+    public function extractMoney(Request $request)
+    {
+        // 判断账户是否过期
+        if (Auth::user()->expire_time < date('Y-m-d')) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '申请失败:账号已过期,请先购买服务吧']);
+        }
+
+        // 判断是否已存在申请
+        $referralApply = ReferralApply::uid()->whereIn('status', [0, 1])->first();
+        if ($referralApply) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '申请失败:已存在申请,请等待之前的申请处理完']);
+        }
+
+        // 校验可以提现金额是否超过系统设置的阀值
+        $ref_amount = ReferralLog::uid()->where('status', 0)->sum('ref_amount');
+        $ref_amount = $ref_amount / 100;
+        if ($ref_amount < self::$systemConfig['referral_money']) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '申请失败:满' . self::$systemConfig['referral_money'] . '元才可以提现,继续努力吧']);
+        }
+
+        // 取出本次申请关联返利日志ID
+        $link_logs = '';
+        $referralLog = ReferralLog::uid()->where('status', 0)->get();
+        foreach ($referralLog as $log) {
+            $link_logs .= $log->id . ',';
+        }
+        $link_logs = rtrim($link_logs, ',');
+
+        $obj = new ReferralApply();
+        $obj->user_id = Auth::user()->id;
+        $obj->before = $ref_amount;
+        $obj->after = 0;
+        $obj->amount = $ref_amount;
+        $obj->link_logs = $link_logs;
+        $obj->status = 0;
+        $obj->save();
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => '申请成功,请等待管理员审核']);
+    }
+
+    // 帮助中心
+    public function help(Request $request)
+    {
+        $view['articleList'] = Article::type(1)->orderBy('sort', 'desc')->orderBy('id', 'desc')->limit(10)->paginate(5);
+
+        //付费用户判断
+        $view['is_paying_user'] = Order::uid()->where('status', 2)->where('is_expire', 0)->where('origin_amount', '>', 0)->get()->isEmpty();
+        //客户端安装
+        $view['Shadowrocket_install'] = 'itms-services://?action=download-manifest&url=' . self::$systemConfig['website_url'] . '/clients/ipa.plist';
+        $view['Quantumult_install'] = 'itms-services://?action=download-manifest&url=' . self::$systemConfig['website_url'] . '/ipa.plist';
+        // 订阅连接
+        $subscribe = UserSubscribe::query()->where('user_id', Auth::user()->id)->first();
+        $view['subscribe_status'] = $subscribe->status;
+        $subscribe_link = (self::$systemConfig['subscribe_domain'] ? self::$systemConfig['subscribe_domain'] : self::$systemConfig['website_url']) . '/s/' . $subscribe->code;
+        $view['link'] = $subscribe_link;
+        $view['Shadowrocket_link'] = 'shadowrocket://add/sub://' . base64url_encode($subscribe_link) . '?remarks=' . self::$systemConfig['website_name'] . '-' . self::$systemConfig['website_url'];
+        $view['Shadowrocket_linkQrcode'] = 'sub://' . base64url_encode($subscribe_link) . '#' . base64url_encode(self::$systemConfig['website_name']);
+        $view['Quantumult_linkOut'] = 'quantumult://configuration?server=' . base64url_encode($subscribe_link) . '&filter=' . base64url_encode('https://raw.githubusercontent.com/ConnersHua/Profiles/master/Quantumult/Pro.conf') . '&rejection=' . base64url_encode('https://raw.githubusercontent.com/ConnersHua/Profiles/master/Quantumult/Rejection.conf');
+        $view['Quantumult_linkIn'] = 'quantumult://configuration?server=' . base64url_encode($subscribe_link) . '&filter=' . base64url_encode('https://raw.githubusercontent.com/ConnersHua/Profiles/master/Quantumult/BacktoCN.conf') . '&rejection=' . base64url_encode('https://raw.githubusercontent.com/ConnersHua/Profiles/master/Quantumult/Rejection.conf');
+
+        return Response::view('user.help', $view);
+    }
+
+    // 更换订阅地址
+    public function exchangeSubscribe(Request $request)
+    {
+        DB::beginTransaction();
+        try {
+            // 更换订阅码
+            UserSubscribe::uid()->update(['code' => Helpers::makeSubscribeCode()]);
+
+            // 更换连接密码
+            User::uid()->update(['passwd' => makeRandStr()]);
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '更换成功']);
+        } catch (\Exception $e) {
+            DB::rollBack();
+
+            Log::info("更换订阅地址异常:" . $e->getMessage());
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '更换失败' . $e->getMessage()]);
+        }
+    }
+
+    // 转换成管理员的身份
+    public function switchToAdmin(Request $request)
+    {
+        if (!Session::has('admin')) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '非法请求']);
+        }
+
+        // 管理员信息重新写入user
+        Auth::loginUsingId(Session::get('admin'));
+        Session::forget('admin');
+
+        return Response::json(['status' => 'success', 'data' => '', 'message' => "身份切换成功"]);
+    }
+
+    // 卡券余额充值
+    public function charge(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'coupon_sn' => [
+                'required',
+                Rule::exists('coupon', 'sn')->where(function ($query) {
+                    $query->where('type', 3)->where('status', 0);
+                }),
+            ]
+        ], [
+            'coupon_sn.required' => '券码不能为空',
+            'coupon_sn.exists'   => '该券不可用'
+        ]);
+
+        if ($validator->fails()) {
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => $validator->getMessageBag()->first()]);
+        }
+
+        $coupon = Coupon::query()->where('sn', $request->input('coupon_sn'))->first();
+
+        DB::beginTransaction();
+        try {
+            // 写入日志
+            $this->addUserBalanceLog(Auth::user()->id, 0, Auth::user()->balance, Auth::user()->balance + $coupon->amount, $coupon->amount, '用户手动充值 - [充值券:' . $request->input('coupon_sn') . ']');
+
+            // 余额充值
+            User::uid()->increment('balance', $coupon->amount * 100);
+
+            // 更改卡券状态
+            $coupon->status = 1;
+            $coupon->save();
+
+            // 写入卡券日志
+            Helpers::addCouponLog($coupon->id, 0, 0, '账户余额充值使用');
+
+            DB::commit();
+
+            return Response::json(['status' => 'success', 'data' => '', 'message' => '充值成功']);
+        } catch (\Exception $e) {
+            Log::error($e);
+            DB::rollBack();
+
+            return Response::json(['status' => 'fail', 'data' => '', 'message' => '充值失败']);
+        }
+    }
+}

+ 70 - 0
app/Http/Kernel.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Http;
+
+use Illuminate\Foundation\Http\Kernel as HttpKernel;
+
+class Kernel extends HttpKernel
+{
+    /**
+     * The application's global HTTP middleware stack.
+     *
+     * These middleware are run during every request to your application.
+     *
+     * @var array
+     */
+    protected $middleware = [
+        \App\Http\Middleware\CheckForMaintenanceMode::class,
+        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
+        \App\Http\Middleware\TrimStrings::class,
+        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
+        \App\Http\Middleware\TrustProxies::class,
+    ];
+
+    /**
+     * The application's route middleware groups.
+     *
+     * @var array
+     */
+    protected $middlewareGroups = [
+        'web' => [
+            \App\Http\Middleware\EncryptCookies::class,
+            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
+            \Illuminate\Session\Middleware\StartSession::class,
+            // \Illuminate\Session\Middleware\AuthenticateSession::class,
+            \App\Http\Middleware\SetLocale::class,
+            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
+            \App\Http\Middleware\VerifyCsrfToken::class,
+            \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        ],
+
+        'api' => [
+            'throttle:60,1',
+            'bindings',
+        ],
+    ];
+
+    /**
+     * The application's route middleware.
+     *
+     * These middleware may be assigned to groups or used individually.
+     *
+     * @var array
+     */
+    protected $routeMiddleware = [
+        'auth'          => \Illuminate\Auth\Middleware\Authenticate::class,
+        'auth.basic'    => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
+        'bindings'      => \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
+        'can'           => \Illuminate\Auth\Middleware\Authorize::class,
+        'guest'         => \App\Http\Middleware\RedirectIfAuthenticated::class,
+        'signed'        => \Illuminate\Routing\Middleware\ValidateSignature::class,
+        'throttle'      => \Illuminate\Routing\Middleware\ThrottleRequests::class,
+        'isAdmin'       => \App\Http\Middleware\isAdmin::class,
+        'isLogin'       => \App\Http\Middleware\isLogin::class,
+        'isSecurity'    => \App\Http\Middleware\isSecurity::class,
+        'isForbidden'   => \App\Http\Middleware\isForbidden::class,
+        'affiliate'     => \App\Http\Middleware\Affiliate::class,
+
+    ];
+}

+ 27 - 0
app/Http/Middleware/Affiliate.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Cookie;
+use Closure;
+
+class Affiliate
+{
+    /**
+     * 返利识别
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure                 $next
+     *
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        $aff = trim($request->input('aff', 0));
+        if ($aff) {
+            Cookie::queue('register_aff', $aff, 129600);
+        }
+
+        return $next($request);
+    }
+}

+ 17 - 0
app/Http/Middleware/CheckForMaintenanceMode.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
+
+class CheckForMaintenanceMode extends Middleware
+{
+    /**
+     * The URIs that should be reachable while maintenance mode is enabled.
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

+ 17 - 0
app/Http/Middleware/EncryptCookies.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
+
+class EncryptCookies extends Middleware
+{
+    /**
+     * The names of the cookies that should not be encrypted.
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

+ 26 - 0
app/Http/Middleware/RedirectIfAuthenticated.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+
+class RedirectIfAuthenticated
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure                 $next
+     * @param  string|null              $guard
+     *
+     * @return mixed
+     */
+    public function handle($request, Closure $next, $guard = null)
+    {
+        if (auth()->guard($guard)->check()) {
+            return redirect('/');
+        }
+
+        return $next($request);
+    }
+}

+ 32 - 0
app/Http/Middleware/SetLocale.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Session;
+
+class SetLocale
+{
+    /**
+     * 变更语言
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure                 $next
+     *
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        if (Session::has('locale')) {
+            app()->setLocale(Session::get('locale'));
+        }
+
+        if ($request->query('locale')) {
+            Session::put('locale', $request->query('locale'));
+            app()->setLocale($request->query('locale'));
+        }
+
+        return $next($request);
+    }
+
+}

+ 18 - 0
app/Http/Middleware/TrimStrings.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
+
+class TrimStrings extends Middleware
+{
+    /**
+     * The names of the attributes that should not be trimmed.
+     *
+     * @var array
+     */
+    protected $except = [
+        'password',
+        'password_confirmation',
+    ];
+}

+ 23 - 0
app/Http/Middleware/TrustProxies.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Http\Request;
+use Fideloper\Proxy\TrustProxies as Middleware;
+
+class TrustProxies extends Middleware
+{
+    /**
+     * The trusted proxies for this application.
+     *
+     * @var array
+     */
+    protected $proxies;
+
+    /**
+     * The headers that should be used to detect proxies.
+     *
+     * @var string
+     */
+    protected $headers = Request::HEADER_X_FORWARDED_ALL;
+}

+ 18 - 0
app/Http/Middleware/VerifyCsrfToken.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
+
+class VerifyCsrfToken extends Middleware
+{
+    /**
+     * The URIs that should be excluded from CSRF verification.
+     *
+     * @var array
+     */
+    protected $except = [
+        "payment/*",
+        "checkIn"
+    ];
+}

+ 27 - 0
app/Http/Middleware/isAdmin.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Auth;
+use Closure;
+use Redirect;
+
+class isAdmin
+{
+    /**
+     * 校验是否为管理员身份
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure                 $next
+     *
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        if (!Auth::user()->is_admin) {
+            return Redirect::to('/');
+        }
+
+        return $next($request);
+    }
+}

+ 94 - 0
app/Http/Middleware/isForbidden.php

@@ -0,0 +1,94 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use App\Components\Helpers;
+use App\Components\IPIP;
+use App\Components\QQWry;
+use Agent;
+use Log;
+use Closure;
+
+class isForbidden
+{
+    /**
+     * 限制机器人、指定IP访问
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure                 $next
+     *
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        // 拒绝机器人访问
+        if (Helpers::systemConfig()['is_forbid_robot']) {
+            if (Agent::isRobot()) {
+                Log::info("识别到机器人访问(" . getClientIp() . ")");
+
+                return response()->view('auth.error', ['message' => trans('error.ForbiddenRobot')], 404);
+            }
+        }
+
+        // 拒绝通过订阅链接域名访问网站,防止网站被探测
+        if (false !== strpos(Helpers::systemConfig()['subscribe_domain'], $request->getHost())) {
+            Log::info("识别到通过订阅链接访问,强制跳转至百度(" . getClientIp() . ")");
+
+            return redirect('https://www.baidu.com');
+        }
+
+        $ip = getClientIP();
+        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
+            Log::info('识别到IPv6,尝试解析:' . $ip);
+            $isIPv6 = true;
+            $ipInfo = getIPv6($ip);
+        } else {
+            $isIPv6 = false;
+            $ipInfo = QQWry::ip($ip); // 通过纯真IP库解析IPv4信息
+            if (isset($ipInfo['error'])) {
+                Log::info('无法识别IPv4,尝试使用IPIP的IP库解析:' . $ip);
+                $ipip = IPIP::ip($ip);
+                $ipInfo = [
+                    'country'  => $ipip['country_name'],
+                    'province' => $ipip['region_name'],
+                    'city'     => $ipip['city_name']
+                ];
+            } else {
+                // 判断纯真IP库获取的国家信息是否与IPIP的IP库获取的信息一致,不一致则用IPIP的(因为纯真IP库的非大陆IP准确率较低)
+                $ipip = IPIP::ip($ip);
+                if ($ipInfo['country'] != $ipip['country_name']) {
+                    $ipInfo['country'] = $ipip['country_name'];
+                    $ipInfo['province'] = $ipip['region_name'];
+                    $ipInfo['city'] = $ipip['city_name'];
+                }
+            }
+        }
+
+        // 拒绝无IP请求
+        if (empty($ipInfo) || empty($ipInfo['country'])) {
+            return response()->view('auth.error', ['message' => trans('error.ForbiddenAccess')], 403);
+        }
+
+        if (!in_array($ipInfo['country'], ['本机地址', '局域网'])) {
+            // 拒绝大陆IP访问
+            if (Helpers::systemConfig()['is_forbid_china']) {
+                if (($ipInfo['country'] == '中国' && !in_array($ipInfo['province'], ['香港', '澳门', '台湾'])) || ($isIPv6 && $ipInfo['country'] == 'China')) {
+                    Log::info('识别到大陆IP,拒绝访问:' . $ip);
+
+                    return response()->view('auth.error', ['message' => trans('error.ForbiddenChina')], 403);
+                }
+            }
+
+            // 拒绝非大陆IP访问
+            if (Helpers::systemConfig()['is_forbid_oversea']) {
+                if ($ipInfo['country'] != '中国' || in_array($ipInfo['province'], ['香港', '澳门', '台湾']) || ($isIPv6 && $ipInfo['country'] != 'China')) {
+                    Log::info('识别到海外IP,拒绝访问:' . $ip . ' - ' . $ipInfo['country']);
+
+                    return response()->view('auth.error', ['message' => trans('error.ForbiddenOversea')], 403);
+                }
+            }
+        }
+
+        return $next($request);
+    }
+}

+ 26 - 0
app/Http/Middleware/isLogin.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Redirect;
+
+class isLogin
+{
+    /**
+     * 校验是否已登录
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure                 $next
+     *
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        if (auth()->guest()) {
+            return Redirect::to('login');
+        }
+
+        return $next($request);
+    }
+}

+ 39 - 0
app/Http/Middleware/isSecurity.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use App\Components\Helpers;
+use Cache;
+use Closure;
+use Log;
+
+class isSecurity
+{
+	/**
+	 * 是否需要安全码才访问(仅用于登录页)
+	 *
+	 * @param         $request
+	 * @param Closure $next
+	 *
+	 * @return mixed
+	 */
+	public function handle($request, Closure $next)
+	{
+		$ip = getClientIP();
+		$code = $request->input('securityCode');
+		$cacheKey = 'SecurityLogin_' . ip2long($ip);
+		$websiteSecurityCode = Helpers::systemConfig()['website_security_code'];
+
+		if ($websiteSecurityCode && !Cache::has($cacheKey)) {
+			if ($code != $websiteSecurityCode) {
+				Log::info("拒绝非安全入口访问(" . $ip . ")");
+
+				return response()->view('auth.error', ['message' => trans('error.SecurityError') . ', ' . trans('error.Visit') . '<a href="/login?securityCode=" target="_self">' . trans('error.SecurityEnter') . '</a>']);
+			} else {
+				Cache::put($cacheKey, $ip, 120); // 缓存120分钟,因为每个session默认存活120分钟
+			}
+		}
+
+		return $next($request);
+	}
+}

+ 28 - 0
app/Http/Models/Article.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * 文章
+ * Class Article
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Article extends Model
+{
+    use SoftDeletes;
+
+    protected $table = 'article';
+    protected $primaryKey = 'id';
+    protected $dates = ['deleted_at'];
+
+    // 筛选类型
+    function scopeType($query, $type)
+    {
+        return $query->where('type', $type);
+    }
+}

+ 20 - 0
app/Http/Models/Config.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 系统配置
+ * Class Config
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Config extends Model
+{
+    protected $table = 'config';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+
+}

+ 19 - 0
app/Http/Models/Country.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 国家/地区
+ * Class Country
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Country extends Model
+{
+    protected $table = 'country';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+}

+ 48 - 0
app/Http/Models/Coupon.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * 优惠券
+ * Class Goods
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Coupon extends Model
+{
+    use SoftDeletes;
+
+    protected $table = 'coupon';
+    protected $primaryKey = 'id';
+    protected $dates = ['deleted_at'];
+
+    // 筛选类型
+    function scopeType($query, $type)
+    {
+        return $query->where('type', $type);
+    }
+
+    function getAmountAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setAmountAttribute($value)
+    {
+        $this->attributes['amount'] = $value * 100;
+    }
+
+    function getDiscountAttribute($value)
+    {
+        return $value * 10;
+    }
+
+    function setDiscountAttribute($value)
+    {
+        $this->attributes['discount'] = $value / 10;
+    }
+}

+ 19 - 0
app/Http/Models/CouponLog.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 优惠券使用日志
+ * Class Goods
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class CouponLog extends Model
+{
+    protected $table = 'coupon_log';
+    protected $primaryKey = 'id';
+
+}

+ 61 - 0
app/Http/Models/Device.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 订阅设备列表
+ * Class Device
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Device extends Model
+{
+    protected $table = 'device';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+
+    function getTypeLabelAttribute()
+    {
+        switch ($this->attributes['type']) {
+            case 1:
+                $type_label = '<span class="label label-danger"> Shadowsocks(R) </span>';
+                break;
+            case 2:
+                $type_label = '<span class="label label-danger"> V2Ray </span>';
+                break;
+            default:
+                $type_label = '<span class="label label-default"> 其他 </span>';
+        }
+
+        return $type_label;
+    }
+
+    function getPlatformLabelAttribute()
+    {
+        switch ($this->attributes['platform']) {
+            case 1:
+                $platform_label = '<i class="fa fa-apple"></i> iOS';
+                break;
+            case 2:
+                $platform_label = '<i class="fa fa-android"></i> Android';
+                break;
+            case 3:
+                $platform_label = '<i class="fa fa-apple"></i> Mac';
+                break;
+            case 4:
+                $platform_label = '<i class="fa fa-windows"></i> Windows';
+                break;
+            case 5:
+                $platform_label = '<i class="fa fa-linux"></i> Linux';
+                break;
+            case 0:
+            default:
+                $platform_label = '其他';
+        }
+
+        return $platform_label;
+    }
+}

+ 19 - 0
app/Http/Models/EmailLog.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 邮件/ServerChan发送日志
+ * Class EmailLog
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class EmailLog extends Model
+{
+    protected $table = 'email_log';
+    protected $primaryKey = 'id';
+
+}

+ 48 - 0
app/Http/Models/Goods.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * 商品
+ * Class Goods
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Goods extends Model
+{
+    use SoftDeletes;
+    protected $table = 'goods';
+    protected $primaryKey = 'id';
+    protected $dates = ['deleted_at'];
+
+    function scopeType($query, $type)
+    {
+        return $query->where('type', $type)->where('status', 1)->orderBy('sort', 'desc');
+    }
+
+    function label()
+    {
+        return $this->hasMany(GoodsLabel::class, 'goods_id', 'id');
+    }
+
+    function getPriceAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setPriceAttribute($value)
+    {
+        $this->attributes['price'] = $value * 100;
+    }
+
+    function getTrafficLabelAttribute()
+    {
+        $traffic_label = flowAutoShow($this->attributes['traffic'] * 1048576);
+
+        return $traffic_label;
+    }
+}

+ 24 - 0
app/Http/Models/GoodsLabel.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 商品标签
+ * Class GoodsLabel
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class GoodsLabel extends Model
+{
+    protected $table = 'goods_label';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+
+    function goods()
+    {
+        return $this->hasOne(Goods::class, 'id', 'goods_id');
+    }
+}

+ 39 - 0
app/Http/Models/Invite.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Http\Models;
+
+use Auth;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+/**
+ * 邀请码
+ * Class Invite
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Invite extends Model
+{
+    use SoftDeletes;
+
+    protected $table = 'invite';
+    protected $primaryKey = 'id';
+    protected $dates = ['deleted_at'];
+
+    function scopeUid($query)
+    {
+        return $query->where('uid', Auth::user()->id);
+    }
+
+    function generator()
+    {
+        return $this->hasOne(User::class, 'id', 'uid');
+    }
+
+    function user()
+    {
+        return $this->hasOne(User::class, 'id', 'fuid');
+    }
+
+}

+ 19 - 0
app/Http/Models/Label.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 标签
+ * Class Label
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Label extends Model
+{
+    protected $table = 'label';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+}

+ 19 - 0
app/Http/Models/Level.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 等级
+ * Class Level
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Level extends Model
+{
+    protected $table = 'level';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+}

+ 37 - 0
app/Http/Models/Marketing.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 营销
+ * Class Marketing
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Marketing extends Model
+{
+    protected $table = 'marketing';
+    protected $primaryKey = 'id';
+    protected $appends = ['status_label'];
+
+    function getStatusLabelAttribute()
+    {
+        $status_label = '';
+        switch ($this->attributes['status']) {
+            case -1:
+                $status_label = '失败';
+                break;
+            case 0:
+                $status_label = '待推送';
+                break;
+            case 1:
+                $status_label = '成功';
+                break;
+        }
+
+        return $status_label;
+    }
+}

+ 85 - 0
app/Http/Models/Order.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Http\Models;
+
+use Auth;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 订单
+ * Class Order
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Order extends Model
+{
+    protected $table = 'order';
+    protected $primaryKey = 'oid';
+    protected $appends = ['status_label'];
+
+    function scopeUid($query)
+    {
+        return $query->where('user_id', Auth::user()->id);
+    }
+
+    function user()
+    {
+        return $this->hasOne(User::class, 'id', 'user_id');
+    }
+
+    function goods()
+    {
+        return $this->hasOne(Goods::class, 'id', 'goods_id')->withTrashed();
+    }
+
+    function coupon()
+    {
+        return $this->hasOne(Coupon::class, 'id', 'coupon_id')->withTrashed();
+    }
+
+    function payment()
+    {
+        return $this->hasOne(Payment::class, 'oid', 'oid');
+    }
+
+    function getOriginAmountAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setOriginAmountAttribute($value)
+    {
+        return $this->attributes['origin_amount'] = $value * 100;
+    }
+
+    function getAmountAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setAmountAttribute($value)
+    {
+        return $this->attributes['amount'] = $value * 100;
+    }
+
+    function getStatusLabelAttribute()
+    {
+        switch ($this->attributes['status']) {
+            case -1:
+                $status_label = '已关闭';
+                break;
+            case 1:
+                $status_label = '已支付待确认';
+                break;
+            case 2:
+                $status_label = '已完成';
+                break;
+            case 0:
+            default:
+                $status_label = '待支付';
+        }
+
+        return $status_label;
+    }
+}

+ 48 - 0
app/Http/Models/OrderGoods.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 订单商品
+ * Class OrderGoods
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class OrderGoods extends Model
+{
+    protected $table = 'order_goods';
+    protected $primaryKey = 'id';
+
+    function user()
+    {
+        return $this->hasOne(User::class, 'id', 'user_id');
+    }
+
+    function goods()
+    {
+        return $this->hasOne(Goods::class, 'id', 'goods_id');
+    }
+
+    function getOriginPriceAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setOriginPriceAttribute($value)
+    {
+        return $this->attributes['origin_price'] = $value * 100;
+    }
+
+    function getPriceAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setPriceAttribute($value)
+    {
+        return $this->attributes['price'] = $value * 100;
+    }
+}

+ 78 - 0
app/Http/Models/Payment.php

@@ -0,0 +1,78 @@
+<?php
+
+namespace App\Http\Models;
+
+use Auth;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 支付单
+ * Class Payment
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Payment extends Model
+{
+    protected $table = 'payment';
+    protected $primaryKey = 'id';
+    protected $appends = ['status_label'];
+
+    function scopeUid($query)
+    {
+        return $query->where('user_id', Auth::user()->id);
+    }
+
+    function user()
+    {
+        return $this->belongsTo(User::class, 'user_id', 'id');
+    }
+
+    function order()
+    {
+        return $this->belongsTo(Order::class, 'oid', 'oid');
+    }
+
+    function getAmountAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setAmountAttribute($value)
+    {
+        return $this->attributes['amount'] = $value * 100;
+    }
+
+    // 订单状态
+    function getStatusLabelAttribute()
+    {
+        switch ($this->attributes['status']) {
+            case -1:
+                $status_label = '支付失败';
+                break;
+            case 1:
+                $status_label = '支付成功';
+                break;
+            case 0:
+            default:
+                $status_label = '等待支付';
+        }
+
+        return $status_label;
+    }
+
+    // 支付方式
+    function getPayWayLabelAttribute()
+    {
+        switch ($this->attributes['pay_way']) {
+            case 1:
+                $pay_way_label = '微信';
+                break;
+            case 2:
+            default:
+                $pay_way_label = '支付宝';
+        }
+
+        return $pay_way_label;
+    }
+}

+ 40 - 0
app/Http/Models/PaymentCallback.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 支付回调(有赞云支付)
+ * Class PaymentCallback
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class PaymentCallback extends Model
+{
+    protected $table = 'payment_callback';
+    protected $primaryKey = 'id';
+    protected $appends = ['status_label'];
+
+    function getStatusLabelAttribute()
+    {
+        $status_label = '';
+        switch ($this->attributes['status']) {
+            case 'WAIT_BUYER_PAY':
+                $status_label = '等待买家付款';
+                break;
+            case 'WAIT_SELLER_SEND_GOODS':
+                $status_label = '等待卖家发货';
+                break;
+            case 'TRADE_SUCCESS':
+                $status_label = '交易成功';
+                break;
+            case 'PAID':
+                $status_label = '支付完成';
+                break;
+        }
+
+        return $status_label;
+    }
+}

+ 59 - 0
app/Http/Models/ReferralApply.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Http\Models;
+
+use Auth;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 返利申请
+ * Class ReferralApply
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class ReferralApply extends Model
+{
+    protected $table = 'referral_apply';
+    protected $primaryKey = 'id';
+
+    function scopeUid($query)
+    {
+        return $query->where('user_id', Auth::user()->id);
+    }
+
+    function User()
+    {
+        return $this->hasOne(User::class, 'id', 'user_id');
+    }
+
+    function getBeforeAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setBeforeAttribute($value)
+    {
+        $this->attributes['before'] = $value * 100;
+    }
+
+    function getAfterAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setAfterAttribute($value)
+    {
+        $this->attributes['after'] = $value * 100;
+    }
+
+    function getAmountAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setAmountAttribute($value)
+    {
+        $this->attributes['amount'] = $value * 100;
+    }
+}

+ 59 - 0
app/Http/Models/ReferralLog.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Http\Models;
+
+use Auth;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 返利日志
+ * Class ReferralLog
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class ReferralLog extends Model
+{
+    protected $table = 'referral_log';
+    protected $primaryKey = 'id';
+
+    function scopeUid($query)
+    {
+        return $query->where('ref_user_id', Auth::user()->id);
+    }
+
+    function user()
+    {
+        return $this->hasOne(User::class, 'id', 'user_id');
+    }
+
+    function ref_user()
+    {
+        return $this->hasOne(User::class, 'id', 'ref_user_id');
+    }
+
+    function order()
+    {
+        return $this->hasOne(Order::class, 'oid', 'order_id');
+    }
+
+    function getAmountAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setAmountAttribute($value)
+    {
+        $this->attributes['amount'] = $value * 100;
+    }
+
+    function getRefAmountAttribute($value)
+    {
+        return $value / 100;
+    }
+
+    function setRefAmountAttribute($value)
+    {
+        $this->attributes['ref_amount'] = $value * 100;
+    }
+}

+ 19 - 0
app/Http/Models/SensitiveWords.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 敏感词
+ * Class SensitiveWords
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SensitiveWords extends Model
+{
+    protected $table = 'sensitive_words';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+}

+ 31 - 0
app/Http/Models/SsConfig.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 配置信息
+ * Class SsConfig
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsConfig extends Model
+{
+    protected $table = 'ss_config';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+
+    // 筛选默认
+    function scopeDefault($query)
+    {
+        $query->where('is_default', 1);
+    }
+
+    // 筛选类型
+    function scopeType($query, $type)
+    {
+        $query->where('type', $type);
+    }
+}

+ 19 - 0
app/Http/Models/SsGroup.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * SS节点分组
+ * Class SsNodeGroup
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsGroup extends Model
+{
+    protected $table = 'ss_group';
+    protected $primaryKey = 'id';
+
+}

+ 20 - 0
app/Http/Models/SsGroupNode.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * SS分组和节点关联表
+ * Class SsNodeGroup
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsGroupNode extends Model
+{
+    protected $table = 'ss_group_node';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+
+}

+ 23 - 0
app/Http/Models/SsNode.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * SS节点信息
+ * Class SsNode
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsNode extends Model
+{
+    protected $table = 'ss_node';
+    protected $primaryKey = 'id';
+
+    function label()
+    {
+        return $this->hasMany(SsNodeLabel::class, 'node_id', 'id');
+    }
+}

+ 20 - 0
app/Http/Models/SsNodeInfo.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * SS节点负载情况
+ * Class SsNodeInfo
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsNodeInfo extends Model
+{
+    protected $table = 'ss_node_info';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+
+}

+ 28 - 0
app/Http/Models/SsNodeIp.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * SS节点在线IP信息
+ * Class SsNodeIp
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsNodeIp extends Model
+{
+    protected $table = 'ss_node_ip';
+    protected $primaryKey = 'id';
+
+    function node()
+    {
+        return $this->belongsTo(SsNode::class, 'node_id', 'id');
+    }
+
+    function user()
+    {
+        return $this->belongsTo(User::class, 'port', 'port');
+    }
+}

+ 25 - 0
app/Http/Models/SsNodeLabel.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 节点标签
+ * Class SsNodeLabel
+ *
+ * @package App\Http\Models
+ * @property-read \App\Http\Models\Label $labelInfo
+ * @mixin \Eloquent
+ */
+class SsNodeLabel extends Model
+{
+    protected $table = 'ss_node_label';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+
+    function labelInfo()
+    {
+        return $this->hasOne(Label::class, 'id', 'label_id');
+    }
+}

+ 20 - 0
app/Http/Models/SsNodeOnlineLog.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * SS节点用户在线情况
+ * Class SsNodeOnlineLog
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsNodeOnlineLog extends Model
+{
+    protected $table = 'ss_node_online_log';
+    protected $primaryKey = 'id';
+    public $timestamps = false;
+
+}

+ 24 - 0
app/Http/Models/SsNodeTrafficDaily.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 节点每日流量统计
+ * Class SsUserTrafficDaily
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsNodeTrafficDaily extends Model
+{
+    protected $table = 'ss_node_traffic_daily';
+    protected $primaryKey = 'id';
+
+    function info()
+    {
+        return $this->hasOne(SsNode::class, 'id', 'node_id');
+    }
+
+}

+ 23 - 0
app/Http/Models/SsNodeTrafficHourly.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 节点每日流量统计
+ * Class SsUserTrafficHourly
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class SsNodeTrafficHourly extends Model
+{
+    protected $table = 'ss_node_traffic_hourly';
+    protected $primaryKey = 'id';
+
+    function info()
+    {
+        return $this->hasOne(SsNode::class, 'id', 'node_id');
+    }
+}

+ 29 - 0
app/Http/Models/Ticket.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Http\Models;
+
+use Auth;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 工单
+ * Class Ticket
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class Ticket extends Model
+{
+    protected $table = 'ticket';
+    protected $primaryKey = 'id';
+
+    function scopeUid($query)
+    {
+        return $query->where('user_id', Auth::user()->id);
+    }
+
+    function user()
+    {
+        return $this->hasOne(User::class, 'id', 'user_id');
+    }
+}

+ 23 - 0
app/Http/Models/TicketReply.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Models;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 工单回复
+ * Class TicketReply
+ *
+ * @package App\Http\Models
+ * @mixin \Eloquent
+ */
+class TicketReply extends Model
+{
+    protected $table = 'ticket_reply';
+    protected $primaryKey = 'id';
+
+    function user()
+    {
+        return $this->hasOne(User::class, 'id', 'user_id');
+    }
+}

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.