create-prisma-php-app 1.23.8 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,9 +18,26 @@ date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'UTC');
18
18
 
19
19
  function determineContentToInclude()
20
20
  {
21
- $scriptUrl = $_SERVER['REQUEST_URI'];
22
- $scriptUrl = explode('?', $scriptUrl, 2)[0];
23
- $uri = $_SERVER['SCRIPT_URL'] ?? uriExtractor($scriptUrl);
21
+ /**
22
+ * ============ URI Handling ============
23
+ * The $requestUri variable now contains the full URI including query parameters.
24
+ * Examples:
25
+ * - Home page: '/'
26
+ * - Dynamic routes with parameters (e.g., '/dashboard?v=2' or '/profile?id=5')
27
+ * ======================================
28
+ */
29
+ $requestUri = $_SERVER['REQUEST_URI'];
30
+ $requestUri = empty($_SERVER['SCRIPT_URL']) ? uriExtractor($requestUri) : $requestUri;
31
+ /**
32
+ * ============ URI Path Handling ============
33
+ * The $uri variable now contains the URI path without query parameters and without the leading slash.
34
+ * Examples:
35
+ * - Home page: '' (empty string)
36
+ * - Dynamic routes (e.g., '/dashboard?v=2' or '/profile?id=5') -> Only the path part is returned (e.g., 'dashboard' or 'profile'), without the query parameters.
37
+ * ============================================
38
+ */
39
+ $scriptUrl = explode('?', $requestUri, 2)[0];
40
+ $uri = $_SERVER['SCRIPT_URL'] ?? $scriptUrl;
24
41
  $uri = ltrim($uri, '/');
25
42
  $baseDir = APP_PATH;
26
43
  $includePath = '';
@@ -46,7 +63,7 @@ function determineContentToInclude()
46
63
  }
47
64
 
48
65
  if (!$sameSiteFetch) {
49
- return ['path' => $includePath, 'layouts' => $layoutsToInclude, 'uri' => $uri];
66
+ return ['path' => $includePath, 'layouts' => $layoutsToInclude, 'uri' => $uri, 'requestUri' => $requestUri];
50
67
  }
51
68
  }
52
69
 
@@ -108,26 +125,26 @@ function determineContentToInclude()
108
125
  $includePath = $baseDir . getFilePrecedence();
109
126
  }
110
127
 
111
- return ['path' => $includePath, 'layouts' => $layoutsToInclude, 'uri' => $uri];
128
+ return ['path' => $includePath, 'layouts' => $layoutsToInclude, 'uri' => $uri, 'requestUri' => $requestUri];
112
129
  }
113
130
 
114
131
  function getFilePrecedence()
