diff --git a/Modules/M3/Config/.gitkeep b/Modules/M3/Config/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Config/config.php b/Modules/M3/Config/config.php
new file mode 100644
index 00000000..ed8568b4
--- /dev/null
+++ b/Modules/M3/Config/config.php
@@ -0,0 +1,8 @@
+ 'M3',
+ 'features' =>
+ [
+ ],
+];
diff --git a/Modules/M3/Console/.gitkeep b/Modules/M3/Console/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Database/Migrations/.gitkeep b/Modules/M3/Database/Migrations/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Database/Seeders/.gitkeep b/Modules/M3/Database/Seeders/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Database/Seeders/M3DatabaseSeeder.php b/Modules/M3/Database/Seeders/M3DatabaseSeeder.php
new file mode 100644
index 00000000..5d9bcb93
--- /dev/null
+++ b/Modules/M3/Database/Seeders/M3DatabaseSeeder.php
@@ -0,0 +1,21 @@
+call("OthersTableSeeder");
+ }
+}
diff --git a/Modules/M3/Database/factories/.gitkeep b/Modules/M3/Database/factories/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Helpers/.gitkeep b/Modules/M3/Helpers/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Helpers/Helper.php b/Modules/M3/Helpers/Helper.php
new file mode 100644
index 00000000..71681133
--- /dev/null
+++ b/Modules/M3/Helpers/Helper.php
@@ -0,0 +1,12 @@
+registerTranslations();
+ $this->registerConfig();
+ $this->registerViews();
+ $this->registerHelpers();
+ $this->registerCommands();
+ $this->loadMigrationsFrom(module_path(ModuleInfo::name(), 'Database/Migrations'));
+ }
+
+ /**
+ * Register the service provider.
+ *
+ * @return void
+ */
+ public function register(): void
+ {
+ $this->app->register(RouteServiceProvider::class);
+ }
+
+ /**
+ * Register the helpers.
+ *
+ * @return void
+ */
+ protected function registerHelpers(): void
+ {
+ foreach (glob(__DIR__.'/../Helpers/*.php') as $filename) {
+ require_once $filename;
+ }
+ }
+
+ /**
+ * Dynamically Register Commands.
+ *
+ * @return void
+ */
+ public function registerCommands(): void
+ {
+ if (!$this->app->runningInConsole()) {
+ return;
+ }
+ $commandPath = __DIR__ . '/../Console';
+ $commands = collect(File::allFiles($commandPath))
+ ->map(function ($file) {
+ $class = 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension();
+ return $class;
+ })
+ ->filter(function ($class) {
+ return class_exists($class);
+ })
+ ->values()
+ ->all();
+ $this->commands($commands);
+ }
+
+ /**
+ * Register config.
+ *
+ * @return void
+ */
+ protected function registerConfig(): void
+ {
+ $this->publishes([
+ module_path(ModuleInfo::name(), 'Config/config.php') => config_path( ModuleInfo::nameLower(). '.php'),
+ ], 'config');
+ $this->mergeConfigFrom(
+ module_path(ModuleInfo::name(), 'Config/config.php'), ModuleInfo::nameLower()
+ );
+ }
+
+ /**
+ * Register views.
+ *
+ * @return void
+ */
+ public function registerViews(): void
+ {
+ $viewPath = resource_path('views/modules/' . ModuleInfo::nameLower());
+ $sourcePath = module_path(ModuleInfo::name(), 'Resources/views');
+ $this->publishes([
+ $sourcePath => $viewPath
+ ], ['views', ModuleInfo::nameLower() . '-module-views']);
+ $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), ModuleInfo::nameLower());
+ }
+
+ /**
+ * Register translations.
+ *
+ * @return void
+ */
+ public function registerTranslations(): void
+ {
+ $langPath = resource_path('lang/modules/' . ModuleInfo::nameLower());
+
+ if (is_dir($langPath)) {
+ $this->loadTranslationsFrom($langPath, ModuleInfo::nameLower());
+ } else {
+ $this->loadTranslationsFrom(module_path(ModuleInfo::name(), 'Resources/lang'), ModuleInfo::nameLower());
+ }
+ }
+
+ /**
+ * Regsiter View Paths
+ * @return array
+ */
+ private function getPublishableViewPaths(): array
+ {
+ $paths = [];
+ foreach (Config::get('view.paths') as $path) {
+ if (is_dir($path . '/modules/' . ModuleInfo::nameLower())) {
+ $paths[] = $path . '/modules/' . ModuleInfo::nameLower();
+ }
+ }
+ return $paths;
+ }
+}
diff --git a/Modules/M3/Providers/RouteServiceProvider.php b/Modules/M3/Providers/RouteServiceProvider.php
new file mode 100644
index 00000000..07019db8
--- /dev/null
+++ b/Modules/M3/Providers/RouteServiceProvider.php
@@ -0,0 +1,69 @@
+mapApiRoutes();
+
+ $this->mapWebRoutes();
+ }
+
+ /**
+ * Define the "web" routes for the application.
+ *
+ * These routes all receive session state, CSRF protection, etc.
+ *
+ * @return void
+ */
+ protected function mapWebRoutes()
+ {
+ Route::middleware('web')
+ ->namespace($this->moduleNamespace)
+ ->group(module_path('M3', '/Routes/web.php'));
+ }
+
+ /**
+ * Define the "api" routes for the application.
+ *
+ * These routes are typically stateless.
+ *
+ * @return void
+ */
+ protected function mapApiRoutes()
+ {
+ Route::prefix('api')
+ ->middleware('api')
+ ->namespace($this->moduleNamespace)
+ ->group(module_path('M3', '/Routes/api.php'));
+ }
+}
diff --git a/Modules/M3/Resources/assets/.gitkeep b/Modules/M3/Resources/assets/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Resources/assets/js/app.js b/Modules/M3/Resources/assets/js/app.js
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Resources/assets/sass/app.scss b/Modules/M3/Resources/assets/sass/app.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Resources/lang/.gitkeep b/Modules/M3/Resources/lang/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Resources/views/.gitkeep b/Modules/M3/Resources/views/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Resources/views/index.blade.php b/Modules/M3/Resources/views/index.blade.php
new file mode 100644
index 00000000..d24a66c3
--- /dev/null
+++ b/Modules/M3/Resources/views/index.blade.php
@@ -0,0 +1,9 @@
+@extends('m3::layouts.master')
+
+@section('content')
+
Hello World
+
+
+ This view is loaded from module: {!! config('m3.name') !!}
+
+@endsection
diff --git a/Modules/M3/Resources/views/layouts/master.blade.php b/Modules/M3/Resources/views/layouts/master.blade.php
new file mode 100644
index 00000000..f89fd014
--- /dev/null
+++ b/Modules/M3/Resources/views/layouts/master.blade.php
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ Module M3
+
+ {{-- Laravel Mix - CSS File --}}
+ {{-- --}}
+
+
+
+ @yield('content')
+
+ {{-- Laravel Mix - JS File --}}
+ {{-- --}}
+
+
diff --git a/Modules/M3/Routes/.gitkeep b/Modules/M3/Routes/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Routes/api.php b/Modules/M3/Routes/api.php
new file mode 100644
index 00000000..c421f8a5
--- /dev/null
+++ b/Modules/M3/Routes/api.php
@@ -0,0 +1,18 @@
+get('/m3', function (Request $request) {
+ return $request->user();
+});
\ No newline at end of file
diff --git a/Modules/M3/Routes/web.php b/Modules/M3/Routes/web.php
new file mode 100644
index 00000000..128ef230
--- /dev/null
+++ b/Modules/M3/Routes/web.php
@@ -0,0 +1,16 @@
+group(function() {
+ Route::get('/', 'M3Controller@index');
+});
diff --git a/Modules/M3/Support/.gitkeep b/Modules/M3/Support/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/M3/Support/ModuleInfo.php b/Modules/M3/Support/ModuleInfo.php
new file mode 100644
index 00000000..b5f72af9
--- /dev/null
+++ b/Modules/M3/Support/ModuleInfo.php
@@ -0,0 +1,26 @@
+ 'OTM',
+ 'features' =>
+ [
+ ],
+];
diff --git a/Modules/OTM/Console/.gitkeep b/Modules/OTM/Console/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Database/Migrations/.gitkeep b/Modules/OTM/Database/Migrations/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Database/Seeders/.gitkeep b/Modules/OTM/Database/Seeders/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Database/Seeders/OTMDatabaseSeeder.php b/Modules/OTM/Database/Seeders/OTMDatabaseSeeder.php
new file mode 100644
index 00000000..350cc60c
--- /dev/null
+++ b/Modules/OTM/Database/Seeders/OTMDatabaseSeeder.php
@@ -0,0 +1,21 @@
+call("OthersTableSeeder");
+ }
+}
diff --git a/Modules/OTM/Database/factories/.gitkeep b/Modules/OTM/Database/factories/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Helpers/.gitkeep b/Modules/OTM/Helpers/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Helpers/Helper.php b/Modules/OTM/Helpers/Helper.php
new file mode 100644
index 00000000..6c1fee50
--- /dev/null
+++ b/Modules/OTM/Helpers/Helper.php
@@ -0,0 +1,12 @@
+registerTranslations();
+ $this->registerConfig();
+ $this->registerViews();
+ $this->registerHelpers();
+ $this->registerCommands();
+ $this->loadMigrationsFrom(module_path(ModuleInfo::name(), 'Database/Migrations'));
+ }
+
+ /**
+ * Register the service provider.
+ *
+ * @return void
+ */
+ public function register(): void
+ {
+ $this->app->register(RouteServiceProvider::class);
+ }
+
+ /**
+ * Register the helpers.
+ *
+ * @return void
+ */
+ protected function registerHelpers(): void
+ {
+ foreach (glob(__DIR__.'/../Helpers/*.php') as $filename) {
+ require_once $filename;
+ }
+ }
+
+ /**
+ * Dynamically Register Commands.
+ *
+ * @return void
+ */
+ public function registerCommands(): void
+ {
+ if (!$this->app->runningInConsole()) {
+ return;
+ }
+ $commandPath = __DIR__ . '/../Console';
+ $commands = collect(File::allFiles($commandPath))
+ ->map(function ($file) {
+ $class = 'Modules\\' . $this->moduleName . '\\Console\\' . $file->getFilenameWithoutExtension();
+ return $class;
+ })
+ ->filter(function ($class) {
+ return class_exists($class);
+ })
+ ->values()
+ ->all();
+ $this->commands($commands);
+ }
+
+ /**
+ * Register config.
+ *
+ * @return void
+ */
+ protected function registerConfig(): void
+ {
+ $this->publishes([
+ module_path(ModuleInfo::name(), 'Config/config.php') => config_path( ModuleInfo::nameLower(). '.php'),
+ ], 'config');
+ $this->mergeConfigFrom(
+ module_path(ModuleInfo::name(), 'Config/config.php'), ModuleInfo::nameLower()
+ );
+ }
+
+ /**
+ * Register views.
+ *
+ * @return void
+ */
+ public function registerViews(): void
+ {
+ $viewPath = resource_path('views/modules/' . ModuleInfo::nameLower());
+ $sourcePath = module_path(ModuleInfo::name(), 'Resources/views');
+ $this->publishes([
+ $sourcePath => $viewPath
+ ], ['views', ModuleInfo::nameLower() . '-module-views']);
+ $this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), ModuleInfo::nameLower());
+ }
+
+ /**
+ * Register translations.
+ *
+ * @return void
+ */
+ public function registerTranslations(): void
+ {
+ $langPath = resource_path('lang/modules/' . ModuleInfo::nameLower());
+
+ if (is_dir($langPath)) {
+ $this->loadTranslationsFrom($langPath, ModuleInfo::nameLower());
+ } else {
+ $this->loadTranslationsFrom(module_path(ModuleInfo::name(), 'Resources/lang'), ModuleInfo::nameLower());
+ }
+ }
+
+ /**
+ * Regsiter View Paths
+ * @return array
+ */
+ private function getPublishableViewPaths(): array
+ {
+ $paths = [];
+ foreach (Config::get('view.paths') as $path) {
+ if (is_dir($path . '/modules/' . ModuleInfo::nameLower())) {
+ $paths[] = $path . '/modules/' . ModuleInfo::nameLower();
+ }
+ }
+ return $paths;
+ }
+}
diff --git a/Modules/OTM/Providers/RouteServiceProvider.php b/Modules/OTM/Providers/RouteServiceProvider.php
new file mode 100644
index 00000000..90c1b80a
--- /dev/null
+++ b/Modules/OTM/Providers/RouteServiceProvider.php
@@ -0,0 +1,69 @@
+mapApiRoutes();
+
+ $this->mapWebRoutes();
+ }
+
+ /**
+ * Define the "web" routes for the application.
+ *
+ * These routes all receive session state, CSRF protection, etc.
+ *
+ * @return void
+ */
+ protected function mapWebRoutes()
+ {
+ Route::middleware('web')
+ ->namespace($this->moduleNamespace)
+ ->group(module_path('OTM', '/Routes/web.php'));
+ }
+
+ /**
+ * Define the "api" routes for the application.
+ *
+ * These routes are typically stateless.
+ *
+ * @return void
+ */
+ protected function mapApiRoutes()
+ {
+ Route::prefix('api')
+ ->middleware('api')
+ ->namespace($this->moduleNamespace)
+ ->group(module_path('OTM', '/Routes/api.php'));
+ }
+}
diff --git a/Modules/OTM/Resources/assets/.gitkeep b/Modules/OTM/Resources/assets/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Resources/assets/js/app.js b/Modules/OTM/Resources/assets/js/app.js
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Resources/assets/sass/app.scss b/Modules/OTM/Resources/assets/sass/app.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Resources/lang/.gitkeep b/Modules/OTM/Resources/lang/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Resources/views/.gitkeep b/Modules/OTM/Resources/views/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Resources/views/index.blade.php b/Modules/OTM/Resources/views/index.blade.php
new file mode 100644
index 00000000..fe3d2a83
--- /dev/null
+++ b/Modules/OTM/Resources/views/index.blade.php
@@ -0,0 +1,9 @@
+@extends('otm::layouts.master')
+
+@section('content')
+ Hello World
+
+
+ This view is loaded from module: {!! config('otm.name') !!}
+
+@endsection
diff --git a/Modules/OTM/Resources/views/layouts/master.blade.php b/Modules/OTM/Resources/views/layouts/master.blade.php
new file mode 100644
index 00000000..531f82c7
--- /dev/null
+++ b/Modules/OTM/Resources/views/layouts/master.blade.php
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ Module OTM
+
+ {{-- Laravel Mix - CSS File --}}
+ {{-- --}}
+
+
+
+ @yield('content')
+
+ {{-- Laravel Mix - JS File --}}
+ {{-- --}}
+
+
diff --git a/Modules/OTM/Routes/.gitkeep b/Modules/OTM/Routes/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Routes/api.php b/Modules/OTM/Routes/api.php
new file mode 100644
index 00000000..11cc6ffd
--- /dev/null
+++ b/Modules/OTM/Routes/api.php
@@ -0,0 +1,18 @@
+get('/otm', function (Request $request) {
+ return $request->user();
+});
\ No newline at end of file
diff --git a/Modules/OTM/Routes/web.php b/Modules/OTM/Routes/web.php
new file mode 100644
index 00000000..671307a1
--- /dev/null
+++ b/Modules/OTM/Routes/web.php
@@ -0,0 +1,16 @@
+group(function() {
+ Route::get('/', 'OTMController@index');
+});
diff --git a/Modules/OTM/Support/.gitkeep b/Modules/OTM/Support/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Modules/OTM/Support/ModuleInfo.php b/Modules/OTM/Support/ModuleInfo.php
new file mode 100644
index 00000000..2a7ade2d
--- /dev/null
+++ b/Modules/OTM/Support/ModuleInfo.php
@@ -0,0 +1,26 @@
+