create-prisma-php-app 1.16.24 → 1.16.25

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.
@@ -1,1394 +1 @@
1
- var eventAttributesB6B56 = [
2
- "onclick",
3
- "ondblclick",
4
- "onmousedown",
5
- "onmouseup",
6
- "onmouseover",
7
- "onmousemove",
8
- "onmouseout",
9
- "onwheel",
10
- "onkeypress",
11
- "onkeydown",
12
- "onkeyup",
13
- "onfocus",
14
- "onblur",
15
- "onchange",
16
- "oninput",
17
- "onselect",
18
- "onsubmit",
19
- "onreset",
20
- "onresize",
21
- "onscroll",
22
- "onload",
23
- "onunload",
24
- "onabort",
25
- "onerror",
26
- "onbeforeunload",
27
- "oncopy",
28
- "oncut",
29
- "onpaste",
30
- "ondrag",
31
- "ondragstart",
32
- "ondragend",
33
- "ondragover",
34
- "ondragenter",
35
- "ondragleave",
36
- "ondrop",
37
- "oncontextmenu",
38
- "ontouchstart",
39
- "ontouchmove",
40
- "ontouchend",
41
- "ontouchcancel",
42
- "onpointerdown",
43
- "onpointerup",
44
- "onpointermove",
45
- "onpointerover",
46
- "onpointerout",
47
- "onpointerenter",
48
- "onpointerleave",
49
- "onpointercancel",
50
- ];
51
- var stateA129A = {
52
- checkedElements: new Set(),
53
- };
54
- var responseDataDEAC2 = null;
55
- var store = null;
56
- var isNavigatingA12E1 = false;
57
- (() => {
58
- // Save a reference to the original addEventListener function
59
- const originalAddEventListener = EventTarget.prototype.addEventListener;
60
- // Create a Map to store the event listeners
61
- const listeners = new Map();
62
- // Override the addEventListener method
63
- EventTarget.prototype.addEventListener = function (type, listener, options) {
64
- // Ensure that the listeners map has a Map for this EventTarget instance
65
- if (!listeners.has(this)) {
66
- listeners.set(this, new Map());
67
- }
68
- const typeListeners = listeners.get(this).get(type) || new Set();
69
- typeListeners.add(listener);
70
- // Store the listener
71
- listeners.get(this).set(type, typeListeners);
72
- // Call the original addEventListener function
73
- originalAddEventListener.call(this, type, listener, options);
74
- };
75
- // Add a method to remove all event listeners of a specific type
76
- EventTarget.prototype.removeAllEventListeners = function (type) {
77
- if (listeners.has(this) && listeners.get(this).has(type)) {
78
- // Remove each listener of the specified type
79
- listeners
80
- .get(this)
81
- .get(type)
82
- .forEach((listener) => {
83
- this.removeEventListener(type, listener);
84
- });
85
- // Remove the type map after all listeners are removed
86
- listeners.get(this).delete(type);
87
- }
88
- };
89
- })();
90
- document.addEventListener("DOMContentLoaded", attachWireFunctionEvents);
91
- function attachWireFunctionEvents() {
92
- handleHiddenAttribute();
93
- const interactiveElements = document.querySelectorAll(
94
- "button, input, select, textarea, a, form, label, div, span"
95
- );
96
- interactiveElements.forEach((element) => {
97
- handleAnchorTag(element);
98
- eventAttributesB6B56.forEach((attr) => {
99
- const originalHandler = element.getAttribute(attr);
100
- const eventType = attr.slice(2); // Get the event type (e.g., "click" from "onclick")
101
- if (originalHandler) {
102
- element.removeAttribute(attr);
103
- handleDebounce(element, eventType, originalHandler);
104
- }
105
- });
106
- // Special handling for form submit
107
- if (element instanceof HTMLFormElement) {
108
- const submitHandler = element.getAttribute("onsubmit");
109
- if (submitHandler) {
110
- element.removeAttribute("onsubmit");
111
- handleDebounce(element, "submit", submitHandler);
112
- }
113
- }
114
- });
115
- initializePpOnListeners();
116
- }
117
- // Function to check if an element has any pp-on attribute
118
- function hasPpOnAttribute(element) {
119
- const attributes = element.attributes;
120
- if (!attributes) return false;
121
- for (let i = 0; i < attributes.length; i++) {
122
- const name = attributes[i].name;
123
- if (
124
- name.startsWith("pp-on:") ||
125
- name.startsWith("data-pp-on:") ||
126
- name.startsWith("pp-on-") ||
127
- name.startsWith("data-pp-on-")
128
- ) {
129
- return true;
130
- }
131
- }
132
- return false;
133
- }
134
- // Function to find all elements with any pp-on attribute within a given context
135
- function findAllPpOnElements(context) {
136
- const result = [];
137
- if (hasPpOnAttribute(context)) {
138
- result.push(context);
139
- }
140
- if (document.evaluate) {
141
- const xpathResult = document.evaluate(
142
- './/*[@*[starts-with(name(), "pp-on:") or starts-with(name(), "data-pp-on:") or' +
143
- ' starts-with(name(), "pp-on-") or starts-with(name(), "data-pp-on-")]]',
144
- context,
145
- null,
146
- XPathResult.ORDERED_NODE_ITERATOR_TYPE,
147
- null
148
- );
149
- let node = xpathResult.iterateNext();
150
- while (node) {
151
- result.push(node);
152
- node = xpathResult.iterateNext();
153
- }
154
- } else if (typeof context.getElementsByTagName === "function") {
155
- const elements = context.getElementsByTagName("*");
156
- for (let i = 0; i < elements.length; i++) {
157
- if (hasPpOnAttribute(elements[i])) {
158
- result.push(elements[i]);
159
- }
160
- }
161
- }
162
- return result;
163
- }
164
- // Function to initialize pp-on event listeners
165
- function initializePpOnListeners() {
166
- const elements = findAllPpOnElements(document);
167
- elements.forEach((element) => {
168
- Array.from(element.attributes).forEach((attr) => {
169
- if (attr.name.startsWith("pp-on:")) {
170
- const eventName = attr.name.split(":")[1];
171
- const handler = attr.value;
172
- if (handler) {
173
- element.addEventListener(eventName, (event) => {
174
- try {
175
- new Function("event", handler).call(element, event);
176
- } catch (error) {
177
- console.error("Error executing handler:", error);
178
- }
179
- });
180
- // Optionally, remove the attribute after adding the event listener
181
- // element.removeAttribute(attr.name);
182
- }
183
- }
184
- });
185
- });
186
- }
187
- function handleHiddenAttribute() {
188
- const visibilityElements = document.querySelectorAll("[pp-visibility]");
189
- const displayNoneElements = document.querySelectorAll("[pp-display]");
190
- visibilityElements.forEach((element) =>
191
- handleVisibilityElementAttribute(
192
- element,
193
- "pp-visibility",
194
- handleElementVisibility
195
- )
196
- );
197
- displayNoneElements.forEach((element) =>
198
- handleVisibilityElementAttribute(
199
- element,
200
- "pp-display",
201
- handleElementDisplay
202
- )
203
- );
204
- }
205
- function handleVisibilityElementAttribute(element, attributeName, handler) {
206
- const attributeValue = element.getAttribute(attributeName);
207
- if (!attributeValue) return;
208
- if (isJsonLike(attributeValue)) {
209
- const config = parseJson(attributeValue);
210
- handler(element, config);
211
- } else {
212
- const timeout = parseTime(attributeValue);
213
- if (timeout > 0) {
214
- // Map attribute names to style properties
215
- const styleProperty =
216
- attributeName === "pp-visibility" ? "visibility" : "display";
217
- const hiddenValue = styleProperty === "visibility" ? "hidden" : "none";
218
- scheduleChange(element, timeout, styleProperty, hiddenValue);
219
- }
220
- }
221
- }
222
- // Function to determine if a string is JSON-like
223
- function isJsonLike(str) {
224
- // A simple check to see if the string starts with '{' and ends with '}'
225
- return str.trim().startsWith("{") && str.trim().endsWith("}");
226
- }
227
- // Function to handle visibility changes based on config
228
- function handleElementVisibility(element, config) {
229
- handleElementChange(element, config, "visibility", "hidden", "visible");
230
- }
231
- // Function to handle display changes based on config
232
- function handleElementDisplay(element, config) {
233
- handleElementChange(element, config, "display", "none", "block");
234
- }
235
- function handleElementChange(
236
- element,
237
- config,
238
- styleProperty,
239
- hiddenValue,
240
- visibleValue
241
- ) {
242
- const startTimeout = config.start ? parseTime(config.start) : 0;
243
- const endTimeout = config.end ? parseTime(config.end) : 0;
244
- if (startTimeout > 0) {
245
- element.style[styleProperty] = hiddenValue;
246
- scheduleChange(element, startTimeout, styleProperty, visibleValue);
247
- if (endTimeout > 0) {
248
- scheduleChange(
249
- element,
250
- startTimeout + endTimeout,
251
- styleProperty,
252
- hiddenValue
253
- );
254
- }
255
- } else if (endTimeout > 0) {
256
- scheduleChange(element, endTimeout, styleProperty, hiddenValue);
257
- }
258
- }
259
- // Function to schedule visibility or display changes using requestAnimationFrame
260
- function scheduleChange(element, timeout, styleProperty, value) {
261
- setTimeout(() => {
262
- requestAnimationFrame(() => {
263
- element.style[styleProperty] = value;
264
- });
265
- }, timeout);
266
- }
267
- // Function to parse time strings into milliseconds
268
- function parseTime(time) {
269
- if (typeof time === "number") {
270
- return time;
271
- }
272
- const match = time.match(/^(\d+)(ms|s|m)?$/);
273
- if (match) {
274
- const value = parseInt(match[1], 10);
275
- const unit = match[2] || "ms"; // Default to milliseconds if no unit specified
276
- switch (unit) {
277
- case "ms":
278
- return value;
279
- case "s":
280
- return value * 1000;
281
- case "m":
282
- return value * 60 * 1000;
283
- default:
284
- return value; // Default to milliseconds
285
- }
286
- }
287
- return 0; // Default to 0 if parsing fails
288
- }
289
- async function handleDebounce(element, eventType, originalHandler) {
290
- const debounceTime = element.getAttribute("pp-debounce") || "";
291
- const executeBeforeRequest = element.getAttribute("pp-beforeRequest") || "";
292
- const executeAfterRequest = element.getAttribute("pp-afterRequest") || "";
293
- const combinedHandler = async (event) => {
294
- event.preventDefault();
295
- try {
296
- if (executeBeforeRequest)
297
- await invokeHandler(element, executeBeforeRequest, event);
298
- await invokeHandler(element, originalHandler, event);
299
- if (executeAfterRequest && executeAfterRequest !== "@close")
300
- await invokeHandler(element, executeAfterRequest, event);
301
- handlerAutofocusAttribute();
302
- } catch (error) {
303
- console.error("Error in debounced handler:", error);
304
- }
305
- };
306
- if (debounceTime) {
307
- const wait = parseTime(debounceTime);
308
- const debouncedHandler = debounce(combinedHandler, wait);
309
- if (element instanceof HTMLFormElement && eventType === "submit") {
310
- element.addEventListener(eventType, (event) => {
311
- event.preventDefault();
312
- debouncedHandler(event);
313
- });
314
- } else {
315
- element.addEventListener(eventType, debouncedHandler);
316
- }
317
- } else {
318
- element.addEventListener(eventType, combinedHandler);
319
- }
320
- }
321
- function handlerAutofocusAttribute() {
322
- const ppAutofocusElements = document.querySelectorAll("[pp-autofocus]");
323
- let hasFocusedElement = false;
324
- ppAutofocusElements.forEach((el) => {
325
- if (hasFocusedElement) return;
326
- const ppAutofocusAttribute = el.getAttribute("pp-autofocus");
327
- if (!ppAutofocusAttribute || !isJsonLike(ppAutofocusAttribute)) return;
328
- const ppAutofocusConfig = parseJson(ppAutofocusAttribute);
329
- if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
330
- if (el.type === "number" && el instanceof HTMLInputElement) {
331
- el.type = "text";
332
- const length = el.value.length || 0;
333
- el.setSelectionRange(length, length);
334
- el.type = "number";
335
- } else {
336
- if (ppAutofocusConfig.start) {
337
- el.setSelectionRange(0, 0);
338
- } else if (ppAutofocusConfig.end) {
339
- const currentAutofocusLength = el.value.length || 0;
340
- el.setSelectionRange(currentAutofocusLength, currentAutofocusLength);
341
- } else if (ppAutofocusConfig.length) {
342
- const length = parseInt(ppAutofocusConfig.length, 10) || 0;
343
- el.setSelectionRange(length, length);
344
- }
345
- }
346
- }
347
- el.focus();
348
- hasFocusedElement = true;
349
- });
350
- }
351
- async function invokeHandler(element, handler, event) {
352
- try {
353
- // Extract method details from the handler string
354
- const methodMatch = handler.match(/^(\w+(\.\w+)*)\((.*)\)$/);
355
- if (methodMatch) {
356
- const fullMethodName = methodMatch[1];
357
- const methodParts = fullMethodName.split(".");
358
- const { context, methodName } = resolveContext(methodParts);
359
- if (typeof context[methodName] === "function") {
360
- new Function("event", handler).call(element, event);
361
- } else {
362
- await handleParsedCallback(element, handler);
363
- }
364
- } else {
365
- await handleParsedCallback(element, handler);
366
- }
367
- } catch (error) {
368
- console.error(`Error executing handler ${handler}:`, error);
369
- }
370
- }
371
- /**
372
- * Resolve the context and method name for nested methods.
373
- * @param methodParts - Array of method parts split by dots.
374
- * @returns Object containing the resolved context and method name.
375
- */
376
- function resolveContext(methodParts) {
377
- let context = window;
378
- for (let i = 0; i < methodParts.length - 1; i++) {
379
- context = context[methodParts[i]];
380
- if (!context) {
381
- throw new Error(`Cannot find object ${methodParts[i]} in the context.`);
382
- }
383
- }
384
- return { context, methodName: methodParts[methodParts.length - 1] };
385
- }
386
- /**
387
- * Handle parsing and executing the callback from the element's handler.
388
- * @param element - HTML element that initiated the handler.
389
- * @param handler - Handler string to be parsed and executed.
390
- */
391
- async function handleParsedCallback(element, handler) {
392
- const { funcName, data } = parseCallback(element, handler);
393
- if (!funcName) return;
394
- const func = window[funcName];
395
- if (typeof func === "function") {
396
- const isAfterRequest = element.hasAttribute("pp-afterRequest");
397
- const args = Array.isArray(data.args) ? data.args : [];
398
- const response = responseDataDEAC2
399
- ? parseJson(responseDataDEAC2)
400
- : { response: responseDataDEAC2 };
401
- let params = {
402
- args,
403
- element,
404
- data,
405
- };
406
- if (isAfterRequest) {
407
- params = {
408
- ...params,
409
- ...response,
410
- };
411
- }
412
- await func(params);
413
- } else {
414
- responseDataDEAC2 = null;
415
- responseDataDEAC2 = await handleUndefinedFunction(element, funcName, data);
416
- }
417
- }
418
- function handleAnchorTag(element) {
419
- if (!(element instanceof HTMLAnchorElement)) return;
420
- element.addEventListener("click", async (event) => {
421
- const anchor = event.currentTarget;
422
- const href = anchor.getAttribute("href");
423
- const target = anchor.getAttribute("target");
424
- // If there's no href, or the target is _blank, or the meta key is pressed, allow default behavior
425
- if (!href || target === "_blank" || event.metaKey || event.ctrlKey) {
426
- return;
427
- }
428
- event.preventDefault(); // Prevent the default navigation
429
- if (isNavigatingA12E1) return; // Prevent multiple navigations
430
- isNavigatingA12E1 = true;
431
- try {
432
- const isExternal =
433
- /^(https?:)?\/\//i.test(href) &&
434
- !href.startsWith(window.location.origin);
435
- if (isExternal) {
436
- // If the link is external, use the default behavior
437
- window.location.href = href;
438
- } else {
439
- // If the link is internal, use history.pushState
440
- history.pushState(null, "", href);
441
- await handleNavigation();
442
- }
443
- } catch (error) {
444
- console.error("Anchor click error:", error);
445
- } finally {
446
- isNavigatingA12E1 = false;
447
- }
448
- });
449
- }
450
- // Handle browser's back/forward navigation
451
- window.addEventListener("popstate", async () => {
452
- await handleNavigation();
453
- });
454
- async function handleNavigation() {
455
- try {
456
- const data = await pphpFetch(window.location.href);
457
- if (data.includes("redirect_7F834=")) {
458
- const url = data.split("=")[1];
459
- await handleRedirect(url);
460
- } else {
461
- updateDocumentContent(data);
462
- }
463
- } catch (error) {
464
- console.error("Navigation error:", error);
465
- }
466
- }
467
- function updateDocumentContent(data) {
468
- const scrollPositions = saveScrollPositions();
469
- document.removeAllEventListeners("DOMContentLoaded");
470
- if (data.includes("<!DOCTYPE html>")) {
471
- const newDoc = new DOMParser().parseFromString(data, "text/html");
472
- const replaceDocumentContent = (newDoc) => {
473
- Array.from(newDoc.head.children).forEach((newHeadChild) => {
474
- const tagName = newHeadChild.tagName;
475
- if (tagName === "META") {
476
- // Exclude specific meta tags like <meta charset="UTF-8">
477
- if (
478
- newHeadChild.getAttribute("charset") ||
479
- newHeadChild.getAttribute("name") === "viewport"
480
- ) {
481
- return;
482
- }
483
- // Check if the meta tag already exists
484
- const nameAttr = newHeadChild.name;
485
- const propertyAttr = newHeadChild.getAttribute("property");
486
- const existingMeta = document.head.querySelector(
487
- nameAttr
488
- ? `meta[name="${nameAttr}"]`
489
- : `meta[property="${propertyAttr}"]`
490
- );
491
- // If the meta tag doesn't exist, add it
492
- if (existingMeta) {
493
- document.head.replaceChild(
494
- newHeadChild.cloneNode(true),
495
- existingMeta
496
- );
497
- } else {
498
- document.head.appendChild(newHeadChild.cloneNode(true));
499
- }
500
- } else if (tagName === "TITLE") {
501
- // Check if the title tag already exists
502
- const existingTitle = document.head.querySelector("title");
503
- if (existingTitle) {
504
- document.head.replaceChild(
505
- newHeadChild.cloneNode(true),
506
- existingTitle
507
- );
508
- } else {
509
- document.head.appendChild(newHeadChild.cloneNode(true));
510
- }
511
- }
512
- });
513
- // Clear old content
514
- document.body.innerHTML = "";
515
- loadAndValidateContent(newDoc);
516
- };
517
- // Replace the document content keeping positions of scripts and styles
518
- replaceDocumentContent(newDoc);
519
- } else {
520
- saveState();
521
- const newDoc = new DOMParser().parseFromString(data, "text/html");
522
- document.body.innerHTML = "";
523
- loadAndValidateContent(newDoc);
524
- restoreState();
525
- }
526
- restoreScrollPositions(scrollPositions);
527
- attachWireFunctionEvents();
528
- document.dispatchEvent(new Event("DOMContentLoaded"));
529
- }
530
- function loadAndValidateContent(newDoc) {
531
- const elementStore = new Map();
532
- function processElement(element) {
533
- switch (element.tagName) {
534
- case "SCRIPT":
535
- const newScript = document.createElement("script");
536
- const scriptElement = element;
537
- if (scriptElement.src) {
538
- newScript.src = scriptElement.src;
539
- } else {
540
- newScript.textContent = scriptElement.textContent;
541
- }
542
- appendToParent(element, newScript);
543
- break;
544
- default:
545
- const clonedElement = element.cloneNode(false);
546
- elementStore.set(element, clonedElement);
547
- Array.from(element.childNodes).forEach((childNode) => {
548
- if (childNode.nodeType === Node.TEXT_NODE) {
549
- clonedElement.appendChild(
550
- document.createTextNode(childNode.textContent || "")
551
- );
552
- } else if (childNode.nodeType === Node.ELEMENT_NODE) {
553
- processElement(childNode);
554
- }
555
- });
556
- appendToParent(element, clonedElement);
557
- break;
558
- }
559
- }
560
- function appendToParent(element, newElement) {
561
- const parentClone = elementStore.get(element.parentNode);
562
- if (parentClone) {
563
- parentClone.appendChild(newElement);
564
- } else {
565
- document.body.appendChild(newElement);
566
- }
567
- }
568
- Array.from(newDoc.body.children).forEach((newBodyChild) => {
569
- processElement(newBodyChild);
570
- });
571
- }
572
- function saveState() {
573
- const focusElement = document.activeElement;
574
- stateA129A.focusId = focusElement?.id || focusElement?.name;
575
- stateA129A.focusValue = focusElement?.value;
576
- stateA129A.focusChecked = focusElement?.checked;
577
- stateA129A.focusType = focusElement?.type;
578
- stateA129A.focusSelectionStart = focusElement?.selectionStart;
579
- stateA129A.focusSelectionEnd = focusElement?.selectionEnd;
580
- stateA129A.isSuspense = focusElement.hasAttribute("pp-suspense");
581
- stateA129A.checkedElements.clear();
582
- document.querySelectorAll('input[type="checkbox"]:checked').forEach((el) => {
583
- stateA129A.checkedElements.add(el.id || el.name);
584
- });
585
- document.querySelectorAll('input[type="radio"]:checked').forEach((el) => {
586
- stateA129A.checkedElements.add(el.id || el.name);
587
- });
588
- }
589
- function restoreState() {
590
- if (stateA129A.focusId) {
591
- const newFocusElement =
592
- document.getElementById(stateA129A.focusId) ||
593
- document.querySelector(`[name="${stateA129A.focusId}"]`);
594
- if (newFocusElement instanceof HTMLInputElement) {
595
- const length = newFocusElement.value.length || 0;
596
- if (
597
- stateA129A.focusSelectionStart !== undefined &&
598
- stateA129A.focusSelectionEnd !== null
599
- ) {
600
- newFocusElement.setSelectionRange(length, length);
601
- }
602
- if (stateA129A.focusValue) {
603
- if (
604
- newFocusElement.type === "checkbox" ||
605
- newFocusElement.type === "radio"
606
- ) {
607
- newFocusElement.checked = !!stateA129A.focusChecked;
608
- } else if (newFocusElement.type === "number") {
609
- newFocusElement.type = "text";
610
- newFocusElement.setSelectionRange(length, length);
611
- newFocusElement.type = "number";
612
- } else {
613
- const isSuspense = newFocusElement.hasAttribute("pp-suspense");
614
- if (!isSuspense && !stateA129A.isSuspense) {
615
- newFocusElement.value = stateA129A.focusValue;
616
- }
617
- }
618
- }
619
- newFocusElement.focus();
620
- } else if (newFocusElement instanceof HTMLTextAreaElement) {
621
- const length = newFocusElement.value.length || 0;
622
- if (
623
- stateA129A.focusSelectionStart !== undefined &&
624
- stateA129A.focusSelectionEnd !== null
625
- ) {
626
- newFocusElement.setSelectionRange(length, length);
627
- }
628
- if (stateA129A.focusValue) {
629
- const isSuspense = newFocusElement.hasAttribute("pp-suspense");
630
- if (!isSuspense && !stateA129A.isSuspense) {
631
- newFocusElement.value = stateA129A.focusValue;
632
- }
633
- }
634
- newFocusElement.focus();
635
- } else if (newFocusElement instanceof HTMLSelectElement) {
636
- if (stateA129A.focusValue) {
637
- const isSuspense = newFocusElement.hasAttribute("pp-suspense");
638
- if (!isSuspense && !stateA129A.isSuspense) {
639
- newFocusElement.value = stateA129A.focusValue;
640
- }
641
- }
642
- newFocusElement.focus();
643
- }
644
- }
645
- stateA129A.checkedElements.forEach((id) => {
646
- const checkbox = document.getElementById(id);
647
- if (checkbox) {
648
- checkbox.checked = true;
649
- }
650
- });
651
- }
652
- function saveScrollPositions() {
653
- const scrollPositions = {};
654
- document.querySelectorAll("*").forEach((el) => {
655
- if (el.scrollTop || el.scrollLeft) {
656
- scrollPositions[getElementKey(el)] = {
657
- scrollTop: el.scrollTop,
658
- scrollLeft: el.scrollLeft,
659
- };
660
- }
661
- });
662
- return scrollPositions;
663
- }
664
- function restoreScrollPositions(scrollPositions) {
665
- document.querySelectorAll("*").forEach((el) => {
666
- const key = getElementKey(el);
667
- if (scrollPositions[key]) {
668
- el.scrollTop = scrollPositions[key].scrollTop;
669
- el.scrollLeft = scrollPositions[key].scrollLeft;
670
- }
671
- });
672
- }
673
- function getElementKey(el) {
674
- return el.id || el.className || el.tagName;
675
- }
676
- async function pphpFetch(url, options) {
677
- const data = await fetch(url, {
678
- ...options,
679
- headers: {
680
- ...options?.headers,
681
- "X-Requested-With": "XMLHttpRequest",
682
- },
683
- });
684
- return await data.text();
685
- }
686
- function parseCallback(element, callback) {
687
- let data = {};
688
- // Check if the element is inside a form
689
- const form = element.closest("form");
690
- if (form) {
691
- // Serialize the form data
692
- const formData = new FormData(form);
693
- formData.forEach((value, key) => {
694
- if (data[key]) {
695
- // Handle multiple values
696
- if (Array.isArray(data[key])) {
697
- data[key].push(value);
698
- } else {
699
- data[key] = [data[key], value];
700
- }
701
- } else {
702
- data[key] = value;
703
- }
704
- });
705
- } else {
706
- // Handle single input element
707
- if (element instanceof HTMLInputElement) {
708
- data = handleInputElement(element);
709
- } else if (element instanceof HTMLSelectElement) {
710
- data[element.name] = element.value;
711
- } else if (element instanceof HTMLTextAreaElement) {
712
- data[element.name] = element.value;
713
- }
714
- }
715
- // Parse function name and arguments from the callback string
716
- const match = callback.match(/(\w+)\((.*)\)/);
717
- if (match) {
718
- const funcName = match[1];
719
- let rawArgs = match[2].trim();
720
- if (rawArgs.startsWith("{") && rawArgs.endsWith("}")) {
721
- try {
722
- const parsedArg = parseJson(rawArgs);
723
- if (typeof parsedArg === "object" && parsedArg !== null) {
724
- data = { ...data, ...parsedArg };
725
- }
726
- } catch (e) {
727
- console.error("Error parsing JSON:", e);
728
- }
729
- } else {
730
- const args = rawArgs
731
- .split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/)
732
- .map((arg) => arg.trim().replace(/^['"]|['"]$/g, ""));
733
- data.args = args;
734
- }
735
- return { funcName, data };
736
- }
737
- return { funcName: callback, data };
738
- }
739
- function handleInputElement(element) {
740
- let data = {};
741
- // Only proceed if the element has a name
742
- if (element.name) {
743
- // Handle checkboxes
744
- if (element.type === "checkbox") {
745
- data[element.name] = {
746
- value: element.value,
747
- checked: element.checked,
748
- };
749
- } else if (element.type === "radio") {
750
- // Handle radio buttons
751
- const checkedRadio = document.querySelector(
752
- `input[name="${element.name}"]:checked`
753
- );
754
- data[element.name] = checkedRadio ? checkedRadio.value : null;
755
- } else {
756
- // Handle other input types
757
- data[element.name] = element.value;
758
- }
759
- } else {
760
- // Handle cases where the element does not have a name
761
- if (element.type === "checkbox" || element.type === "radio") {
762
- data.value = element.checked;
763
- } else {
764
- data.value = element.value;
765
- }
766
- }
767
- return data;
768
- }
769
- function updateElementAttributes(element, data) {
770
- for (const key in data) {
771
- if (!data.hasOwnProperty(key)) continue;
772
- switch (key) {
773
- case "innerHTML":
774
- case "outerHTML":
775
- case "textContent":
776
- case "innerText":
777
- element[key] = decodeHTML(data[key]);
778
- break;
779
- case "insertAdjacentHTML":
780
- element.insertAdjacentHTML(
781
- data.position || "beforeend",
782
- decodeHTML(data[key].html)
783
- );
784
- break;
785
- case "insertAdjacentText":
786
- element.insertAdjacentText(
787
- data.position || "beforeend",
788
- decodeHTML(data[key].text)
789
- );
790
- break;
791
- case "setAttribute":
792
- element.setAttribute(data.attrName, decodeHTML(data[key]));
793
- break;
794
- case "removeAttribute":
795
- element.removeAttribute(data[key]);
796
- break;
797
- case "className":
798
- element.className = decodeHTML(data[key]);
799
- break;
800
- case "classList.add":
801
- element.classList.add(...decodeHTML(data[key]).split(","));
802
- break;
803
- case "classList.remove":
804
- element.classList.remove(...decodeHTML(data[key]).split(","));
805
- break;
806
- case "classList.toggle":
807
- element.classList.toggle(decodeHTML(data[key]));
808
- break;
809
- case "classList.replace":
810
- const [oldClass, newClass] = decodeHTML(data[key]).split(",");
811
- element.classList.replace(oldClass, newClass);
812
- break;
813
- case "dataset":
814
- element.dataset[data.attrName] = decodeHTML(data[key]);
815
- break;
816
- case "style":
817
- Object.assign(element.style, data[key]);
818
- break;
819
- case "value":
820
- element.value = decodeHTML(data[key]);
821
- break;
822
- case "checked":
823
- element.checked = data[key];
824
- break;
825
- default:
826
- element.setAttribute(key, decodeHTML(data[key]));
827
- }
828
- }
829
- }
830
- function decodeHTML(html) {
831
- const txt = document.createElement("textarea");
832
- txt.innerHTML = html;
833
- return txt.value;
834
- }
835
- function saveElementOriginalState(element) {
836
- if (
837
- element.hasAttribute("pp-suspense") &&
838
- !element.hasAttribute("pp-original-state")
839
- ) {
840
- const originalState = {};
841
- // Save text content if the element has it
842
- if (element.textContent) {
843
- originalState.textContent = element.textContent.trim();
844
- }
845
- // Save value for input, textarea, and select elements
846
- if (
847
- element instanceof HTMLInputElement ||
848
- element instanceof HTMLTextAreaElement ||
849
- element instanceof HTMLSelectElement
850
- ) {
851
- originalState.value = element.value;
852
- }
853
- // Save other attributes if necessary
854
- for (let i = 0; i < element.attributes.length; i++) {
855
- const attr = element.attributes[i];
856
- originalState[attr.name] = attr.value;
857
- }
858
- // Save the original state as a JSON string in a custom attribute
859
- element.setAttribute("pp-original-state", JSON.stringify(originalState));
860
- }
861
- // Save the state of child elements with pp-suspense attribute
862
- const childrenWithSuspense = element.querySelectorAll("[pp-suspense]");
863
- childrenWithSuspense.forEach((child) => saveElementOriginalState(child));
864
- }
865
- async function handleSuspenseElement(element) {
866
- let suspenseElement = element.getAttribute("pp-suspense") || "";
867
- const handleFormElement = (form, data) => {
868
- for (const key in data) {
869
- if (!data.hasOwnProperty(key)) continue;
870
- for (const formElement of form.elements) {
871
- if (
872
- formElement instanceof HTMLInputElement ||
873
- formElement instanceof HTMLButtonElement ||
874
- formElement instanceof HTMLTextAreaElement ||
875
- formElement instanceof HTMLSelectElement
876
- ) {
877
- const suspenseElement = formElement.getAttribute("pp-suspense") || "";
878
- if (suspenseElement) {
879
- if (isJsonLike(suspenseElement)) {
880
- const suspenseData = parseJson(suspenseElement);
881
- if (suspenseData.onsubmit !== "disabled")
882
- updateElementAttributes(formElement, suspenseData);
883
- } else {
884
- updateElementTextContent(formElement, suspenseElement);
885
- }
886
- }
887
- }
888
- }
889
- }
890
- };
891
- const updateElementTextContent = (element, data) => {
892
- if (element instanceof HTMLInputElement) {
893
- element.value = data;
894
- } else {
895
- element.textContent = data;
896
- }
897
- };
898
- const handleTargetElement = (element, data) => {
899
- if (element instanceof HTMLFormElement) {
900
- handleFormElement(element, data);
901
- } else {
902
- updateElementAttributes(element, data);
903
- }
904
- };
905
- try {
906
- if (suspenseElement && isJsonLike(suspenseElement)) {
907
- const data = parseJson(suspenseElement);
908
- if (data) {
909
- if (element instanceof HTMLFormElement) {
910
- const formData = new FormData(element);
911
- const formDataToProcess = {};
912
- formData.forEach((value, key) => {
913
- formDataToProcess[key] = value;
914
- });
915
- if (data.disabled) {
916
- toggleFormElements(element, true);
917
- }
918
- const { disabled, ...restData } = data;
919
- updateElementAttributes(element, restData);
920
- handleFormElement(element, formDataToProcess);
921
- } else if (data.targets) {
922
- data.targets.forEach((target) => {
923
- const { id, ...rest } = target;
924
- const targetElement = document.querySelector(id);
925
- if (targetElement) {
926
- handleTargetElement(targetElement, rest);
927
- }
928
- });
929
- const { targets, ...restData } = data;
930
- updateElementAttributes(element, restData);
931
- } else {
932
- if (data.empty === "disabled" && element.value === "") return;
933
- const { empty, ...restData } = data;
934
- updateElementAttributes(element, restData);
935
- }
936
- }
937
- } else if (suspenseElement) {
938
- updateElementTextContent(element, suspenseElement);
939
- } else {
940
- if (element instanceof HTMLFormElement) {
941
- const formData = new FormData(element);
942
- const formDataToProcess = {};
943
- formData.forEach((value, key) => {
944
- formDataToProcess[key] = value;
945
- });
946
- handleFormElement(element, formDataToProcess);
947
- }
948
- }
949
- } catch (error) {
950
- console.error("🚀 ~ handleSuspenseElement ~ JSON parse error:", error);
951
- }
952
- }
953
- // Function to restore the original state of an element
954
- function restoreSuspenseElement(element) {
955
- const originalStateAttribute = element.getAttribute("pp-original-state");
956
- if (element.hasAttribute("pp-suspense") && originalStateAttribute) {
957
- const restoreElement = (element, data) => {
958
- const newElement = document.createElement(element.tagName);
959
- for (const key in data) {
960
- if (data.hasOwnProperty(key)) {
961
- if (key === "textContent") {
962
- element.textContent = "";
963
- newElement.textContent = data[key];
964
- } else if (key === "disabled") {
965
- if (data[key] === true) {
966
- newElement.setAttribute("disabled", "true");
967
- } else {
968
- newElement.removeAttribute("disabled");
969
- }
970
- } else {
971
- newElement.setAttribute(key, data[key]);
972
- }
973
- }
974
- }
975
- while (element.firstChild) {
976
- newElement.appendChild(element.firstChild);
977
- }
978
- element.replaceWith(newElement);
979
- return newElement;
980
- };
981
- const restoreFormElement = (form, data) => {
982
- for (const key in data) {
983
- if (!data.hasOwnProperty(key)) continue;
984
- for (const formElement of Array.from(form.elements)) {
985
- if (
986
- formElement instanceof HTMLInputElement ||
987
- formElement instanceof HTMLButtonElement ||
988
- formElement instanceof HTMLTextAreaElement ||
989
- formElement instanceof HTMLSelectElement
990
- ) {
991
- const originalStateAttribute =
992
- formElement.getAttribute("pp-original-state") || "";
993
- if (originalStateAttribute) {
994
- if (isJsonLike(originalStateAttribute)) {
995
- const originalData = parseJson(originalStateAttribute);
996
- const newFormElement = restoreElement(
997
- formElement,
998
- originalData
999
- );
1000
- formElement.replaceWith(newFormElement);
1001
- } else {
1002
- restoreElementTextContent(formElement, originalStateAttribute);
1003
- }
1004
- formElement.removeAttribute("pp-original-state");
1005
- }
1006
- }
1007
- }
1008
- }
1009
- };
1010
- const restoreElementTextContent = (element, data) => {
1011
- if (element instanceof HTMLInputElement) {
1012
- element.value = data;
1013
- } else {
1014
- element.textContent = data;
1015
- }
1016
- };
1017
- const restoreTargetElement = (element, data) => {
1018
- if (element instanceof HTMLFormElement) {
1019
- restoreFormElement(element, data);
1020
- } else {
1021
- const newElement = restoreElement(element, data);
1022
- element.replaceWith(newElement);
1023
- }
1024
- };
1025
- try {
1026
- const data = JSON.parse(originalStateAttribute);
1027
- if (data) {
1028
- if (element instanceof HTMLFormElement) {
1029
- const formData = new FormData(element);
1030
- const formDataToProcess = {};
1031
- formData.forEach((value, key) => {
1032
- formDataToProcess[key] = value;
1033
- });
1034
- restoreFormElement(element, formDataToProcess);
1035
- // Handle the removal of disabled attribute if it was set by suspense
1036
- if (element.hasAttribute("pp-suspense")) {
1037
- const suspenseDataAttribute =
1038
- element.getAttribute("pp-suspense") || "";
1039
- const suspenseData = parseJson(suspenseDataAttribute);
1040
- if (suspenseData.disabled) {
1041
- for (const formElement of Array.from(element.elements)) {
1042
- if (
1043
- formElement instanceof HTMLInputElement ||
1044
- formElement instanceof HTMLButtonElement ||
1045
- formElement instanceof HTMLTextAreaElement ||
1046
- formElement instanceof HTMLSelectElement
1047
- ) {
1048
- formElement.removeAttribute("disabled");
1049
- }
1050
- }
1051
- }
1052
- }
1053
- } else if (data.targets) {
1054
- data.targets.forEach((target) => {
1055
- const { id, ...rest } = target;
1056
- const targetElement = document.querySelector(id);
1057
- if (targetElement) {
1058
- restoreTargetElement(targetElement, rest);
1059
- }
1060
- });
1061
- const { targets, ...restData } = data;
1062
- const newElement = restoreElement(element, restData);
1063
- element.replaceWith(newElement);
1064
- } else {
1065
- const { empty, ...restData } = data;
1066
- const newElement = restoreElement(element, restData);
1067
- element.replaceWith(newElement);
1068
- }
1069
- }
1070
- } catch (error) {
1071
- console.error("🚀 ~ restoreSuspenseElement ~ JSON parse error:", error);
1072
- }
1073
- }
1074
- // Restore the state of child elements with pp-suspense attribute
1075
- const childrenWithSuspense = element.querySelectorAll("[pp-suspense]");
1076
- childrenWithSuspense.forEach((child) => restoreSuspenseElement(child));
1077
- // Clean up the saved state after restoration
1078
- element.removeAttribute("pp-original-state");
1079
- }
1080
- function parseJson(jsonString) {
1081
- if (!isJsonLike(jsonString)) return null;
1082
- return JSON.parse(jsonString.replace(/'/g, '"'));
1083
- }
1084
- function toggleFormElements(form, disable) {
1085
- Array.from(form.elements).forEach((element) => {
1086
- if (
1087
- element instanceof HTMLInputElement ||
1088
- element instanceof HTMLButtonElement ||
1089
- element instanceof HTMLSelectElement ||
1090
- element instanceof HTMLTextAreaElement
1091
- ) {
1092
- element.disabled = disable;
1093
- }
1094
- });
1095
- }
1096
- async function handleUndefinedFunction(element, funcName, data) {
1097
- const body = {
1098
- callback: funcName,
1099
- ...data,
1100
- };
1101
- const firstFetchOptions = {
1102
- method: "POST",
1103
- headers: {
1104
- "Content-Type": "application/json",
1105
- HTTP_PPHP_WIRE_REQUEST: "true",
1106
- },
1107
- body: JSON.stringify(body),
1108
- };
1109
- const secondFetchOptions = {
1110
- method: "POST",
1111
- headers: {
1112
- "Content-Type": "application/json",
1113
- HTTP_PPHP_WIRE_REQUEST: "true",
1114
- },
1115
- body: JSON.stringify({ secondRequestC69CD: true }),
1116
- };
1117
- try {
1118
- saveElementOriginalState(element);
1119
- handleSuspenseElement(element);
1120
- const url = window.location.pathname;
1121
- let firstResponseText = await pphpFetch(url, firstFetchOptions);
1122
- const firstResponseJSON = extractJson(firstResponseText) || "";
1123
- const jsonResponse = firstResponseJSON ? JSON.parse(firstResponseJSON) : {};
1124
- const isPpOnAttribute = hasPpOnAttribute(element);
1125
- const beforeRequestAttribute =
1126
- element.getAttribute("pp-beforeRequest") || "";
1127
- const afterRequestAttribute = element.getAttribute("pp-afterRequest") || "";
1128
- if (
1129
- isPpOnAttribute ||
1130
- beforeRequestAttribute ||
1131
- (afterRequestAttribute && jsonResponse.success)
1132
- )
1133
- restoreSuspenseElement(element);
1134
- if (isPpOnAttribute || beforeRequestAttribute) {
1135
- let contentToAppend = "";
1136
- if (jsonResponse.success) {
1137
- const remainder = firstResponseText.replace(firstResponseJSON, "");
1138
- contentToAppend = remainder;
1139
- } else {
1140
- contentToAppend = firstResponseText;
1141
- }
1142
- appendAfterbegin(contentToAppend);
1143
- return;
1144
- }
1145
- if (afterRequestAttribute && jsonResponse.success) {
1146
- handleAfterRequest(afterRequestAttribute, firstResponseJSON);
1147
- const remainder = firstResponseText.replace(firstResponseJSON, "");
1148
- appendAfterbegin(remainder);
1149
- return firstResponseJSON;
1150
- }
1151
- const secondResponseText = await pphpFetch(url, secondFetchOptions);
1152
- if (firstResponseText.includes("redirect_7F834=")) {
1153
- const url = firstResponseText.split("=")[1];
1154
- await handleRedirect(url);
1155
- } else {
1156
- const parser = new DOMParser();
1157
- const doc = parser.parseFromString(secondResponseText, "text/html");
1158
- let combinedHTML = document.createElement("div");
1159
- combinedHTML.id = "afterbegin-8D95D";
1160
- if (firstResponseJSON) {
1161
- if (jsonResponse.success) {
1162
- const remainder = firstResponseText.replace(firstResponseJSON, "");
1163
- combinedHTML.innerHTML = remainder;
1164
- } else {
1165
- combinedHTML.innerHTML = firstResponseText;
1166
- }
1167
- } else {
1168
- combinedHTML.innerHTML = firstResponseText;
1169
- }
1170
- if (combinedHTML.innerHTML)
1171
- doc.body.insertAdjacentElement("afterbegin", combinedHTML);
1172
- updateDocumentContent(doc.body.outerHTML);
1173
- }
1174
- } catch (error) {
1175
- console.error("Error:", error);
1176
- }
1177
- }
1178
- function appendAfterbegin(content) {
1179
- if (!content) return;
1180
- let afterBeginNode = document.getElementById("afterbegin-8D95D");
1181
- if (afterBeginNode) {
1182
- afterBeginNode.innerHTML = content;
1183
- document.body.insertAdjacentElement("afterbegin", afterBeginNode);
1184
- } else {
1185
- afterBeginNode = document.createElement("div");
1186
- afterBeginNode.id = "afterbegin-8D95D";
1187
- afterBeginNode.innerHTML = content;
1188
- document.body.insertAdjacentElement("afterbegin", afterBeginNode);
1189
- }
1190
- }
1191
- function extractJson(responseText) {
1192
- const jsonMatch = responseText.match(/\{.*\}/);
1193
- return jsonMatch ? jsonMatch[0] : null;
1194
- }
1195
- function handleAfterRequest(functionOnlyAttribute, firstResponseText) {
1196
- if (!isJsonLike(functionOnlyAttribute)) return;
1197
- const functionOnlyData = parseJson(functionOnlyAttribute);
1198
- const responseData = firstResponseText ? parseJson(firstResponseText) : null;
1199
- const targets = functionOnlyData.targets; // Assuming targets is an array of objects
1200
- if (Array.isArray(targets)) {
1201
- targets.forEach((targetData) => {
1202
- const { id, ...restData } = targetData;
1203
- const targetToProcess = document.querySelector(id);
1204
- let targetAttributes = {};
1205
- if (responseData) {
1206
- for (const key in restData) {
1207
- if (restData.hasOwnProperty(key)) {
1208
- switch (key) {
1209
- case "innerHTML":
1210
- case "outerHTML":
1211
- case "textContent":
1212
- case "innerText":
1213
- if (restData[key] === "response") {
1214
- targetAttributes[key] = targetData.responseKey
1215
- ? responseData[targetData.responseKey]
1216
- : responseData.response;
1217
- }
1218
- break;
1219
- default:
1220
- targetAttributes[key] = restData[key];
1221
- break;
1222
- }
1223
- }
1224
- }
1225
- } else {
1226
- targetAttributes = restData;
1227
- }
1228
- if (targetToProcess) {
1229
- updateElementAttributes(targetToProcess, targetAttributes);
1230
- }
1231
- });
1232
- }
1233
- }
1234
- // Function to handle redirection without a full page reload
1235
- async function handleRedirect(url) {
1236
- if (!url) return;
1237
- try {
1238
- history.pushState(null, "", url);
1239
- await handleNavigation();
1240
- } catch (error) {
1241
- console.error("Redirect error:", error);
1242
- }
1243
- }
1244
- /**
1245
- * Debounces a function to limit the rate at which it is called.
1246
- *
1247
- * The debounced function will postpone its execution until after the specified wait time
1248
- * has elapsed since the last time it was invoked. If `immediate` is `true`, the function
1249
- * will be called at the beginning of the wait period instead of at the end.
1250
- *
1251
- * @param {Function} func - The function to debounce.
1252
- * @param {number} [wait=300] - The number of milliseconds to wait before invoking the function.
1253
- * @param {boolean} [immediate=false] - If `true`, the function is invoked immediately on the leading edge.
1254
- * @returns {Function} - Returns the debounced version of the original function.
1255
- */
1256
- function debounce(func, wait = 300, immediate = false) {
1257
- let timeout;
1258
- return function (...args) {
1259
- const context = this;
1260
- if (timeout) clearTimeout(timeout);
1261
- timeout = setTimeout(() => {
1262
- timeout = null;
1263
- if (!immediate) func.apply(context, args);
1264
- }, wait);
1265
- if (immediate && !timeout) {
1266
- func.apply(context, args);
1267
- }
1268
- };
1269
- }
1270
- /**
1271
- * Copies code to the clipboard and updates the button icon.
1272
- *
1273
- * @param {HTMLElement} btnElement - The button element that triggered the copy action.
1274
- * @param {string} containerClass - The class of the container element that contains the code block.
1275
- * @param {string} initialIconClass - The initial class for the icon.
1276
- * @param {string} successIconClass - The class for the icon after a successful copy.
1277
- * @param {number} [timeout=2000] - The time in milliseconds to revert to the initial icon class.
1278
- */
1279
- function copyCode(
1280
- btnElement,
1281
- containerClass,
1282
- initialIconClass,
1283
- successIconClass,
1284
- timeout = 2000
1285
- ) {
1286
- // Ensure btnElement is an instance of HTMLElement
1287
- if (!(btnElement instanceof HTMLElement)) return;
1288
- // Find the closest container with the specified class relative to the button
1289
- const codeBlock = btnElement
1290
- .closest(`.${containerClass}`)
1291
- ?.querySelector("pre code");
1292
- const textToCopy = codeBlock?.textContent?.trim() || ""; // Get the text content of the code block and trim whitespace
1293
- if (textToCopy) {
1294
- navigator.clipboard.writeText(textToCopy).then(
1295
- () => {
1296
- // Clipboard successfully set
1297
- const icon = btnElement.querySelector("i");
1298
- if (icon) {
1299
- icon.className = successIconClass; // Change to success icon
1300
- }
1301
- // Set a timeout to change the icon back to initial after the specified timeout
1302
- setTimeout(() => {
1303
- if (icon) {
1304
- icon.className = initialIconClass; // Change back to initial icon
1305
- }
1306
- }, timeout); // Timeout delay
1307
- },
1308
- () => {
1309
- // Clipboard write failed
1310
- alert("Failed to copy command to clipboard");
1311
- }
1312
- );
1313
- } else {
1314
- alert("Failed to find the code block to copy");
1315
- }
1316
- }
1317
- if (store === null) {
1318
- class StateManager {
1319
- static instance = null;
1320
- state;
1321
- listeners;
1322
- /**
1323
- * Creates a new StateManager instance.
1324
- *
1325
- * @param {State} [initialState={}] - The initial state.
1326
- */
1327
- constructor(initialState = {}) {
1328
- this.state = initialState;
1329
- this.listeners = [];
1330
- }
1331
- /**
1332
- * Gets the singleton instance of StateManager.
1333
- *
1334
- * @param {State} [initialState={}] - The initial state.
1335
- * @returns {StateManager} - The StateManager instance.
1336
- */
1337
- static getInstance(initialState = {}) {
1338
- if (!StateManager.instance) {
1339
- StateManager.instance = new StateManager(initialState);
1340
- StateManager.instance.loadState(); // Load state immediately after instance creation
1341
- }
1342
- return StateManager.instance;
1343
- }
1344
- /**
1345
- * Sets the state.
1346
- *
1347
- * @param {Partial<State>} update - The state update.
1348
- */
1349
- setState(update) {
1350
- this.state = { ...this.state, ...update };
1351
- this.listeners.forEach((listener) => listener(this.state));
1352
- this.saveState();
1353
- }
1354
- /**
1355
- * Subscribes to state changes.
1356
- *
1357
- * @param {(state: State) => void} listener - The listener function.
1358
- * @returns {() => void} - A function to unsubscribe the listener.
1359
- */
1360
- subscribe(listener) {
1361
- this.listeners.push(listener);
1362
- listener(this.state); // Immediately invoke the listener with the current state
1363
- return () => {
1364
- this.listeners = this.listeners.filter((l) => l !== listener);
1365
- };
1366
- }
1367
- /**
1368
- * Saves the state to localStorage.
1369
- */
1370
- saveState() {
1371
- localStorage.setItem("appState_59E13", JSON.stringify(this.state));
1372
- }
1373
- /**
1374
- * Loads the state from localStorage.
1375
- */
1376
- loadState() {
1377
- const state = localStorage.getItem("appState_59E13");
1378
- if (state) {
1379
- this.state = JSON.parse(state);
1380
- this.listeners.forEach((listener) => listener(this.state));
1381
- }
1382
- }
1383
- /**
1384
- * Resets the state to its initial value.
1385
- * This will also clear the state from localStorage.
1386
- */
1387
- resetState() {
1388
- this.state = {}; // Reset the state to an empty object or a default state if you prefer
1389
- this.listeners.forEach((listener) => listener(this.state));
1390
- localStorage.removeItem("appState_59E13"); // Clear the state from localStorage
1391
- }
1392
- }
1393
- store = StateManager.getInstance();
1394
- }
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;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 e.trim().startsWith("{")&&e.trim().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-beforeRequest")||"",o=e.getAttribute("pp-afterRequest")||"",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-afterRequest"),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{/^(https?:)?\/\//i.test(n)&&!n.startsWith(window.location.origin)?window.location.href=n:(history.pushState(null,"",n),await handleNavigation())}catch(e){}finally{isNavigatingA12E1=!1}}}))}async function handleNavigation(){try{const e=await pphpFetch(window.location.href);if(e.includes("redirect_7F834=")){const t=e.split("=")[1];await handleRedirect(t)}else updateDocumentContent(e)}catch(e){}}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))}})),document.body.innerHTML="",loadAndValidateContent(e)};t((new DOMParser).parseFromString(e,"text/html"))}else{saveState();const t=(new DOMParser).parseFromString(e,"text/html");document.body.innerHTML="",loadAndValidateContent(t),restoreState()}restoreScrollPositions(t),attachWireFunctionEvents(),document.dispatchEvent(new Event("DOMContentLoaded"))}function loadAndValidateContent(e){const t=new Map;function n(e){switch(e.tagName){case"SCRIPT":const a=document.createElement("script"),o=e;o.src?a.src=o.src:a.textContent=o.textContent,s(e,a);break;default:const i=e.cloneNode(!1);t.set(e,i),Array.from(e.childNodes).forEach((e=>{e.nodeType===Node.TEXT_NODE?i.appendChild(document.createTextNode(e.textContent||"")):e.nodeType===Node.ELEMENT_NODE&&n(e)})),s(e,i);break}}function s(e,n){const s=t.get(e.parentNode);s?s.appendChild(n):document.body.appendChild(n)}Array.from(e.body.children).forEach((e=>{n(e)}))}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;if(void 0!==stateA129A.focusSelectionStart&&null!==stateA129A.focusSelectionEnd&&e.setSelectionRange(t,t),stateA129A.focusValue)if("checkbox"===e.type||"radio"===e.type)e.checked=!!stateA129A.focusChecked;else if("number"===e.type)e.type="text",e.setSelectionRange(t,t),e.type="number";else{e.hasAttribute("pp-suspense")||stateA129A.isSuspense||(e.value=stateA129A.focusValue)}e.focus()}else if(e instanceof HTMLTextAreaElement){const t=e.value.length||0;if(void 0!==stateA129A.focusSelectionStart&&null!==stateA129A.focusSelectionEnd&&e.setSelectionRange(t,t),stateA129A.focusValue){e.hasAttribute("pp-suspense")||stateA129A.isSuspense||(e.value=stateA129A.focusValue)}e.focus()}else if(e instanceof HTMLSelectElement){if(stateA129A.focusValue){e.hasAttribute("pp-suspense")||stateA129A.isSuspense||(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 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)}else s(t,e)}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=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,...s}=e,a=document.querySelector(t);a&&((e,t)=>{e instanceof HTMLFormElement?n(e,t):updateElementAttributes(e,t)})(a,s)}));const{targets:t,...a}=s;updateElementAttributes(e,a)}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)=>{const n=document.createElement(e.tagName);for(const s in t)t.hasOwnProperty(s)&&("textContent"===s?(e.textContent="",n.textContent=t[s]):"disabled"===s?!0===t[s]?n.setAttribute("disabled","true"):n.removeAttribute("disabled"):n.setAttribute(s,t[s]));for(;e.firstChild;)n.appendChild(e.firstChild);return e.replaceWith(n),n},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),a=n(t,s);t.replaceWith(a)}else a(t,e);t.removeAttribute("pp-original-state")}}},a=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t},o=(e,t)=>{if(e instanceof HTMLFormElement)s(e,t);else{const s=n(e,t);e.replaceWith(s)}};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,i=n(e,s);e.replaceWith(i)}else{const{empty:t,...s}=a,o=n(e,s);e.replaceWith(o)}}catch(e){}}e.querySelectorAll("[pp-suspense]").forEach((e=>restoreSuspenseElement(e))),e.removeAttribute("pp-original-state")}function parseJson(e){return isJsonLike(e)?JSON.parse(e.replace(/'/g,'"')):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 handleUndefinedFunction(e,t,n){const s={callback:t,...n},a={method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(s)},o={method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify({secondRequestC69CD:!0})};try{saveElementOriginalState(e),handleSuspenseElement(e);const t=window.location.pathname;let n=await pphpFetch(t,a);const s=extractJson(n)||"",i=s?JSON.parse(s):{},r=hasPpOnAttribute(e),c=e.getAttribute("pp-beforeRequest")||"",l=e.getAttribute("pp-afterRequest")||"";if((r||c||l&&i.success)&&restoreSuspenseElement(e),r||c){let e="";if(i.success){e=n.replace(s,"")}else e=n;return void appendAfterbegin(e)}if(l&&i.success){handleAfterRequest(l,s);return appendAfterbegin(n.replace(s,"")),s}const u=await pphpFetch(t,o);if(n.includes("redirect_7F834=")){const e=n.split("=")[1];await handleRedirect(e)}else{const e=(new DOMParser).parseFromString(u,"text/html");let t=document.createElement("div");if(t.id="afterbegin-8D95D",s)if(i.success){const e=n.replace(s,"");t.innerHTML=e}else t.innerHTML=n;else t.innerHTML=n;t.innerHTML&&e.body.insertAdjacentElement("afterbegin",t),updateDocumentContent(e.body.outerHTML)}}catch(e){}}function appendAfterbegin(e){if(!e)return;let t=document.getElementById("afterbegin-8D95D");t?(t.innerHTML=e,document.body.insertAdjacentElement("afterbegin",t)):(t=document.createElement("div"),t.id="afterbegin-8D95D",t.innerHTML=e,document.body.insertAdjacentElement("afterbegin",t))}function extractJson(e){const t=e.match(/\{.*\}/);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{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=2e3){if(!(e instanceof HTMLElement))return;const o=e.closest(`.${t}`)?.querySelector("pre code"),i=o?.textContent?.trim()||"";i?navigator.clipboard.writeText(i).then((()=>{const t=e.querySelector("i");t&&(t.className=s),setTimeout((()=>{t&&(t.className=n)}),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,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))}})(),document.addEventListener("DOMContentLoaded",attachWireFunctionEvents),window.addEventListener("popstate",(async()=>{await handleNavigation()})),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()}