115
132
  {
116
133
  global $_filesListRoutes;
117
134
 
118
- // Normalize the file paths for consistent comparison
119
135
  foreach ($_filesListRoutes as $route) {
120
- $normalizedRoute = str_replace('\\', '/', $route);
121
- // First, check for route.php
122
- if (preg_match('/^\.\/src\/app\/route\.php$/', $normalizedRoute)) {
136
+ // Check if the file has a .php extension
137
+ if (pathinfo($route, PATHINFO_EXTENSION) !== 'php') {
138
+ continue; // Skip files that are not PHP files
139
+ }
140
+
141
+ // Check for route.php first
142
+ if (preg_match('/^\.\/src\/app\/route\.php$/', $route)) {
123
143
  return '/route.php';
124
144
  }
125
- }
126
145
 
127
- // If no route.php is found, check for index.php
128
- foreach ($_filesListRoutes as $route) {
129
- $normalizedRoute = str_replace('\\', '/', $route);
130
- if (preg_match('/^\.\/src\/app\/index\.php$/', $normalizedRoute)) {
146
+ // If route.php is not found, check for index.php
147
+ if (preg_match('/^\.\/src\/app\/index\.php$/', $route)) {
131
148
  return '/index.php';
132
149
  }
133
150
  }
@@ -292,6 +309,10 @@ function matchGroupFolder($constructedPath): ?string
292
309
  $indexFile = "/src/app/$normalizedConstructedPath/index.php";
293
310
 
294
311
  foreach ($_filesListRoutes as $route) {
312
+ if (pathinfo($route, PATHINFO_EXTENSION) !== 'php') {
313
+ continue;
314
+ }
315
+
295
316
  $normalizedRoute = trim(str_replace('\\', '/', $route), '.');
296
317
 
297
318
  $cleanedRoute = preg_replace('/\/\([^)]+\)/', '', $normalizedRoute);
@@ -340,6 +361,10 @@ function checkForDuplicateRoutes()
340
361
  global $_filesListRoutes;
341
362
  $normalizedRoutesMap = [];
342
363
  foreach ($_filesListRoutes as $route) {
364
+ if (pathinfo($route, PATHINFO_EXTENSION) !== 'php') {
365
+ continue;
366
+ }
367
+
343
368
  $routeWithoutGroups = preg_replace('/\(.*?\)/', '', $route);
344
369
  $routeTrimmed = ltrim($routeWithoutGroups, '.\\/');
345
370
  $routeTrimmed = preg_replace('#/{2,}#', '/', $routeTrimmed);
@@ -603,6 +628,54 @@ function modifyOutputLayoutForError($contentToAdd)
603
628
  exit;
604
629
  }
605
630
 
631
+ function createUpdateRequestData()
632
+ {
633
+ global $_requestUriForFilesIncludes;
634
+
635
+ $requestJsonData = SETTINGS_PATH . '/request-data.json';
636
+
637
+ // Check if the JSON file exists
638
+ if (file_exists($requestJsonData)) {
639
+ // Read the current data from the JSON file
640
+ $currentData = json_decode(file_get_contents($requestJsonData), true);
641
+ } else {
642
+ // If the file doesn't exist, initialize an empty array
643
+ $currentData = [];
644
+ }
645
+
646
+ // Get the list of included/required files
647
+ $includedFiles = get_included_files();
648
+
649
+ // Filter only the files inside the src/app directory
650
+ $srcAppFiles = [];
651
+ foreach ($includedFiles as $filename) {
652
+ if (strpos($filename, DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR) !== false) {
653
+ $srcAppFiles[] = $filename;
654
+ }
655
+ }
656
+
657
+ // Extract the current request URL
658
+ $currentUrl = $_requestUriForFilesIncludes;
659
+
660
+ // If the URL already exists in the data, merge new included files with the existing ones
661
+ if (isset($currentData[$currentUrl])) {
662
+ // Merge the existing and new included files, removing duplicates
663
+ $currentData[$currentUrl]['includedFiles'] = array_unique(
664
+ array_merge($currentData[$currentUrl]['includedFiles'], $srcAppFiles)
665
+ );
666
+ } else {
667
+ // If the URL doesn't exist, add a new entry
668
+ $currentData[$currentUrl] = [
669
+ 'url' => $currentUrl,
670
+ 'includedFiles' => $srcAppFiles,
671
+ ];
672
+ }
673
+
674
+ // Convert the array back to JSON and save it to the file
675
+ $jsonData = json_encode($currentData, JSON_PRETTY_PRINT);
676
+ file_put_contents($requestJsonData, $jsonData);
677
+ }
678
+
606
679
  set_error_handler(function ($severity, $message, $file, $line) {
607
680
  if (!(error_reporting() & $severity)) {
608
681
  // This error code is not included in error_reporting
@@ -659,14 +732,10 @@ function authenticateUserToken()
659
732
  * @var array $metadata Metadata information
660
733
  */
661
734
  $metadata = [];
662
- /**
663
- * @var string $uri The URI of the current request
664
- */
665
- $uri = "";
666
735
  /**
667
736
  * @var string $pathname The pathname of the current request
668
737
  */
669
- $pathname = "";
738
+ $pathname = '';
670
739
  /**
671
740
  * @var array $dynamicRouteParams The dynamic route parameters
672
741
  */
@@ -674,11 +743,11 @@ $dynamicRouteParams = [];
674
743
  /**
675
744
  * @var string $content The content to be included in the main layout file
676
745
  */
677
- $content = "";
746
+ $content = '';
678
747
  /**
679
748
  * @var string $childContent The child content to be included in the layout file
680
749
  */
681
- $childContent = "";
750
+ $childContent = '';
682
751
  /**
683
752
  * @var array $mainLayoutHead The head content to be included in the main layout file
684
753
  */
@@ -687,18 +756,23 @@ $mainLayoutHead = [];
687
756
  * @var array $mainLayoutFooter The footer content to be included in the main layout file
688
757
  */
689
758
  $mainLayoutFooter = [];
759
+ /**
760
+ * @var string $requestUrl - The request URL.
761
+ */
762
+ $requestUri = '';
690
763
 
691
764
  try {
692
765
  $_determineContentToInclude = determineContentToInclude();
693
766
  $_contentToInclude = $_determineContentToInclude['path'] ?? '';
694
767
  $_layoutsToInclude = $_determineContentToInclude['layouts'] ?? [];
695
- $uri = $_determineContentToInclude['uri'] ?? '';
696
- $pathname = $uri ? "/" . $uri : "/";
768
+ $pathname = $_determineContentToInclude['uri'] ? '/' . $_determineContentToInclude['uri'] : '/';
769
+ $requestUri = $_determineContentToInclude['requestUri'] ? $_determineContentToInclude['requestUri'] : '/';
770
+ $_requestUriForFilesIncludes = $requestUri;
697
771
  $_fileToInclude = null;
698
772
  if (is_file($_contentToInclude)) {
699
773
  $_fileToInclude = basename($_contentToInclude); // returns the file name
700
774
  }
701
- $metadata = $_metadataArray[$uri] ?? ($_metadataArray['default'] ?? []);
775
+ $metadata = $_metadataArray[$pathname] ?? ($_metadataArray['default'] ?? []);
702
776
 
703
777
  checkForDuplicateRoutes();
704
778
  authenticateUserToken();
@@ -715,7 +789,7 @@ try {
715
789
  exit;
716
790
  }
717
791
 
718
- $filePath = APP_PATH . '/' . $uri;
792
+ $filePath = APP_PATH . $pathname;
719
793
  if (is_file($filePath)) {
720
794
  if (file_exists($filePath)) {
721
795
  // Check if the file is a PHP file
@@ -791,15 +865,42 @@ try {
791
865
  }
792
866
 
793
867
  if (!$_isContentIncluded && !$_isChildContentIncluded) {
868
+ $secondRequestC69CD = $_data53C84['secondRequestC69CD'] ?? false;
869
+
870
+ if (!$secondRequestC69CD) {
871
+ createUpdateRequestData();
872
+ }
873
+
874
+ $_requestFilesJson = SETTINGS_PATH . '/request-data.json';
875
+ $_requestFilesData = file_exists($_requestFilesJson) ? json_decode(file_get_contents($_requestFilesJson), true) : [];
876
+ if ($_requestFilesData[$_requestUriForFilesIncludes]) {
877
+ $_requestDataToLoop = $_requestFilesData[$_requestUriForFilesIncludes];
878
+
879
+ foreach ($_requestDataToLoop['includedFiles'] as $file) {
880
+ if (file_exists($file)) {
881
+ ob_start();
882
+ require_once $file;
883
+ $childContent .= ob_get_clean();
884
+ }
885
+ }
886
+ }
887
+
794
888
  $content .= $childContent;
795
889
  $content .= getLoadingsFiles();
796
890
 
891
+ if ($secondRequestC69CD) {
892
+ echo $content;
893
+ return;
894
+ }
895
+
797
896
  ob_start();
798
897
  require_once APP_PATH . '/layout.php';
799
898
 
800
- if ($isWire && !isset($_data53C84['secondRequestC69CD'])) {
899
+ if ($isWire && !$secondRequestC69CD) {
801
900
  ob_end_clean();
802
901
  wireCallback();
902
+ } else {
903
+ echo ob_get_clean();
803
904
  }
804
905
  } else {
805
906
  if ($_isContentIncluded) {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{execSync}from"child_process";import fs from"fs";import{fileURLToPath}from"url";import path from"path";import chalk from"chalk";import prompts from"prompts";import https from"https";const __filename=fileURLToPath(import.meta.url),__dirname=path.dirname(__filename);let updateAnswer=null;const nonBackendFiles=["favicon.ico","\\src\\app\\index.php","metadata.php","not-found.php"],dockerFiles=[".dockerignore","docker-compose.yml","Dockerfile","apache.conf"];function bsConfigUrls(e){const s=e.indexOf("\\htdocs\\");if(-1===s)return{bsTarget:"",bsPathRewrite:{}};const t=e.substring(0,s+"\\htdocs\\".length).replace(/\\/g,"\\\\"),n=e.replace(new RegExp(`^${t}`),"").replace(/\\/g,"/");let c=`http://localhost/${n}`;c=c.endsWith("/")?c.slice(0,-1):c;const i=c.replace(/(?<!:)(\/\/+)/g,"/"),o=n.replace(/\/\/+/g,"/");return{bsTarget:`${i}/`,bsPathRewrite:{"^/":`/${o.startsWith("/")?o.substring(1):o}/`}}}async function updatePackageJson(e,s){const t=path.join(e,"package.json");if(checkExcludeFiles(t))return;const n=JSON.parse(fs.readFileSync(t,"utf8"));n.scripts={...n.scripts,projectName:"tsx settings/project-name.ts"};let c=[];s.tailwindcss&&(n.scripts={...n.scripts,tailwind:"postcss src/app/css/tailwind.css -o src/app/css/styles.css --watch"},c.push("tailwind")),s.websocket&&(n.scripts={...n.scripts,websocket:"tsx settings/restart-websocket.ts"},c.push("websocket")),s.docker&&(n.scripts={...n.scripts,docker:"docker-compose up"},c.push("docker")),s.swaggerDocs&&(n.scripts={...n.scripts,"create-swagger-docs":"tsx settings/swagger-config.ts"});let i={...n.scripts};i.browserSync="tsx settings/bs-config.ts",i.dev=`npm-run-all -p projectName browserSync ${c.join(" ")}`,n.scripts=i,n.type="module",s.prisma&&(n.prisma={seed:"tsx prisma/seed.ts"}),fs.writeFileSync(t,JSON.stringify(n,null,2))}async function updateComposerJson(e,s){const t=path.join(e,"composer.json");if(checkExcludeFiles(t))return;let n;if(fs.existsSync(t)){{const e=fs.readFileSync(t,"utf8");n=JSON.parse(e)}s.websocket&&(n.require={...n.require,"cboden/ratchet":"^0.4.4"}),s.prisma&&(n.require={...n.require,"ramsey/uuid":"5.x-dev","hidehalo/nanoid-php":"1.x-dev"}),fs.writeFileSync(t,JSON.stringify(n,null,2))}}async function updateIndexJsForWebSocket(e,s){if(!s.websocket)return;const t=path.join(e,"src","app","js","index.js");if(checkExcludeFiles(t))return;let n=fs.readFileSync(t,"utf8");n+='\n// WebSocket initialization\nconst ws = new WebSocket("ws://localhost:8080");\n',fs.writeFileSync(t,n,"utf8")}async function createUpdateGitignoreFile(e,s){const t=path.join(e,".gitignore");if(checkExcludeFiles(t))return;let n="";s.forEach((e=>{n.includes(e)||(n+=`\n${e}`)})),n=n.trimStart(),fs.writeFileSync(t,n)}function copyRecursiveSync(e,s,t){const n=fs.existsSync(e),c=n&&fs.statSync(e);if(n&&c&&c.isDirectory()){const n=s.toLowerCase();if(!t.websocket&&n.includes("src\\lib\\websocket"))return;if(!t.prisma&&n.includes("src\\lib\\prisma"))return;if(t.backendOnly&&n.includes("src\\app\\js")||t.backendOnly&&n.includes("src\\app\\css"))return;if(!t.swaggerDocs&&n.includes("src\\app\\swagger-docs"))return;const c=s.replace(/\\/g,"/");if(updateAnswer?.excludeFilePath?.includes(c))return;fs.existsSync(s)||fs.mkdirSync(s,{recursive:!0}),fs.readdirSync(e).forEach((n=>{copyRecursiveSync(path.join(e,n),path.join(s,n),t)}))}else{if(checkExcludeFiles(s))return;if(!t.tailwindcss&&(s.includes("tailwind.css")||s.includes("styles.css")))return;if(!t.websocket&&(s.includes("restart-websocket.ts")||s.includes("restart-websocket.bat")))return;if(!t.docker&&dockerFiles.some((e=>s.includes(e))))return;if(t.backendOnly&&nonBackendFiles.some((e=>s.includes(e))))return;if(!t.backendOnly&&s.includes("route.php"))return;if(!t.swaggerDocs&&s.includes("swagger-config.ts"))return;fs.copyFileSync(e,s,0)}}async function executeCopy(e,s,t){s.forEach((({src:s,dest:n})=>{copyRecursiveSync(path.join(__dirname,s),path.join(e,n),t)}))}function createOrUpdateTailwindConfig(e){const s=path.join(e,"tailwind.config.js");if(checkExcludeFiles(s))return;let t=fs.readFileSync(s,"utf8");const n=["./src/**/*.{html,js,php}"].map((e=>` "${e}"`)).join(",\n");t=t.replace(/content: \[\],/g,`content: [\n${n}\n],`),fs.writeFileSync(s,t,{flag:"w"})}function modifyPostcssConfig(e){const s=path.join(e,"postcss.config.js");if(checkExcludeFiles(s))return;fs.writeFileSync(s,"export default {\n plugins: {\n tailwindcss: {},\n autoprefixer: {},\n cssnano: {},\n },\n};",{flag:"w"})}function modifyLayoutPHP(e,s){const t=path.join(e,"src","app","layout.php");if(!checkExcludeFiles(t))try{let e=fs.readFileSync(t,"utf8"),n="";s.backendOnly||(n='\n <link href="<?= $baseUrl; ?>/css/index.css" rel="stylesheet">\n <script src="<?= $baseUrl; ?>/js/index.js"><\/script>');let c="";s.backendOnly||(c=s.tailwindcss?` <link href="<?= $baseUrl; ?>/css/styles.css" rel="stylesheet"> ${n}`:` <script src="https://cdn.tailwindcss.com"><\/script> ${n}`);const i=c.length>0?"\n":"";e=e.replace("</head>",`${c}${i} \x3c!-- Dynamic Head --\x3e\n <?= implode("\\n", $mainLayoutHead); ?>\n</head>`),fs.writeFileSync(t,e,{flag:"w"})}catch(e){}}async function createOrUpdateEnvFile(e,s){const t=path.join(e,".env");checkExcludeFiles(t)||fs.writeFileSync(t,s,{flag:"w"})}function checkExcludeFiles(e){return!!updateAnswer?.isUpdate&&(updateAnswer?.excludeFilePath?.includes(e.replace(/\\/g,"/"))??!1)}async function createDirectoryStructure(e,s){const t=[{src:"/bootstrap.php",dest:"/bootstrap.php"},{src:"/.htaccess",dest:"/.htaccess"},{src:"/../composer.json",dest:"/composer.json"},{src:"/tsconfig.json",dest:"/tsconfig.json"}];s.tailwindcss&&t.push({src:"/postcss.config.js",dest:"/postcss.config.js"},{src:"/tailwind.config.js",dest:"/tailwind.config.js"});const n=[{src:"/settings",dest:"/settings"},{src:"/src",dest:"/src"}];s.backendOnly&&s.swaggerDocs&&n.push({src:"/swagger-docs-layout.php",dest:"/src/app/layout.php"}),s.prisma&&n.push({src:"/prisma",dest:"/prisma"}),s.docker&&n.push({src:"/.dockerignore",dest:"/.dockerignore"},{src:"/docker-compose.yml",dest:"/docker-compose.yml"},{src:"/Dockerfile",dest:"/Dockerfile"},{src:"/apache.conf",dest:"/apache.conf"}),t.forEach((({src:s,dest:t})=>{const n=path.join(__dirname,s),c=path.join(e,t);if(checkExcludeFiles(c))return;const i=fs.readFileSync(n,"utf8");fs.writeFileSync(c,i,{flag:"w"})})),await executeCopy(e,n,s),await updatePackageJson(e,s),await updateComposerJson(e,s),s.backendOnly||await updateIndexJsForWebSocket(e,s),s.tailwindcss&&(createOrUpdateTailwindConfig(e),modifyPostcssConfig(e)),(s.tailwindcss||!s.backendOnly||s.swaggerDocs)&&modifyLayoutPHP(e,s);const c='# Prisma PHP Auth Secret Key For development only - Change this in production\nAUTH_SECRET=uxsjXVPHN038DEYls2Kw0QUgBcXKUyrjv416nIFWPY4= \n \n# PHPMailer\n# SMTP_HOST=smtp.gmail.com or your SMTP host\n# SMTP_USERNAME=john.doe@gmail.com or your SMTP username\n# SMTP_PASSWORD=123456\n# SMTP_PORT=587 for TLS, 465 for SSL or your SMTP port\n# SMTP_ENCRYPTION=ssl or tls\n# MAIL_FROM=john.doe@gmail.com\n# MAIL_FROM_NAME="John Doe"\n\n# SHOW ERRORS - Set to true to show errors in the browser for development only - Change this in production to false\nSHOW_ERRORS=true\n\n# APP TIMEZONE - Set your application timezone - Default is "UTC"\nAPP_TIMEZONE="UTC"\n\n# APP ENV - Set your application environment - Default is "development" - Change this in production to "production"\nAPP_ENV=development';if(s.prisma){const s=`${'# Environment variables declared in this file are automatically made available to Prisma.\n# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema\n\n# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.\n# See the documentation for all the connection string options: https://pris.ly/d/connection-strings\n\nDATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"'}\n\n${c}`;await createOrUpdateEnvFile(e,s)}else await createOrUpdateEnvFile(e,c);await createUpdateGitignoreFile(e,["vendor",".env","node_modules"])}async function getAnswer(e={}){const s=[];e.projectName||s.push({type:"text",name:"projectName",message:"What is your project named?",initial:"my-app"}),e.backendOnly||s.push({type:"toggle",name:"backendOnly",message:`Would you like to create a ${chalk.blue("backend-only project")}?`,initial:!1,active:"Yes",inactive:"No"});const t=()=>{process.exit(0)},n=await prompts(s,{onCancel:t}),c=[];n.backendOnly||e.backendOnly?(e.swaggerDocs||c.push({type:"toggle",name:"swaggerDocs",message:`Would you like to use ${chalk.blue("Swagger Docs")}?`,initial:!1,active:"Yes",inactive:"No"}),e.websocket||c.push({type:"toggle",name:"websocket",message:`Would you like to use ${chalk.blue("Websocket")}?`,initial:!0,active:"Yes",inactive:"No"}),e.prisma||c.push({type:"toggle",name:"prisma",message:`Would you like to use ${chalk.blue("Prisma PHP ORM")}?`,initial:!0,active:"Yes",inactive:"No"}),e.docker||c.push({type:"toggle",name:"docker",message:`Would you like to use ${chalk.blue("Docker")}?`,initial:!1,active:"Yes",inactive:"No"})):(e.swaggerDocs||c.push({type:"toggle",name:"swaggerDocs",message:`Would you like to use ${chalk.blue("Swagger Docs")}?`,initial:!1,active:"Yes",inactive:"No"}),e.tailwindcss||c.push({type:"toggle",name:"tailwindcss",message:`Would you like to use ${chalk.blue("Tailwind CSS")}?`,initial:!0,active:"Yes",inactive:"No"}),e.websocket||c.push({type:"toggle",name:"websocket",message:`Would you like to use ${chalk.blue("Websocket")}?`,initial:!0,active:"Yes",inactive:"No"}),e.prisma||c.push({type:"toggle",name:"prisma",message:`Would you like to use ${chalk.blue("Prisma PHP ORM")}?`,initial:!0,active:"Yes",inactive:"No"}),e.docker||c.push({type:"toggle",name:"docker",message:`Would you like to use ${chalk.blue("Docker")}?`,initial:!1,active:"Yes",inactive:"No"}));const i=await prompts(c,{onCancel:t});return{projectName:n.projectName?String(n.projectName).trim().replace(/ /g,"-"):e.projectName??"my-app",backendOnly:n.backendOnly??e.backendOnly??!1,swaggerDocs:i.swaggerDocs??e.swaggerDocs??!1,tailwindcss:i.tailwindcss??e.tailwindcss??!1,websocket:i.websocket??e.websocket??!1,prisma:i.prisma??e.prisma??!1,docker:i.docker??e.docker??!1}}async function uninstallDependencies(e,s,t=!1){s.forEach((e=>{}));const n=`npm uninstall ${t?"--save-dev":"--save"} ${s.join(" ")}`;execSync(n,{stdio:"inherit",cwd:e})}function fetchPackageVersion(e){return new Promise(((s,t)=>{https.get(`https://registry.npmjs.org/${e}`,(e=>{let n="";e.on("data",(e=>n+=e)),e.on("end",(()=>{try{const e=JSON.parse(n);s(e["dist-tags"].latest)}catch(e){t(new Error("Failed to parse JSON response"))}}))})).on("error",(e=>t(e)))}))}const readJsonFile=e=>{const s=fs.readFileSync(e,"utf8");return JSON.parse(s)};function compareVersions(e,s){const t=e.split(".").map(Number),n=s.split(".").map(Number);for(let e=0;e<t.length;e++){if(t[e]>n[e])return 1;if(t[e]<n[e])return-1}return 0}function getInstalledPackageVersion(e){try{const s=execSync(`npm list -g ${e} --depth=0`).toString().match(new RegExp(`${e}@(\\d+\\.\\d+\\.\\d+)`));return s?s[1]:null}catch(e){return null}}
2
+ import{execSync}from"child_process";import fs from"fs";import{fileURLToPath}from"url";import path from"path";import chalk from"chalk";import prompts from"prompts";import https from"https";const __filename=fileURLToPath(import.meta.url),__dirname=path.dirname(__filename);let updateAnswer=null;const nonBackendFiles=["favicon.ico","\\src\\app\\index.php","metadata.php","not-found.php"],dockerFiles=[".dockerignore","docker-compose.yml","Dockerfile","apache.conf"];function bsConfigUrls(e){const s=e.indexOf("\\htdocs\\");if(-1===s)return{bsTarget:"",bsPathRewrite:{}};const t=e.substring(0,s+"\\htdocs\\".length).replace(/\\/g,"\\\\"),n=e.replace(new RegExp(`^${t}`),"").replace(/\\/g,"/");let c=`http://localhost/${n}`;c=c.endsWith("/")?c.slice(0,-1):c;const i=c.replace(/(?<!:)(\/\/+)/g,"/"),o=n.replace(/\/\/+/g,"/");return{bsTarget:`${i}/`,bsPathRewrite:{"^/":`/${o.startsWith("/")?o.substring(1):o}/`}}}async function updatePackageJson(e,s){const t=path.join(e,"package.json");if(checkExcludeFiles(t))return;const n=JSON.parse(fs.readFileSync(t,"utf8"));n.scripts={...n.scripts,projectName:"tsx settings/project-name.ts"};let c=[];s.tailwindcss&&(n.scripts={...n.scripts,tailwind:"postcss src/app/css/tailwind.css -o src/app/css/styles.css --watch"},c.push("tailwind")),s.websocket&&(n.scripts={...n.scripts,websocket:"tsx settings/restart-websocket.ts"},c.push("websocket")),s.docker&&(n.scripts={...n.scripts,docker:"docker-compose up"},c.push("docker")),s.swaggerDocs&&(n.scripts={...n.scripts,"create-swagger-docs":"tsx settings/swagger-config.ts"});let i={...n.scripts};i.browserSync="tsx settings/bs-config.ts",i.dev=`npm-run-all -p projectName browserSync ${c.join(" ")}`,n.scripts=i,n.type="module",s.prisma&&(n.prisma={seed:"tsx prisma/seed.ts"}),fs.writeFileSync(t,JSON.stringify(n,null,2))}async function updateComposerJson(e,s){const t=path.join(e,"composer.json");if(checkExcludeFiles(t))return;let n;if(fs.existsSync(t)){{const e=fs.readFileSync(t,"utf8");n=JSON.parse(e)}s.websocket&&(n.require={...n.require,"cboden/ratchet":"^0.4.4"}),s.prisma&&(n.require={...n.require,"ramsey/uuid":"5.x-dev","hidehalo/nanoid-php":"1.x-dev"}),fs.writeFileSync(t,JSON.stringify(n,null,2))}}async function updateIndexJsForWebSocket(e,s){if(!s.websocket)return;const t=path.join(e,"src","app","js","index.js");if(checkExcludeFiles(t))return;let n=fs.readFileSync(t,"utf8");n+='\n// WebSocket initialization\nvar ws = new WebSocket("ws://localhost:8080");\n',fs.writeFileSync(t,n,"utf8")}async function createUpdateGitignoreFile(e,s){const t=path.join(e,".gitignore");if(checkExcludeFiles(t))return;let n="";s.forEach((e=>{n.includes(e)||(n+=`\n${e}`)})),n=n.trimStart(),fs.writeFileSync(t,n)}function copyRecursiveSync(e,s,t){const n=fs.existsSync(e),c=n&&fs.statSync(e);if(n&&c&&c.isDirectory()){const n=s.toLowerCase();if(!t.websocket&&n.includes("src\\lib\\websocket"))return;if(!t.prisma&&n.includes("src\\lib\\prisma"))return;if(t.backendOnly&&n.includes("src\\app\\js")||t.backendOnly&&n.includes("src\\app\\css"))return;if(!t.swaggerDocs&&n.includes("src\\app\\swagger-docs"))return;const c=s.replace(/\\/g,"/");if(updateAnswer?.excludeFilePath?.includes(c))return;fs.existsSync(s)||fs.mkdirSync(s,{recursive:!0}),fs.readdirSync(e).forEach((n=>{copyRecursiveSync(path.join(e,n),path.join(s,n),t)}))}else{if(checkExcludeFiles(s))return;if(!t.tailwindcss&&(s.includes("tailwind.css")||s.includes("styles.css")))return;if(!t.websocket&&(s.includes("restart-websocket.ts")||s.includes("restart-websocket.bat")))return;if(!t.docker&&dockerFiles.some((e=>s.includes(e))))return;if(t.backendOnly&&nonBackendFiles.some((e=>s.includes(e))))return;if(!t.backendOnly&&s.includes("route.php"))return;if(!t.swaggerDocs&&s.includes("swagger-config.ts"))return;fs.copyFileSync(e,s,0)}}async function executeCopy(e,s,t){s.forEach((({src:s,dest:n})=>{copyRecursiveSync(path.join(__dirname,s),path.join(e,n),t)}))}function createOrUpdateTailwindConfig(e){const s=path.join(e,"tailwind.config.js");if(checkExcludeFiles(s))return;let t=fs.readFileSync(s,"utf8");const n=["./src/**/*.{html,js,php}"].map((e=>` "${e}"`)).join(",\n");t=t.replace(/content: \[\],/g,`content: [\n${n}\n],`),fs.writeFileSync(s,t,{flag:"w"})}function modifyPostcssConfig(e){const s=path.join(e,"postcss.config.js");if(checkExcludeFiles(s))return;fs.writeFileSync(s,"export default {\n plugins: {\n tailwindcss: {},\n autoprefixer: {},\n cssnano: {},\n },\n};",{flag:"w"})}function modifyLayoutPHP(e,s){const t=path.join(e,"src","app","layout.php");if(!checkExcludeFiles(t))try{let e=fs.readFileSync(t,"utf8"),n="";s.backendOnly||(n='\n <link href="<?= $baseUrl; ?>/css/index.css" rel="stylesheet">\n <script src="<?= $baseUrl; ?>/js/index.js"><\/script>');let c="";s.backendOnly||(c=s.tailwindcss?` <link href="<?= $baseUrl; ?>/css/styles.css" rel="stylesheet"> ${n}`:` <script src="https://cdn.tailwindcss.com"><\/script> ${n}`);const i=c.length>0?"\n":"";e=e.replace("</head>",`${c}${i} \x3c!-- Dynamic Head --\x3e\n <?= getMainLayoutHead(); ?>\n</head>`),fs.writeFileSync(t,e,{flag:"w"})}catch(e){}}async function createOrUpdateEnvFile(e,s){const t=path.join(e,".env");checkExcludeFiles(t)||fs.writeFileSync(t,s,{flag:"w"})}function checkExcludeFiles(e){return!!updateAnswer?.isUpdate&&(updateAnswer?.excludeFilePath?.includes(e.replace(/\\/g,"/"))??!1)}async function createDirectoryStructure(e,s){const t=[{src:"/bootstrap.php",dest:"/bootstrap.php"},{src:"/.htaccess",dest:"/.htaccess"},{src:"/../composer.json",dest:"/composer.json"},{src:"/tsconfig.json",dest:"/tsconfig.json"}];s.tailwindcss&&t.push({src:"/postcss.config.js",dest:"/postcss.config.js"},{src:"/tailwind.config.js",dest:"/tailwind.config.js"});const n=[{src:"/settings",dest:"/settings"},{src:"/src",dest:"/src"}];s.backendOnly&&s.swaggerDocs&&n.push({src:"/swagger-docs-layout.php",dest:"/src/app/layout.php"}),s.prisma&&n.push({src:"/prisma",dest:"/prisma"}),s.docker&&n.push({src:"/.dockerignore",dest:"/.dockerignore"},{src:"/docker-compose.yml",dest:"/docker-compose.yml"},{src:"/Dockerfile",dest:"/Dockerfile"},{src:"/apache.conf",dest:"/apache.conf"}),t.forEach((({src:s,dest:t})=>{const n=path.join(__dirname,s),c=path.join(e,t);if(checkExcludeFiles(c))return;const i=fs.readFileSync(n,"utf8");fs.writeFileSync(c,i,{flag:"w"})})),await executeCopy(e,n,s),await updatePackageJson(e,s),await updateComposerJson(e,s),s.backendOnly||await updateIndexJsForWebSocket(e,s),s.tailwindcss&&(createOrUpdateTailwindConfig(e),modifyPostcssConfig(e)),(s.tailwindcss||!s.backendOnly||s.swaggerDocs)&&modifyLayoutPHP(e,s);const c='# Prisma PHP Auth Secret Key For development only - Change this in production\nAUTH_SECRET=uxsjXVPHN038DEYls2Kw0QUgBcXKUyrjv416nIFWPY4= \n \n# PHPMailer\n# SMTP_HOST=smtp.gmail.com or your SMTP host\n# SMTP_USERNAME=john.doe@gmail.com or your SMTP username\n# SMTP_PASSWORD=123456\n# SMTP_PORT=587 for TLS, 465 for SSL or your SMTP port\n# SMTP_ENCRYPTION=ssl or tls\n# MAIL_FROM=john.doe@gmail.com\n# MAIL_FROM_NAME="John Doe"\n\n# SHOW ERRORS - Set to true to show errors in the browser for development only - Change this in production to false\nSHOW_ERRORS=true\n\n# APP TIMEZONE - Set your application timezone - Default is "UTC"\nAPP_TIMEZONE="UTC"\n\n# APP ENV - Set your application environment - Default is "development" - Change this in production to "production"\nAPP_ENV=development';if(s.prisma){const s=`${'# Environment variables declared in this file are automatically made available to Prisma.\n# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema\n\n# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.\n# See the documentation for all the connection string options: https://pris.ly/d/connection-strings\n\nDATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"'}\n\n${c}`;await createOrUpdateEnvFile(e,s)}else await createOrUpdateEnvFile(e,c);await createUpdateGitignoreFile(e,["vendor",".env","node_modules"])}async function getAnswer(e={}){const s=[];e.projectName||s.push({type:"text",name:"projectName",message:"What is your project named?",initial:"my-app"}),e.backendOnly||s.push({type:"toggle",name:"backendOnly",message:`Would you like to create a ${chalk.blue("backend-only project")}?`,initial:!1,active:"Yes",inactive:"No"});const t=()=>{process.exit(0)},n=await prompts(s,{onCancel:t}),c=[];n.backendOnly||e.backendOnly?(e.swaggerDocs||c.push({type:"toggle",name:"swaggerDocs",message:`Would you like to use ${chalk.blue("Swagger Docs")}?`,initial:!1,active:"Yes",inactive:"No"}),e.websocket||c.push({type:"toggle",name:"websocket",message:`Would you like to use ${chalk.blue("Websocket")}?`,initial:!0,active:"Yes",inactive:"No"}),e.prisma||c.push({type:"toggle",name:"prisma",message:`Would you like to use ${chalk.blue("Prisma PHP ORM")}?`,initial:!0,active:"Yes",inactive:"No"}),e.docker||c.push({type:"toggle",name:"docker",message:`Would you like to use ${chalk.blue("Docker")}?`,initial:!1,active:"Yes",inactive:"No"})):(e.swaggerDocs||c.push({type:"toggle",name:"swaggerDocs",message:`Would you like to use ${chalk.blue("Swagger Docs")}?`,initial:!1,active:"Yes",inactive:"No"}),e.tailwindcss||c.push({type:"toggle",name:"tailwindcss",message:`Would you like to use ${chalk.blue("Tailwind CSS")}?`,initial:!0,active:"Yes",inactive:"No"}),e.websocket||c.push({type:"toggle",name:"websocket",message:`Would you like to use ${chalk.blue("Websocket")}?`,initial:!0,active:"Yes",inactive:"No"}),e.prisma||c.push({type:"toggle",name:"prisma",message:`Would you like to use ${chalk.blue("Prisma PHP ORM")}?`,initial:!0,active:"Yes",inactive:"No"}),e.docker||c.push({type:"toggle",name:"docker",message:`Would you like to use ${chalk.blue("Docker")}?`,initial:!1,active:"Yes",inactive:"No"}));const i=await prompts(c,{onCancel:t});return{projectName:n.projectName?String(n.projectName).trim().replace(/ /g,"-"):e.projectName??"my-app",backendOnly:n.backendOnly??e.backendOnly??!1,swaggerDocs:i.swaggerDocs??e.swaggerDocs??!1,tailwindcss:i.tailwindcss??e.tailwindcss??!1,websocket:i.websocket??e.websocket??!1,prisma:i.prisma??e.prisma??!1,docker:i.docker??e.docker??!1}}async function uninstallDependencies(e,s,t=!1){s.forEach((e=>{}));const n=`npm uninstall ${t?"--save-dev":"--save"} ${s.join(" ")}`;execSync(n,{stdio:"inherit",cwd:e})}function fetchPackageVersion(e){return new Promise(((s,t)=>{https.get(`https://registry.npmjs.org/${e}`,(e=>{let n="";e.on("data",(e=>n+=e)),e.on("end",(()=>{try{const e=JSON.parse(n);s(e["dist-tags"].latest)}catch(e){t(new Error("Failed to parse JSON response"))}}))})).on("error",(e=>t(e)))}))}const readJsonFile=e=>{const s=fs.readFileSync(e,"utf8");return JSON.parse(s)};function compareVersions(e,s){const t=e.split(".").map(Number),n=s.split(".").map(Number);for(let e=0;e<t.length;e++){if(t[e]>n[e])return 1;if(t[e]<n[e])return-1}return 0}function getInstalledPackageVersion(e){try{const s=execSync(`npm list -g ${e} --depth=0`).toString().match(new RegExp(`${e}@(\\d+\\.\\d+\\.\\d+)`));return s?s[1]:null}catch(e){return null}}
3
3
  /**
4
4
  * Install dependencies in the specified directory.
5
5
  * @param {string} baseDir - The base directory where to install the dependencies.
@@ -0,0 +1,6 @@
1
+ {
2
+ "local": "http://localhost:3000",
3
+ "external": "http://192.168.1.23:3000",
4
+ "ui": "http://localhost:3001",
5
+ "uiExternal": "http://192.168.1.23:3001"
6
+ }
@@ -0,0 +1,12 @@
1
+ [
2
+ "./src/app/assets/fonts/GeistMonoVF.woff",
3
+ "./src/app/assets/fonts/GeistVF.woff",
4
+ "./src/app/assets/images/prisma-php.png",
5
+ "./src/app/css/index.css",
6
+ "./src/app/favicon.ico",
7
+ "./src/app/index.php",
8
+ "./src/app/js/index.js",
9
+ "./src/app/layout.php",
10
+ "./src/app/metadata.php",
11
+ "./src/app/not-found.php"
12
+ ]
@@ -1,4 +1,4 @@
1
- import { writeFile } from "fs";
1
+ import { existsSync, unlink, writeFile } from "fs";
2
2
  import { join, basename, dirname, normalize, sep } from "path";
3
3
  import prismaPhpConfig from "../prisma-php.json";
4
4
  import { getFileMeta } from "./utils.js";
@@ -84,3 +84,13 @@ const configFilePath = join(__dirname, "..", "prisma-php.json");
84
84
 
85
85
  // Run the function with your config file path and the new project name
86
86
  updateProjectNameInConfig(configFilePath, newProjectName);
87
+
88
+ const requestDataPath = join(__dirname, "request-data.json");
89
+ if (existsSync(requestDataPath)) {
90
+ unlink(requestDataPath, (err) => {
91
+ if (err) {
92
+ // console.error("Error deleting request-data.json file:", err);
93
+ return;
94
+ }
95
+ });
96
+ }
@@ -117,3 +117,43 @@ function getBearerToken(): ?string
117
117
 
118
118
  return null;
119
119
  }
120
+
121
+ /**
122
+ * Outputs the main layout head content.
123
+ *
124
+ * This function checks if the global variable $mainLayoutHead is an array.
125
+ * If it is, it concatenates the array elements into a single string separated by newlines
126
+ * and echoes the result. If $mainLayoutHead is not an array, it echoes an empty string.
127
+ *
128
+ * @global array|string $mainLayoutHead The main layout head content.
129
+ */
130
+ function getMainLayoutHead()
131
+ {
132
+ global $mainLayoutHead;
133
+
134
+ if (is_array($mainLayoutHead)) {
135
+ echo implode("\n", $mainLayoutHead);
136
+ } else {
137
+ echo '';
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Outputs the main layout footer.
143
+ *
144
+ * This function checks if the global variable $mainLayoutFooter is an array.
145
+ * If it is, it concatenates the array elements into a single string separated by new lines
146
+ * and outputs it. If $mainLayoutFooter is not an array, it outputs an empty string.
147
+ *
148
+ * @global array|string $mainLayoutFooter The main layout footer content.
149
+ */
150
+ function getMainLayoutFooter()
151
+ {
152
+ global $mainLayoutFooter;
153
+
154
+ if (is_array($mainLayoutFooter)) {
155
+ echo implode("\n", $mainLayoutFooter);
156
+ } else {
157
+ echo '';
158
+ }
159
+ }
@@ -1 +1 @@
1
- var eventAttributesB6B56=["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onwheel","onkeypress","onkeydown","onkeyup","onfocus","onblur","onchange","oninput","onselect","onsubmit","onreset","onresize","onscroll","onload","onunload","onabort","onerror","onbeforeunload","oncopy","oncut","onpaste","ondrag","ondragstart","ondragend","ondragover","ondragenter","ondragleave","ondrop","oncontextmenu","ontouchstart","ontouchmove","ontouchend","ontouchcancel","onpointerdown","onpointerup","onpointermove","onpointerover","onpointerout","onpointerenter","onpointerleave","onpointercancel"],stateA129A={checkedElements:new Set},responseDataDEAC2=null,store=null,isNavigatingA12E1=!1,redirectRegex3AE99=/redirect_7F834\s*=\s*(\/[^\s]*)/;function attachWireFunctionEvents(){handleHiddenAttribute();document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((e=>{if(handleAnchorTag(e),eventAttributesB6B56.forEach((t=>{const n=e.getAttribute(t),s=t.slice(2);n&&(e.removeAttribute(t),handleDebounce(e,s,n))})),e instanceof HTMLFormElement){const t=e.getAttribute("onsubmit");t&&(e.removeAttribute("onsubmit"),handleDebounce(e,"submit",t))}})),initializePpOnListeners()}function hasPpOnAttribute(e){const t=e.attributes;if(!t)return!1;for(let e=0;e<t.length;e++){const n=t[e].name;if(n.startsWith("pp-on:")||n.startsWith("data-pp-on:")||n.startsWith("pp-on-")||n.startsWith("data-pp-on-"))return!0}return!1}function findAllPpOnElements(e){const t=[];if(hasPpOnAttribute(e)&&t.push(e),document.evaluate){const n=document.evaluate('.//*[@*[starts-with(name(), "pp-on:") or starts-with(name(), "data-pp-on:") or starts-with(name(), "pp-on-") or starts-with(name(), "data-pp-on-")]]',e,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);let s=n.iterateNext();for(;s;)t.push(s),s=n.iterateNext()}else if("function"==typeof e.getElementsByTagName){const n=e.getElementsByTagName("*");for(let e=0;e<n.length;e++)hasPpOnAttribute(n[e])&&t.push(n[e])}return t}function initializePpOnListeners(){findAllPpOnElements(document).forEach((e=>{Array.from(e.attributes).forEach((t=>{if(t.name.startsWith("pp-on:")){const n=t.name.split(":")[1],s=t.value;s&&e.addEventListener(n,(t=>{try{new Function("event",s).call(e,t)}catch(e){}}))}}))}))}function handleHiddenAttribute(){const e=document.querySelectorAll("[pp-visibility]"),t=document.querySelectorAll("[pp-display]");e.forEach((e=>handleVisibilityElementAttribute(e,"pp-visibility",handleElementVisibility))),t.forEach((e=>handleVisibilityElementAttribute(e,"pp-display",handleElementDisplay)))}function handleVisibilityElementAttribute(e,t,n){const s=e.getAttribute(t);if(s)if(isJsonLike(s)){n(e,parseJson(s))}else{const n=parseTime(s);if(n>0){const s="pp-visibility"===t?"visibility":"display";scheduleChange(e,n,s,"visibility"===s?"hidden":"none")}}}function isJsonLike(e){return"string"==typeof e&&((e=e.trim()).startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))}function handleElementVisibility(e,t){handleElementChange(e,t,"visibility","hidden","visible")}function handleElementDisplay(e,t){handleElementChange(e,t,"display","none","block")}function handleElementChange(e,t,n,s,a){const o=t.start?parseTime(t.start):0,i=t.end?parseTime(t.end):0;o>0?(e.style[n]=s,scheduleChange(e,o,n,a),i>0&&scheduleChange(e,o+i,n,s)):i>0&&scheduleChange(e,i,n,s)}function scheduleChange(e,t,n,s){setTimeout((()=>{requestAnimationFrame((()=>{e.style[n]=s}))}),t)}function parseTime(e){if("number"==typeof e)return e;const t=e.match(/^(\d+)(ms|s|m)?$/);if(t){const e=parseInt(t[1],10);switch(t[2]||"ms"){case"ms":return e;case"s":return 1e3*e;case"m":return 60*e*1e3;default:return e}}return 0}async function handleDebounce(e,t,n){const s=e.getAttribute("pp-debounce")||"",a=e.getAttribute("pp-before-request")||"",o=e.getAttribute("pp-after-request")||"",i=async t=>{t.preventDefault();try{a&&await invokeHandler(e,a,t),await invokeHandler(e,n,t),o&&"@close"!==o&&await invokeHandler(e,o,t),handlerAutofocusAttribute()}catch(e){}};if(s){const n=debounce(i,parseTime(s));e instanceof HTMLFormElement&&"submit"===t?e.addEventListener(t,(e=>{e.preventDefault(),n(e)})):e.addEventListener(t,n)}else e.addEventListener(t,i)}function handlerAutofocusAttribute(){const e=document.querySelectorAll("[pp-autofocus]");let t=!1;e.forEach((e=>{if(t)return;const n=e.getAttribute("pp-autofocus");if(!n||!isJsonLike(n))return;const s=parseJson(n);if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)if("number"===e.type&&e instanceof HTMLInputElement){e.type="text";const t=e.value.length||0;e.setSelectionRange(t,t),e.type="number"}else if(s.start)e.setSelectionRange(0,0);else if(s.end){const t=e.value.length||0;e.setSelectionRange(t,t)}else if(s.length){const t=parseInt(s.length,10)||0;e.setSelectionRange(t,t)}e.focus(),t=!0}))}async function invokeHandler(e,t,n){try{const s=t.match(/^(\w+(\.\w+)*)\((.*)\)$/);if(s){const a=s[1].split("."),{context:o,methodName:i}=resolveContext(a);"function"==typeof o[i]?new Function("event",t).call(e,n):await handleParsedCallback(e,t)}else await handleParsedCallback(e,t)}catch(e){}}function resolveContext(e){let t=window;for(let n=0;n<e.length-1;n++)if(t=t[e[n]],!t)throw new Error(`Cannot find object ${e[n]} in the context.`);return{context:t,methodName:e[e.length-1]}}async function handleParsedCallback(e,t){const{funcName:n,data:s}=parseCallback(e,t);if(!n)return;const a=window[n];if("function"==typeof a){const t=e.hasAttribute("pp-after-request"),n=Array.isArray(s.args)?s.args:[],o=responseDataDEAC2?parseJson(responseDataDEAC2):{response:responseDataDEAC2};let i={args:n,element:e,data:s};t&&(i={...i,...o}),await a(i)}else responseDataDEAC2=null,responseDataDEAC2=await handleUndefinedFunction(e,n,s)}function handleAnchorTag(e){e instanceof HTMLAnchorElement&&e.addEventListener("click",(async e=>{const t=e.currentTarget,n=t.getAttribute("href"),s=t.getAttribute("target");if(n&&"_blank"!==s&&!e.metaKey&&!e.ctrlKey&&(e.preventDefault(),!isNavigatingA12E1)){isNavigatingA12E1=!0;try{if(/^(https?:)?\/\//i.test(n)&&!n.startsWith(window.location.origin))window.location.href=n;else{const e=t.getAttribute("pp-append-params");if(n.startsWith("?")&&"true"===e){const e=new URL(window.location.href),t=new URLSearchParams(e.search);let s="";const[a,o]=n.split("#");o&&(s=`#${o}`);new URLSearchParams(a.split("?")[1]).forEach(((e,n)=>{t.set(n,e)}));const i=`${e.pathname}?${t.toString()}${s}`;history.pushState(null,"",i)}else{const[e,t]=n.split("#"),s=`${e}${t?`#${t}`:""}`;history.pushState(null,"",s)}const s=n.indexOf("#");if(-1!==s){const e=n.slice(s+1),t=document.getElementById(e);if(t)t.scrollIntoView({behavior:"smooth"});else{await handleNavigation();const t=document.getElementById(e);t&&t.scrollIntoView({behavior:"smooth"})}}else await handleNavigation()}}catch(e){}finally{isNavigatingA12E1=!1}}}))}async function handleNavigation(){try{const e=e=>{const t=e.querySelector("[pp-loading-transition]")?.getAttribute("pp-loading-transition");let n=250,s=250;if(t)try{const e=parseJson(t);n=parseTime(e.fadeIn||n),s=parseTime(e.fadeOut||s)}catch(e){}return{fadeIn:n,fadeOut:s}},t=(e,t)=>new Promise((n=>{e.style.transition=`opacity ${t}ms ease-out`,e.style.opacity="0",setTimeout((()=>{e.style.transition="",n()}),t)})),n=(e,t)=>{e.style.transition=`opacity ${t}ms ease-in`,e.style.opacity="1",setTimeout((()=>{e.style.transition=""}),t)},s=async s=>{const a=document.querySelector("[pp-loading-content='true']")||document.body;if(a){const{fadeIn:o,fadeOut:i}=e(s);await t(a,i),a.innerHTML=s.innerHTML,n(a,o)}},a=window.location.pathname,o=document.getElementById("loading-file-1B87E");if(o){let e=o.querySelector(`div[pp-loading-url='${a}']`);e||(e=o.querySelector("div[pp-loading-url='/']")),e&&await s(e)}const i=await pphpFetch(window.location.href),r=i.match(redirectRegex3AE99);if(r&&r[1]){const e=r[1];await handleRedirect(e)}else updateDocumentContent(i)}catch(e){}}function onUrlChange(){}function updateDocumentContent(e){const t=saveScrollPositions();if(document.removeAllEventListeners("DOMContentLoaded"),e.includes("<!DOCTYPE html>")){const t=e=>{Array.from(e.head.children).forEach((e=>{const t=e.tagName;if("META"===t){if(e.getAttribute("charset")||"viewport"===e.getAttribute("name"))return;const t=e.name,n=e.getAttribute("property"),s=document.head.querySelector(t?`meta[name="${t}"]`:`meta[property="${n}"]`);s?document.head.replaceChild(e.cloneNode(!0),s):document.head.appendChild(e.cloneNode(!0))}else if("TITLE"===t){const t=document.head.querySelector("title");t?document.head.replaceChild(e.cloneNode(!0),t):document.head.appendChild(e.cloneNode(!0))}else if("LINK"===t){const t=t=>{const n=document.head.querySelector('link[rel="icon"]');if(n)document.head.replaceChild(e.cloneNode(!0),n);else{const e=document.createElement("link");e.rel="icon",e.href=t,document.head.appendChild(e)}};if("icon"===e.getAttribute("rel")){t(e.href)}}})),loadAndValidateContent(e)};t((new DOMParser).parseFromString(e,"text/html"))}else{saveState();loadAndValidateContent((new DOMParser).parseFromString(e,"text/html")),restoreState()}restoreScrollPositions(t),attachWireFunctionEvents(),document.dispatchEvent(new Event("DOMContentLoaded"))}function loadAndValidateContent(e){const t=new Map,n=document.createDocumentFragment();function s(e,n){let a=null;if("SCRIPT"===e.tagName){const t=document.createElement("script"),n=e;n.src?(t.src=n.src,t.async=!1):t.textContent=n.textContent,a=t}else a=e.cloneNode(!1),t.set(e,a),Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.TEXT_NODE?a.appendChild(document.createTextNode(e.textContent||"")):e.nodeType===Node.ELEMENT_NODE&&s(e,a)}));n.appendChild(a)}Array.from(e.body.children).forEach((e=>{s(e,n)})),document.body.innerHTML="",document.body.appendChild(n)}function saveState(){const e=document.activeElement;stateA129A.focusId=e?.id||e?.name,stateA129A.focusValue=e?.value,stateA129A.focusChecked=e?.checked,stateA129A.focusType=e?.type,stateA129A.focusSelectionStart=e?.selectionStart,stateA129A.focusSelectionEnd=e?.selectionEnd,stateA129A.isSuspense=e.hasAttribute("pp-suspense"),stateA129A.checkedElements.clear(),document.querySelectorAll('input[type="checkbox"]:checked').forEach((e=>{stateA129A.checkedElements.add(e.id||e.name)})),document.querySelectorAll('input[type="radio"]:checked').forEach((e=>{stateA129A.checkedElements.add(e.id||e.name)}))}function restoreState(){if(stateA129A.focusId){const e=document.getElementById(stateA129A.focusId)||document.querySelector(`[name="${stateA129A.focusId}"]`);if(e instanceof HTMLInputElement){const t=e.value.length||0;void 0!==stateA129A.focusSelectionStart&&null!==stateA129A.focusSelectionEnd&&e.setSelectionRange(t,t),stateA129A.focusValue&&("checkbox"===e.type||"radio"===e.type?e.checked=!!stateA129A.focusChecked:"number"===e.type?(e.type="text",e.setSelectionRange(t,t),e.type="number"):""!==e.value&&(e.value=stateA129A.focusValue)),e.focus()}else if(e instanceof HTMLTextAreaElement){const t=e.value.length||0;void 0!==stateA129A.focusSelectionStart&&null!==stateA129A.focusSelectionEnd&&e.setSelectionRange(t,t),stateA129A.focusValue&&""!==e.value&&(e.value=stateA129A.focusValue),e.focus()}else e instanceof HTMLSelectElement&&(stateA129A.focusValue&&""!==e.value&&(e.value=stateA129A.focusValue),e.focus())}stateA129A.checkedElements.forEach((e=>{const t=document.getElementById(e);t&&(t.checked=!0)}))}function saveScrollPositions(){const e={};return document.querySelectorAll("*").forEach((t=>{(t.scrollTop||t.scrollLeft)&&(e[getElementKey(t)]={scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})})),e}function restoreScrollPositions(e){document.querySelectorAll("*").forEach((t=>{const n=getElementKey(t);e[n]&&(t.scrollTop=e[n].scrollTop,t.scrollLeft=e[n].scrollLeft)}))}function getElementKey(e){return e.id||e.className||e.tagName}async function pphpFetch(e,t){const n=await fetch(e,{...t,headers:{...t?.headers,"X-Requested-With":"XMLHttpRequest"}});return await n.text()}function parseCallback(e,t){let n={};const s=e.closest("form");if(s){new FormData(s).forEach(((e,t)=>{n[t]?Array.isArray(n[t])?n[t].push(e):n[t]=[n[t],e]:n[t]=e}))}else e instanceof HTMLInputElement?n=handleInputElement(e):(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(n[e.name]=e.value);const a=t.match(/(\w+)\((.*)\)/);if(a){const e=a[1];let t=a[2].trim();if(t.startsWith("{")&&t.endsWith("}"))try{const e=parseJson(t);"object"==typeof e&&null!==e&&(n={...n,...e})}catch(e){}else{const e=t.split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/).map((e=>e.trim().replace(/^['"]|['"]$/g,"")));n.args=e}return{funcName:e,data:n}}return{funcName:t,data:n}}function handleInputElement(e){let t={};if(e.name)if("checkbox"===e.type)t[e.name]={value:e.value,checked:e.checked};else if("radio"===e.type){const n=document.querySelector(`input[name="${e.name}"]:checked`);t[e.name]=n?n.value:null}else t[e.name]=e.value;else"checkbox"===e.type||"radio"===e.type?t.value=e.checked:t.value=e.value;return t}function updateElementAttributes(e,t){for(const n in t)if(t.hasOwnProperty(n))switch(n){case"innerHTML":case"outerHTML":case"textContent":case"innerText":e[n]=decodeHTML(t[n]);break;case"insertAdjacentHTML":e.insertAdjacentHTML(t.position||"beforeend",decodeHTML(t[n].html));break;case"insertAdjacentText":e.insertAdjacentText(t.position||"beforeend",decodeHTML(t[n].text));break;case"setAttribute":e.setAttribute(t.attrName,decodeHTML(t[n]));break;case"removeAttribute":e.removeAttribute(t[n]);break;case"className":e.className=decodeHTML(t[n]);break;case"classList.add":e.classList.add(...decodeHTML(t[n]).split(","));break;case"classList.remove":e.classList.remove(...decodeHTML(t[n]).split(","));break;case"classList.toggle":e.classList.toggle(decodeHTML(t[n]));break;case"classList.replace":const[s,a]=decodeHTML(t[n]).split(",");e.classList.replace(s,a);break;case"dataset":e.dataset[t.attrName]=decodeHTML(t[n]);break;case"style":Object.assign(e.style,t[n]);break;case"value":e.value=decodeHTML(t[n]);break;case"checked":e.checked=t[n];break;default:e.setAttribute(n,decodeHTML(t[n]))}}function decodeHTML(e){const t=document.createElement("textarea");return t.innerHTML=e,t.value}function saveElementOriginalState(e){if(e.hasAttribute("pp-suspense")&&!e.hasAttribute("pp-original-state")){const t={};e.textContent&&(t.textContent=e.textContent.trim()),e.innerHTML&&(t.innerHTML=e.innerHTML.trim()),(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)&&(t.value=e.value);for(let n=0;n<e.attributes.length;n++){const s=e.attributes[n];t[s.name]=s.value}e.setAttribute("pp-original-state",JSON.stringify(t))}e.querySelectorAll("[pp-suspense]").forEach((e=>saveElementOriginalState(e)))}async function handleSuspenseElement(e){let t=e.getAttribute("pp-suspense")||"";const n=(e,t)=>{for(const n in t)if(t.hasOwnProperty(n))for(const t of e.elements)if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-suspense")||"";if(e)if(isJsonLike(e)){const n=parseJson(e);"disabled"!==n.onsubmit&&updateElementAttributes(t,n),n.targets&&n.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&a(s,n)}))}else s(t,e)}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},a=(e,t)=>{e instanceof HTMLFormElement?n(e,t):updateElementAttributes(e,t)};try{if(t&&isJsonLike(t)){const s=parseJson(t);if(s)if(e instanceof HTMLFormElement){const t=new FormData(e),a={};t.forEach(((e,t)=>{a[t]=e})),s.disabled&&toggleFormElements(e,!0);const{disabled:o,...i}=s;updateElementAttributes(e,i),n(e,a)}else if(s.targets){s.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&a(s,n)}));const{targets:t,...n}=s;updateElementAttributes(e,n)}else{if("disabled"===s.empty&&""===e.value)return;const{empty:t,...n}=s;updateElementAttributes(e,n)}}else if(t)s(e,t);else if(e instanceof HTMLFormElement){const t=new FormData(e),s={};t.forEach(((e,t)=>{s[t]=e})),n(e,s)}}catch(e){}}function restoreSuspenseElement(e){const t=e.getAttribute("pp-original-state");if(e.hasAttribute("pp-suspense")&&t){const n=(e,t)=>{for(const n in t)t.hasOwnProperty(n)&&("textContent"===n?e.textContent=t[n]:"innerHTML"===n?e.innerHTML=t[n]:"disabled"===n?!0===t[n]?e.setAttribute("disabled","true"):e.removeAttribute("disabled"):e.setAttribute(n,t[n]));for(const n of Array.from(e.attributes))t.hasOwnProperty(n.name)||e.removeAttribute(n.name)},s=(e,t)=>{for(const s in t)if(t.hasOwnProperty(s))for(const t of Array.from(e.elements))if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-original-state")||"";if(e){if(isJsonLike(e)){const s=parseJson(e);n(t,s)}else a(t,e);t.removeAttribute("pp-original-state")}}},a=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},o=(e,t)=>{e instanceof HTMLFormElement?s(e,t):n(e,t)};try{const a=JSON.parse(t);if(a)if(e instanceof HTMLFormElement){const t=new FormData(e),n={};if(t.forEach(((e,t)=>{n[t]=e})),s(e,n),e.hasAttribute("pp-suspense")){const t=e.getAttribute("pp-suspense")||"";if(parseJson(t).disabled)for(const t of Array.from(e.elements))(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement)&&t.removeAttribute("disabled")}}else if(a.targets){a.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&o(s,n)}));const{targets:t,...s}=a;n(e,s)}else{const{empty:t,...s}=a;n(e,s)}}catch(e){}}e.querySelectorAll("[pp-suspense]").forEach((e=>restoreSuspenseElement(e))),e.removeAttribute("pp-original-state")}function parseJson(e){try{return isJsonLike(e)?(e=(e=(e=(e=(e=(e=(e=(e=e.replace(/\\'/g,"'")).replace(/(?<!\\)'/g,'"')).replace(/[\u2018\u2019]/g,"'").replace(/[\u201C\u201D]/g,'"')).replace(/(\w)"s/g,"$1's")).replace(/(\w)"(\w)/g,"$1'$2")).replace(/"(\w+)"\s*([\[\{])/g,'"$1": $2')).replace(/(\w+)\s*([\[\{])/g,'"$1": $2')).replace(/\\([^"\\/bfnrtu])/g,"\\\\$1"),JSON.parse(e)):null}catch(e){const t=e.message.match(/position (\d+)/);t&&parseInt(t[1]);return null}}function toggleFormElements(e,t){Array.from(e.elements).forEach((e=>{(e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(e.disabled=t)}))}async function pphpFetchFile(e,t,n){const s=new FormData,a=n.files;if(a)for(let e=0;e<a.length;e++)s.append("file[]",a[e]);s.append("callback",t);const o=await fetch(e,{method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:s});return await o.text()}async function handleUndefinedFunction(e,t,n){const s=createFetchOptions({callback:t,...n}),a=createFetchOptions({secondRequestC69CD:!0});try{saveElementOriginalState(e),handleSuspenseElement(e);const n=window.location.pathname;let o="",i="",r={success:!1};const c=e.querySelector("input[type='file']");if(c){if(o=await pphpFetchFile(n,t,c),i=extractJson(o)||"",i)try{r=JSON.parse(i)}catch(e){}}else if(o=await pphpFetch(n,s),i=extractJson(o)||"",i)try{r=JSON.parse(i)}catch(e){}const l=hasPpOnAttribute(e),u=e.getAttribute("pp-before-request")||"",d=e.getAttribute("pp-after-request")||"";if((l||u||d&&r.success)&&restoreSuspenseElement(e),l||u||d){let e="";if(r.success){e=o.replace(i,"")}else e=o;if(appendAfterbegin(e),!d&&!r.success)return}if(d&&r.success){handleAfterRequest(d,i);return appendAfterbegin(o.replace(i,"")),i}const p=await pphpFetch(n,a);await handleResponseRedirectOrUpdate(o,p,i,r)}catch(e){}}function createFetchOptions(e){return{method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(e)}}async function handleResponseRedirectOrUpdate(e,t,n,s){const a=e.match(redirectRegex3AE99);if(a&&a[1])await handleRedirect(a[1]);else{const a=(new DOMParser).parseFromString(t,"text/html");let o=document.createElement("div");if(o.id="afterbegin-8D95D",n)if(s.success){const t=e.replace(n,"");o.innerHTML=t}else o.innerHTML=e;else o.innerHTML=e;o.innerHTML&&a.body.insertAdjacentElement("afterbegin",o),updateDocumentContent(a.body.outerHTML)}}function appendAfterbegin(e){if(!e)return;const t="afterbegin-8D95D";let n=document.getElementById(t);n?(n.innerHTML=e,document.body.insertAdjacentElement("afterbegin",n)):(n=document.createElement("div"),n.id=t,n.innerHTML=e,document.body.insertAdjacentElement("afterbegin",n))}function extractJson(e){const t=e?.match(/\{[\s\S]*\}/);return t?t[0]:null}function handleAfterRequest(e,t){if(!isJsonLike(e))return;const n=parseJson(e),s=t?parseJson(t):null,a=n.targets;Array.isArray(a)&&a.forEach((e=>{const{id:t,...n}=e,a=document.querySelector(t);let o={};if(s){for(const t in n)if(n.hasOwnProperty(t))switch(t){case"innerHTML":case"outerHTML":case"textContent":case"innerText":"response"===n[t]&&(o[t]=e.responseKey?s[e.responseKey]:s.response);break;default:o[t]=n[t];break}}else o=n;a&&updateElementAttributes(a,o)}))}async function handleRedirect(e){if(e)try{const t=new URL(e,window.location.origin);t.origin!==window.location.origin?window.location.href=e:(history.pushState(null,"",e),await handleNavigation())}catch(e){}}function debounce(e,t=300,n=!1){let s;return function(...a){const o=this;s&&clearTimeout(s),s=setTimeout((()=>{s=null,n||e.apply(o,a)}),t),n&&!s&&e.apply(o,a)}}function copyCode(e,t,n,s,a="img",o=2e3){if(!(e instanceof HTMLElement))return;const i=e.closest(`.${t}`)?.querySelector("pre code"),r=i?.textContent?.trim()||"";r?navigator.clipboard.writeText(r).then((()=>{const t=e.querySelector(a);if(t)for(const[e,n]of Object.entries(s))t.setAttribute(e,n);setTimeout((()=>{if(t)for(const[e,s]of Object.entries(n))t.setAttribute(e,s)}),o)}),(()=>{alert("Failed to copy command to clipboard")})):alert("Failed to find the code block to copy")}if((()=>{const e=EventTarget.prototype.addEventListener,t=new Map;EventTarget.prototype.addEventListener=function(n,s,a){t.has(this)||t.set(this,new Map);const o=t.get(this).get(n)||new Set;o.add(s),t.get(this).set(n,o),e.call(this,n,s,a)},EventTarget.prototype.removeAllEventListeners=function(e){t.has(this)&&t.get(this).has(e)&&(t.get(this).get(e).forEach((t=>{this.removeEventListener(e,t)})),t.get(this).delete(e))}})(),(e=>{const t=e.pushState,n=e.replaceState;e.pushState=function(n,s,a){const o=t.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),o},e.replaceState=function(t,s,a){const o=n.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),o}})(window.history),document.addEventListener("DOMContentLoaded",attachWireFunctionEvents),window.addEventListener("popstate",(async()=>{await handleNavigation()})),window.addEventListener("urlchange",(()=>{})),null===store){class e{static instance=null;state;listeners;constructor(e={}){this.state=e,this.listeners=[]}static getInstance(t={}){return e.instance||(e.instance=new e(t),e.instance.loadState()),e.instance}setState(e){this.state={...this.state,...e},this.listeners.forEach((e=>e(this.state))),this.saveState()}subscribe(e){return this.listeners.push(e),e(this.state),()=>{this.listeners=this.listeners.filter((t=>t!==e))}}saveState(){localStorage.setItem("appState_59E13",JSON.stringify(this.state))}loadState(){const e=localStorage.getItem("appState_59E13");e&&(this.state=JSON.parse(e),this.listeners.forEach((e=>e(this.state))))}resetState(){this.state={},this.listeners.forEach((e=>e(this.state))),localStorage.removeItem("appState_59E13")}}store=e.getInstance()}
1
+ var eventAttributesB6B56=["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onwheel","onkeypress","onkeydown","onkeyup","onfocus","onblur","onchange","oninput","onselect","onsubmit","onreset","onresize","onscroll","onload","onunload","onabort","onerror","onbeforeunload","oncopy","oncut","onpaste","ondrag","ondragstart","ondragend","ondragover","ondragenter","ondragleave","ondrop","oncontextmenu","ontouchstart","ontouchmove","ontouchend","ontouchcancel","onpointerdown","onpointerup","onpointermove","onpointerover","onpointerout","onpointerenter","onpointerleave","onpointercancel"],stateA129A={checkedElements:new Set},responseDataDEAC2=null,store=null,isNavigatingA12E1=!1,redirectRegex3AE99=/redirect_7F834\s*=\s*(\/[^\s]*)/;function attachWireFunctionEvents(){handleHiddenAttribute();document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((e=>{if(handleAnchorTag(e),eventAttributesB6B56.forEach((t=>{const n=e.getAttribute(t),s=t.slice(2);n&&(e.removeAttribute(t),handleDebounce(e,s,n))})),e instanceof HTMLFormElement){const t=e.getAttribute("onsubmit");t&&(e.removeAttribute("onsubmit"),handleDebounce(e,"submit",t))}})),initializePpOnListeners()}function hasPpOnAttribute(e){const t=e.attributes;if(!t)return!1;for(let e=0;e<t.length;e++){const n=t[e].name;if(n.startsWith("pp-on:")||n.startsWith("data-pp-on:")||n.startsWith("pp-on-")||n.startsWith("data-pp-on-"))return!0}return!1}function findAllPpOnElements(e){const t=[];if(hasPpOnAttribute(e)&&t.push(e),document.evaluate){const n=document.evaluate('.//*[@*[starts-with(name(), "pp-on:") or starts-with(name(), "data-pp-on:") or starts-with(name(), "pp-on-") or starts-with(name(), "data-pp-on-")]]',e,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);let s=n.iterateNext();for(;s;)t.push(s),s=n.iterateNext()}else if("function"==typeof e.getElementsByTagName){const n=e.getElementsByTagName("*");for(let e=0;e<n.length;e++)hasPpOnAttribute(n[e])&&t.push(n[e])}return t}function initializePpOnListeners(){findAllPpOnElements(document).forEach((e=>{Array.from(e.attributes).forEach((t=>{if(t.name.startsWith("pp-on:")){const n=t.name.split(":")[1],s=t.value;s&&e.addEventListener(n,(t=>{try{new Function("event",s).call(e,t)}catch(e){}}))}}))}))}function handleHiddenAttribute(){const e=document.querySelectorAll("[pp-visibility]"),t=document.querySelectorAll("[pp-display]");e.forEach((e=>handleVisibilityElementAttribute(e,"pp-visibility",handleElementVisibility))),t.forEach((e=>handleVisibilityElementAttribute(e,"pp-display",handleElementDisplay)))}function handleVisibilityElementAttribute(e,t,n){const s=e.getAttribute(t);if(s)if(isJsonLike(s)){n(e,parseJson(s))}else{const n=parseTime(s);if(n>0){const s="pp-visibility"===t?"visibility":"display";scheduleChange(e,n,s,"visibility"===s?"hidden":"none")}}}function isJsonLike(e){return"string"==typeof e&&((e=e.trim()).startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))}function handleElementVisibility(e,t){handleElementChange(e,t,"visibility","hidden","visible")}function handleElementDisplay(e,t){handleElementChange(e,t,"display","none","block")}function handleElementChange(e,t,n,s,a){const o=t.start?parseTime(t.start):0,r=t.end?parseTime(t.end):0;o>0?(e.style[n]=s,scheduleChange(e,o,n,a),r>0&&scheduleChange(e,o+r,n,s)):r>0&&scheduleChange(e,r,n,s)}function scheduleChange(e,t,n,s){setTimeout((()=>{requestAnimationFrame((()=>{e.style[n]=s}))}),t)}function parseTime(e){if("number"==typeof e)return e;const t=e.match(/^(\d+)(ms|s|m)?$/);if(t){const e=parseInt(t[1],10);switch(t[2]||"ms"){case"ms":return e;case"s":return 1e3*e;case"m":return 60*e*1e3;default:return e}}return 0}async function handleDebounce(e,t,n){const s=e.getAttribute("pp-debounce")||"",a=e.getAttribute("pp-before-request")||"",o=e.getAttribute("pp-after-request")||"",r=async t=>{t.preventDefault();try{a&&await invokeHandler(e,a,t),await invokeHandler(e,n,t),o&&"@close"!==o&&await invokeHandler(e,o,t),handlerAutofocusAttribute()}catch(e){}};if(s){const n=debounce(r,parseTime(s));e instanceof HTMLFormElement&&"submit"===t?e.addEventListener(t,(e=>{e.preventDefault(),n(e)})):e.addEventListener(t,n)}else e.addEventListener(t,r)}function handlerAutofocusAttribute(){const e=document.querySelectorAll("[pp-autofocus]");let t=!1;e.forEach((e=>{if(t)return;const n=e.getAttribute("pp-autofocus");if(!n||!isJsonLike(n))return;const s=parseJson(n);if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)if("number"===e.type&&e instanceof HTMLInputElement){e.type="text";const t=e.value.length||0;e.setSelectionRange(t,t),e.type="number"}else if(s.start)e.setSelectionRange(0,0);else if(s.end){const t=e.value.length||0;e.setSelectionRange(t,t)}else if(s.length){const t=parseInt(s.length,10)||0;e.setSelectionRange(t,t)}e.focus(),t=!0}))}async function invokeHandler(e,t,n){try{const s=t.match(/^(\w+(\.\w+)*)\((.*)\)$/);if(s){const a=s[1].split("."),{context:o,methodName:r}=resolveContext(a);"function"==typeof o[r]?new Function("event",t).call(e,n):await handleParsedCallback(e,t)}else await handleParsedCallback(e,t)}catch(e){}}function resolveContext(e){let t=window;for(let n=0;n<e.length-1;n++)if(t=t[e[n]],!t)throw new Error(`Cannot find object ${e[n]} in the context.`);return{context:t,methodName:e[e.length-1]}}async function handleParsedCallback(e,t){const{funcName:n,data:s}=parseCallback(e,t);if(!n)return;const a=window[n];if("function"==typeof a){const t=e.hasAttribute("pp-after-request"),n=Array.isArray(s.args)?s.args:[],o=responseDataDEAC2?parseJson(responseDataDEAC2):{response:responseDataDEAC2};let r={args:n,element:e,data:s};t&&(r={...r,...o}),await a(r)}else responseDataDEAC2=null,responseDataDEAC2=await handleUndefinedFunction(e,n,s)}function handleAnchorTag(e){e instanceof HTMLAnchorElement&&e.addEventListener("click",(async e=>{const t=e.currentTarget,n=t.getAttribute("href"),s=t.getAttribute("target");if(n&&"_blank"!==s&&!e.metaKey&&!e.ctrlKey&&(e.preventDefault(),!isNavigatingA12E1)){isNavigatingA12E1=!0;try{if(/^(https?:)?\/\//i.test(n)&&!n.startsWith(window.location.origin))window.location.href=n;else{const e=t.getAttribute("pp-append-params");if(n.startsWith("?")&&"true"===e){const e=new URL(window.location.href),t=new URLSearchParams(e.search);let s="";const[a,o]=n.split("#");o&&(s=`#${o}`);new URLSearchParams(a.split("?")[1]).forEach(((e,n)=>{t.set(n,e)}));const r=`${e.pathname}?${t.toString()}${s}`;history.pushState(null,"",r)}else{const[e,t]=n.split("#"),s=`${e}${t?`#${t}`:""}`;history.pushState(null,"",s)}const s=n.indexOf("#");if(-1!==s){const e=n.slice(s+1),t=document.getElementById(e);if(t)t.scrollIntoView({behavior:"smooth"});else{await handleNavigation();const t=document.getElementById(e);t&&t.scrollIntoView({behavior:"smooth"})}}else await handleNavigation()}}catch(e){}finally{isNavigatingA12E1=!1}}}))}async function handleNavigation(){try{const e=e=>{const t=e.querySelector("[pp-loading-transition]")?.getAttribute("pp-loading-transition");let n=250,s=250;if(t)try{const e=parseJson(t);n=parseTime(e.fadeIn||n),s=parseTime(e.fadeOut||s)}catch(e){}return{fadeIn:n,fadeOut:s}},t=(e,t)=>new Promise((n=>{e.style.transition=`opacity ${t}ms ease-out`,e.style.opacity="0",setTimeout((()=>{e.style.transition="",n()}),t)})),n=(e,t)=>{e.style.transition=`opacity ${t}ms ease-in`,e.style.opacity="1",setTimeout((()=>{e.style.transition=""}),t)},s=async s=>{const a=document.querySelector("[pp-loading-content='true']")||document.body;if(a){const{fadeIn:o,fadeOut:r}=e(s);await t(a,r),a.innerHTML=s.innerHTML,n(a,o)}},a=window.location.pathname,o=document.getElementById("loading-file-1B87E");if(o){let e=o.querySelector(`div[pp-loading-url='${a}']`);e||(e=o.querySelector("div[pp-loading-url='/']")),e&&await s(e)}const r=await pphpFetch(window.location.href),i=r.match(redirectRegex3AE99);if(i&&i[1]){const e=i[1];await handleRedirect(e)}else updateDocumentContent(r)}catch(e){}}function onUrlChange(){}async function updateBodyContent(e){const t=saveScrollPositions();document.removeAllEventListeners("DOMContentLoaded"),saveState();loadAndValidateContent((new DOMParser).parseFromString(e,"text/html")),restoreState(),restoreScrollPositions(t),attachWireFunctionEvents(),document.dispatchEvent(new Event("DOMContentLoaded"))}async function updateDocumentContent(e){const t=saveScrollPositions();document.removeAllEventListeners("DOMContentLoaded");const n=(new DOMParser).parseFromString(e,"text/html");await(async e=>{Array.from(e.head.children).forEach((e=>{const t=e.tagName;if("META"===t){if(e.getAttribute("charset")||"viewport"===e.getAttribute("name"))return;const t=e.name,n=e.getAttribute("property"),s=document.head.querySelector(t?`meta[name="${t}"]`:`meta[property="${n}"]`);s?document.head.replaceChild(e.cloneNode(!0),s):document.head.appendChild(e.cloneNode(!0))}else if("TITLE"===t){const t=document.head.querySelector("title");t?document.head.replaceChild(e.cloneNode(!0),t):document.head.appendChild(e.cloneNode(!0))}else if("LINK"===t){const t=t=>{const n=document.head.querySelector('link[rel="icon"]');if(n)document.head.replaceChild(e.cloneNode(!0),n);else{const e=document.createElement("link");e.rel="icon",e.href=t,document.head.appendChild(e)}};if("icon"===e.getAttribute("rel")){t(e.href)}}})),loadAndValidateContent(e)})(n),restoreScrollPositions(t),attachWireFunctionEvents(),document.dispatchEvent(new Event("DOMContentLoaded"))}function loadAndValidateContent(e){const t=new Map,n=document.createDocumentFragment();function s(e,n){let a=null;if("SCRIPT"===e.tagName){const t=document.createElement("script"),n=e;n.src?(t.src=n.src,t.async=!1):t.textContent=n.textContent,a=t}else a=e.cloneNode(!1),t.set(e,a),Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.TEXT_NODE?a.appendChild(document.createTextNode(e.textContent||"")):e.nodeType===Node.ELEMENT_NODE&&s(e,a)}));n.appendChild(a)}Array.from(e.body.children).forEach((e=>{s(e,n)})),document.body.innerHTML="",document.body.appendChild(n)}function saveState(){const e=document.activeElement;stateA129A.focusId=e?.id||e?.name,stateA129A.focusValue=e?.value,stateA129A.focusChecked=e?.checked,stateA129A.focusType=e?.type,stateA129A.focusSelectionStart=e?.selectionStart,stateA129A.focusSelectionEnd=e?.selectionEnd,stateA129A.isSuspense=e.hasAttribute("pp-suspense"),stateA129A.checkedElements.clear(),document.querySelectorAll('input[type="checkbox"]:checked').forEach((e=>{stateA129A.checkedElements.add(e.id||e.name)})),document.querySelectorAll('input[type="radio"]:checked').forEach((e=>{stateA129A.checkedElements.add(e.id||e.name)}))}function restoreState(){if(stateA129A.focusId){const e=document.getElementById(stateA129A.focusId)||document.querySelector(`[name="${stateA129A.focusId}"]`);if(e instanceof HTMLInputElement){const t=e.value.length||0;void 0!==stateA129A.focusSelectionStart&&null!==stateA129A.focusSelectionEnd&&e.setSelectionRange(t,t),stateA129A.focusValue&&("checkbox"===e.type||"radio"===e.type?e.checked=!!stateA129A.focusChecked:"number"===e.type?(e.type="text",e.setSelectionRange(t,t),e.type="number"):""!==e.value&&(e.value=stateA129A.focusValue)),e.focus()}else if(e instanceof HTMLTextAreaElement){const t=e.value.length||0;void 0!==stateA129A.focusSelectionStart&&null!==stateA129A.focusSelectionEnd&&e.setSelectionRange(t,t),stateA129A.focusValue&&""!==e.value&&(e.value=stateA129A.focusValue),e.focus()}else e instanceof HTMLSelectElement&&(stateA129A.focusValue&&""!==e.value&&(e.value=stateA129A.focusValue),e.focus())}stateA129A.checkedElements.forEach((e=>{const t=document.getElementById(e);t&&(t.checked=!0)}))}function saveScrollPositions(){const e={};return document.querySelectorAll("*").forEach((t=>{(t.scrollTop||t.scrollLeft)&&(e[getElementKey(t)]={scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})})),e}function restoreScrollPositions(e){document.querySelectorAll("*").forEach((t=>{const n=getElementKey(t);e[n]&&(t.scrollTop=e[n].scrollTop,t.scrollLeft=e[n].scrollLeft)}))}function getElementKey(e){return e.id||e.className||e.tagName}async function pphpFetch(e,t){const n=await fetch(e,{...t,headers:{...t?.headers,"X-Requested-With":"XMLHttpRequest"}});return await n.text()}function parseCallback(e,t){let n={};const s=e.closest("form");if(s){new FormData(s).forEach(((e,t)=>{n[t]?Array.isArray(n[t])?n[t].push(e):n[t]=[n[t],e]:n[t]=e}))}else e instanceof HTMLInputElement?n=handleInputElement(e):(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(n[e.name]=e.value);const a=t.match(/(\w+)\((.*)\)/);if(a){const e=a[1];let t=a[2].trim();if(t.startsWith("{")&&t.endsWith("}"))try{const e=parseJson(t);"object"==typeof e&&null!==e&&(n={...n,...e})}catch(e){}else{const e=t.split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/).map((e=>e.trim().replace(/^['"]|['"]$/g,"")));n.args=e}return{funcName:e,data:n}}return{funcName:t,data:n}}function handleInputElement(e){let t={};if(e.name)if("checkbox"===e.type)t[e.name]={value:e.value,checked:e.checked};else if("radio"===e.type){const n=document.querySelector(`input[name="${e.name}"]:checked`);t[e.name]=n?n.value:null}else t[e.name]=e.value;else"checkbox"===e.type||"radio"===e.type?t.value=e.checked:t.value=e.value;return t}function updateElementAttributes(e,t){for(const n in t)if(t.hasOwnProperty(n))switch(n){case"innerHTML":case"outerHTML":case"textContent":case"innerText":e[n]=decodeHTML(t[n]);break;case"insertAdjacentHTML":e.insertAdjacentHTML(t.position||"beforeend",decodeHTML(t[n].html));break;case"insertAdjacentText":e.insertAdjacentText(t.position||"beforeend",decodeHTML(t[n].text));break;case"setAttribute":e.setAttribute(t.attrName,decodeHTML(t[n]));break;case"removeAttribute":e.removeAttribute(t[n]);break;case"className":e.className=decodeHTML(t[n]);break;case"classList.add":e.classList.add(...decodeHTML(t[n]).split(","));break;case"classList.remove":e.classList.remove(...decodeHTML(t[n]).split(","));break;case"classList.toggle":e.classList.toggle(decodeHTML(t[n]));break;case"classList.replace":const[s,a]=decodeHTML(t[n]).split(",");e.classList.replace(s,a);break;case"dataset":e.dataset[t.attrName]=decodeHTML(t[n]);break;case"style":Object.assign(e.style,t[n]);break;case"value":e.value=decodeHTML(t[n]);break;case"checked":e.checked=t[n];break;default:e.setAttribute(n,decodeHTML(t[n]))}}function decodeHTML(e){const t=document.createElement("textarea");return t.innerHTML=e,t.value}function saveElementOriginalState(e){if(e.hasAttribute("pp-suspense")&&!e.hasAttribute("pp-original-state")){const t={};e.textContent&&(t.textContent=e.textContent.trim()),e.innerHTML&&(t.innerHTML=e.innerHTML.trim()),(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)&&(t.value=e.value);for(let n=0;n<e.attributes.length;n++){const s=e.attributes[n];t[s.name]=s.value}e.setAttribute("pp-original-state",JSON.stringify(t))}e.querySelectorAll("[pp-suspense]").forEach((e=>saveElementOriginalState(e)))}async function handleSuspenseElement(e){let t=e.getAttribute("pp-suspense")||"";const n=(e,t)=>{for(const n in t)if(t.hasOwnProperty(n))for(const t of e.elements)if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-suspense")||"";if(e)if(isJsonLike(e)){const n=parseJson(e);"disabled"!==n.onsubmit&&updateElementAttributes(t,n),n.targets&&n.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&a(s,n)}))}else s(t,e)}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},a=(e,t)=>{e instanceof HTMLFormElement?n(e,t):updateElementAttributes(e,t)};try{if(t&&isJsonLike(t)){const s=parseJson(t);if(s)if(e instanceof HTMLFormElement){const t=new FormData(e),a={};t.forEach(((e,t)=>{a[t]=e})),s.disabled&&toggleFormElements(e,!0);const{disabled:o,...r}=s;updateElementAttributes(e,r),n(e,a)}else if(s.targets){s.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&a(s,n)}));const{targets:t,...n}=s;updateElementAttributes(e,n)}else{if("disabled"===s.empty&&""===e.value)return;const{empty:t,...n}=s;updateElementAttributes(e,n)}}else if(t)s(e,t);else if(e instanceof HTMLFormElement){const t=new FormData(e),s={};t.forEach(((e,t)=>{s[t]=e})),n(e,s)}}catch(e){}}function restoreSuspenseElement(e){const t=e.getAttribute("pp-original-state");if(e.hasAttribute("pp-suspense")&&t){const n=(e,t)=>{for(const n in t)t.hasOwnProperty(n)&&("textContent"===n?e.textContent=t[n]:"innerHTML"===n?e.innerHTML=t[n]:"disabled"===n?!0===t[n]?e.setAttribute("disabled","true"):e.removeAttribute("disabled"):e.setAttribute(n,t[n]));for(const n of Array.from(e.attributes))t.hasOwnProperty(n.name)||e.removeAttribute(n.name)},s=(e,t)=>{for(const s in t)if(t.hasOwnProperty(s))for(const t of Array.from(e.elements))if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-original-state")||"";if(e){if(isJsonLike(e)){const s=parseJson(e);n(t,s)}else a(t,e);t.removeAttribute("pp-original-state")}}},a=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},o=(e,t)=>{e instanceof HTMLFormElement?s(e,t):n(e,t)};try{const a=JSON.parse(t);if(a)if(e instanceof HTMLFormElement){const t=new FormData(e),n={};if(t.forEach(((e,t)=>{n[t]=e})),s(e,n),e.hasAttribute("pp-suspense")){const t=e.getAttribute("pp-suspense")||"";if(parseJson(t).disabled)for(const t of Array.from(e.elements))(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement)&&t.removeAttribute("disabled")}}else if(a.targets){a.targets.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);s&&o(s,n)}));const{targets:t,...s}=a;n(e,s)}else{const{empty:t,...s}=a;n(e,s)}}catch(e){}}e.querySelectorAll("[pp-suspense]").forEach((e=>restoreSuspenseElement(e))),e.removeAttribute("pp-original-state")}function parseJson(e){try{return isJsonLike(e)?(e=(e=(e=(e=(e=(e=(e=(e=e.replace(/\\'/g,"'")).replace(/(?<!\\)'/g,'"')).replace(/[\u2018\u2019]/g,"'").replace(/[\u201C\u201D]/g,'"')).replace(/(\w)"s/g,"$1's")).replace(/(\w)"(\w)/g,"$1'$2")).replace(/"(\w+)"\s*([\[\{])/g,'"$1": $2')).replace(/(\w+)\s*([\[\{])/g,'"$1": $2')).replace(/\\([^"\\/bfnrtu])/g,"\\\\$1"),JSON.parse(e)):null}catch(e){const t=e.message.match(/position (\d+)/);t&&parseInt(t[1]);return null}}function toggleFormElements(e,t){Array.from(e.elements).forEach((e=>{(e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(e.disabled=t)}))}async function pphpFetchFile(e,t,n){const s=new FormData,a=n.files;if(a)for(let e=0;e<a.length;e++)s.append("file[]",a[e]);s.append("callback",t);const o=await fetch(e,{method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:s});return await o.text()}function getUrlParams(){const e={};return new URLSearchParams(window.location.search).forEach(((t,n)=>{e[n]=t})),e}async function handleUndefinedFunction(e,t,n){const s=createFetchOptions({callback:t,...n}),a=createFetchOptions({secondRequestC69CD:!0,...getUrlParams()});try{saveElementOriginalState(e),handleSuspenseElement(e);const n=new URL(window.location.href);let o="",r="",i={success:!1};const c=e.querySelector("input[type='file']");if(c){if(o=await pphpFetchFile(n.href,t,c),r=extractJson(o)||"",r)try{i=JSON.parse(r)}catch(e){}}else if(o=await pphpFetch(n.href,s),r=extractJson(o)||"",r)try{i=JSON.parse(r)}catch(e){}const l=hasPpOnAttribute(e),u=e.getAttribute("pp-before-request")||"",d=e.getAttribute("pp-after-request")||"";if((l||u||d&&i.success)&&restoreSuspenseElement(e),l||u||d){let e="";if(i.success){e=o.replace(r,"")}else e=o;if(appendAfterbegin(e),!d&&!i.success)return}if(d&&i.success){handleAfterRequest(d,r);return appendAfterbegin(o.replace(r,"")),r}const p=await pphpFetch(n.href,a);await handleResponseRedirectOrUpdate(o,p,r,i)}catch(e){}}function createFetchOptions(e){return{method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(e)}}function getRedirectUrl(e){const t=e.match(redirectRegex3AE99);return t?t[1]:null}function getUpdatedHTMLContent(e,t,n){const s=document.createElement("div");if(s.id="afterbegin-8D95D",n&&t?.success){const t=e.replace(n,"");s.innerHTML=t}else s.innerHTML=e;return s.innerHTML?s:null}async function handleResponseRedirectOrUpdate(e,t,n,s){const a=getRedirectUrl(e);if(a)await handleRedirect(a);else{const a=getUpdatedHTMLContent(e,n,s),o=(new DOMParser).parseFromString(t,"text/html");a&&o.body.insertAdjacentElement("afterbegin",a),updateBodyContent(o.body.outerHTML)}}function appendAfterbegin(e){if(!e)return;const t="afterbegin-8D95D";let n=document.getElementById(t);n?(n.innerHTML=e,document.body.insertAdjacentElement("afterbegin",n)):(n=document.createElement("div"),n.id=t,n.innerHTML=e,document.body.insertAdjacentElement("afterbegin",n))}function extractJson(e){const t=e?.match(/\{[\s\S]*\}/);return t?t[0]:null}function handleAfterRequest(e,t){if(!isJsonLike(e))return;const n=parseJson(e),s=t?parseJson(t):null,a=n.targets;Array.isArray(a)&&a.forEach((e=>{const{id:t,...n}=e,a=document.querySelector(t);let o={};if(s){for(const t in n)if(n.hasOwnProperty(t))switch(t){case"innerHTML":case"outerHTML":case"textContent":case"innerText":"response"===n[t]&&(o[t]=e.responseKey?s[e.responseKey]:s.response);break;default:o[t]=n[t];break}}else o=n;a&&updateElementAttributes(a,o)}))}async function handleRedirect(e){if(e)try{const t=new URL(e,window.location.origin);t.origin!==window.location.origin?window.location.href=e:(history.pushState(null,"",e),await handleNavigation())}catch(e){}}function debounce(e,t=300,n=!1){let s;return function(...a){const o=this;s&&clearTimeout(s),s=setTimeout((()=>{s=null,n||e.apply(o,a)}),t),n&&!s&&e.apply(o,a)}}function copyCode(e,t,n,s,a="img",o=2e3){if(!(e instanceof HTMLElement))return;const r=e.closest(`.${t}`)?.querySelector("pre code"),i=r?.textContent?.trim()||"";i?navigator.clipboard.writeText(i).then((()=>{const t=e.querySelector(a);if(t)for(const[e,n]of Object.entries(s))t.setAttribute(e,n);setTimeout((()=>{if(t)for(const[e,s]of Object.entries(n))t.setAttribute(e,s)}),o)}),(()=>{alert("Failed to copy command to clipboard")})):alert("Failed to find the code block to copy")}if((()=>{const e=EventTarget.prototype.addEventListener,t=new Map;EventTarget.prototype.addEventListener=function(n,s,a){t.has(this)||t.set(this,new Map);const o=t.get(this).get(n)||new Set;o.add(s),t.get(this).set(n,o),e.call(this,n,s,a)},EventTarget.prototype.removeAllEventListeners=function(e){t.has(this)&&t.get(this).has(e)&&(t.get(this).get(e).forEach((t=>{this.removeEventListener(e,t)})),t.get(this).delete(e))}})(),(e=>{const t=e.pushState,n=e.replaceState;e.pushState=function(n,s,a){const o=t.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),o},e.replaceState=function(t,s,a){const o=n.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),o}})(window.history),document.addEventListener("DOMContentLoaded",attachWireFunctionEvents),window.addEventListener("popstate",(async()=>{await handleNavigation()})),window.addEventListener("urlchange",(()=>{})),null===store){class e{static instance=null;state;listeners;constructor(e={}){this.state=e,this.listeners=[]}static getInstance(t={}){return e.instance||(e.instance=new e(t),e.instance.loadState()),e.instance}setState(e){this.state={...this.state,...e},this.listeners.forEach((e=>e(this.state))),this.saveState()}subscribe(e){return this.listeners.push(e),e(this.state),()=>{this.listeners=this.listeners.filter((t=>t!==e))}}saveState(){localStorage.setItem("appState_59E13",JSON.stringify(this.state))}loadState(){const e=localStorage.getItem("appState_59E13");e&&(this.state=JSON.parse(e),this.listeners.forEach((e=>e(this.state))))}resetState(){this.state={},this.listeners.forEach((e=>e(this.state))),localStorage.removeItem("appState_59E13")}}store=e.getInstance()}
@@ -12,7 +12,7 @@
12
12
  <body>
13
13
  <?= $content; ?>
14
14
  <!-- Dynamic Footer -->
15
- <?= implode("\n", $mainLayoutFooter); ?>
15
+ <?= getMainLayoutFooter() ?>
16
16
  </body>
17
17
 
18
18
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma-php-app",
3
- "version": "1.23.8",
3
+ "version": "1.24.0",
4
4
  "description": "Prisma-PHP: A Revolutionary Library Bridging PHP with Prisma ORM",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",