create-prisma-php-app 1.26.509 → 1.26.520
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.
- package/dist/bootstrap.php +50 -7
- package/dist/settings/project-name.ts +21 -9
- package/dist/src/Lib/Auth/Auth.php +1 -1
- package/dist/src/Lib/Auth/AuthConfig.php +31 -6
- package/dist/src/Lib/Middleware/AuthMiddleware.php +70 -24
- package/dist/src/Lib/PHPX/TemplateCompiler.php +129 -0
- package/dist/src/Lib/PrismaPHPSettings.php +16 -0
- package/dist/src/app/assets/images/prisma-php.svg +147 -0
- package/dist/src/app/favicon.ico +0 -0
- package/dist/src/app/index.php +2 -2
- package/dist/src/app/js/index.js +1 -1
- package/package.json +1 -1
- package/dist/src/app/assets/images/prisma-php.png +0 -0
package/dist/bootstrap.php
CHANGED
|
@@ -14,6 +14,7 @@ use Lib\StateManager;
|
|
|
14
14
|
use Lib\Middleware\AuthMiddleware;
|
|
15
15
|
use Lib\Auth\Auth;
|
|
16
16
|
use Lib\MainLayout;
|
|
17
|
+
use Lib\PHPX\TemplateCompiler;
|
|
17
18
|
|
|
18
19
|
$dotenv = Dotenv::createImmutable(\DOCUMENT_PATH);
|
|
19
20
|
$dotenv->load();
|
|
@@ -35,7 +36,7 @@ function determineContentToInclude()
|
|
|
35
36
|
* ======================================
|
|
36
37
|
*/
|
|
37
38
|
$requestUri = $_SERVER['REQUEST_URI'];
|
|
38
|
-
$requestUri = empty($_SERVER['SCRIPT_URL']) ? uriExtractor($requestUri) : $requestUri;
|
|
39
|
+
$requestUri = empty($_SERVER['SCRIPT_URL']) ? trim(uriExtractor($requestUri)) : trim($requestUri);
|
|
39
40
|
/**
|
|
40
41
|
* ============ URI Path Handling ============
|
|
41
42
|
* The $uri variable now contains the URI path without query parameters and without the leading slash.
|
|
@@ -46,7 +47,7 @@ function determineContentToInclude()
|
|
|
46
47
|
*/
|
|
47
48
|
$scriptUrl = explode('?', $requestUri, 2)[0];
|
|
48
49
|
$pathname = $_SERVER['SCRIPT_URL'] ?? $scriptUrl;
|
|
49
|
-
$pathname =
|
|
50
|
+
$pathname = trim($pathname, '/');
|
|
50
51
|
$baseDir = APP_PATH;
|
|
51
52
|
$includePath = '';
|
|
52
53
|
$layoutsToInclude = [];
|
|
@@ -671,6 +672,15 @@ function authenticateUserToken()
|
|
|
671
672
|
}
|
|
672
673
|
}
|
|
673
674
|
|
|
675
|
+
function isAjaxOrXFileRequestOrRouteFile(): bool
|
|
676
|
+
{
|
|
677
|
+
if (Request::$fileToInclude === 'index.php') {
|
|
678
|
+
return false;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
return Request::$isAjax || Request::$isXFileRequest || Request::$fileToInclude === 'route.php';
|
|
682
|
+
}
|
|
683
|
+
|
|
674
684
|
set_exception_handler(function ($exception) {
|
|
675
685
|
if (isAjaxOrXFileRequestOrRouteFile()) {
|
|
676
686
|
$errorContent = "Exception: " . $exception->getMessage();
|
|
@@ -695,10 +705,43 @@ register_shutdown_function(function () {
|
|
|
695
705
|
}
|
|
696
706
|
});
|
|
697
707
|
|
|
698
|
-
function
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
708
|
+
spl_autoload_register(function ($class) {
|
|
709
|
+
// Path to the log file
|
|
710
|
+
$logFile = SETTINGS_PATH . '/class-log.json';
|
|
711
|
+
|
|
712
|
+
// Check if the file exists
|
|
713
|
+
if (!file_exists($logFile)) {
|
|
714
|
+
// Create an empty JSON file
|
|
715
|
+
file_put_contents($logFile, json_encode([]));
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// Read the current log data (fresh start each time)
|
|
719
|
+
$logData = json_decode(file_get_contents($logFile), true) ?? [];
|
|
720
|
+
|
|
721
|
+
// Attempt to load the class file and get the file path
|
|
722
|
+
$classParts = explode('\\', $class);
|
|
723
|
+
$filePath = __DIR__ . '/src/' . implode('/', $classParts) . '.php';
|
|
724
|
+
|
|
725
|
+
// Require the file if it exists
|
|
726
|
+
if (file_exists($filePath)) {
|
|
727
|
+
require_once $filePath;
|
|
728
|
+
|
|
729
|
+
// Use reflection to get all declared classes and register them
|
|
730
|
+
$declaredClasses = get_declared_classes();
|
|
731
|
+
foreach ($declaredClasses as $declaredClass) {
|
|
732
|
+
$classNamespace = implode('\\', $classParts);
|
|
733
|
+
if (strpos($declaredClass, $classNamespace) !== false) {
|
|
734
|
+
$logData[$declaredClass] = [
|
|
735
|
+
'class_name' => $declaredClass,
|
|
736
|
+
'file_path' => $filePath,
|
|
737
|
+
];
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// Save back to the JSON file
|
|
743
|
+
file_put_contents($logFile, json_encode($logData, JSON_PRETTY_PRINT));
|
|
744
|
+
}, true, true);
|
|
702
745
|
|
|
703
746
|
try {
|
|
704
747
|
$_determineContentToInclude = determineContentToInclude();
|
|
@@ -826,7 +869,7 @@ try {
|
|
|
826
869
|
|
|
827
870
|
MainLayout::$children = MainLayout::$childLayoutChildren;
|
|
828
871
|
MainLayout::$children .= getLoadingsFiles();
|
|
829
|
-
MainLayout::$children =
|
|
872
|
+
MainLayout::$children = TemplateCompiler::compile(MainLayout::$children);
|
|
830
873
|
|
|
831
874
|
ob_start();
|
|
832
875
|
require_once APP_PATH . '/layout.php';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { writeFile } from "fs";
|
|
2
2
|
import { join, basename, dirname, normalize, sep } from "path";
|
|
3
3
|
import prismaPhpConfigJson from "../prisma-php.json";
|
|
4
4
|
import { getFileMeta } from "./utils.js";
|
|
5
|
+
import { promises as fsPromises } from "fs";
|
|
5
6
|
|
|
6
7
|
const { __dirname } = getFileMeta();
|
|
7
8
|
|
|
@@ -88,12 +89,23 @@ const configFilePath = join(__dirname, "..", "prisma-php.json");
|
|
|
88
89
|
// Run the function with your config file path and the new project name
|
|
89
90
|
updateProjectNameInConfig(configFilePath, newProjectName);
|
|
90
91
|
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
// console.
|
|
96
|
-
|
|
92
|
+
const deleteFilesIfExist = async (filePaths: string[]): Promise<void> => {
|
|
93
|
+
for (const filePath of filePaths) {
|
|
94
|
+
try {
|
|
95
|
+
await fsPromises.unlink(filePath);
|
|
96
|
+
// console.log(`Deleted ${filePath}`);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
|
|
99
|
+
// Ignore error if file doesn't exist
|
|
100
|
+
console.error(`Error deleting ${filePath}:`, error);
|
|
101
|
+
}
|
|
97
102
|
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const filePaths = [
|
|
107
|
+
join(__dirname, "request-data.json"),
|
|
108
|
+
join(__dirname, "class-log.json"),
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
deleteFilesIfExist(filePaths);
|
|
@@ -20,14 +20,35 @@ final class AuthConfig
|
|
|
20
20
|
public const ROLE_IDENTIFIER = 'role';
|
|
21
21
|
public const IS_ROLE_BASE = false;
|
|
22
22
|
public const IS_TOKEN_AUTO_REFRESH = false;
|
|
23
|
+
public const IS_ALL_ROUTES_PRIVATE = false;
|
|
23
24
|
|
|
24
25
|
/**
|
|
26
|
+
* This is the (default) option for authentication. If IS_ALL_ROUTES_PRIVATE is set to false,
|
|
25
27
|
* An array of private routes that are accessible to all authenticated users
|
|
26
28
|
* without specific role-based access control. Routes should be listed as string paths.
|
|
27
29
|
* Example: public static $privateRoutes = ['/']; // This makes the home page private
|
|
28
30
|
* Example: public static $privateRoutes = ['/profile', '/dashboard/settings']; // These routes are private
|
|
29
31
|
*/
|
|
30
|
-
public static $privateRoutes = [];
|
|
32
|
+
public static array $privateRoutes = [];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* This is the (default) option for authentication. If IS_ALL_ROUTES_PRIVATE is set to true,
|
|
36
|
+
* An array of public routes that are accessible to all users, authenticated or not.
|
|
37
|
+
*/
|
|
38
|
+
public const DEFAULT_SIGNIN_REDIRECT = '/dashboard'; // Default redirect route after sign in
|
|
39
|
+
public const API_AUTH_PREFIX = '/api/auth'; // Prefix for third-party API authentication routes (github, google, etc.)
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* An array of public routes that are accessible to all users, authenticated or not.
|
|
43
|
+
* Routes should be listed as string paths.
|
|
44
|
+
* Example: public static $publicRoutes = ['/']; // This makes the home page public
|
|
45
|
+
* Example: public static $publicRoutes = ['/about', '/contact']; // These routes are public
|
|
46
|
+
*/
|
|
47
|
+
public static array $publicRoutes = ['/'];
|
|
48
|
+
public static array $authRoutes = [
|
|
49
|
+
'/signin',
|
|
50
|
+
'/signup',
|
|
51
|
+
];
|
|
31
52
|
|
|
32
53
|
/**
|
|
33
54
|
* An associative array mapping specific routes to required user roles for access control.
|
|
@@ -41,17 +62,21 @@ final class AuthConfig
|
|
|
41
62
|
* 'sales' => [self::ROLE_IDENTIFIER => [AuthRole::Admin, AuthRole::User]]
|
|
42
63
|
* ];
|
|
43
64
|
*/
|
|
44
|
-
public static $roleBasedRoutes = [];
|
|
65
|
+
public static array $roleBasedRoutes = [];
|
|
45
66
|
|
|
46
67
|
/**
|
|
47
68
|
* Checks if the given user role is authorized to access a set of roles.
|
|
48
69
|
*
|
|
49
|
-
* @param string $userRole The
|
|
50
|
-
* @param array $roles An array of AuthRole instances specifying allowed roles.
|
|
51
|
-
* @return bool Returns true if the user role
|
|
70
|
+
* @param \ArrayObject|string $userRole The user's role to check.
|
|
71
|
+
* @param array<AuthRole> $roles An array of AuthRole instances specifying allowed roles.
|
|
72
|
+
* @return bool Returns true if the user's role matches any of the allowed roles, false otherwise.
|
|
52
73
|
*/
|
|
53
|
-
public static function checkAuthRole($userRole, $roles)
|
|
74
|
+
public static function checkAuthRole(\ArrayObject|string $userRole, array $roles): bool
|
|
54
75
|
{
|
|
76
|
+
if ($userRole instanceof \ArrayObject) {
|
|
77
|
+
$userRole = $userRole[Auth::ROLE_NAME] ?? '';
|
|
78
|
+
}
|
|
79
|
+
|
|
55
80
|
foreach ($roles as $role) {
|
|
56
81
|
if ($userRole === $role->value) {
|
|
57
82
|
return true;
|
|
@@ -12,26 +12,62 @@ final class AuthMiddleware
|
|
|
12
12
|
{
|
|
13
13
|
public static function handle($requestPathname)
|
|
14
14
|
{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
if (AuthConfig::IS_ALL_ROUTES_PRIVATE) {
|
|
16
|
+
$isLogin = Auth::getInstance()->isAuthenticated();
|
|
17
|
+
$isApiAuthRoute = stripos($requestPathname, AuthConfig::API_AUTH_PREFIX) === 0;
|
|
18
|
+
$isPublicRoute = self::matches($requestPathname, AuthConfig::$publicRoutes);
|
|
19
|
+
$isAuthRoute = self::matches($requestPathname, AuthConfig::$authRoutes);
|
|
20
|
+
|
|
21
|
+
// Skip the middleware if the route is api auth route
|
|
22
|
+
if ($isApiAuthRoute) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Redirect to the default sign in route if the user is already authenticated
|
|
27
|
+
if ($isAuthRoute) {
|
|
28
|
+
if ($isLogin) {
|
|
29
|
+
Request::redirect(AuthConfig::DEFAULT_SIGNIN_REDIRECT);
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Redirect to the default home route if the user is already authenticated
|
|
35
|
+
if (!$isLogin && !$isPublicRoute) {
|
|
36
|
+
Request::redirect("/signin");
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
// Skip the middleware if the route is public
|
|
40
|
+
if (!self::matches($requestPathname, AuthConfig::$privateRoutes)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
19
43
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
44
|
+
// Check if the user is authorized to access the route or redirect to login
|
|
45
|
+
if (!self::isAuthorized()) {
|
|
46
|
+
Request::redirect('/signin');
|
|
47
|
+
}
|
|
23
48
|
}
|
|
24
49
|
|
|
25
50
|
// Check if the user has the required role to access the route or redirect to denied
|
|
26
|
-
if (AuthConfig::IS_ROLE_BASE
|
|
27
|
-
|
|
51
|
+
if (AuthConfig::IS_ROLE_BASE) {
|
|
52
|
+
$matchValue = self::hasRequiredRole($requestPathname);
|
|
53
|
+
if ($matchValue === "Route not in array") {
|
|
54
|
+
// echo "No validation needed for this route.";
|
|
55
|
+
} elseif ($matchValue === "Match") {
|
|
56
|
+
// echo "You are authorized to access this route";
|
|
57
|
+
} elseif ($matchValue === "Role mismatch") {
|
|
58
|
+
// echo "You are not authorized to access this route";
|
|
59
|
+
Request::redirect('/denied');
|
|
60
|
+
} else {
|
|
61
|
+
// echo "Unexpected error encountered";
|
|
62
|
+
}
|
|
28
63
|
}
|
|
29
64
|
}
|
|
30
65
|
|
|
31
|
-
protected static function matches($requestPathname)
|
|
66
|
+
protected static function matches(string $requestPathname, array $routes): bool
|
|
32
67
|
{
|
|
33
|
-
foreach (
|
|
34
|
-
|
|
68
|
+
foreach ($routes ?? [] as $pattern) {
|
|
69
|
+
$getUriRegexValue = self::getUriRegex($pattern, $requestPathname);
|
|
70
|
+
if ($getUriRegexValue) {
|
|
35
71
|
return true;
|
|
36
72
|
}
|
|
37
73
|
}
|
|
@@ -67,34 +103,44 @@ final class AuthMiddleware
|
|
|
67
103
|
return false;
|
|
68
104
|
}
|
|
69
105
|
|
|
70
|
-
protected static function hasRequiredRole($requestPathname):
|
|
106
|
+
protected static function hasRequiredRole(string $requestPathname): string
|
|
71
107
|
{
|
|
72
108
|
$auth = Auth::getInstance();
|
|
73
109
|
$roleBasedRoutes = AuthConfig::$roleBasedRoutes ?? [];
|
|
110
|
+
|
|
111
|
+
// Normalize the request path for matching
|
|
112
|
+
$requestPathnameValue = trim($requestPathname, '/');
|
|
113
|
+
|
|
74
114
|
foreach ($roleBasedRoutes as $pattern => $data) {
|
|
75
|
-
|
|
115
|
+
$patternValue = trim($pattern, '/');
|
|
116
|
+
if ($patternValue === $requestPathnameValue) {
|
|
117
|
+
// Route is found in array, check permissions
|
|
76
118
|
$userRole = Auth::ROLE_NAME ? $auth->getPayload()[Auth::ROLE_NAME] : $auth->getPayload();
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
119
|
+
return ($userRole !== null && AuthConfig::checkAuthRole($userRole, $data[AuthConfig::ROLE_IDENTIFIER]))
|
|
120
|
+
? "Match"
|
|
121
|
+
: "Role mismatch";
|
|
80
122
|
}
|
|
81
123
|
}
|
|
82
|
-
|
|
124
|
+
|
|
125
|
+
// Route not found in role-based routes array
|
|
126
|
+
return "Route not in array";
|
|
83
127
|
}
|
|
84
128
|
|
|
85
|
-
private static function getUriRegex($pattern, $requestPathname)
|
|
129
|
+
private static function getUriRegex(string $pattern, string $requestPathname): int|bool
|
|
86
130
|
{
|
|
87
|
-
|
|
88
|
-
$
|
|
131
|
+
// Normalize both the pattern and the request path
|
|
132
|
+
$pattern = strtolower(trim($pattern, '/'));
|
|
133
|
+
$requestPathname = strtolower(trim($requestPathname, '/'));
|
|
89
134
|
|
|
90
135
|
// Handle the case where the requestPathname is empty, which means home or "/"
|
|
91
|
-
if (empty($requestPathname)
|
|
136
|
+
if (empty($requestPathname)) {
|
|
92
137
|
$requestPathname = '/';
|
|
93
138
|
} else {
|
|
94
|
-
$requestPathname = "
|
|
139
|
+
$requestPathname = "/$requestPathname";
|
|
95
140
|
}
|
|
96
141
|
|
|
97
|
-
|
|
142
|
+
// Construct the regex pattern
|
|
143
|
+
$regex = "#^/?" . preg_quote("/$pattern", '#') . "(/.*)?$#";
|
|
98
144
|
return preg_match($regex, $requestPathname);
|
|
99
145
|
}
|
|
100
146
|
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
declare(strict_types=1);
|
|
4
|
+
|
|
5
|
+
namespace Lib\PHPX;
|
|
6
|
+
|
|
7
|
+
use Lib\PrismaPHPSettings;
|
|
8
|
+
|
|
9
|
+
class TemplateCompiler
|
|
10
|
+
{
|
|
11
|
+
public static function compile($templateContent)
|
|
12
|
+
{
|
|
13
|
+
// Updated pattern to match self-closing and regular tags, allowing for nested tags
|
|
14
|
+
$pattern = '/<([A-Z][a-zA-Z0-9]*)\b([^>]*)\/?>((?:.*?)<\/\1>)?/s';
|
|
15
|
+
|
|
16
|
+
$compiledContent = preg_replace_callback($pattern, function ($matches) {
|
|
17
|
+
$componentName = strtolower($matches[1]);
|
|
18
|
+
$attributes = $matches[2];
|
|
19
|
+
$hasClosingTag = isset($matches[3]) && !empty($matches[3]);
|
|
20
|
+
|
|
21
|
+
$innerContent = '';
|
|
22
|
+
if ($hasClosingTag) {
|
|
23
|
+
$innerContent = $matches[3];
|
|
24
|
+
// Recursively compile the inner content
|
|
25
|
+
$innerContent = self::compile($innerContent);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Parse attributes into an associative array
|
|
29
|
+
$attrArray = self::parseAttributes($attributes);
|
|
30
|
+
|
|
31
|
+
if (trim($innerContent)) {
|
|
32
|
+
$attrArray['children'] = $innerContent;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return self::processComponent($componentName, $attrArray, $innerContent);
|
|
36
|
+
}, $templateContent);
|
|
37
|
+
|
|
38
|
+
return $compiledContent;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected static function parseAttributes($attributes)
|
|
42
|
+
{
|
|
43
|
+
// Regex to match attributes with and without values
|
|
44
|
+
$attrPattern = '/([a-zA-Z0-9\-]+)(?:="([^"]*)")?/';
|
|
45
|
+
|
|
46
|
+
// Capture attributes with and without values
|
|
47
|
+
preg_match_all($attrPattern, $attributes, $attrMatches, PREG_SET_ORDER);
|
|
48
|
+
$attrArray = [];
|
|
49
|
+
|
|
50
|
+
foreach ($attrMatches as $attr) {
|
|
51
|
+
if (isset($attr[2])) {
|
|
52
|
+
// Attribute with a value
|
|
53
|
+
$attrArray[$attr[1]] = $attr[2];
|
|
54
|
+
} else {
|
|
55
|
+
// Boolean attribute (e.g., disabled, checked)
|
|
56
|
+
$attrArray[$attr[1]] = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return $attrArray;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
protected static function isClassLogged($componentName)
|
|
64
|
+
{
|
|
65
|
+
// Read the JSON content
|
|
66
|
+
$classLog = PrismaPHPSettings::$classLogFiles;
|
|
67
|
+
|
|
68
|
+
// Normalize the component name to ensure case-insensitive comparison
|
|
69
|
+
$normalizedComponent = strtolower($componentName);
|
|
70
|
+
// Loop through the class log to check for a match
|
|
71
|
+
foreach ($classLog as $classPath => $classInfo) {
|
|
72
|
+
$className = strtolower(pathinfo($classPath, PATHINFO_FILENAME));
|
|
73
|
+
|
|
74
|
+
if ($normalizedComponent === $className) {
|
|
75
|
+
return $classPath;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
protected static function stripSpecificTags($content, $tags)
|
|
83
|
+
{
|
|
84
|
+
foreach ($tags as $tag) {
|
|
85
|
+
// Strip opening and closing tags, case insensitive
|
|
86
|
+
$content = preg_replace('/<' . $tag . '.*?>|<\/' . $tag . '>/i', '', $content);
|
|
87
|
+
}
|
|
88
|
+
return $content;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
protected static function processComponent($componentName, $attrPhp, $innerContent)
|
|
92
|
+
{
|
|
93
|
+
// Start output buffering to capture dynamic content
|
|
94
|
+
ob_start();
|
|
95
|
+
|
|
96
|
+
// Check if the class is logged and exists
|
|
97
|
+
$classPath = self::isClassLogged($componentName);
|
|
98
|
+
if ($classPath && class_exists($classPath)) {
|
|
99
|
+
$componentInstance = new $classPath($attrPhp);
|
|
100
|
+
echo $componentInstance->render(); // Echo directly, which will be captured by output buffer
|
|
101
|
+
} else {
|
|
102
|
+
// If no class exists or it wasn't found in the log, render it as an HTML tag
|
|
103
|
+
$attributes = self::renderAttributes($attrPhp);
|
|
104
|
+
|
|
105
|
+
// Check if it's a self-closing tag by checking if there's no inner content
|
|
106
|
+
if ($innerContent === '') {
|
|
107
|
+
echo "<$componentName $attributes />";
|
|
108
|
+
} else {
|
|
109
|
+
echo "<$componentName $attributes>$innerContent</$componentName>";
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Capture and return the output buffer content
|
|
114
|
+
return ob_get_clean();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
protected static function renderAttributes($attrArray)
|
|
118
|
+
{
|
|
119
|
+
// Convert array back into HTML attributes
|
|
120
|
+
$attrString = '';
|
|
121
|
+
foreach ($attrArray as $key => $value) {
|
|
122
|
+
if ($key !== 'children') {
|
|
123
|
+
$attrString .= "{$key}=\"{$value}\" ";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return trim($attrString);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -70,10 +70,18 @@ class PrismaPHPSettings
|
|
|
70
70
|
*/
|
|
71
71
|
public static array $routeFiles = [];
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* The list of class log files.
|
|
75
|
+
*
|
|
76
|
+
* @var array
|
|
77
|
+
*/
|
|
78
|
+
public static array $classLogFiles = [];
|
|
79
|
+
|
|
73
80
|
public static function init(): void
|
|
74
81
|
{
|
|
75
82
|
self::$option = self::getPrismaSettings();
|
|
76
83
|
self::$routeFiles = self::getRoutesFileList();
|
|
84
|
+
self::$classLogFiles = self::getClassesLogFiles();
|
|
77
85
|
}
|
|
78
86
|
|
|
79
87
|
/**
|
|
@@ -107,4 +115,12 @@ class PrismaPHPSettings
|
|
|
107
115
|
|
|
108
116
|
return $routeFiles;
|
|
109
117
|
}
|
|
118
|
+
|
|
119
|
+
private static function getClassesLogFiles(): array
|
|
120
|
+
{
|
|
121
|
+
$jsonFileName = SETTINGS_PATH . '/class-log.json';
|
|
122
|
+
$classLogFiles = file_exists($jsonFileName) ? json_decode(file_get_contents($jsonFileName), true) : [];
|
|
123
|
+
|
|
124
|
+
return $classLogFiles;
|
|
125
|
+
}
|
|
110
126
|
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 123.78 126.83">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: #4fbddb;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.cls-2 {
|
|
10
|
+
fill: #485ca3;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.cls-3 {
|
|
14
|
+
fill: #84ca7a;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.cls-4 {
|
|
18
|
+
fill: #4ab65d;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.cls-5 {
|
|
22
|
+
fill: #5d6dc9;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.cls-6 {
|
|
26
|
+
fill: #202b6b;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.cls-7 {
|
|
30
|
+
fill: #4e99dd;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.cls-8 {
|
|
34
|
+
fill: #167c23;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.cls-9 {
|
|
38
|
+
fill: #8094e8;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.cls-10 {
|
|
42
|
+
fill: #299939;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.cls-11 {
|
|
46
|
+
fill: #8ce87c;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.cls-12 {
|
|
50
|
+
fill: #3d7bbe;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.cls-13 {
|
|
54
|
+
fill: #2bd0f7;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.cls-14 {
|
|
58
|
+
fill: #77c1f7;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.cls-15 {
|
|
62
|
+
fill: #454fa0;
|
|
63
|
+
}
|
|
64
|
+
</style>
|
|
65
|
+
</defs>
|
|
66
|
+
<g>
|
|
67
|
+
<polygon class="cls-9" points="123.78 58.16 112.21 51.64 113.89 50.58 123.78 58.16"/>
|
|
68
|
+
<polygon class="cls-5" points="113.89 50.58 112.21 51.64 111.46 49.39 113.89 50.58"/>
|
|
69
|
+
<polygon class="cls-5" points="111.46 49.39 112.21 51.64 107.18 49.88 111.46 49.39"/>
|
|
70
|
+
<polygon class="cls-5" points="111.46 49.39 107.18 49.88 105.01 46.24 111.46 49.39"/>
|
|
71
|
+
<polygon class="cls-15" points="105.01 46.24 107.18 49.88 99.79 47.32 105.01 46.24"/>
|
|
72
|
+
<polygon class="cls-5" points="105.01 46.24 99.79 47.32 97.09 42.37 105.01 46.24"/>
|
|
73
|
+
<polygon class="cls-15" points="97.09 42.37 99.79 47.32 94.14 46.58 94.14 44.2 97.09 42.37"/>
|
|
74
|
+
<polygon class="cls-5" points="92.74 37.04 97.09 42.37 88.67 36.83 88.95 32.69 92.74 37.04"/>
|
|
75
|
+
<polygon class="cls-12" points="97.09 42.37 94.14 44.2 87.37 42.05 97.09 42.37"/>
|
|
76
|
+
<polygon class="cls-6" points="97.09 42.37 87.37 42.05 84.18 38.9 89.29 39.21 97.09 42.37"/>
|
|
77
|
+
<polygon class="cls-7" points="97.09 42.37 89.29 39.21 86.29 39.47 88.67 36.83 97.09 42.37"/>
|
|
78
|
+
<polygon class="cls-8" points="94.14 44.2 94.14 46.58 90.78 51.07 87.69 46.58 94.14 44.2"/>
|
|
79
|
+
<polygon class="cls-10" points="94.14 44.2 87.69 46.58 80.11 42.37 87.37 42.05 94.14 44.2"/>
|
|
80
|
+
<polygon class="cls-10" points="87.69 46.58 90.78 51.07 87.97 62.58 80.11 53.74 87.69 46.58"/>
|
|
81
|
+
<polygon class="cls-7" points="88.95 32.69 88.67 36.83 81.65 36.41 88.95 32.69"/>
|
|
82
|
+
<polygon class="cls-1" points="88.95 32.69 81.65 36.41 84.6 31.29 88.95 32.69"/>
|
|
83
|
+
<polygon class="cls-1" points="88.67 36.83 86.29 39.47 81.65 36.41 88.67 36.83"/>
|
|
84
|
+
<polygon class="cls-4" points="80.11 53.74 87.97 62.58 80.11 66.68 73.66 58.65 80.11 53.74"/>
|
|
85
|
+
<polygon class="cls-8" points="87.97 62.58 84.04 72.26 80.11 66.68 87.97 62.58"/>
|
|
86
|
+
<polygon class="cls-11" points="87.69 46.58 80.11 53.74 80.11 42.37 87.69 46.58"/>
|
|
87
|
+
<polygon class="cls-4" points="87.37 42.05 80.11 42.37 81.65 36.41 86.29 39.47 87.37 42.05"/>
|
|
88
|
+
<polygon class="cls-13" points="84.6 31.29 81.65 36.41 77.94 32.55 84.6 31.29"/>
|
|
89
|
+
<polygon class="cls-10" points="80.11 66.68 84.04 72.26 77.03 80.68 80.11 66.68"/>
|
|
90
|
+
<polygon class="cls-1" points="77.94 32.55 81.65 36.41 72.4 37.88 77.94 32.55"/>
|
|
91
|
+
<polygon class="cls-1" points="81.65 36.41 80.11 42.37 71.28 45.46 81.65 36.41"/>
|
|
92
|
+
<polygon class="cls-7" points="81.65 36.41 71.28 45.46 72.4 37.88 81.65 36.41"/>
|
|
93
|
+
<polygon class="cls-3" points="80.11 42.37 80.11 53.74 73.66 58.65 71.28 45.46 80.11 42.37"/>
|
|
94
|
+
<polygon class="cls-11" points="73.66 58.65 80.11 66.68 72.04 70.57 73.66 58.65"/>
|
|
95
|
+
<polygon class="cls-3" points="80.11 66.68 77.03 80.68 72.04 70.57 80.11 66.68"/>
|
|
96
|
+
<polygon class="cls-7" points="72.04 70.57 77.03 80.68 61.59 79.83 72.04 70.57"/>
|
|
97
|
+
<polygon class="cls-2" points="77.03 80.68 58.79 90.07 61.59 79.83 77.03 80.68"/>
|
|
98
|
+
<polygon class="cls-2" points="72.68 101.72 74.22 110.14 67.76 108.31 62.88 98.37 72.68 101.72"/>
|
|
99
|
+
<polygon class="cls-12" points="71.28 45.46 73.66 58.65 70.15 55.56 68.11 50.89 71.28 45.46"/>
|
|
100
|
+
<polygon class="cls-9" points="73.66 58.65 72.04 70.57 66.08 61.87 70.15 55.56 73.66 58.65"/>
|
|
101
|
+
<polygon class="cls-7" points="72.68 101.72 62.88 98.37 58.79 90.07 72.68 101.72"/>
|
|
102
|
+
<polygon class="cls-5" points="66.08 61.87 72.04 70.57 61.59 79.83 56.82 68.05 66.08 61.87"/>
|
|
103
|
+
<polygon class="cls-4" points="68.11 50.89 70.15 55.56 55 51.07 66.22 46.58 68.11 50.89"/>
|
|
104
|
+
<polygon class="cls-3" points="70.15 55.56 66.08 61.87 55 51.07 70.15 55.56"/>
|
|
105
|
+
<polygon class="cls-2" points="67.76 108.31 68.33 115.33 62.15 113.16 58.23 103.58 67.76 108.31"/>
|
|
106
|
+
<polygon class="cls-12" points="62.88 98.37 67.76 108.31 55 95.69 62.88 98.37"/>
|
|
107
|
+
<polygon class="cls-7" points="67.76 108.31 58.23 103.58 55 95.69 67.76 108.31"/>
|
|
108
|
+
<polygon class="cls-5" points="64.55 33.11 66.22 46.58 55 38.68 64.55 33.11"/>
|
|
109
|
+
<polygon class="cls-3" points="66.22 46.58 55 51.07 39 27.42 46.72 32.86 55 38.68 66.22 46.58"/>
|
|
110
|
+
<polygon class="cls-4" points="66.08 61.87 56.82 68.05 55 51.07 66.08 61.87"/>
|
|
111
|
+
<polygon class="cls-15" points="64.55 33.1 64.55 33.11 55 38.68 46.72 32.86 46.72 20.48 64.55 33.1"/>
|
|
112
|
+
<polygon class="cls-5" points="63.13 21.6 64.55 33.1 46.72 20.48 60.33 15.1 63.13 21.6"/>
|
|
113
|
+
<polygon class="cls-2" points="62.88 98.37 55 95.69 58.79 90.07 62.88 98.37"/>
|
|
114
|
+
<polygon class="cls-2" points="58.23 103.58 62.15 113.16 60.8 123.24 53.39 117.87 54.55 101.76 58.23 103.58"/>
|
|
115
|
+
<polygon class="cls-12" points="56.82 68.05 61.59 79.83 50.55 85.2 56.82 68.05"/>
|
|
116
|
+
<polygon class="cls-1" points="61.59 79.83 58.79 90.07 50.55 85.2 61.59 79.83"/>
|
|
117
|
+
<polygon class="cls-9" points="60.33 15.1 46.72 20.48 50.37 5.47 60.33 15.1"/>
|
|
118
|
+
<polygon class="cls-12" points="58.79 90.07 55 95.69 49.66 99.33 50.55 85.2 58.79 90.07"/>
|
|
119
|
+
<polygon class="cls-14" points="55 95.69 58.23 103.58 54.55 101.76 55 95.69"/>
|
|
120
|
+
<polygon class="cls-2" points="55 51.07 56.82 68.05 47.7 66.22 55 51.07"/>
|
|
121
|
+
<polygon class="cls-12" points="56.82 68.05 50.55 85.2 45.18 73.52 56.82 68.05"/>
|
|
122
|
+
<polygon class="cls-1" points="56.82 68.05 45.18 73.52 47.7 66.22 56.82 68.05"/>
|
|
123
|
+
<polygon class="cls-15" points="39 27.42 55 51.07 27.78 42.09 39 27.42"/>
|
|
124
|
+
<polygon class="cls-15" points="55 51.07 47.7 66.22 40.96 55.56 55 51.07"/>
|
|
125
|
+
<polygon class="cls-1" points="55 95.69 54.55 101.76 52.36 100.67 55 95.69"/>
|
|
126
|
+
<polygon class="cls-1" points="55 95.69 52.36 100.67 49.66 99.33 55 95.69"/>
|
|
127
|
+
<polygon class="cls-5" points="55 51.07 40.96 55.56 27.78 42.09 55 51.07"/>
|
|
128
|
+
<polygon class="cls-12" points="54.55 101.76 53.39 117.87 50.6 103.99 52.36 100.67 54.55 101.76"/>
|
|
129
|
+
<polygon class="cls-2" points="50.6 103.99 53.39 117.87 47.7 126.83 44.06 116.31 50.6 103.99"/>
|
|
130
|
+
<polygon class="cls-14" points="52.36 100.67 50.6 103.99 49.66 99.33 52.36 100.67"/>
|
|
131
|
+
<polygon class="cls-12" points="49.66 99.33 50.6 103.99 44.06 116.31 49.66 99.33"/>
|
|
132
|
+
<polygon class="cls-2" points="45.18 73.52 50.55 85.2 44.06 88.95 45.18 73.52"/>
|
|
133
|
+
<polygon class="cls-2" points="50.55 85.2 49.66 99.33 44.62 96.39 44.06 88.95 50.55 85.2"/>
|
|
134
|
+
<polygon class="cls-7" points="49.66 99.33 44.06 116.31 44.36 105.31 49.66 99.33"/>
|
|
135
|
+
<polygon class="cls-1" points="49.66 99.33 44.36 105.31 44.62 96.39 49.66 99.33"/>
|
|
136
|
+
<polygon class="cls-7" points="44.06 88.95 44.62 96.39 35.78 99.33 44.06 88.95"/>
|
|
137
|
+
<polygon class="cls-12" points="44.62 96.39 44.36 105.31 37.13 113.46 39.71 105.23 44.62 96.39"/>
|
|
138
|
+
<polygon class="cls-2" points="44.62 96.39 39.71 105.23 34.09 106.77 44.62 96.39"/>
|
|
139
|
+
<polygon class="cls-12" points="44.62 96.39 34.09 106.77 35.78 99.33 44.62 96.39"/>
|
|
140
|
+
<polygon class="cls-2" points="37.13 113.46 44.36 105.31 44.06 116.31 39.35 122.49 37.13 113.46"/>
|
|
141
|
+
<polygon class="cls-15" points="24.13 11.78 39 27.42 18.24 24.7 24.13 11.78"/>
|
|
142
|
+
<polygon class="cls-5" points="39 27.42 27.78 42.09 18.24 24.7 39 27.42"/>
|
|
143
|
+
<polygon class="cls-5" points="24.13 11.78 18.24 24.7 6.46 12.07 24.13 11.78"/>
|
|
144
|
+
<polygon class="cls-9" points="24.13 11.78 6.46 12.07 0 0 24.13 11.78"/>
|
|
145
|
+
</g>
|
|
146
|
+
<polygon class="cls-15" points="89.29 39.21 90.14 42.14 97.09 42.37 89.29 39.21"/>
|
|
147
|
+
</svg>
|
package/dist/src/app/favicon.ico
CHANGED
|
Binary file
|
package/dist/src/app/index.php
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div class="flex flex-col min-h-[100vh] bg-gradient-to-b from-[#a1b8c2] to-white dark:from-[#334455] dark:to-black">
|
|
4
4
|
<header class="px-4 lg:px-6 h-14 flex items-center">
|
|
5
5
|
<a class="flex items-center justify-center" href="/">
|
|
6
|
-
<img class="
|
|
6
|
+
<img class="size-9" src="<?= Request::baseUrl ?>/assets/images/prisma-php.svg" alt="Prisma PHP">
|
|
7
7
|
<span class="sr-only">Prisma PHP</span>
|
|
8
8
|
</a>
|
|
9
9
|
<nav class="ml-auto flex gap-4 sm:gap-6">
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<div class="px-4 md:px-6">
|
|
27
27
|
<div class="flex flex-col items-center space-y-4 text-center">
|
|
28
28
|
<h1 class="text-3xl font-bold tracking-tighter sm:text-4xl md:text-5xl lg:text-6xl/none flex items-center gap-3 justify-center">
|
|
29
|
-
Welcome to Prisma PHP <img class="
|
|
29
|
+
Welcome to Prisma PHP <img class="size-20 hidden sm:block" src="<?= Request::baseUrl ?>/assets/images/prisma-php.svg" alt="Prisma PHP">
|
|
30
30
|
</h1>
|
|
31
31
|
<p class="mx-auto max-w-[700px] text-gray-500 md:text-xl dark:text-gray-400">
|
|
32
32
|
Your Next Generation PHP Framework
|
package/dist/src/app/js/index.js
CHANGED
|
@@ -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 observeDOMChanges(){new MutationObserver((e=>{for(const t of e)"childList"===t.type&&t.addedNodes.length>0&&attachWireFunctionEvents()})).observe(document.body,{childList:!0,subtree:!0})}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),o=t.slice(2);n&&(e.removeAttribute(t),handleDebounce(e,o,n))})),e instanceof HTMLFormElement){const t=e.getAttribute("onsubmit");t&&(e.removeAttribute("onsubmit"),handleDebounce(e,"submit",t))}}))}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 o=e.getAttribute(t);if(o)if(isJsonLike(o)){n(e,parseJson(o))}else{const n=parseTime(o);if(n>0){const o="pp-visibility"===t?"visibility":"display";scheduleChange(e,n,o,"visibility"===o?"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,o,s){const a=t.start?parseTime(t.start):0,r=t.end?parseTime(t.end):0;a>0?(e.style[n]=o,scheduleChange(e,a,n,s),r>0&&scheduleChange(e,a+r,n,o)):r>0&&scheduleChange(e,r,n,o)}function scheduleChange(e,t,n,o){setTimeout((()=>{requestAnimationFrame((()=>{e.style[n]=o}))}),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){e.removeAllEventListeners(t);const o=e.getAttribute("pp-debounce")||"",s=e.getAttribute("pp-before-request")||"",a=e.getAttribute("pp-after-request")||"",r=async t=>{t.preventDefault();try{s&&await invokeHandler(e,s,t),await invokeHandler(e,n,t),a&&"@close"!==a&&await invokeHandler(e,a,t),handlerAutofocusAttribute()}catch(e){}};if(o){const n=debounce(r,parseTime(o));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 o=parseJson(n);if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){const t=["text","search","tel","url","password"];if(e instanceof HTMLInputElement)if(t.includes(e.type))if("number"===e.type){e.type="text";const t=e.value.length||0;e.setSelectionRange(t,t),e.type="number"}else setCursorPosition(e,o);else;else e instanceof HTMLTextAreaElement&&setCursorPosition(e,o)}e.focus(),t=!0}))}function setCursorPosition(e,t){if(t.start)e.setSelectionRange(0,0);else if(t.end){const t=e.value.length||0;e.setSelectionRange(t,t)}else if(t.length){const n=parseInt(t.length,10)||0;e.setSelectionRange(n,n)}}async function invokeHandler(e,t,n){try{const o=t.match(/^(\w+(\.\w+)*)\((.*)\)$/);if(o){const s=o[1].split("."),{context:a,methodName:r}=resolveContext(s);"function"==typeof a[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:o}=parseCallback(e,t);if(!n)return;const s=window[n];if("function"==typeof s){const t=e.hasAttribute("pp-after-request"),n=Array.isArray(o.args)?o.args:[],a=responseDataDEAC2?parseJson(responseDataDEAC2):{response:responseDataDEAC2};let r={args:n,element:e,data:o};t&&(r={...r,...a}),await s(r)}else responseDataDEAC2=null,responseDataDEAC2=await handleUndefinedFunction(e,n,o)}function handleAnchorTag(e){e instanceof HTMLAnchorElement&&e.addEventListener("click",(async e=>{const t=e.currentTarget,n=t.getAttribute("href"),o=t.getAttribute("target");if(n&&"_blank"!==o&&!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 o="";const[s,a]=n.split("#");a&&(o=`#${a}`);new URLSearchParams(s.split("?")[1]).forEach(((e,n)=>{t.set(n,e)}));const r=`${e.pathname}?${t.toString()}${o}`;history.pushState(null,"",r)}else{const[e,t]=n.split("#"),o=`${e}${t?`#${t}`:""}`;history.pushState(null,"",o)}const o=n.indexOf("#");if(-1!==o){const e=n.slice(o+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,o=250;if(t)try{const e=parseJson(t);n=parseTime(e.fadeIn||n),o=parseTime(e.fadeOut||o)}catch(e){}return{fadeIn:n,fadeOut:o}},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)},o=async o=>{const s=document.querySelector("[pp-loading-content='true']")||document.body;if(s){const{fadeIn:a,fadeOut:r}=e(o);await t(s,r),s.innerHTML=o.innerHTML,n(s,a)}},s=window.location.pathname,a=document.getElementById("loading-file-1B87E");if(a){let e=a.querySelector(`div[pp-loading-url='${s}']`);e||(e=a.querySelector("div[pp-loading-url='/']")),e&&await o(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(){}function updateContentPreservingChanges(e,t){"true"!==e.getAttribute("pp-static")&&"true"!==t.getAttribute("pp-static")&&(updateAttributes(e,t),updateChildNodes(e,t))}function updateAttributes(e,t){const n=e.attributes,o=t.attributes,s=new Set;for(let t=0;t<o.length;t++){const n=o[t];s.add(n.name),e.getAttribute(n.name)!==n.value&&e.setAttribute(n.name,n.value)}for(let t=n.length-1;t>=0;t--){const o=n[t].name;s.has(o)||e.removeAttribute(o)}}function updateChildNodes(e,t){const n=Array.from(e.childNodes),o=Array.from(t.childNodes);let s=0,a=0;for(;a<o.length;){const t=o[a],r=n[s];r&&r.nodeType===Node.ELEMENT_NODE&&"true"===r.getAttribute("pp-static")||t.nodeType===Node.ELEMENT_NODE&&"true"===t.getAttribute("pp-static")?(s++,a++):r?isSameNodeType(r,t)?(r.nodeType===Node.ELEMENT_NODE?updateContentPreservingChanges(r,t):r.nodeType===Node.TEXT_NODE&&r.textContent!==t.textContent&&(r.textContent=t.textContent),s++,a++):(e.replaceChild(t.cloneNode(!0),r),s++,a++):(e.appendChild(t.cloneNode(!0)),a++)}for(;n.length>o.length;){const t=n.pop();if(!(t&&t instanceof Node))break;e.removeChild(t)}}function isSameNodeType(e,t){return e.nodeType===t.nodeType&&(e.nodeType!==Node.ELEMENT_NODE||e.tagName===t.tagName)}async function updateBodyContent(e){const t=saveScrollPositions();saveState();const n=(new DOMParser).parseFromString(e,"text/html"),o=document.getElementById("pphp-7CA7BB68A3656A88"),s=n.getElementById("afterbegin-8D95D"),a=n.getElementById("pphp-7CA7BB68A3656A88");if(s){const e=document.getElementById("afterbegin-8D95D");e?e.innerHTML=s.innerHTML:document.body.insertAdjacentHTML("afterbegin",s.outerHTML)}o&&a&&updateContentPreservingChanges(o,a),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"),o="pp-dynamic-script",s="pp-dynamic-link";document.head.querySelectorAll("[pp-dynamic-meta]").forEach((e=>e.remove()));document.head.querySelectorAll("[pp-dynamic-link]").forEach((e=>e.remove()));document.head.querySelectorAll("[pp-dynamic-script]").forEach((e=>e.remove()));await(async e=>{Array.from(e.head.children).forEach((e=>{const t=e.tagName;if("SCRIPT"===t&&e.hasAttribute(o)){const t=document.createElement("script");Array.from(e.attributes).forEach((e=>t.setAttribute(e.name,e.value))),e.textContent&&(t.textContent=e.textContent),document.head.appendChild(t)}else if("META"===t){if(e.getAttribute("charset")||"viewport"===e.getAttribute("name"))return;const t=e.name,n=e.getAttribute("property"),o=document.head.querySelector(t?`meta[name="${t}"]`:`meta[property="${n}"]`);o?document.head.replaceChild(e.cloneNode(!0),o):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)}else if(e.hasAttribute(s)){const t=e.cloneNode(!0);document.head.appendChild(t)}}})),populateDocumentBody(e)})(n),restoreScrollPositions(t),attachWireFunctionEvents(),document.dispatchEvent(new Event("DOMContentLoaded"))}async function populateDocumentBody(e){const t=new Map,n=document.createDocumentFragment();function o(e,n){let s=null;if("SCRIPT"===e.tagName){const t=e,n=document.createElement("script");Array.from(t.attributes).forEach((e=>{n.setAttribute(e.name,e.value)})),t.src?(n.src=t.src,n.async=!1):n.textContent=t.textContent,s=n}else s=e.cloneNode(!1),t.set(e,s),Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.TEXT_NODE?s.appendChild(document.createTextNode(e.textContent||"")):e.nodeType===Node.ELEMENT_NODE&&o(e,s)}));n.appendChild(s)}Array.from(e.body.children).forEach((e=>{o(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||"email"===e.type?(e.type="text",e.setSelectionRange(t,t),e.type="number"===e.type?"number":"email"):"date"===e.type||"month"===e.type||"week"===e.type||"time"===e.type||"datetime-local"===e.type||"color"===e.type||"file"===e.type||""!==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={window:{scrollTop:window.scrollY||document.documentElement.scrollTop,scrollLeft:window.scrollX||document.documentElement.scrollLeft}};return document.querySelectorAll("*").forEach((t=>{(t.scrollTop||t.scrollLeft)&&(e[getElementKey(t)]={scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})})),e}function restoreScrollPositions(e){requestAnimationFrame((()=>{const t=e.window;t&&window.scrollTo(t.scrollLeft,t.scrollTop),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 o=e.closest("form");if(o){new FormData(o).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 s=t.match(/(\w+)\((.*)\)/);if(s){const e=s[1];let t=s[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[o,s]=decodeHTML(t[n]).split(",");e.classList.replace(o,s);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 o=e.attributes[n];t[o.name]=o.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,o=document.querySelector(t);o&&s(o,n)}))}else o(t,e)}},o=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},s=(e,t)=>{e instanceof HTMLFormElement?n(e,t):updateElementAttributes(e,t)};try{if(t&&isJsonLike(t)){const o=parseJson(t);if(o)if(e instanceof HTMLFormElement){const t=new FormData(e),s={};t.forEach(((e,t)=>{s[t]=e})),o.disabled&&toggleFormElements(e,!0);const{disabled:a,...r}=o;updateElementAttributes(e,r),n(e,s)}else if(o.targets){o.targets.forEach((e=>{const{id:t,...n}=e,o=document.querySelector(t);o&&s(o,n)}));const{targets:t,...n}=o;updateElementAttributes(e,n)}else{if("disabled"===o.empty&&""===e.value)return;const{empty:t,...n}=o;updateElementAttributes(e,n)}}else if(t)o(e,t);else if(e instanceof HTMLFormElement){const t=new FormData(e),o={};t.forEach(((e,t)=>{o[t]=e})),n(e,o)}}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)},o=(e,t)=>{for(const o in t)if(t.hasOwnProperty(o))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 o=parseJson(e);n(t,o)}else s(t,e);t.removeAttribute("pp-original-state")}}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},a=(e,t)=>{e instanceof HTMLFormElement?o(e,t):n(e,t)};try{const s=parseJson(t);if(s)if(e instanceof HTMLFormElement){const t=new FormData(e),n={};if(t.forEach(((e,t)=>{n[t]=e})),o(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(s.targets){s.targets.forEach((e=>{const{id:t,...n}=e,o=document.querySelector(t);o&&a(o,n)}));const{targets:t,...o}=s;n(e,o)}else{const{empty:t,...o}=s;n(e,o)}}catch(e){}}e.querySelectorAll("[pp-suspense]").forEach((e=>restoreSuspenseElement(e))),e.removeAttribute("pp-original-state")}function parseJson(e){try{return JSON5.parse(e)}catch(e){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 o=new FormData,s=n.files;if(s)for(let e=0;e<s.length;e++)o.append("file[]",s[e]);o.append("callback",t);const a=await fetch(e,{method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:o});return await a.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 o=createFetchOptions({callback:t,...n}),s=createFetchOptions({secondRequestC69CD:!0,...getUrlParams()});try{saveElementOriginalState(e),handleSuspenseElement(e);const n=new URL(window.location.href);let a="",r="",i={success:!1};const c=e.querySelector("input[type='file']");if(c){if(a=await pphpFetchFile(n.href,t,c),r=extractJson(a)||"",r)try{i=parseJson(r)}catch(e){}}else if(a=await pphpFetch(n.href,o),r=extractJson(a)||"",r)try{i=parseJson(r)}catch(e){}const l=e.getAttribute("pp-before-request")||"",u=e.getAttribute("pp-after-request")||"";if((l||u&&i.success)&&restoreSuspenseElement(e),l||u){let e="";if(i.success){e=a.replace(r,"")}else e=a;if(appendAfterbegin(e),!u&&!i.success)return}if(u&&i.success){handleAfterRequest(u,r);return appendAfterbegin(a.replace(r,"")),r}if("@close"===u)return i.success?r:void 0;const d=await pphpFetch(n.href,s);await handleResponseRedirectOrUpdate(a,d,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 o=document.createElement("div");if(o.id="afterbegin-8D95D",n&&t?.success){const t=e.replace(n,"");o.innerHTML=t}else o.innerHTML=e;return o.innerHTML?o:null}async function handleResponseRedirectOrUpdate(e,t,n,o){const s=getRedirectUrl(e);if(s)await handleRedirect(s);else{const s=getUpdatedHTMLContent(e,n,o),a=(new DOMParser).parseFromString(t,"text/html");s&&a.body.insertAdjacentElement("afterbegin",s),updateBodyContent(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),o=t?parseJson(t):null,s=n.targets;Array.isArray(s)&&s.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);let a={};if(o){for(const t in n)if(n.hasOwnProperty(t))switch(t){case"innerHTML":case"outerHTML":case"textContent":case"innerText":"response"===n[t]&&(a[t]=e.responseKey?o[e.responseKey]:o.response);break;default:a[t]=n[t];break}}else a=n;s&&updateElementAttributes(s,a)}))}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 o;return function(...s){const a=this;o&&clearTimeout(o),o=setTimeout((()=>{o=null,n||e.apply(a,s)}),t),n&&!o&&e.apply(a,s)}}function copyCode(e,t,n,o,s="img",a=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(s);if(t)for(const[e,n]of Object.entries(o))t.setAttribute(e,n);setTimeout((()=>{if(t)for(const[e,o]of Object.entries(n))t.setAttribute(e,o)}),a)}),(()=>{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,o,s){t.has(this)||t.set(this,new Map);const a=t.get(this).get(n)||new Set;a.add(o),t.get(this).set(n,a),e.call(this,n,o,s)},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,o,s){const a=t.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),a},e.replaceState=function(t,o,s){const a=n.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),a}})(window.history),document.addEventListener("DOMContentLoaded",observeDOMChanges),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=parseJson(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
|
+
let 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;var store=null;let isNavigatingA12E1=!1,redirectRegex3AE99=/redirect_7F834\s*=\s*(\/[^\s]*)/;function observeDOMChanges(){new MutationObserver((e=>{for(const t of e)"childList"===t.type&&t.addedNodes.length>0&&attachWireFunctionEvents()})).observe(document.body,{childList:!0,subtree:!0})}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),o=t.slice(2);n&&(e.removeAttribute(t),handleDebounce(e,o,n))})),e instanceof HTMLFormElement){const t=e.getAttribute("onsubmit");t&&(e.removeAttribute("onsubmit"),handleDebounce(e,"submit",t))}}))}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 o=e.getAttribute(t);if(o)if(isJsonLike(o)){n(e,parseJson(o))}else{const n=parseTime(o);if(n>0){const o="pp-visibility"===t?"visibility":"display";scheduleChange(e,n,o,"visibility"===o?"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,o,s){const a=t.start?parseTime(t.start):0,r=t.end?parseTime(t.end):0;a>0?(e.style[n]=o,scheduleChange(e,a,n,s),r>0&&scheduleChange(e,a+r,n,o)):r>0&&scheduleChange(e,r,n,o)}function scheduleChange(e,t,n,o){setTimeout((()=>{requestAnimationFrame((()=>{e.style[n]=o}))}),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){e.removeAllEventListeners(t);const o=e.getAttribute("pp-debounce")||"",s=e.getAttribute("pp-before-request")||"",a=e.getAttribute("pp-after-request")||"",r=async t=>{t.preventDefault();try{s&&await invokeHandler(e,s,t),await invokeHandler(e,n,t),a&&"@close"!==a&&await invokeHandler(e,a,t),handlerAutofocusAttribute()}catch(e){}};if(o){const n=debounce(r,parseTime(o));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 o=parseJson(n);if(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement){const t=["text","search","tel","url","password"];if(e instanceof HTMLInputElement)if(t.includes(e.type))if("number"===e.type){e.type="text";const t=e.value.length||0;e.setSelectionRange(t,t),e.type="number"}else setCursorPosition(e,o);else;else e instanceof HTMLTextAreaElement&&setCursorPosition(e,o)}e.focus(),t=!0}))}function setCursorPosition(e,t){if(t.start)e.setSelectionRange(0,0);else if(t.end){const t=e.value.length||0;e.setSelectionRange(t,t)}else if(t.length){const n=parseInt(t.length,10)||0;e.setSelectionRange(n,n)}}async function invokeHandler(e,t,n){try{const o=t.match(/^(\w+(\.\w+)*)\((.*)\)$/);if(o){const s=o[1].split("."),{context:a,methodName:r}=resolveContext(s);"function"==typeof a[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:o}=parseCallback(e,t);if(!n)return;const s=window[n];if("function"==typeof s){const t=e.hasAttribute("pp-after-request"),n=Array.isArray(o.args)?o.args:[],a=responseDataDEAC2?parseJson(responseDataDEAC2):{response:responseDataDEAC2};let r={args:n,element:e,data:o};t&&(r={...r,...a}),await s(r)}else responseDataDEAC2=null,responseDataDEAC2=await handleUndefinedFunction(e,n,o)}function handleAnchorTag(e){e instanceof HTMLAnchorElement&&e.addEventListener("click",(async e=>{const t=e.currentTarget,n=t.getAttribute("href"),o=t.getAttribute("target");if(n&&"_blank"!==o&&!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 o="";const[s,a]=n.split("#");a&&(o=`#${a}`);new URLSearchParams(s.split("?")[1]).forEach(((e,n)=>{t.set(n,e)}));const r=`${e.pathname}?${t.toString()}${o}`;history.pushState(null,"",r)}else{const[e,t]=n.split("#"),o=`${e}${t?`#${t}`:""}`;history.pushState(null,"",o)}const o=n.indexOf("#");if(-1!==o){const e=n.slice(o+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,o=250;if(t)try{const e=parseJson(t);n=parseTime(e.fadeIn||n),o=parseTime(e.fadeOut||o)}catch(e){}return{fadeIn:n,fadeOut:o}},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)},o=async o=>{const s=document.querySelector("[pp-loading-content='true']")||document.body;if(s){const{fadeIn:a,fadeOut:r}=e(o);await t(s,r),s.innerHTML=o.innerHTML,n(s,a)}},s=window.location.pathname,a=document.getElementById("loading-file-1B87E");if(a){let e=a.querySelector(`div[pp-loading-url='${s}']`);e||(e=a.querySelector("div[pp-loading-url='/']")),e&&await o(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();saveState();const n=(new DOMParser).parseFromString(e,"text/html");await appendCallbackResponse(n),restoreState(),restoreScrollPositions(t),attachWireFunctionEvents(),document.dispatchEvent(new Event("DOMContentLoaded"))}async function appendCallbackResponse(e){const t=e.getElementById("afterbegin-8D95D");if(t){const e=document.getElementById("afterbegin-8D95D");e?e.innerHTML=t.innerHTML:document.body.insertAdjacentHTML("afterbegin",t.outerHTML)}await populateDocumentBody(e)}async function updateDocumentContent(e){const t=saveScrollPositions();document.removeAllEventListeners("DOMContentLoaded");const n=(new DOMParser).parseFromString(e,"text/html"),o="pp-dynamic-script",s="pp-dynamic-link";document.head.querySelectorAll("[pp-dynamic-meta]").forEach((e=>e.remove()));document.head.querySelectorAll("[pp-dynamic-link]").forEach((e=>e.remove()));document.head.querySelectorAll("[pp-dynamic-script]").forEach((e=>e.remove()));await(async e=>{Array.from(e.head.children).forEach((e=>{const t=e.tagName;if("SCRIPT"===t&&e.hasAttribute(o)){const t=document.createElement("script");Array.from(e.attributes).forEach((e=>t.setAttribute(e.name,e.value))),e.textContent&&(t.textContent=e.textContent),document.head.appendChild(t)}else if("META"===t){if(e.getAttribute("charset")||"viewport"===e.getAttribute("name"))return;const t=e.name,n=e.getAttribute("property"),o=document.head.querySelector(t?`meta[name="${t}"]`:`meta[property="${n}"]`);o?document.head.replaceChild(e.cloneNode(!0),o):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)}else if(e.hasAttribute(s)){const t=e.cloneNode(!0);document.head.appendChild(t)}}})),await populateDocumentBody(e)})(n),restoreScrollPositions(t),attachWireFunctionEvents(),document.dispatchEvent(new Event("DOMContentLoaded"))}async function populateDocumentBody(e){const t=e.body.cloneNode(!0);t.querySelectorAll("script").forEach((e=>{const t=document.createElement("script");Array.from(e.attributes).forEach((e=>{t.setAttribute(e.name,e.value)})),e.src?(t.src=e.src,t.async=!1):t.textContent=`(function() {\n ${e.textContent}\n })();`,e.parentNode?.replaceChild(t,e)})),document.body.replaceWith(t)}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||"email"===e.type?(e.type="text",e.setSelectionRange(t,t),e.type="number"===e.type?"number":"email"):"date"===e.type||"month"===e.type||"week"===e.type||"time"===e.type||"datetime-local"===e.type||"color"===e.type||"file"===e.type||""!==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={window:{scrollTop:window.scrollY||document.documentElement.scrollTop,scrollLeft:window.scrollX||document.documentElement.scrollLeft}};return document.querySelectorAll("*").forEach((t=>{(t.scrollTop||t.scrollLeft)&&(e[getElementKey(t)]={scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})})),e}function restoreScrollPositions(e){requestAnimationFrame((()=>{const t=e.window;t&&window.scrollTo(t.scrollLeft,t.scrollTop),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 o=e.closest("form");if(o){new FormData(o).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 s=t.match(/(\w+)\((.*)\)/);if(s){const e=s[1];let t=s[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[o,s]=decodeHTML(t[n]).split(",");e.classList.replace(o,s);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 o=e.attributes[n];t[o.name]=o.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,o=document.querySelector(t);o&&s(o,n)}))}else o(t,e)}},o=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},s=(e,t)=>{e instanceof HTMLFormElement?n(e,t):updateElementAttributes(e,t)};try{if(t&&isJsonLike(t)){const o=parseJson(t);if(o)if(e instanceof HTMLFormElement){const t=new FormData(e),s={};t.forEach(((e,t)=>{s[t]=e})),o.disabled&&toggleFormElements(e,!0);const{disabled:a,...r}=o;updateElementAttributes(e,r),n(e,s)}else if(o.targets){o.targets.forEach((e=>{const{id:t,...n}=e,o=document.querySelector(t);o&&s(o,n)}));const{targets:t,...n}=o;updateElementAttributes(e,n)}else{if("disabled"===o.empty&&""===e.value)return;const{empty:t,...n}=o;updateElementAttributes(e,n)}}else if(t)o(e,t);else if(e instanceof HTMLFormElement){const t=new FormData(e),o={};t.forEach(((e,t)=>{o[t]=e})),n(e,o)}}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)},o=(e,t)=>{for(const o in t)if(t.hasOwnProperty(o))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 o=parseJson(e);n(t,o)}else s(t,e);t.removeAttribute("pp-original-state")}}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},a=(e,t)=>{e instanceof HTMLFormElement?o(e,t):n(e,t)};try{const s=parseJson(t);if(s)if(e instanceof HTMLFormElement){const t=new FormData(e),n={};if(t.forEach(((e,t)=>{n[t]=e})),o(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(s.targets){s.targets.forEach((e=>{const{id:t,...n}=e,o=document.querySelector(t);o&&a(o,n)}));const{targets:t,...o}=s;n(e,o)}else{const{empty:t,...o}=s;n(e,o)}}catch(e){}}e.querySelectorAll("[pp-suspense]").forEach((e=>restoreSuspenseElement(e))),e.removeAttribute("pp-original-state")}function parseJson(e){try{return JSON5.parse(e)}catch(e){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 o=new FormData,s=n.files;if(s)for(let e=0;e<s.length;e++)o.append("file[]",s[e]);o.append("callback",t);const a=await fetch(e,{method:"POST",headers:{HTTP_PPHP_WIRE_REQUEST:"true"},body:o});return await a.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 o=createFetchOptions({callback:t,...n}),s=createFetchOptions({secondRequestC69CD:!0,...getUrlParams()});try{saveElementOriginalState(e),handleSuspenseElement(e);const n=new URL(window.location.href);let a="",r="",i={success:!1};const c=e.querySelector("input[type='file']");if(c){if(a=await pphpFetchFile(n.href,t,c),r=extractJson(a)||"",r)try{i=parseJson(r)}catch(e){}}else if(a=await pphpFetch(n.href,o),r=extractJson(a)||"",r)try{i=parseJson(r)}catch(e){}const l=e.getAttribute("pp-before-request")||"",u=e.getAttribute("pp-after-request")||"";if((l||u&&i.success)&&restoreSuspenseElement(e),l||u){let e="";if(i.success){e=a.replace(r,"")}else e=a;if(appendAfterbegin(e),!u&&!i.success)return}if(u&&i.success){handleAfterRequest(u,r);return appendAfterbegin(a.replace(r,"")),r}if("@close"===u)return i.success?r:void 0;const d=await pphpFetch(n.href,s);await handleResponseRedirectOrUpdate(a,d,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 o=document.createElement("div");if(o.id="afterbegin-8D95D",n&&t?.success){const t=e.replace(n,"");o.innerHTML=t}else o.innerHTML=e;return o.innerHTML?o:null}async function handleResponseRedirectOrUpdate(e,t,n,o){const s=getRedirectUrl(e);if(s)await handleRedirect(s);else{const s=getUpdatedHTMLContent(e,n,o),a=(new DOMParser).parseFromString(t,"text/html");s&&a.body.insertAdjacentElement("afterbegin",s),updateBodyContent(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),o=t?parseJson(t):null,s=n.targets;Array.isArray(s)&&s.forEach((e=>{const{id:t,...n}=e,s=document.querySelector(t);let a={};if(o){for(const t in n)if(n.hasOwnProperty(t))switch(t){case"innerHTML":case"outerHTML":case"textContent":case"innerText":"response"===n[t]&&(a[t]=e.responseKey?o[e.responseKey]:o.response);break;default:a[t]=n[t];break}}else a=n;s&&updateElementAttributes(s,a)}))}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 o;return function(...s){const a=this;o&&clearTimeout(o),o=setTimeout((()=>{o=null,n||e.apply(a,s)}),t),n&&!o&&e.apply(a,s)}}function copyCode(e,t,n,o,s="img",a=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(s);if(t)for(const[e,n]of Object.entries(o))e in t?t[e]=n:t.setAttribute(e,n);setTimeout((()=>{if(t)for(const[e,o]of Object.entries(n))e in t?t[e]=o:t.setAttribute(e,o)}),a)}),(()=>{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,o,s){t.has(this)||t.set(this,new Map);const a=t.get(this).get(n)||new Set;a.add(o),t.get(this).set(n,a),e.call(this,n,o,s)},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,o,s){const a=t.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),a},e.replaceState=function(t,o,s){const a=n.apply(e,arguments);return window.dispatchEvent(new Event("urlchange")),a}})(window.history),document.addEventListener("DOMContentLoaded",observeDOMChanges),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=parseJson(e),this.listeners.forEach((e=>e(this.state))))}resetState(e){e?(delete this.state[e],this.saveState()):(this.state={},localStorage.removeItem("appState_59E13")),this.listeners.forEach((e=>e(this.state)))}}store=e.getInstance()}
|
package/package.json
CHANGED
|
Binary file
|