<?php 

namespace Webfan;

use Dotenv\Dotenv;
use Dotenv\Exception\InvalidEncodingException;
use Dotenv\Exception\InvalidPathException;
use Dotenv\Loader\Loader;
use Dotenv\Parser\Parser;
use Dotenv\Repository\RepositoryBuilder;
use Dotenv\Store\StoreBuilder;

use frdlweb\StubRunnerInterface;
use Frdlweb\WebAppInterface;

use GuzzleHttp\Psr7\Response;

use Webfan\Webfat\App\KernelFunctions;

use Webfan\Webfat\App\Kernel;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;

use Webfan\Webfat\App\ContainerCollection;


use Psr\Log\LogLevel;
use Monolog\Logger;
use Monolog\Handler\StreamHandler as LoggerStreamHandler;
use Psr\Log\LoggerInterface;
use Monolog\Registry as LoggerRegistry;

use Webfan\Webfat\Filesystems\PathResolvingFilesystem as StreamHandler;

use IvoPetkov\HTML5DOMDocument;
use Webfan\Webfat\HTMLServerComponentsCompiler;

use League\Route\Router as MainRouter;

use Webfan\Batch as Sequence;

use Webfan\Module;

class AppLauncher 
	//extends Module 
	implements WebAppInterface
{
	//use \Webfan\ngModuleTrait;
	
   protected $dotenv=false;
   protected $app=null;
   protected $Stubrunner;
   protected $container = null;
   protected $_env = null;
   protected $_booted = false;
   protected $webUriBase = null;
   protected $_Document = null;
	
   public function __construct( StubRunnerInterface $Stubrunner ){ 
	   $this->Stubrunner = $Stubrunner;	   
   }
	
   public function getName():string
   {
		return self::class;
   }

	public function KernelFunctions(){ 
		return new KernelFunctions;
	}	
	
/*	
	public function getBootSequence(){
		if($this->getContainer()->has('$.boot.sequence') ){
			return $this->getContainer()->get('$.boot.sequence');
		}
		
		
		$this->getContainer()->set('$.boot.sequence', function(){
			$sequence = new Sequence(\get_class($this));
			$sequence->setTimezone();
			$sequence->detect();
			$sequence->getENV();
			$sequence->Application->config(); 
			$sequence->Application->Modules->load();        
			$sequence->Autoloader->register();
			$sequence->loadContainer();        
			$sequence->setApplication = [$sequence->Application];
			$sequence->Requesthandler->handleCliRequest();
			$sequence->Requesthandler->handleHttpRequest();
			return $sequence;
		});
		
		return $this->getContainer()->get('$.boot.sequence');
	}
	
*/	
  public function boot(){
	if(false === $this->_booted){
		 $this->_boot();	
	}	  
  }
	
	
    public function setTimezone(){
		\Webfan\Patches\Start\Timezone::defaults( );
	}
	
	public function getWebUriBase() : string | bool {
 
        if(null !== $this->webUriBase){
             return $this->webUriBase;
        }


		$u = explode('?', $_SERVER['REQUEST_URI']);
		$uri = $u[0];
	 //	$this->webUriBase = dirname($_SERVER['PHP_SELF']);
       
		// $base = dirname($_SERVER['PHP_SELF']);
			 $base =  $this->KernelFunctions()->webUriRoot(dirname($this->Stubrunner->getStubVM()->location), false);
		 
         if( $this->KernelFunctions()->isRewriteRequest()
		       && file_exists($_SERVER['DOCUMENT_ROOT'].\DIRECTORY_SEPARATOR.'.htaccess')
		   ){ 
				   $this->webUriBase = $base;
	      //    $this->webUriBase  =  rtrim($base, '/ ').'/'. basename($this->Stubrunner->getStubVM()->location);	
			
		 }elseif(!file_exists($_SERVER['DOCUMENT_ROOT'].\DIRECTORY_SEPARATOR.'.htaccess')){ 
			  $this->webUriBase  = $base.'/'. basename($this->Stubrunner->getStubVM()->location);	
		 }elseif(!$this->KernelFunctions()->isRewriteRequest() && !file_exists($_SERVER['DOCUMENT_ROOT'].\DIRECTORY_SEPARATOR.'.htaccess')){ 
			  $this->webUriBase  = $base.'/'. basename($this->Stubrunner->getStubVM()->location);	
		 }
//
	  	$this->webUriBase = rtrim($base, '/ ').'/'; 
 
		return $this->webUriBase;
	}	
	
  protected function _boot(){
	if(false !== $this->_booted){
		return;
	}
		 $this->_booted=true;	
	  $me= &$this;
	  
  //    $Sequence = $this->getBootSequence();
	 

	  $this->detect();	 
	  $this->container = $this->bootContainer();	  
	  
	 // $this->container = $this->bootContainer();	  
  }	
	
   protected function _clearClass(){
	   if(null === $this->app || !is_object($this->app) || true !== $this->app instanceof WebAppInterface){
		       $ShutdownTasks = \frdlweb\Thread\ShutdownTasks::mutex();
		        $ShutdownTasks(function($file){
					if(file_exists($file)  && filemtime($file) < time() - (60 * 60)){
					  unlink($file);	
					}
				}, $this->Stubrunner->getRemoteAutoloader()->file(\get_class($this)));
	   }	  
   }
						
   public function __destruct(){
	// NO NO NO  not in __destruct $this->_clearClass();
   }
	
	
   public function launch(bool $verbose = true){
	   $this->boot(); 
	   
	   if(!$this->KernelFunctions()->isCLI() ){
		   $request = $this->getContainer()->get('request');
		   $response = $this->handle($request);
		   if(true === $verbose && is_object($response) && $response instanceof \Psr\Http\Message\ResponseInterface){ 
			   (new \Laminas\HttpHandlerRunner\Emitter\SapiEmitter)->emit($response);
		   }
		 
	   }elseif($this->KernelFunctions()->isCLI() ){
		 return $this->handleCliRequest();
	   }/*else{
		   $response = $this->getContainer()->get('response');
             $response =  $response->withBody(
				 \GuzzleHttp\Psr7\Utils::streamFor('Could not handle request ('.\PHP_SAPI.') in '.__METHOD__)
			 );				
		   $response = $response->withStatus(500);		   
	    // throw new \Exception('Could not handle request ('.\PHP_SAPI.') in '.__METHOD__);	
       }*/
	   
	  return $response;
   }	
	
	public function handle(ServerRequestInterface $request) : ResponseInterface
	{		
	   $this->boot();
		
	   if($this->app !== $this && null !== $this->app && is_object($this->app) &&  $this->app instanceof WebAppInterface){			  
		 return \call_user_func_array([$this->app, 'handle'], func_get_args());
	   }
		
	//	$response = $this->getContainer()->get('response');
		
	///	$response = $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor( $this->_patch_index() ));	
		
		//use https://relayphp.com/ !!!
			$origin = $request->getHeader('Origin');
 

	if(  $this->getContainer()->has('router') ){	
		
		 
		$path = $this->getContainer()->get('request')->getUri()->getPath();
		$method = $this->getContainer()->get('request')->getMethod();
		
		$homeRoute = 'home.'.strtolower($method);
		if(!$this->hasRoute($homeRoute) && $method !== 'GET'){
			$homeRoute = 'home.post';
		}
		
		 
		if('/'===$path && $path !== $this->getContainer()->get('params.webroot.uri') && $this->hasRoute($homeRoute)  ){
			$response = $this->getContainer()->get('response');
			$response =  $response->withHeader('Location', $this->getRoute($homeRoute,  []) );	
		    $response = $response->withStatus(302);
			return $response;
		}//  / = $path
		
		
		try{
		  $router = $this->getContainer()->get('router');
		  $response = $router->dispatch($request);
		   $response = $response->withStatus(200);
		}catch(\League\Route\Http\Exception\NotFoundException $e){
		//	die($e->getMessage());
		     $response = new Response(404);
          //   $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor( $this->_patch_index( '404.html') ));		
			$response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor( $this->_patch_index( 'template.404.php') ));		
		   $response = $response->withStatus(404);
		}catch(\Exception $e){
		     $response = new Response(500);
             $response =  $response->withBody(
				 \GuzzleHttp\Psr7\Utils::streamFor( '<h1>Error</h1><error>'. $e->getMessage().'</error>')
			 );				
		   $response = $response->withStatus(500);
		}
		
			if(is_string($response)){
	           $response2 = new Response(200);
               $response =  $response2->withBody(\GuzzleHttp\Psr7\Utils::streamFor($response));			
			}
	}else{//$this->hasContainer()
		     $response = new Response(404);
             $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor( 
				 '<h1>Not found</h1>'																				
				 .'There is no container available which has a router!'
			     .' - You should continue the installation!'										   
			 ));			
		   $response = $response->withStatus(404);
	}
		
	    if($origin){
			$response =  $response->withHeader('Access-Control-Allow-Origin', $origin);	
		}else{
           $response = $response->withHeader('Access-Control-Allow-Origin', '*');	
		}

			
		$ConentType = $this->getResponseHeader('Content-Type', $response);
		if(false === $ConentType || 'text/html' === $ConentType){
		  $contents = (string) $response->getBody();
	//	  $contents = $this->patch_ob_handler($this->Document->compile($contents));
		  $contents = $this->Document->compile($contents);
		  $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor($contents));
		}	
		
		
		return $response;
	}
	
	public function getContainer() : ContainerInterface
	{
	  //  $this->boot(); 
	   if($this->app !== $this && null !== $this->app && is_object($this->app) &&  $this->app instanceof WebAppInterface){			  
		 return \call_user_func_array([$this->app, 'getContainer'], func_get_args());
	   }		
		
		if(null === $this->container){
		 $this->container = $this->bootContainer();	 
		}
		return $this->container;
	}
		
	public function handleCliRequest()
	{		
	   $this->boot();
	   if($this->app !== $this && null !== $this->app && is_object($this->app) &&  $this->app instanceof WebAppInterface){			  
		 return \call_user_func_array([$this->app, 'handleCliRequest'], func_get_args());
	   }
		
		 // throw new \Exception('Not implemented yet ('.\PHP_SAPI.') in '.__METHOD__.' '.$argv[0]);	
	}
			
	
   protected function detect(){		   
	   $this->getENV();
   }	
   public function env(){	
	   if(null !== $this->_env){
		  return $this->_env;   
	   }
	   $this->_env = $this->getENV()->load();
	  return $this->_env;
   }	
   public function getApplication() :?WebAppInterface{	
	   return $this->app;
   }
   public function setApplication(WebAppInterface $app){		   
	   $this->app = $app;
	   return $this;
   }	
	
   protected function getENV(){	
	   if(false !== $this->dotenv){
		 return $this->dotenv;   
	   }
	   $repository = RepositoryBuilder::createWithDefaultAdapters()->make();	   
	   
	  // $StoreBuilder = StoreBuilder::createWithDefaultName( ['.env', 'example.env']);
	    $StoreBuilder = StoreBuilder::createWithNoNames(  );
	   $StoreBuilder =  $StoreBuilder ->addName('.env.dist');
	   $StoreBuilder = $StoreBuilder ->addName('.env');
	    $StoreBuilder = $StoreBuilder ->addName('.env.local');
	    $StoreBuilder = $StoreBuilder ->addName('.frdl.env');
	   $StoreBuilder =  $StoreBuilder ->addName('.webfan.env'); 
	  // die(getenv('HOME'));
	   $StoreBuilder->addPath(getcwd());
	   $globs = [getcwd().'/*.env'];
	   if(is_dir(getenv('HOME'))){
	        $globs = [getenv('HOME').'/*.env'];
	        $StoreBuilder = $StoreBuilder->addPath(getenv('HOME'));
	   }
	   if(is_dir(getenv('FRDL_WORKSPACE'))){
	        $globs = [getenv('FRDL_WORKSPACE').'/*.env'];
		 $StoreBuilder =   $StoreBuilder->addPath(getenv('FRDL_WORKSPACE'));
	   }
	   
	    $StoreBuilder =   $StoreBuilder->addPath($_SERVER['DOCUMENT_ROOT']);
	   
	   
	   $envFiles = [];
	   foreach($globs as $glob){
		   $envFiles = array_merge($envFiles, glob($glob));
	   }
	   
	   /*
	   if( 0 === count($envFiles)){
					
		   $envFile = rtrim(getenv('FRDL_WORKSPACE'), \DIRECTORY_SEPARATOR) . \DIRECTORY_SEPARATOR . '.env';						  
		   if(!file_exists($envFile)){							
			   touch($envFile);						
		   }

           $writer = new \MirazMac\DotEnv\Writer($envFile);
           $writer->set('FRDL_BUILD_FLAVOR', '1.3.6.1.4.1.37553.8.1.8.1.1089085');
           $writer->write();
	   }
	   */
	   $store = $StoreBuilder->make();
	   
	    $this->dotenv = new Dotenv($store, new Parser(), new Loader(), $repository);
	   
	   return $this->dotenv;
   }		


	
	
	public function getResponseHeader($header, $response = null) : string | bool {  
		if(!is_null($response) && is_object($response) && $response instanceof ResponseInterface){
			foreach ($response->getHeaders() as $name => $values) {   
				if($name === $header || strtolower($name) === strtolower($header) ){
					return implode(', ', $values);
				}
			}			
		}
		
		if( $this->getContainer()->has('response') ){
			foreach ($this->getContainer()->get('response')->getHeaders() as $name => $values) {   
				if($name === $header || strtolower($name) === strtolower($header)){
					return implode(', ', $values);
				}
			}
		}


		// if(null === $response){
		// 	$response = \headers_list();
		// }
		// foreach ($response as $key => $r) {
		foreach (\headers_list() as $key => $r) {
     // Match the header name up to ':', compare lower case   
			if (\stripos($r, $header . ':') === 0) {      
				list($headername, $headervalue) = explode(":", $r, 2);      
				return trim($headervalue);    
			}  
		}
		return false;	
	}	
	
	
	
	
	public function &__get($name){
		$me = &$this;
		switch($name){			
			case 'Stubrunner' :
				 return $this->Stubrunner;
				break;
			case 'Document' :
				  if(null === $this->_Document){	
				    	$this->_Document = $this->HTMLDOcument;
				  }
				  return $this->_Document;
				break;
			case 'HTML5DOMDocument' :	
			case 'HTMLDOcument' :			
			//$HTMLDOcument = call_user_func(function(Kernel $me){
				 $obj = \Webfan\Script::create(function ($arg = []) use(&$me)  {  		
					 $withDocType = isset($arg['DocType']) ? $arg['DocType'] : '<!DOCTYPE html>';		
					 $content = isset($arg['content']) ? $arg['content'] : '';		
					 if(is_string($withDocType) && $withDocType !== substr($content, 0, strlen($withDocType))){        
						 $strtpl = "%s%s";          
						 $content=sprintf($strtpl, $withDocType, $content);		       
					 }
					 
					 $this->compiler = isset($arg['compiler']) ? $arg['compiler'] : $me->HTMLCompiler;	
				//	 $this->compiler =$arg['compiler'];					 				
				//	 $this->content =$arg['content'];					
                     $this->dom = new HTML5DOMDocument();
					 $this->dom->substituteEntities = false;
					 $this->dom->loadHTML($content, HTML5DOMDocument::ALLOW_DUPLICATE_IDS);
				 });	
				 $obj->prototype = \Webfan\Script::create([  
					 'compile' => function (string | HTML5DOMDocument $content = '') : string {     	
	                       if(!empty($content)){
						      $this->dom->insertHTML($content);		
						   }
						 
						   $content = $this->save();	   
						   $content = $this->compiler->process($content);						
						 return $content;  
					 },
					 'load' => function (string | HTML5DOMDocument $content = '')  {     	
						 $this->dom->loadHTML($content, HTML5DOMDocument::ALLOW_DUPLICATE_IDS);
						return $this;
					 },
					 'save' => function () : string {     	
						return $this->dom->saveHTML();	 
					 },
					 'doc' => function () {  
						//return $this->document();	
						 return $this->dom;	 
					 },
					 'document' => function () {  
						return $this->dom;	 
					 },
					 'write' => function (string | HTML5DOMDocument $content = '')  {     	
						 $this->dom->insertHTML($content);		 
						return $this;
					 },
				 ]);
			//	 return $obj;
			// }, $this);
				
				$obj = $obj([
			'content' => '',
			'compiler' => $this->HTMLComponentsCompiler,
			'DocType' => '<!DOCTYPE html>',
		]);
					
				     $obj->compiler =  $this->HTMLCompiler;	 		
                     $obj->dom = new HTML5DOMDocument();
					 $obj->dom->substituteEntities = false;
					 $obj->dom->loadHTML('', HTML5DOMDocument::ALLOW_DUPLICATE_IDS);			
				
			return $obj;			
			/* new $HTMLDOcument([					
				'compiler' =>&$this->HTMLComponentsCompiler,	
				'content' => '',
			]);
				 
			return $HTMLDOcument([					
				'compiler' =>&$this->HTMLComponentsCompiler,	
				'content' => '',
			]);*/
				break;
			case HTMLServerComponentsCompiler::class :
			case 'HTMLServerComponentsCompiler' :
			case 'HTMLCompiler' :
			case 'HTMLComponentsCompiler' :
			if(null !== $this->getContainer()){
				
				if($this->getContainer()->has('invoker')){
				 $invoker = $this->getContainer()->get('invoker');
			      $call = function(array | \callable | \closure $callback, array $params = []) use(&$invoker){	 	          
				 	if(is_array($callback)){
			            $fn = (\Closure::fromCallable($callback))->bindTo($callback[0], \get_class($callback[0]));
			             $callback = $fn;		           
				 	}		                                     
					 
					return $invoker->call($callback, $params);		           
				  };
				}else{
					$call = null;
				}
			$compiler = $this->getContainer()->has(HTMLServerComponentsCompiler::class) 
														  ? $this->getContainer()->get(HTMLServerComponentsCompiler::class)        
				    : new HTMLServerComponentsCompiler($this->getContainer()->has('website.components.paths') 
														  ? $this->getContainer()->get('website.components.paths') 
														  : null, 
														 $this->getContainer()->has('call') 
														  ? $this->getContainer()->get('call') 
														  : $call, 
														 $this->getContainer()->has('require') 
														  ? $this->getContainer()->get('require') 
														  : null, 
														  $this->getContainer()->has('define') 
														  ? $this->getContainer()->get('define') 
														  : null);
			

		}else{
			$compiler = new HTMLServerComponentsCompiler();
		}		
					
		if(null === $compiler->getViewTemplateRenderer() 
		   && null !== $this->container
		   && $this->container->has('app.runtime.renderer.default') 
		  ){
			$compiler->setViewTemplateRenderer($this->container->get('app.runtime.renderer.default'));				
		}		
			 	  return $compiler;				
				break;
			case 'CommandCall' :
                    if(null === $this->_CommandCall){            
						if(!is_array($this->argv)){				
							$this->argv = [];   					
						}							      
						if ($this->isCLI() || isset($_SERVER['argv']) ) {	
							$this->argv = array_merge($this->argv, isset($_SERVER['argv']) ? $_SERVER['argv'] : []);       
						} 					
						$this->_CommandCall = new \Webfan\Webfat\Console\CommandCall($this->argv);
					}
				 return $this->_CommandCall;
                break;
		    case 'Console' :				
			case 'console' :
				if( $this->getContainer()->has('Console')){		
					return $this->getContainer()->get('Console');		
				}else{	      
					return new Console([
		             'BIN_PATH.PHP'=>(new \Webfan\Helper\PhpBinFinder())->find(),
		             // 'app_path' => [
		             //     __DIR__ . '/app/Command',
		             //   '@minicli/command-help'
		             // ],
		             'debug' => true,		   		
					], $this->getContainer() );				
				}
				break;
			default:
				if(  $this->getContainer()->has($name)){		
					return $this->getContainer()->get($name);		
				}
				
                 if(isset($this->{$name})){
					 return $this->{$name};
				 }
				
				 // throw new \InvalidArgumentException('Cannot magically __get('.$name.') in '.__METHOD__);
				 return null;
				break;
		}
	}	
	
	
	
	
	
	//@@webfanconfigquery@@
   public function _patch_index($filename = 'index.html'){
	   
	 //  return($this->getRoute('worker.get'));
	 //  die(__FILE__.__LINE__.$filename);
	   $webfanconfigquery = $this->getContainer()->get('config.webfan.js.config.query'); //'DEBUG.enabled=true';
	   
	   $filename.=(!empty($webfanconfigquery))  
		         ? ''//'?'.$webfanconfigquery 
		         : '';
	   
	   
return <<<HTMLCODE
<!DOCTYPE html>
<html>
<head>
<script>
(async ()=>{
 var c = await fetch('https://cdn.startdir.de'  
			  +'/@webfan3/io4/$filename');
	var HtmlContents =  (await c.text())		     
		    .replace(/(\@\@title\@\@)/g, '⚙️ Default-Page - @@domain@@  ����')
		    .replace(/(\@\@domain\@\@)/g, self.location.host) 
		    .replace(/(\@\@headline\@\@)/g, 'Default-Page')  
		    .replace(/(\@\@webfanconfigquery\@\@)/g, '$webfanconfigquery');			  
	//console.log('HtmlContents', HtmlContents);
    document.open(  );	
    document.write(HtmlContents);	
    document.close(  );	
})(); 
</script>
</head>
<body>
<noscript>
Your browser must support javascript to run this application! [<a href="https://startdir.de">start</a>]
</noscript>
<img class="loading-img" style="border: none;" src="data:image/gif;base64,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"> Loading...
</body>
</html>
HTMLCODE; 
   }	
	
	
	public function getAppId(){
	  return 'circuit:1.3.6.1.4.1.37553.8.1.8.8.1958965301.5.1';	
	}
	
    public function findAppDir($AppId = null, string $userdir = null, $create = false, bool $getSources = false)
    { 
		
        if(null===$userdir){ 
            $userdir = getcwd();
        }		
        if(null===$AppId){ 
            $AppId = $this->getAppId();
        }

        $dir = getenv('FRDL_WORKSPACE');

        $sources = [];   
        $pathFinderStageOneApp = \Phpactor\PathFinder\PathFinder::fromAbsoluteDestinations($userdir, [
                         'source' =>'<module>/<section>',
                         'legacy' =>  $_SERVER['DOCUMENT_ROOT'].'/../<module>/<section>/../..',
                         'blue' =>  $dir.'/apps/'.urlencode($AppId).'/deployments/blue/<module>/<section>',
                         'green' => $dir.'/apps/'.urlencode($AppId).'/deployments/green/<module>/<section>',
          ]);

        $pathFinderStageOneAppSuggestions = $pathFinderStageOneApp->destinationsFor('deploy/app');
        $pathFinderStageOneAppSuggestions['legacy' ] = $_SERVER['DOCUMENT_ROOT'].'/..';

        $pathFinder = \Phpactor\PathFinder\PathFinder::fromAbsoluteDestinations($userdir, [
                         'source' => 'config/<module>/<section>.php',
                         'dir' =>  $dir.'/config/<module>',
                         'file' => $dir.'/config/<module>/<section>.php',
          ]);

        $targetsAdmin = $pathFinder->destinationsFor('config/superadmin/superadmin.php');
        $sources['superadmin'] = $targetsAdmin;
		
      //  $domains = $pathFinder->destinationsFor('config/domains/domains.php');
     //   $this->sources['domains'] = $domains;		

        $pathFinderWebrootDir = \Phpactor\PathFinder\PathFinder::fromAbsoluteDestinations($userdir, [
                         'source' => //'1.3.6.1.4.1.37553.8.1.8.8.11.6'
                                     urlencode($AppId)
                                     .'/'. '<module>'.'/'.'<section>.php',
                         'dir' =>  $dir.'/'
                      //   . '1.3.6.1.4.1.37553.8.1.8.8.11.6'
                         .urlencode($AppId)
                         .'/'. '<module>',
                         'file' => $dir.'/'
                        // . '1.3.6.1.4.1.37553.8.1.8.8.11.6'
                          .urlencode($AppId)
                         .'/'.'<module>'.'/'.'<section>.php',
          ]);

        $targetsWebrootDir = $pathFinderWebrootDir->destinationsFor(
         //  '1.3.6.1.4.1.37553.8.1.8.8.11.6'
             urlencode($AppId)
           .'/'.sha1(str_replace(getenv('HOME'), '', $_SERVER['DOCUMENT_ROOT'])).'/'.'app.php');
        $sources['webrootconfig'] = $targetsWebrootDir;

             $data = [
                'VERSION'=> sha1_file(__FILE__),
                'DOCUMENT_ROOT'=>[
                    'relative'=> str_replace(getenv('HOME'), '', $_SERVER['DOCUMENT_ROOT']),
                    'absolute'=> $_SERVER['DOCUMENT_ROOT'],

                ],
				'app' => [					
					//'initial' =>$this->getAppId(),
					//'main' => null,
					//'api'=>null,
					//'cdn'=>null,
					//'central'=>null,
					//'global'=>null,
				],
				'apps' => [
					//$this->getAppId() => [						
					//
					//],
				 ],
                'stage'=>'blue',
                'stages'=>$pathFinderStageOneAppSuggestions,
             ];


        if(true === $create && !is_dir($sources['webrootconfig']['dir'])){
            mkdir($sources['webrootconfig']['dir'], 0775, true);
        }

        $webrootconfig = file_exists($sources['webrootconfig']['file'])
                          ? require $sources['webrootconfig']['file']
                          : [
                             'VERSION'=> false,//sha1_file(__FILE__),
                          ];

        if(true === $create &&
             (
                    !file_exists($sources['webrootconfig']['file'])
                 || $webrootconfig['VERSION'] !== $data['VERSION']
             )
          ){
		//	$data = array_merge_recursive($webrootconfig, $data);
			
			$data = array_merge($webrootconfig, $data);
			
			if(!isset($data['app']['initial'])){
				$data['app']['initial'] = $AppId;
			}
			
			if(!isset($data['apps'][$AppId])){
				$data['apps'][$AppId] = [];
			}
			
            $exp = var_export($data, true);
            $code = '<?php return '.$exp.';';

            file_put_contents($sources['webrootconfig']['file'], $code);
        }


        $webrootconfig = file_exists($sources['webrootconfig']['file'])
                          ? require $sources['webrootconfig']['file']
                          : $data;

        $sources['@runtime/webrootconfig'] = $webrootconfig;
		$stage =$this->getContainer()->has('stage') && is_string($this->getContainer()->get('stage')) 
			? $this->getContainer()->get('stage')
			: $webrootconfig['stage'];
    
		return true === $getSources ? $sources : $webrootconfig['stages'][$stage];
    }	

	public function getCommonJSDefinition(){
	  return (function(ContainerInterface $container){

               $ContainerBuilder = $container;

		  $publicKeyChanged = false;
		  $increaseTimelimit = true;

		 $setPublicKey = function($baseUrl, $expFile, $pubKeyFile){
		 if(file_exists($expFile)){
		  $expires = intval(file_get_contents($expFile));
		 }else{
		   $expires = 0;
		 }


			if(!is_dir(dirname($expFile))){
			   mkdir(dirname($expFile), 0775, true);
			}

			if(!is_dir(dirname($pubKeyFile))){
			   mkdir(dirname($pubKeyFile), 0775, true);
			}

		   if($expires > 0 && ($expires === time() || ($expires > time() - 3 && $expires < time() + 3))){
		   sleep(3);
		   }
		  if($expires <= time()  || !file_exists($pubKeyFile) ){
		  	$opts =[
		'http'=>[
		    'method'=>'GET',
		    //'header'=>"Accept-Encoding: deflate, gzip\r\n",
		    ],

			];
		  $context = stream_context_create($opts);
		  $key = file_get_contents($baseUrl.'/?source=@server.key', false, $context);
		  foreach($http_response_header as $i => $header){
		    $h = explode(':', $header);
			if('x-frdlweb-source-expires' === strtolower(trim($h[0]))){
				file_put_contents($expFile, trim($h[1]) );
				break;
			}
		 }

		  file_put_contents($pubKeyFile, $key);
		  }

		 };

		 $getDefaultValidatorForUrl = function($baseUrl, $cacheDir, $increaseTimelimit = true) use($setPublicKey, &$publicKeyChanged) {
		 $expFile =  rtrim($cacheDir, '\\/ ') .	\DIRECTORY_SEPARATOR.'validator-'.sha1($baseUrl).strlen($baseUrl).'.expires.txt';
		 $pubKeyFile =  rtrim($cacheDir, '\\/ ') .	\DIRECTORY_SEPARATOR.'validator-'.sha1($baseUrl).strlen($baseUrl).'.public-key.txt';

		//  $setPublicKey($baseUrl, $expFile, $pubKeyFile);

		// $condition = function($url, &$loader, $class) use($baseUrl, $increaseTimelimit){
		$condition = function($url) use($baseUrl, $increaseTimelimit){

		if($baseUrl === substr($url, 0, strlen($baseUrl) ) ){
	    	if($increaseTimelimit){
		    	set_time_limit(max(180, intval(ini_get('max_execution_time')) + 90));
		    }
			return true;
		}else{
		  return false;
		}
		 };


		 $cb = null;
		// $filter = function($code, &$loader, $class, $c = 0) use(&$cb, $baseUrl, $expFile, $pubKeyFile, $setPublicKey, &$publicKeyChanged) {
		 $filter = function($code, $c = 0) use(&$cb, $baseUrl, $expFile, $pubKeyFile, $setPublicKey, &$publicKeyChanged) {
		    $c++;
		$sep = 'X19oYWx0X2NvbXBpbGVyKCk7';
		$my_signed_data=$code;
		  $setPublicKey($baseUrl, $expFile, $pubKeyFile);
		$public_key = file_get_contents($pubKeyFile);

		list($plain_data,$sigdata) = explode(base64_decode($sep), $my_signed_data, 2);
		list($nullVoid,$old_sig_1) = explode("----SIGNATURE:----", $sigdata, 2);
		list($old_sig,$ATTACHMENT) = explode("----ATTACHMENT:----", $old_sig_1, 2);
		 $old_sig = base64_decode($old_sig);
		 $ATTACHMENT = base64_decode($ATTACHMENT);
		if(empty($old_sig)){
		  return new \Exception("ERROR -- unsigned data");
		}
		\openssl_public_decrypt($old_sig, $decrypted_sig, $public_key);
		$data_hash = sha1($plain_data.$ATTACHMENT).substr(str_pad(strlen($plain_data.$ATTACHMENT).'', 128, strlen($plain_data.$ATTACHMENT) % 10, \STR_PAD_LEFT), 0, 128);
		if($decrypted_sig === $data_hash && strlen($data_hash)>0){
		return $plain_data;
		}else{
		if(!$publicKeyChanged && $c <= 1){
		   $publicKeyChanged = true;
		   unlink($pubKeyFile);
		   unlink($expFile);
		   $setPublicKey($baseUrl, $expFile, $pubKeyFile);
		   return $cb($code, $c);
		}
		return new \Exception("ERROR -- untrusted signature");
		}
		  };
		$cb = $filter;
		   return [$condition, $filter];
		 };


		 $getDefaultValidators = function($cacheDir, $increaseTimelimit = true) use($getDefaultValidatorForUrl) {
		return [
		    $getDefaultValidatorForUrl('https://latest.software-download.frdlweb.de', $cacheDir, $increaseTimelimit),
		    $getDefaultValidatorForUrl('https://stable.software-download.frdlweb.de', $cacheDir, $increaseTimelimit),
		//    $getDefaultValidatorForUrl('https://startdir.de/install', $cacheDir, $increaseTimelimit),
		    $getDefaultValidatorForUrl('https://startdir.de/install/latest', $cacheDir, $increaseTimelimit),
		    $getDefaultValidatorForUrl('https://startdir.de/install/stable', $cacheDir, $increaseTimelimit),
		    $getDefaultValidatorForUrl('https://webfan.de/install/stable', $cacheDir, $increaseTimelimit),
		    $getDefaultValidatorForUrl('https://webfan.de/install/latest', $cacheDir, $increaseTimelimit),
		    $getDefaultValidatorForUrl('https://webfan.de/install/modules', $cacheDir, $increaseTimelimit),
		];
		 };

			   $cacheDir = rtrim(($ContainerBuilder->has('app.runtime.dir')
								 ? $ContainerBuilder->get('app.runtime.dir') 
								 : getenv('FRDL_WORKSPACE') ) )
						              .\DIRECTORY_SEPARATOR. 'runtime' .\DIRECTORY_SEPARATOR
				                       . 'cache' .\DIRECTORY_SEPARATOR. 'modules' .\DIRECTORY_SEPARATOR;

		        if(!is_dir($cacheDir)){
		           mkdir($cacheDir, 0775, true);
				}

		   $commonJS =\Webfan\Script\Modules::getInstance('global',[
		           'tmpPath' =>$cacheDir,  // \sys_get_temp_dir(),
		           'basePath' =>  [//'oid:1.3.6.1.4.1.37553.8.1.8.1.1089085' => AppBuilderWebmasters::class,

					   rtrim(($ContainerBuilder->has('app.runtime.dir')
								 ? $ContainerBuilder->get('app.runtime.dir') 
								 : getenv('FRDL_WORKSPACE') ))
						              .\DIRECTORY_SEPARATOR. 'modules' .\DIRECTORY_SEPARATOR,

					   rtrim(($ContainerBuilder->has('app.runtime.dir')
								 ? $ContainerBuilder->get('app.runtime.dir') 
								 : getenv('FRDL_WORKSPACE') ))
						              .\DIRECTORY_SEPARATOR. 'node_modules' .\DIRECTORY_SEPARATOR,
					    ($ContainerBuilder->has('app.runtime.stub')
						 && $ContainerBuilder->has('app.runtime.codebase') && null !== $ContainerBuilder->get('app.runtime.stub') )
					       ? $ContainerBuilder->get('app.runtime.codebase')->getRemoteModulesBaseUrl()
					       : 'https://webfan.de/install/modules',
					   'https://startdir.de/install',
		               'https://webfan.de/install/stable',
		               'https://webfan.de/install/latest',
		           //    'https://webfan.de/install/modules',
                      'https://stable.software-download.frdlweb.de',
					   'https://latest.software-download.frdlweb.de',
		               $ContainerBuilder->get('app.runtime.dir'),
		           ],
		           'modulesExt' => '.php',
		           'folderAsModuleFileName' => 'index.php',
		           'packageInfoFileName' => 'package.php',
		           //   'autoNamespacing' => false,
		           'autoNamespacing' => true,
		           'autoNamespacingCacheExpires' =>
				   ('dev'===$ContainerBuilder->get('app.runtime.env')?1:3)
					* 24*60*60,
		           'validators' => $getDefaultValidators( rtrim($ContainerBuilder->get('app.runtime.dir'), '\\/ ')
						              .\DIRECTORY_SEPARATOR. 'runtime' .\DIRECTORY_SEPARATOR. 'cache' .\DIRECTORY_SEPARATOR
		                                                 .'prune-month'.\DIRECTORY_SEPARATOR, true),
		       ],
		        [
		            'json' => __DIR__ . '/plugins/commonsjs-plugin.json.php',
		            'yaml' => __DIR__ . '/plugins/commonsjs-plugin.yaml.php',
		            ]
		        );
		       $commonJS['exec'] = function(\callable | \closure $callback, array $params = []) use(&$commonJS){
		              extract($commonJS);
		           $args = [$define, $require, &$exports, &$module];
		           foreach($params as $param){
		              array_push($args, $param);
		           }
		           return call_user_func_array($callback, $args);
		       };
 

		       return $commonJS;
		   });	
	}
	
		
	/*
$this->container->get('router')
   ->getNamedRoute('webmaster.dashboard')
   ->getPath([
	   'module' => 'welcome',
	   'path' => 'index.html',
   ]))
*/
	public function getRoute(string $name, array $params = []) : bool |  string
	{
		if(!$this->hasRoute($name)){
			 return false;
		}
		

		return $this->getContainer()->get('router')  
			->getNamedRoute($name)   
			->getPath($params);
	}

	public function hasRoute(string $name) : bool 
	{
		$router = null !== $this->getContainer() && $this->getContainer()->has('router') 
			? $this->getContainer()->get('router') 
			: false;
      
		 if(false === $router){
		   return false;	 
		 }
		try{
			return is_string( $router->getNamedRoute($name) ->getPath() );
		}catch(\Exception $e){
		   return false;	
		}
			
	}


  public function bootContainer(){
	if(null !== $this->container){
		return $this->container;
	}
	 
	  $me= &$this;
	  

	  $this->container = new ContainerCollection([
			/*
		  'call' =>(function(ContainerInterface $container)  {                 
				$invoker = $container->get('invoker');
			      $call = function(array | \callable | \closure $callback, array $params = []) use(&$invoker){		
                    //$call = function(  \callable | \closure $callback, array $params = []) use(&$invoker){		          
				 	if(is_array($callback)){
			            $fn = (\Closure::fromCallable($callback))->bindTo($callback[0], \get_class($callback[0]));
			             $callback = $fn;		           
				 	}		                                     
					 
					return $invoker->call($callback, $params);		           
				  };
                   
			  return $call;
		     }),	 			  
		  */
		  
		  
		     'config.webfan.js.config'=> [function(ContainerInterface $container, $previous = null)  {
				 $config =[];
				$config['DEBUG'] =(object)  [
					  'enabled' => 'true',	
					  'test' => [
						  'main' ,
						  'maintenance' ,
					   ],
				];
				  
				$config['website'] = (object)  [
					  'worker' =>  (object) [
						   'enabled' => 'true',	
						 // 'script' => urlencode('https://'.$_SERVER['HTTP_HOST'].$container->get('kernel')->getRoute('worker.get')),
						   'script' => urlencode($container->get('kernel')->getRoute('worker.get', [
							       'buildhash' => $container->get('config.webfan.js.buildhash'),
							       'file' => 'service-worker.js',							   
						   ])),
						  'scope' => urlencode('/'),
					   ],					
				];
				return  (object) $config;
			 }, 'factory'],	 	 


		
		  
		  
		     'config.webfan.js.config.query'=> [function(ContainerInterface $container, $previous = null)  {
				 $configquery =  preg_replace('/\.[0-9]+/simU', '[]', 
											  str_replace(['%5B', '%5D', '%2F'], ['.', '', ''],  \http_build_query(
					 //[]
					 $container->get('config.webfan.js.config')
					 , '', '&', \PHP_QUERY_RFC1738
					 //, '', '&', \PHP_QUERY_RFC1738
				 )));
				return $configquery;
			 }, 'factory'],	 	  
 
 			'container'=> [function(ContainerInterface $container, $previous = null)  {
				return $container->get('kernel')->getContainer();
			 }, 'factory'],	 			  
 			'kernel'=> [function(ContainerInterface $container, $previous = null)  {
				return $container->get(AppLauncher::class);
			 }, 'factory'],	   			  
 			WebAppInterface::class=> [function(ContainerInterface $container, $previous = null)  {
				return $container->get('kernel');
			 }, 'factory'],	   
		   'app.runtime.kernel' => [function(ContainerInterface $container){	
				 return $container->get('kernel');
			 }, 'factory'],	    
		   'app.runtime.dir' => [function(ContainerInterface $container, $previous = null)  {
				// return $container->get(AppLauncher::class)->findAppDir($container->get(AppLauncher::class)->getAppId());
			    return $container->get('kernel')->findAppDir($container->get('kernel')->getAppId(), null, true);
			 }, 'factory'],	    
			
	 'router.builder.main.decorated' =>  [function(ContainerInterface $container, $previous = null)  {
		  
		  // if(null === $previous){
		//	 $previous =new MainRouter;   
		 //  }
		 // $previous =new MainRouter;   
		 
		 //  $router = $previous;
		     $router =new MainRouter;   
		  
          $webBaseUri =$container->get('params.webroot.uri');
		 
		 $router->group($webBaseUri, function (\League\Route\RouteGroup $route) {  			
			 
			 //PUT IT IN GLOBAL SCOPE "/" !!!   
			//	$route->map('GET', '/assets/{buildhash}/{file:.*}',
			 $route->map('GET', '/service-worker.js',
							//'/index.php/'. str_replace('/index.php/', '', '/index.php/service-worker.js'),
						 //controller.assets.view.service-worker.main.script
							function(  \Psr\Http\Message\ServerRequestInterface $request, array $args,WebAppInterface $kernel ){
								$buildhash =$kernel->getContainer()->get('config.webfan.js.buildhash');
								$filename = 'service-worker.js';
								 $webfanconfigquery = $kernel->getContainer()->get('config.webfan.js.config.query');
								 $regexSplitHost = '/\:\/\//';
								

								         $contents = '';
								 $contents.=<<<WORKERSCRIPT
'use strict';
 
  if('undefined'!==typeof self && 'undefined'===typeof window && 
	 'function' === typeof importScripts){
      workerContext();
  }else{
      windowContext();
  }


function windowContext(){

(async ()=>{
 var c = await fetch('https://cdn.startdir.de/webfan.php?$webfanconfigquery' );
    Function( await c.text() )();	
})(); 

}


 function workerContext(){
  importScripts('https://cdn.startdir.de/~bundle/run/$buildhash'
				+ '-'+(new Date()).getFullYear() + '-' + ((new Date()).getMonth()+1)+ '-' + (new Date()).getDate()
				+'/@webfan3/io4/$filename');
 }	
WORKERSCRIPT;
								// $contents.= print_r($args, true);
								 $response = new Response(200);
				                 $response =  $response->withHeader('Content-Type', 'application/javascript');
								 $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor($contents));
								 return $response;						
							 })->setName('worker.get');	
	 
	 
	 
	 
	 
	 			$homepageIndexHandler = function(  \Psr\Http\Message\ServerRequestInterface $request,WebAppInterface  $kernel ){
								         $contents = '';
								 $contents.=$kernel->_patch_index('template.php');
								// $contents.= print_r($args, true);
								 $response = new Response(200);            
								 $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor($contents));
								 return $response;						
							 };
	
				$route->map('GET', '/', $homepageIndexHandler)->setName('home.get');	
			//	$route->map('GET', 'index.php', $homepageIndexHandler);
			//	$route->map('GET', 'index.php/', $homepageIndexHandler);
			//	$route->map('POST', 'index.php/', $homepageIndexHandler)->setName('home.post');	
			 	$route->map('POST', '/', $homepageIndexHandler)->setName('home.post');	
		});
          //root group
								
		/*						
		$router->group($webBaseUri.'app', function (\League\Route\RouteGroup $route) { 
				$route->map('GET', '/assets/{website}/{build}/{app}/{module}/{type}/{path}', 
							 function(  \Psr\Http\Message\ServerRequestInterface $request,
									  array $args){
								         $contents = '';
								 $contents.='ToDo admin...';
								 $response = new Response(200);            
								 $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor($contents));
								 return $response;						
							 })
					->setName('website.assets.build.item');		
		});
		 
		 
		 //1.3.6.1.4.1.37553.8.1.8.8.1958965301.4
		$router->group($webBaseUri.'1.3.6.1.4.1.37553.8.1.8.8.1958965301.4', function (\League\Route\RouteGroup $route) { 
				$route->map('GET', '/webfake/cron', 
							 function(  \Psr\Http\Message\ServerRequestInterface $request,
									  array $args, \Frdlweb\WebAppInterface $kernel){
								        $shared = $kernel->getShared('cronjobs',   'txt', 'webfan');
				                        if(($shared->isLocked() && isset($shared->lastrun) && intval($shared->lastrun) >= time() - 60)
										   || isset($shared->lastrun) && intval($shared->lastrun) >= time() - 60
										  ){
											return [
											  'message' => 'Cronjob running allready!',
											  'code'=>200,
											];
										}else{
											$result = $kernel->exec('cron default --fake=web', true);
											return [
											  'message' => 'Run cron...',
											  'code'=>200,
											  'result' => $result,
											];											
										}
							 })
					->setName('global.console.cron.webfake');		
		});		 
		 
		 */
        return $router;
	 }, 'factory'],	   		
		 
		'router.builder.injector' =>  (function(){
		
 
	$builder = \call_user_func(function(){
		     $b = \Webfan\Script::create(function () {	
		
			 });					 
        $b->prototype = \Webfan\Script::create([
	     'build' => function(\League\Route\Router $router, string $webBaseUri, WebAppInterface $kernel)   {
                  

		 /*
			$router->group($webBaseUri.'1.3.6.1.4.1.37553.8.1.8.8.91397908338147', function (\League\Route\RouteGroup $route) { 
			
          
 
				$route->map('GET', '/admin/dashboard/{module}/{path}', 
							 function(\Psr\Http\Message\ServerRequestInterface $request,
									  array $args){
						         $contents = '';
								 $contents.='ToDo admin...';
								 $response = new Response(200);            
								 $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor($contents));
								 return $response;			
							 })
					->setName('webmaster.dashboard');		
				
					$route->map('GET', '/admin/error/resolver', 
							 function(\Psr\Http\Message\ServerRequestInterface $request,
									  array $args){
						         $contents = '';
								 $contents.='ToDo admin...';
								 $response = new Response(200);            
								 $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor($contents));
								 return $response;			
							 })
					->setName('webmaster.error.resolver');					
				
					
				$route->map('GET', '/admin/{intent}/{module}/{action}/{path}', 
							 function(\Psr\Http\Message\ServerRequestInterface $request,
									  array $args){
					         $contents = '';
								 $contents.='ToDo admin...';
								 $response = new Response(200);            
								 $response =  $response->withBody(\GuzzleHttp\Psr7\Utils::streamFor($contents));
								 return $response;					
							 })
					->setName('webmaster.setup');			
				
				
			})
				 // ->lazyMiddleware(string $middleware)
				;
					 

							*/

						
		return $router;				
	},//$fn $b->build			
		
		]);		//$b->prototype
		
		
		
		return $b;		
	});	 
				

		
	  $RouterBuilder = $builder();
     return $RouterBuilder;
	}),			
			
			
			
	//$manager = new Statical\Manager();
	'FacadesAliasManager'=>  (function(ContainerInterface $container){				 
	     $manager = class_exists(\frdl\Facades::class) ? new \frdl\Facades() : new \Statical\Manager();
	  return $manager;
	}),				  
		  
	'router'=>  (function(ContainerInterface $container){				 
	//	$router = $container->get('router.cached')->setStrategy( $container->get('ApplicationStrategy') );
		$router = $container->get('router.cached');
	  return $router;
	}),		
			
	'router.cached'=> (function(ContainerInterface $container){	 
		
		     $webBaseUri =$container->get('params.webroot.uri');
		
		         $routerBuildHash = $container->get('config.webfan.js.buildhash');
		
				  $cacheFile =  rtrim($container->get('app.runtime.dir'), '\\/ ') 
					  .	\DIRECTORY_SEPARATOR.'runtime'
					  .	\DIRECTORY_SEPARATOR.'cache.compiled-cache'
					  .	\DIRECTORY_SEPARATOR.'router'
					  .	\DIRECTORY_SEPARATOR 
					     .$container->get('kernel')->KernelFunctions()->toUUID5(
					        $container->get('request.host'),
                            \Webfan\Webfat\App\KernelFunctions::UUID_NAMEBASED_NS_DNS
					     )
					  .	\DIRECTORY_SEPARATOR.'routes.cache.'
					  .$routerBuildHash
					  .'.txt';
		
		           //routes.cache.3b778af416b89b7eb5921fc9353664a65b9107e6.txt		          		 
		          $ShutdownTasks = \frdlweb\Thread\ShutdownTasks::mutex();
		          $ShutdownTasks(function($cacheFile){
		           $oldfiles = glob(dirname($cacheFile).'/routes.cache.*.txt');
		           foreach($oldfiles as $oFile){ 
		               if(filemtime($oFile)<time()-24*60*60 && $oFile !== $cacheFile){
						   unlink($oFile);
					   }
				   }				  
			      }, $cacheFile);
		
		        //  echo $cacheFile;
		                       
		 		
		
				  if(!is_dir(dirname($cacheFile))){
					 mkdir(dirname($cacheFile), 0775, true);  
				  }
				
				 $cacheStore = new \League\Route\Cache\FileCache($cacheFile, 86400);

		      

				$cachedRouter = (new \Webfan\Router(
					                                          //$container,
					                                         $container->get('container'),
															  $cacheStore,
															  'league/route/cache', 
															  'router.builder.injector', 
															   'router.builder.main.decorated',
															   $container->get('ApplicationStrategy'),
															   $container->get('app.runtime.kernel'),
															   true
															 ));			
				
				
				 // $cachedRouter = $cachedRouter->setStrategy( $strategy );
				return $cachedRouter;
		}),			
					  
		  
			   'params.webroot.uri' => [function(ContainerInterface $container, $previous = null)  {
				 return \is_callable([$container->get('app.runtime.kernel'), 'getWebUriBase'])
					    ? \call_user_func([$container->get('app.runtime.kernel'), 'getWebUriBase'])
					 : dirname($_SERVER['PHP_SELF']);
			 }, 'factory'],	    
/*
		  'params.webroot.uri' => [$this, 'getWebUriBase'],
		  */
		   'config.webfan.js.buildhash' => (function(ContainerInterface $container, $previous = null)  {
			 
			   $webBaseUri =$container->get('params.webroot.uri');
			   
			     $routerBuildHash = sha1(
                           \sha1_file(__FILE__)	
					 .'@@@'
					 .$container->get('app.runtime.dir')
					 .'@@@'
					 .$webBaseUri
				 );
			    // echo($routerBuildHash);
			   return $routerBuildHash;
			 }),	    		  
		  	  

		  
			\League\Route\Strategy\StrategyInterface::class =>(function(ContainerInterface $container){
			   return $container->get('ApplicationStrategy');
			}),
			'ApplicationStrategy' =>  (function(ContainerInterface $container){
				 $ApplicationStrategy = new \Webfan\Webfat\App\ApplicationStrategy();
		    	 $ApplicationStrategy = $ApplicationStrategy->setContainer($container->get('container'));
					//$ApplicationStrategy = $ApplicationStrategy->setContainer($container);
				return $ApplicationStrategy;
			}),
		  
			\Invoker\InvokerInterface::class =>  (function(ContainerInterface $container){	
				 return $container->get('invoker');
			}),
		  
			'invoker' =>(function(ContainerInterface $container){			  		
				$invoker =  (new \Invoker\Invoker(null, $container->get('container') ));
				//$invoker =  (new \Invoker\Invoker(null, $container ));
				$invoker->getParameterResolver()->prependResolver(						
					new \Invoker\ParameterResolver\Container\ParameterNameContainerResolver($container->get('container'))
				//	new \Invoker\ParameterResolver\Container\ParameterNameContainerResolver($container)
				);
				$invoker->getParameterResolver()->prependResolver(
					new \Invoker\ParameterResolver\Container\TypeHintContainerResolver($container->get('container'))
					//new \Invoker\ParameterResolver\Container\TypeHintContainerResolver($container)
				); 
				return $invoker;
		    }),	

 
		   \Psr\Http\Message\ResponseInterface::class =>(function(ContainerInterface $container){
			   return $container->get('response');
			}),		      
			'response'=> (function(ContainerInterface $container){
				 return new Response(200);
			}),		   
			'request'=> (function(ContainerInterface $container){
				
			   //   $webBaseUri =$container->get('params.webroot.uri');
		
		   		
				 $request = \GuzzleHttp\Psr7\ServerRequest::fromGlobals();
				 $request = $request->withUri($request->getUri()->withHost($container->has('context.host')
											    ? $container->get('context.host')
											    : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST']) 
											  )); 
				/*
				 if($container->get('kernel')->KernelFunctions()->isRewriteRequest() 
					&& $webBaseUri !== substr($request->getUri()->getPath(), 0, strlen($webBaseUri)) ){
					 $request = $request->withUri($request->getUri()->withPath($webBaseUri.$request->getUri()->getPath())); 				 
				 }
				 */
				 if($container->get('kernel')->KernelFunctions()->isRewriteRequest() ){
					 $request = $request->withUri($request->getUri()->withPath($request->getUri()->getPath())); 				 
				 }
				return $request;
			}),
			  
			'request.host'=> [function(ContainerInterface $container, $previous = null){
				return $container->get('request')->getUri()->getHost();
			 }, 'factory'],	   
		   
		   
				
		   'module.loader.CommonJS' => $this->getCommonJSDefinition(), 				
		
			'define' => (function(ContainerInterface $container){
				 $commonJS = $container->get('module.loader.CommonJS');
		       return $commonJS['define'];
		    }),
	
		  'defined' =>(function(ContainerInterface $container){
				 $commonJS = $container->get('module.loader.CommonJS');
		       return $commonJS['defined'];
		   }),
			
			'require' => (function(ContainerInterface $container){
				 $commonJS = $container->get('module.loader.CommonJS');
		       return $commonJS['require'];
		   }),		   
	   ], ContainerCollection::NULL_ONERROR);
	   			
	   
	   
	        $this->container->factory('app.runtime.stub', function( $container, $previous = null) {
				return $container->get('kernel')->Stubrunner->getStub();
			//	return $container->get('kernel')->Stubrunner;
		     });	
	 	
			$this->container->factory('app.runtime.stubrunner', function( $container, $previous = null) use(&$me){
				return $me->Stubrunner;
		     });	
						
			$this->container->factory('app.runtime.codebase', function( $container, $previous = null) {
				return   $container->get('app.runtime.stubrunner')->getCodebase();
		     });	
			$this->container->factory('app.runtime.autoloader.remote', function( $container, $previous = null) {
				return // !$container->has('app.runtime.stub')
					// || !$container->has('app.runtime.stubrunner')
					// || null===$container->get('app.runtime.stub') 
					//? $previous 
					//: $container->get('app.runtime.stubrunner')->getRemoteAutoloader();
					$container->get('app.runtime.stubrunner')->getRemoteAutoloader();
		     });				
				
			
					$this->container->set('files.index.php', (null !== $this->Stubrunner->getStub() )
								  ? ''.$this->Stubrunner->getStub()->location
								  : \get_included_files()[0]
								 );	
	   $this->container->set(self::class, $this);	  
	  
	  
			/*
		  'call' =>(function(ContainerInterface $container)  {                 
				$invoker = $container->get('invoker');
			      $call = function(array | \callable | \closure $callback, array $params = []) use(&$invoker){		
                    //$call = function(  \callable | \closure $callback, array $params = []) use(&$invoker){		          
				 	if(is_array($callback)){
			            $fn = (\Closure::fromCallable($callback))->bindTo($callback[0], \get_class($callback[0]));
			             $callback = $fn;		           
				 	}		                                     
					 
					return $invoker->call($callback, $params);		           
				  };
                   
			  return $call;
		     }),	 			  
			  
	     $this->container->set('call', function(){
			 
		 });  	
			$this->container->set('call', function( )  use(&$me){
				$invoker = $me->getContainer()->get('invoker');
			      $call = function(array | \callable | \closure $callback, array $params = []) use(&$invoker){		
                    //$call = function(  \callable | \closure $callback, array $params = []) use(&$invoker){		          
				 	if(is_array($callback)){
			            $fn = (\Closure::fromCallable($callback))->bindTo($callback[0], \get_class($callback[0]));
			             $callback = $fn;		           
				 	}		                                     
					 
					return $invoker->call($callback, $params);		           
				  };
                   
			  return $call;
		     });	  
	  */
	  
	  
	    // $this->detect();	 
	   if(null === $this->app || !is_object($this->app) || true !== $this->app instanceof WebAppInterface){
		     //  $this->container->unregister('kernel');
		      // $this->container->set('kernel', $this->app);
		   
		      $this->_clearClass();
	   }else{
		   if($this->container->has('kernel')){
		   	$this->container->unregister('kernel');
		   }
		   $this->container->set('kernel', $this->app);   
	   }
	  
	return $this->container;
  }	
						

}__halt_compiler();----SIGNATURE:----mXS7H10Y1Ob9ee5/0sIqejvTzix48a6/x0OlR9pbYcaoCyIB08Cvj1e5q5G6AuLgAMWnU2jo3Uvb99UKQVEa3AeMSKoFBxtnEoy+5iWwM9VDtGjB7G/0IFu1v2uJf6AU2MWHe1Fhq/jaIVaVbx3PF604Y1PxESG85SP44DeGk+/zPpGozls+DihFAzueDdRDuQx1a+aKhX10/Of3QebPZV48MqttG3uIAb4IjRPnQKzah3DghIWl4ZJ62pKUQpgiwQfMCYPkvVyzYan6l038vQVlLytTpABfeDpYFuLH0rXr8OmDa+FXIBM0uiiU2/1M4r8mKnWVvN+YOlZjGe71j6KkcRGKLnBAaonLo+o6put2VcwW87TJG/8v25iIW94NLEmKHhUJpJ2K8tQ4cMYhjeTApGiZA7oiM+UeSKXR6FPfZDSu3NEb6EySqQyYitKLVJc1pa47LFyGcGJWOEt+bOg7xOUohb1PbB5dccgOK+qoYpUB5rGe25PGUspVNujKYTDsI+Rescw0YM9aTI+KDJ8uo7CG7Rx5bxyxqJIXbwH/ChwfTP5+8NvXDzw5fWn2pcRO1gzS6Q7NglP71W42rlEf8jmKMc8XrmpTXvG6fKhTrTA1QIkx2q1HU6mTuHPH3BapAEDPdPqzgMbftbyXrncg5Yem8AjXvjRFsdTaZUo=----ATTACHMENT:----Mjg2Mjg0NjMyNzM2MDMxNiA2NTYxNDQyMTQwNDQ4NDggMzAzOTY5NjA1NTk3ODU5Mg==