Twan07 commited on
Commit
9ff1fd4
·
verified ·
1 Parent(s): 4f2bfca

Upload 15 files

Browse files
exocore-web/public/FileManager.jsx ADDED
@@ -0,0 +1,1288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, For, Show, onCleanup, createEffect } from 'solid-js';
3
+
4
+ import hljs from 'highlight.js/lib/core';
5
+ import javascript_hljs from 'highlight.js/lib/languages/javascript';
6
+ import typescript_hljs from 'highlight.js/lib/languages/typescript';
7
+ import json_hljs from 'highlight.js/lib/languages/json';
8
+ import xml_hljs from 'highlight.js/lib/languages/xml';
9
+ import css_hljs from 'highlight.js/lib/languages/css';
10
+ import bash_hljs from 'highlight.js/lib/languages/bash';
11
+ import markdown_hljs from 'highlight.js/lib/languages/markdown';
12
+ import sql_hljs from 'highlight.js/lib/languages/sql';
13
+
14
+ import { EditorView, keymap, lineNumbers } from '@codemirror/view';
15
+ import { EditorState, Compartment } from '@codemirror/state';
16
+ import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
17
+ import { syntaxHighlighting, defaultHighlightStyle, foldGutter, foldKeymap } from '@codemirror/language';
18
+ import { lintGutter } from "@codemirror/lint";
19
+ import { oneDark } from '@codemirror/theme-one-dark';
20
+
21
+ import { javascript } from '@codemirror/lang-javascript';
22
+ import { json } from '@codemirror/lang-json';
23
+ import { html } from '@codemirror/lang-html';
24
+ import { css } from '@codemirror/lang-css';
25
+ import { markdown } from '@codemirror/lang-markdown';
26
+
27
+ hljs.registerLanguage('javascript', javascript_hljs);
28
+ hljs.registerLanguage('typescript', typescript_hljs);
29
+ hljs.registerLanguage('json', json_hljs);
30
+ hljs.registerLanguage('html', xml_hljs);
31
+ hljs.registerLanguage('css', css_hljs);
32
+ hljs.registerLanguage('bash', bash_hljs);
33
+ hljs.registerLanguage('markdown', markdown_hljs);
34
+ hljs.registerLanguage('sql', sql_hljs);
35
+
36
+ function App() {
37
+ const [loading, setLoading] = createSignal(true);
38
+ const [status, setStatus] = createSignal('');
39
+ const [notifications, setNotifications] = createSignal([]);
40
+ const [userData, setUserData] = createSignal(null);
41
+ const [files, setFiles] = createSignal([]);
42
+ const [selectedFile, setSelectedFile] = createSignal(null);
43
+ const [fileContent, setFileContent] = createSignal('');
44
+ const [newFileName, setNewFileName] = createSignal('');
45
+ const [newFolderName, setNewFolderName] = createSignal('');
46
+ const [openFolders, setOpenFolders] = createSignal({});
47
+ const [contextMenu, setContextMenu] = createSignal({
48
+ visible: false,
49
+ x: 0,
50
+ y: 0,
51
+ file: null,
52
+ });
53
+ const [isMobileView, setIsMobileView] = createSignal(false);
54
+ const [isEditingFile, setIsEditingFile] = createSignal(true);
55
+ const [initialLoadComplete, setInitialLoadComplete] = createSignal(false);
56
+
57
+ const [renameContainerInfo, setRenameContainerInfo] = createSignal({
58
+ visible: false,
59
+ file: null,
60
+ newName: '',
61
+ });
62
+ const [createItemModalInfo, setCreateItemModalInfo] = createSignal({
63
+ visible: false,
64
+ parentPath: null,
65
+ isDir: false,
66
+ itemName: '',
67
+ });
68
+
69
+ let renameInputRef;
70
+ let codeRef;
71
+ let createItemInputRef;
72
+ let editorRef;
73
+ let editorViewInstance = null;
74
+
75
+ const languageCompartment = new Compartment();
76
+ const themeCompartment = new Compartment();
77
+ const editableCompartment = new Compartment();
78
+
79
+ const linkManager = '/private/server/exocore/web/file';
80
+
81
+ const getToken = () => localStorage.getItem('exocore-token') || '';
82
+ const getCookies = () => localStorage.getItem('exocore-cookies') || '';
83
+
84
+ const addNotification = (message, type = 'info', duration = 4000) => {
85
+ const id = Date.now();
86
+ setNotifications(prev => [...prev, { id, message, type }]);
87
+ setTimeout(() => {
88
+ setNotifications(prev => prev.filter(n => n.id !== id));
89
+ }, duration);
90
+ };
91
+
92
+ function sortFileSystemItems(items) {
93
+ if (!Array.isArray(items)) return [];
94
+
95
+ const specialOrder = ['.git', 'package.json', 'package-lock.json'];
96
+ const nodeModulesName = 'node_modules';
97
+
98
+ const regularItems = items.filter(item => !specialOrder.includes(item.name) && item.name !== nodeModulesName);
99
+ const specialItemsOnList = items.filter(item => specialOrder.includes(item.name));
100
+ const nodeModulesItem = items.find(item => item.name === nodeModulesName);
101
+
102
+ regularItems.sort((a, b) => {
103
+ if (a.isDir && !b.isDir) return -1;
104
+ if (!a.isDir && b.isDir) return 1;
105
+ return a.name.localeCompare(b.name);
106
+ });
107
+ specialItemsOnList.sort((a, b) => specialOrder.indexOf(a.name) - specialOrder.indexOf(b.name));
108
+
109
+ const sortedItems = [...regularItems, ...specialItemsOnList];
110
+ if (nodeModulesItem) {
111
+ sortedItems.push(nodeModulesItem);
112
+ }
113
+ return sortedItems;
114
+ }
115
+
116
+ async function fetchUserInfo() {
117
+ setLoading(true);
118
+ const token = getToken();
119
+ const cookies = getCookies();
120
+
121
+ if (!token || !cookies) {
122
+ setLoading(false);
123
+ setInitialLoadComplete(true);
124
+ window.location.href = '/private/server/exocore/web/public/login';
125
+ return;
126
+ }
127
+
128
+ try {
129
+ const res = await fetch('/private/server/exocore/web/userinfo', {
130
+ method: 'POST',
131
+ headers: { 'Content-Type': 'application/json' },
132
+ body: JSON.stringify({ token, cookies }),
133
+ });
134
+
135
+ if (!res.ok) {
136
+ let errorMsg = `Server error: ${res.status}`;
137
+ try {
138
+ const errorData = await res.json();
139
+ errorMsg = errorData.message || errorMsg;
140
+ } catch (parseError) {}
141
+ throw new Error(errorMsg);
142
+ }
143
+
144
+ const data = await res.json();
145
+
146
+ if (data.data?.user && data.data.user.verified === 'success') {
147
+ setUserData(data.data.user);
148
+ await fetchFiles('');
149
+ } else {
150
+ setUserData(null);
151
+ const redirectMsg = data.message || 'User verification failed. Redirecting to login...';
152
+ setStatus(redirectMsg);
153
+ localStorage.removeItem('exocore-token');
154
+ localStorage.removeItem('exocore-cookies');
155
+ setTimeout(() => {
156
+ window.location.href = '/private/server/exocore/web/public/login';
157
+ }, 2500);
158
+ }
159
+ } catch (err) {
160
+ setUserData(null);
161
+ const errorMessage = err instanceof Error ? err.message : String(err);
162
+ const redirectMsg = 'Failed to fetch user info: ' + errorMessage + '. Redirecting to login...';
163
+ setStatus(redirectMsg);
164
+ localStorage.removeItem('exocore-token');
165
+ localStorage.removeItem('exocore-cookies');
166
+ setTimeout(() => {
167
+ window.location.href = '/private/server/exocore/web/public/login';
168
+ }, 2500);
169
+ } finally {
170
+ setLoading(false);
171
+ setInitialLoadComplete(true);
172
+ }
173
+ }
174
+
175
+ async function fetchFiles(currentPath = '') {
176
+ setLoading(true);
177
+ let endpoint = '';
178
+ let bodyPayload = {};
179
+ if (currentPath) {
180
+ endpoint = `${linkManager}/open-folder`;
181
+ bodyPayload = {
182
+ folder: currentPath,
183
+ };
184
+ } else {
185
+ endpoint = `${linkManager}/list`;
186
+ bodyPayload = {};
187
+ }
188
+ try {
189
+ const res = await fetch(endpoint, {
190
+ method: 'POST',
191
+ headers: {
192
+ 'Content-Type': 'application/json',
193
+ },
194
+ body: JSON.stringify(bodyPayload),
195
+ });
196
+ const responseText = await res.text();
197
+ if (!res.ok) {
198
+ let errorMsg = responseText;
199
+ try {
200
+ const errData = JSON.parse(responseText);
201
+ errorMsg = errData.message || errData.error || responseText;
202
+ } catch (e) {}
203
+ throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
204
+ }
205
+ const data = JSON.parse(responseText);
206
+ if (currentPath) {
207
+ if (data && Array.isArray(data.items)) {
208
+ setOpenFolders((prev) => ({
209
+ ...prev,
210
+ [currentPath]: sortFileSystemItems(data.items),
211
+ }));
212
+ } else {
213
+ setOpenFolders((prev) => ({ ...prev, [currentPath]: [] }));
214
+ addNotification(`Error: Could not load content for folder ${currentPath}.`, 'error');
215
+ }
216
+ } else {
217
+ if (Array.isArray(data)) {
218
+ setFiles(sortFileSystemItems(data));
219
+ } else {
220
+ setFiles([]);
221
+ addNotification(`Error: Could not load root directory.`, 'error');
222
+ }
223
+ }
224
+ } catch (err) {
225
+ const errorMessage = err instanceof Error ? err.message : String(err);
226
+ addNotification(`Failed to list ${currentPath || 'root'}: ${errorMessage}`, 'error');
227
+ if (currentPath) {
228
+ setOpenFolders((prev) => ({ ...prev, [currentPath]: undefined }));
229
+ }
230
+ } finally {
231
+ setLoading(false);
232
+ }
233
+ }
234
+
235
+ async function openFile(file) {
236
+ setLoading(true);
237
+ try {
238
+ const res = await fetch(`${linkManager}/open`, {
239
+ method: 'POST',
240
+ headers: {
241
+ 'Content-Type': 'application/json',
242
+ },
243
+ body: JSON.stringify({
244
+ file,
245
+ }),
246
+ });
247
+ const text = await res.text();
248
+ if (!res.ok) throw new Error(text || `HTTP error! status: ${res.status}`);
249
+ setSelectedFile(file);
250
+ setFileContent(text);
251
+ setIsEditingFile(true);
252
+ } catch (err) {
253
+ const errorMessage = err instanceof Error ? err.message : String(err);
254
+ addNotification('Failed to open file: ' + errorMessage, 'error');
255
+ } finally {
256
+ setLoading(false);
257
+ }
258
+ }
259
+
260
+ function closeFileEditor() {
261
+ setSelectedFile(null);
262
+ setFileContent('');
263
+ }
264
+
265
+ async function saveFile() {
266
+ if (!selectedFile()) return;
267
+ setLoading(true);
268
+ try {
269
+ const res = await fetch(`${linkManager}/save`, {
270
+ method: 'POST',
271
+ headers: {
272
+ 'Content-Type': 'application/json',
273
+ },
274
+ body: JSON.stringify({
275
+ file: selectedFile(),
276
+ content: fileContent(),
277
+ }),
278
+ });
279
+ const message = await res.text();
280
+ if (!res.ok) throw new Error(message || `HTTP error! status: ${res.status}`);
281
+ addNotification(message, 'success');
282
+ } catch (err) {
283
+ const errorMessage = err instanceof Error ? err.message : String(err);
284
+ addNotification('Failed to save file: ' + errorMessage, 'error');
285
+ } finally {
286
+ setLoading(false);
287
+ }
288
+ }
289
+
290
+ async function refreshFileSystem(affectedItemPath = '') {
291
+ let parentPath = '';
292
+ if (affectedItemPath) {
293
+ const lastSlashIndex = affectedItemPath.lastIndexOf('/');
294
+ if (lastSlashIndex !== -1) {
295
+ parentPath = affectedItemPath.substring(0, lastSlashIndex);
296
+ }
297
+ }
298
+ await fetchFiles();
299
+ if (parentPath && openFolders()[parentPath]) {
300
+ await fetchFiles(parentPath);
301
+ }
302
+ }
303
+
304
+ function fileOrFolderNameIsDirectory(path) {
305
+ if (openFolders()[path] !== undefined) return true;
306
+ const checkList = (list, currentBuildPath = '') => {
307
+ for (const item of list) {
308
+ const itemFullPath = currentBuildPath ? `${currentBuildPath}/${item.name}` : item.name;
309
+ if (itemFullPath === path) return item.isDir;
310
+ if (item.isDir && openFolders()[itemFullPath]) {
311
+ const foundInSub = checkList(openFolders()[itemFullPath], itemFullPath);
312
+ if (foundInSub !== undefined) return foundInSub;
313
+ }
314
+ }
315
+ return undefined;
316
+ };
317
+ return checkList(files()) || false;
318
+ }
319
+
320
+ async function createFile() {
321
+ const name = newFileName().trim();
322
+ if (!name) {
323
+ addNotification('Please enter a file name.', 'error');
324
+ return;
325
+ }
326
+ setLoading(true);
327
+ try {
328
+ const res = await fetch(`${linkManager}/create`, {
329
+ method: 'POST',
330
+ headers: { 'Content-Type': 'application/json' },
331
+ body: JSON.stringify({ file: name }),
332
+ });
333
+ const message = await res.text();
334
+ if (!res.ok) throw new Error(message || `HTTP error! status: ${res.status}`);
335
+ setNewFileName('');
336
+ await refreshFileSystem(name);
337
+ addNotification(`File "${name}" created successfully.`, 'success');
338
+ } catch (err) {
339
+ const errorMessage = err instanceof Error ? err.message : String(err);
340
+ addNotification('Failed to create file: ' + errorMessage, 'error');
341
+ } finally {
342
+ setLoading(false);
343
+ }
344
+ }
345
+
346
+ async function createFolder() {
347
+ const name = newFolderName().trim();
348
+ if (!name) {
349
+ addNotification('Please enter a folder name.', 'error');
350
+ return;
351
+ }
352
+ setLoading(true);
353
+ try {
354
+ const res = await fetch(`${linkManager}/create-folder`, {
355
+ method: 'POST',
356
+ headers: { 'Content-Type': 'application/json' },
357
+ body: JSON.stringify({ folder: name }),
358
+ });
359
+ const message = await res.text();
360
+ if (!res.ok) throw new Error(message || `HTTP error! status: ${res.status}`);
361
+ setNewFolderName('');
362
+ await refreshFileSystem(name);
363
+ addNotification(`Folder "${name}" created successfully.`, 'success');
364
+ } catch (err) {
365
+ const errorMessage = err instanceof Error ? err.message : String(err);
366
+ addNotification('Failed to create folder: ' + errorMessage, 'error');
367
+ } finally {
368
+ setLoading(false);
369
+ }
370
+ }
371
+
372
+ async function uploadFile(e) {
373
+ const fileToUpload = e.target.files[0];
374
+ if (!fileToUpload) return;
375
+ const targetPathForUpload = fileToUpload.name;
376
+ const form = new FormData();
377
+ form.append('file', fileToUpload);
378
+ setLoading(true);
379
+ try {
380
+ const res = await fetch(`${linkManager}/upload`, {
381
+ method: 'POST',
382
+ body: form,
383
+ });
384
+ const message = await res.text();
385
+ if (!res.ok) throw new Error(message || `HTTP error! status: ${res.status}`);
386
+ await refreshFileSystem(targetPathForUpload);
387
+ addNotification(`File "${fileToUpload.name}" uploaded successfully.`, 'success');
388
+ } catch (err) {
389
+ const errorMessage = err instanceof Error ? err.message : String(err);
390
+ addNotification('Failed to upload file: ' + errorMessage, 'error');
391
+ } finally {
392
+ setLoading(false);
393
+ e.target.value = null;
394
+ }
395
+ }
396
+
397
+ function download(file) {
398
+ const form = document.createElement('form');
399
+ form.method = 'POST';
400
+ form.action = `${linkManager}/download`;
401
+ form.style.display = 'none';
402
+ const input = document.createElement('input');
403
+ input.name = 'file';
404
+ input.value = file;
405
+ input.type = 'hidden';
406
+ form.appendChild(input);
407
+ document.body.appendChild(form);
408
+ form.submit();
409
+ document.body.removeChild(form);
410
+ addNotification(`Downloading "${file}"...`, 'info');
411
+ }
412
+
413
+ function toggleFolder(folderPath) {
414
+ if (openFolders()[folderPath]) {
415
+ setOpenFolders((prev) => {
416
+ const updated = { ...prev };
417
+ delete updated[folderPath];
418
+ Object.keys(updated).forEach(key => {
419
+ if (key.startsWith(folderPath + '/')) {
420
+ delete updated[key];
421
+ }
422
+ });
423
+ return updated;
424
+ });
425
+ } else {
426
+ fetchFiles(folderPath);
427
+ }
428
+ }
429
+
430
+ function handleFileClick(file, fullPath) {
431
+ if (file.isDir) {
432
+ toggleFolder(fullPath);
433
+ } else {
434
+ openFile(fullPath);
435
+ }
436
+ }
437
+
438
+ function handleContextMenu(e, file, fullPath) {
439
+ e.preventDefault();
440
+ e.stopPropagation();
441
+ setContextMenu({
442
+ visible: true,
443
+ x: e.clientX,
444
+ y: e.clientY,
445
+ file: { ...file, path: fullPath },
446
+ });
447
+ }
448
+
449
+ function handleOpenFolderFromContextMenu() {
450
+ const folderToOpen = contextMenu().file;
451
+ if (folderToOpen && folderToOpen.isDir) {
452
+ if (!openFolders()[folderToOpen.path]) {
453
+ fetchFiles(folderToOpen.path);
454
+ }
455
+ }
456
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
457
+ }
458
+
459
+ function handleDownloadSelected() {
460
+ if (contextMenu().file && !contextMenu().file.isDir) {
461
+ download(contextMenu().file.path);
462
+ }
463
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
464
+ }
465
+
466
+ async function handleUnzipSelected() {
467
+ const fileToUnzip = contextMenu().file;
468
+ if (!fileToUnzip || fileToUnzip.isDir || !fileToUnzip.name.toLowerCase().endsWith('.zip')) {
469
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
470
+ return;
471
+ }
472
+
473
+ const zipFilePath = fileToUnzip.path;
474
+ setLoading(true);
475
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
476
+
477
+ try {
478
+ const res = await fetch(`${linkManager}/unzip`, {
479
+ method: 'POST',
480
+ headers: { 'Content-Type': 'application/json' },
481
+ body: JSON.stringify({
482
+ zipFilePath: zipFilePath,
483
+ overwrite: true,
484
+ destinationPath: '',
485
+ }),
486
+ });
487
+ const message = await res.text();
488
+ if (!res.ok) {
489
+ let errorMsg = message;
490
+ try {
491
+ const errData = JSON.parse(message);
492
+ errorMsg = errData.message || errData.error || message;
493
+ } catch (e) { }
494
+ throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
495
+ }
496
+ addNotification(message, 'success');
497
+ await refreshFileSystem(zipFilePath);
498
+
499
+ } catch (err) {
500
+ const errorMessage = err instanceof Error ? err.message : String(err);
501
+ addNotification(`Failed to unzip "${fileToUnzip.name}": ${errorMessage}`, 'error');
502
+ } finally {
503
+ setLoading(false);
504
+ }
505
+ }
506
+
507
+ function handleRenameClick() {
508
+ if (contextMenu().file) {
509
+ setRenameContainerInfo({
510
+ visible: true,
511
+ file: contextMenu().file,
512
+ newName: contextMenu().file.name,
513
+ });
514
+ }
515
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
516
+ }
517
+
518
+ async function handleDeleteSelected() {
519
+ const fileToDelete = contextMenu().file;
520
+ if (!fileToDelete) return;
521
+
522
+ const confirmation = window.confirm(`Are you sure you want to delete "${fileToDelete.name}"? This action cannot be undone.`);
523
+ if (!confirmation) {
524
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
525
+ return;
526
+ }
527
+
528
+ setLoading(true);
529
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
530
+
531
+ try {
532
+ const res = await fetch(`${linkManager}/delete`, {
533
+ method: 'POST',
534
+ headers: { 'Content-Type': 'application/json' },
535
+ body: JSON.stringify({ path: fileToDelete.path }),
536
+ });
537
+ const message = await res.text();
538
+ if (!res.ok) {
539
+ let errorMsg = message;
540
+ try {
541
+ const errData = JSON.parse(message);
542
+ errorMsg = errData.message || errData.error || message;
543
+ } catch (e) { }
544
+ throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
545
+ }
546
+ addNotification(message || `Successfully deleted "${fileToDelete.name}".`, 'success');
547
+
548
+ if (selectedFile() && selectedFile().startsWith(fileToDelete.path)) {
549
+ closeFileEditor();
550
+ }
551
+ if (fileToDelete.isDir) {
552
+ setOpenFolders((prev) => {
553
+ const updated = { ...prev };
554
+ delete updated[fileToDelete.path];
555
+ Object.keys(updated).forEach(key => {
556
+ if (key.startsWith(fileToDelete.path + '/')) {
557
+ delete updated[key];
558
+ }
559
+ });
560
+ return updated;
561
+ });
562
+ }
563
+ await refreshFileSystem(fileToDelete.path);
564
+ } catch (err) {
565
+ const errorMessage = err instanceof Error ? err.message : String(err);
566
+ addNotification(`Failed to delete "${fileToDelete.name}": ${errorMessage}`, 'error');
567
+ } finally {
568
+ setLoading(false);
569
+ }
570
+ }
571
+
572
+ function cancelRename() {
573
+ setRenameContainerInfo({ visible: false, file: null, newName: '' });
574
+ }
575
+
576
+ async function performRename() {
577
+ const fileToRename = renameContainerInfo().file;
578
+ const newName = renameContainerInfo().newName.trim();
579
+
580
+ if (!fileToRename || !newName) {
581
+ addNotification('Invalid rename operation. New name cannot be empty.', 'error');
582
+ cancelRename();
583
+ return;
584
+ }
585
+ setLoading(true);
586
+ try {
587
+ const oldPath = fileToRename.path;
588
+ const parentPath = oldPath.substring(0, oldPath.lastIndexOf('/'));
589
+ const newPath = parentPath ? `${parentPath}/${newName}` : newName;
590
+
591
+ if (oldPath === newPath) {
592
+ addNotification('No change detected. Renaming cancelled.', 'info');
593
+ cancelRename();
594
+ setLoading(false);
595
+ return;
596
+ }
597
+
598
+ const res = await fetch(`${linkManager}/rename`, {
599
+ method: 'POST',
600
+ headers: { 'Content-Type': 'application/json' },
601
+ body: JSON.stringify({ oldPath, newPath }),
602
+ });
603
+ const message = await res.text();
604
+ if (!res.ok) {
605
+ let errorMsg = message;
606
+ try {
607
+ const errData = JSON.parse(message);
608
+ errorMsg = errData.message || errData.error || message;
609
+ } catch (e) { }
610
+ throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
611
+ }
612
+ addNotification(`Renamed "${fileToRename.name}" to "${newName}" successfully.`, 'success');
613
+
614
+ if (fileToRename.isDir && openFolders()[oldPath]) {
615
+ const contents = openFolders()[oldPath];
616
+ setOpenFolders((prev) => {
617
+ const updated = { ...prev };
618
+ delete updated[oldPath];
619
+ updated[newPath] = contents;
620
+ Object.keys(updated).forEach(key => {
621
+ if (key.startsWith(oldPath + '/')) {
622
+ const subPath = key.substring(oldPath.length);
623
+ const oldSubOpenFolderContent = updated[key];
624
+ delete updated[key];
625
+ updated[newPath + subPath] = oldSubOpenFolderContent;
626
+ }
627
+ });
628
+ return updated;
629
+ });
630
+ }
631
+
632
+ if (selectedFile() === oldPath) {
633
+ setSelectedFile(newPath);
634
+ }
635
+
636
+ await refreshFileSystem(newPath);
637
+ cancelRename();
638
+
639
+ } catch (err) {
640
+ const errorMessage = err instanceof Error ? err.message : String(err);
641
+ addNotification('Failed to rename: ' + errorMessage, 'error');
642
+ } finally {
643
+ setLoading(false);
644
+ }
645
+ }
646
+
647
+ function handleShowCreateItemModal(isDirContext) {
648
+ const contextFile = contextMenu().file;
649
+ let parentPathTarget = '';
650
+
651
+ if (contextFile) {
652
+ if (contextFile.isDir) {
653
+ parentPathTarget = contextFile.path;
654
+ } else {
655
+ const lastSlash = contextFile.path.lastIndexOf('/');
656
+ parentPathTarget = lastSlash === -1 ? '' : contextFile.path.substring(0, lastSlash);
657
+ }
658
+ }
659
+
660
+ setCreateItemModalInfo({
661
+ visible: true,
662
+ parentPath: parentPathTarget,
663
+ isDir: isDirContext,
664
+ itemName: '',
665
+ });
666
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
667
+ }
668
+
669
+ function cancelCreateItem() {
670
+ setCreateItemModalInfo({ visible: false, parentPath: null, isDir: false, itemName: '' });
671
+ }
672
+
673
+ async function performCreateItem() {
674
+ const { parentPath, itemName, isDir } = createItemModalInfo();
675
+ const newItemNameTrimmed = itemName.trim();
676
+
677
+ if (!newItemNameTrimmed) {
678
+ addNotification(`Please enter a ${isDir ? 'folder' : 'file'} name.`, 'error');
679
+ return;
680
+ }
681
+ const fullPath = parentPath ? `${parentPath}/${newItemNameTrimmed}` : newItemNameTrimmed;
682
+ setLoading(true);
683
+ try {
684
+ const endpoint = isDir ? `${linkManager}/create-folder` : `${linkManager}/create`;
685
+ const payload = isDir ? { folder: fullPath } : { file: fullPath };
686
+ const res = await fetch(endpoint, {
687
+ method: 'POST',
688
+ headers: { 'Content-Type': 'application/json' },
689
+ body: JSON.stringify(payload),
690
+ });
691
+ const message = await res.text();
692
+ if (!res.ok) {
693
+ let errorMsg = message;
694
+ try {
695
+ const errData = JSON.parse(message);
696
+ errorMsg = errData.message || errData.error || message;
697
+ } catch (e) { }
698
+ throw new Error(errorMsg || `HTTP error! status: ${res.status}`);
699
+ }
700
+ addNotification(`${isDir ? 'Folder' : 'File'} "${newItemNameTrimmed}" created successfully in "${parentPath || 'root'}".`, 'success');
701
+ cancelCreateItem();
702
+ await refreshFileSystem(fullPath);
703
+ if (parentPath) {
704
+ await fetchFiles(parentPath);
705
+ }
706
+ } catch (err) {
707
+ const errorMessage = err instanceof Error ? err.message : String(err);
708
+ addNotification(`Failed to create ${isDir ? 'folder' : 'file'}: ${errorMessage}`, 'error');
709
+ } finally {
710
+ setLoading(false);
711
+ }
712
+ }
713
+
714
+ function getFileIconPath(fileItem, isFolderOpen) {
715
+ const baseIconPath = './icons/';
716
+ const nameLower = fileItem.name.toLowerCase();
717
+ if (fileItem.isDir) {
718
+ if (nameLower === '.git') {
719
+ return `${baseIconPath}git.svg`;
720
+ }
721
+ return isFolderOpen ? `${baseIconPath}folder-open.svg` : `${baseIconPath}folder.svg`;
722
+ }
723
+ if (nameLower === 'exocore.run') { return `${baseIconPath}exocore.run.svg`; }
724
+ if (nameLower === '.gitignore' || nameLower === '.gitattributes' || nameLower === '.gitmodules') {
725
+ return `${baseIconPath}git.svg`;
726
+ }
727
+ const parts = nameLower.split('.');
728
+ let extension = '';
729
+ if (parts.length > 1) {
730
+ const potentialExtension = parts.pop();
731
+ if (parts[0] !== '' || parts.length > 0) {
732
+ if (potentialExtension !== undefined) {
733
+ extension = potentialExtension;
734
+ }
735
+ } else if (potentialExtension !== undefined) {
736
+ extension = potentialExtension;
737
+ }
738
+ }
739
+ switch (extension) {
740
+ case 'js': return `${baseIconPath}js.svg`;
741
+ case 'jsx': return `${baseIconPath}jsx.svg`;
742
+ case 'ts': return `${baseIconPath}ts.svg`;
743
+ case 'tsx': return `${baseIconPath}tsx.svg`;
744
+ case 'json': return `${baseIconPath}json.svg`;
745
+ case 'xml': return `${baseIconPath}xml.svg`;
746
+ case 'html': return `${baseIconPath}html.svg`;
747
+ case 'css': return `${baseIconPath}css.svg`;
748
+ case 'md': return `${baseIconPath}md.svg`;
749
+ case 'sh': return `${baseIconPath}sh.svg`;
750
+ case 'sql': return `${baseIconPath}sql.svg`;
751
+ case 'zip': return `${baseIconPath}zip.svg`;
752
+ case 'gif': return `${baseIconPath}gifImage.svg`;
753
+ case 'jpg':
754
+ case 'jpeg':
755
+ case 'png':
756
+ return `${baseIconPath}image.svg`;
757
+ case 'mp4':
758
+ case 'mov':
759
+ case 'avi':
760
+ case 'mkv':
761
+ case 'webm':
762
+ case 'flv':
763
+ case 'wmv':
764
+ return `${baseIconPath}video.svg`;
765
+ case 'git':
766
+ return `${baseIconPath}git.svg`;
767
+ default:
768
+ return `${baseIconPath}undefined.svg`;
769
+ }
770
+ }
771
+
772
+ function renderFiles(list, parentPath = '') {
773
+ return (
774
+ <ul style={{ 'margin-left': '1rem', 'padding-left': '0', 'list-style-type': 'none' }}>
775
+ <For each={list}>
776
+ {(file) => {
777
+ const fullPath = parentPath ? `${parentPath}/${file.name}` : file.name;
778
+ const isDirOpen = file.isDir && openFolders()[fullPath];
779
+ const iconPath = getFileIconPath(file, isDirOpen);
780
+ let listItemRef;
781
+ const baseItemStyle = {
782
+ 'user-select': 'none',
783
+ padding: '0.2rem 0.1rem',
784
+ 'border-radius': theme.borderRadius,
785
+ transition: 'background-color 0.2s',
786
+ 'margin-bottom': '2px',
787
+ };
788
+
789
+ return (
790
+ <li
791
+ ref={listItemRef}
792
+ style={baseItemStyle}
793
+ onMouseEnter={() => { if (listItemRef) listItemRef.style.backgroundColor = theme.itemHoverBg; }}
794
+ onMouseLeave={() => { if (listItemRef) listItemRef.style.backgroundColor = 'transparent'; }}
795
+ title={fullPath}
796
+ >
797
+ <div style={{ display: 'flex', 'align-items': 'center', 'justify-content': 'space-between' }}>
798
+ <div
799
+ onClick={() => handleFileClick(file, fullPath)}
800
+ style={{ flexGrow: 1, display: 'flex', 'align-items': 'center', cursor: 'pointer', padding: '0.3rem 0.2rem' }}
801
+ >
802
+ <img src={iconPath} alt={file.isDir ? 'Folder' : 'File'} style={{ width: '18px', height: '18px', 'margin-right': '0.75rem', 'flex-shrink': 0 }} />
803
+ <span style={{ color: theme.text, 'font-size': '1.05rem' }}>{file.name}</span>
804
+ </div>
805
+ <span
806
+ onClick={(e) => handleContextMenu(e, file, fullPath)}
807
+ style={{ cursor: 'pointer', 'font-weight': 'bold', padding: '0 0.5rem', color: theme.textMuted, 'font-size': '1.2rem' }}
808
+ onMouseEnter={(e) => e.target.style.color = theme.primary}
809
+ onMouseLeave={(e) => e.target.style.color = theme.textMuted}
810
+ > ⋮ </span>
811
+ </div>
812
+ <Show when={file.isDir && openFolders()[fullPath] && Array.isArray(openFolders()[fullPath]) && openFolders()[fullPath].length > 0}>
813
+ {renderFiles(openFolders()[fullPath], fullPath)}
814
+ </Show>
815
+ <Show when={file.isDir && openFolders()[fullPath] && Array.isArray(openFolders()[fullPath]) && openFolders()[fullPath].length === 0}>
816
+ <div style={{ 'margin-left': '2rem', padding: '0.3rem 0', color: theme.textMuted, 'font-style': 'italic', 'font-size': '0.9rem' }}>(empty folder)</div>
817
+ </Show>
818
+ </li>
819
+ );
820
+ }}
821
+ </For>
822
+ </ul>
823
+ );
824
+ }
825
+
826
+ function handleDownloadAll() {
827
+ const form = document.createElement('form');
828
+ form.method = 'POST';
829
+ form.action = `${linkManager}/download-zip`;
830
+ form.style.display = 'none';
831
+ document.body.appendChild(form);
832
+ form.submit();
833
+ document.body.removeChild(form);
834
+ addNotification('Downloading all files (root) as ZIP...', 'info');
835
+ }
836
+
837
+ const getCodeMirrorLanguageSupport = (filename) => {
838
+ const extension = filename?.split('.').pop()?.toLowerCase();
839
+ if (!extension) return javascript();
840
+ switch (extension) {
841
+ case 'js': case 'jsx': return javascript();
842
+ case 'ts': case 'tsx': return javascript({typescript: true, jsx: true});
843
+ case 'json': return json();
844
+ case 'html': case 'htm': case 'xml': case 'svg': return html();
845
+ case 'css': return css();
846
+ case 'md': case 'markdown': return markdown();
847
+ default: return javascript();
848
+ }
849
+ };
850
+
851
+ onMount(() => {
852
+ const patrickHandFontLink = document.createElement('link');
853
+ patrickHandFontLink.href = 'https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap';
854
+ patrickHandFontLink.rel = 'stylesheet';
855
+ document.head.appendChild(patrickHandFontLink);
856
+
857
+ const firaCodeFontLink = document.createElement('link');
858
+ firaCodeFontLink.href = 'https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap';
859
+ firaCodeFontLink.rel = 'stylesheet';
860
+ document.head.appendChild(firaCodeFontLink);
861
+
862
+ const hljsThemeLink = document.createElement('link');
863
+ hljsThemeLink.href = 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css';
864
+ hljsThemeLink.rel = 'stylesheet';
865
+ document.head.appendChild(hljsThemeLink);
866
+
867
+ const appElement = document.getElementById('app');
868
+ if (appElement) {
869
+ appElement.style.fontFamily = theme.fontFamily;
870
+ appElement.style.minHeight = '100vh';
871
+ }
872
+
873
+ fetchUserInfo();
874
+
875
+ const handleClickOutside = (e) => {
876
+ const contextMenuElement = document.getElementById('context-menu');
877
+ const createItemModalOverlayElement = document.querySelector('.create-item-modal-overlay');
878
+ const renameModalOverlayElement = document.querySelector('.rename-modal-overlay');
879
+
880
+ if (contextMenu().visible && contextMenuElement && !contextMenuElement.contains(e.target)) {
881
+ setContextMenu({ visible: false, x: 0, y: 0, file: null });
882
+ }
883
+ if (createItemModalInfo().visible && createItemModalOverlayElement && e.target === createItemModalOverlayElement) {
884
+ cancelCreateItem();
885
+ }
886
+ if (renameContainerInfo().visible && renameModalOverlayElement && e.target === renameModalOverlayElement) {
887
+ cancelRename();
888
+ }
889
+ };
890
+ document.addEventListener('click', handleClickOutside);
891
+
892
+ const checkMobile = () => setIsMobileView(window.innerWidth < 768);
893
+ checkMobile();
894
+ window.addEventListener('resize', checkMobile);
895
+
896
+ onCleanup(() => {
897
+ window.removeEventListener('resize', checkMobile);
898
+ document.removeEventListener('click', handleClickOutside);
899
+ if (editorViewInstance) {
900
+ editorViewInstance.destroy();
901
+ editorViewInstance = null;
902
+ }
903
+ });
904
+ });
905
+
906
+ createEffect(() => {
907
+ const currentFile = selectedFile();
908
+ const editing = isEditingFile();
909
+ const content = fileContent();
910
+
911
+ if (editorRef && editing && currentFile) {
912
+ const cmLanguageSupport = getCodeMirrorLanguageSupport(currentFile);
913
+ if (editorViewInstance) {
914
+ if (editorViewInstance.state.doc.toString() !== content) {
915
+ editorViewInstance.dispatch({
916
+ changes: { from: 0, to: editorViewInstance.state.doc.length, insert: content || '' }
917
+ });
918
+ }
919
+ editorViewInstance.dispatch({
920
+ effects: [
921
+ languageCompartment.reconfigure(cmLanguageSupport),
922
+ editableCompartment.reconfigure(EditorView.editable.of(true)),
923
+ ]
924
+ });
925
+ } else {
926
+ const state = EditorState.create({
927
+ doc: content || '',
928
+ extensions: [
929
+ EditorView.lineWrapping,
930
+ history(),
931
+ keymap.of([...defaultKeymap, ...historyKeymap, ...foldKeymap]),
932
+ lineNumbers(),
933
+ foldGutter(),
934
+ lintGutter(),
935
+ editableCompartment.of(EditorView.editable.of(true)),
936
+ languageCompartment.of(cmLanguageSupport),
937
+ themeCompartment.of(oneDark),
938
+ syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
939
+ EditorView.theme({
940
+ '&': { fontSize: '12px' },
941
+ '.cm-content': { fontFamily: theme.monospaceFontFamily },
942
+ '.cm-gutters': { fontSize: '13px', backgroundColor: '#282c34' },
943
+ '.cm-lineNumbers .cm-gutterElement': { padding: '0 3px 0 5px', minWidth: '20px', textAlign: 'right' }
944
+ }),
945
+ EditorView.updateListener.of(update => {
946
+ if (update.docChanged) {
947
+ if (update.transactions.some(tr => tr.isUserEvent('input') || tr.isUserEvent('delete'))) {
948
+ setFileContent(update.state.doc.toString());
949
+ }
950
+ }
951
+ })
952
+ ]
953
+ });
954
+ editorViewInstance = new EditorView({ state, parent: editorRef });
955
+ }
956
+ } else if (editorViewInstance) {
957
+ editorViewInstance.destroy();
958
+ editorViewInstance = null;
959
+ }
960
+ });
961
+
962
+ let hasFocusedRenameInput = false;
963
+ createEffect(() => {
964
+ if (renameContainerInfo().visible && renameInputRef && !hasFocusedRenameInput) {
965
+ setTimeout(() => {
966
+ if (renameInputRef) {
967
+ renameInputRef.focus();
968
+ renameInputRef.select();
969
+ }
970
+ hasFocusedRenameInput = true;
971
+ }, 50);
972
+ } else if (!renameContainerInfo().visible) {
973
+ hasFocusedRenameInput = false;
974
+ }
975
+ });
976
+
977
+ let hasFocusedCreateItemInput = false;
978
+ createEffect(() => {
979
+ if (createItemModalInfo().visible && createItemInputRef && !hasFocusedCreateItemInput) {
980
+ setTimeout(() => {
981
+ if (createItemInputRef) {
982
+ createItemInputRef.focus();
983
+ }
984
+ hasFocusedCreateItemInput = true;
985
+ }, 50);
986
+ } else if (!createItemModalInfo().visible) {
987
+ hasFocusedCreateItemInput = false;
988
+ }
989
+ });
990
+
991
+ const theme = {
992
+ bg: '#0F172A',
993
+ panelBg: '#1E293B',
994
+ border: '#334155',
995
+ text: '#E2E8F0',
996
+ textMuted: '#94A3B8',
997
+ primary: '#38BDF8',
998
+ primaryHover: '#0EA5E9',
999
+ primaryText: '#0F172A',
1000
+ secondary: '#FACC15',
1001
+ secondaryHover: '#EAB308',
1002
+ secondaryText: '#1E293B',
1003
+ destructive: '#F43F5E',
1004
+ destructiveHover: '#E11D48',
1005
+ destructiveText: '#E2E8F0',
1006
+ inputBg: '#0A0F1A',
1007
+ inputBorder: '#334155',
1008
+ inputFocusBorder: '#38BDF8',
1009
+ fontFamily: "'Patrick Hand', cursive",
1010
+ monospaceFontFamily: "'Fira Code', 'Source Code Pro', monospace",
1011
+ borderRadius: '6px',
1012
+ itemHoverBg: 'rgba(51, 65, 85, 0.7)',
1013
+ shadow: '0 6px 16px rgba(0, 0, 0, 0.4)',
1014
+ itemSelectedBg: '#38BDF8',
1015
+ notificationSuccess: '#10B981',
1016
+ notificationError: '#F43F5E',
1017
+ notificationInfo: '#38BDF8',
1018
+ };
1019
+
1020
+ const NotificationContainer = () => {
1021
+ const baseStyle = {
1022
+ padding: '1rem 1.5rem',
1023
+ 'margin-bottom': '0.75rem',
1024
+ 'border-radius': theme.borderRadius,
1025
+ color: 'white',
1026
+ 'font-size': '1.05rem',
1027
+ 'box-shadow': '0 4px 10px rgba(0,0,0,0.3)',
1028
+ 'font-family': theme.fontFamily,
1029
+ 'letter-spacing': '0.5px',
1030
+ transition: 'transform 0.3s ease-out, opacity 0.3s ease-out',
1031
+ transform: 'translateX(0)',
1032
+ opacity: 1,
1033
+ };
1034
+
1035
+ const typeStyles = {
1036
+ success: { 'background-color': theme.notificationSuccess },
1037
+ error: { 'background-color': theme.notificationError },
1038
+ info: { 'background-color': theme.notificationInfo, color: theme.primaryText },
1039
+ };
1040
+
1041
+ return (
1042
+ <div style={{ position: 'fixed', top: '20px', right: '20px', 'z-index': '2000', width: '350px', 'max-width': '90%' }}>
1043
+ <For each={notifications()}>
1044
+ {notification => (
1045
+ <div style={{ ...baseStyle, ...typeStyles[notification.type] }}>
1046
+ {notification.message}
1047
+ </div>
1048
+ )}
1049
+ </For>
1050
+ </div>
1051
+ );
1052
+ };
1053
+
1054
+ const baseButtonStyle = {
1055
+ padding: '0.6rem 1.2rem',
1056
+ 'font-size': '1.1rem',
1057
+ border: 'none',
1058
+ 'border-radius': theme.borderRadius,
1059
+ cursor: 'pointer',
1060
+ 'font-family': theme.fontFamily,
1061
+ 'letter-spacing': '0.5px',
1062
+ transition: 'background-color 0.2s, transform 0.1s',
1063
+ 'margin-right': '0.5rem',
1064
+ 'line-height': '1.4',
1065
+ };
1066
+
1067
+ const createButtonStyler = (baseColor, hoverColor, textColor) => {
1068
+ let btnRef;
1069
+ return {
1070
+ ref: el => btnRef = el,
1071
+ style: { ...baseButtonStyle, background: baseColor, color: textColor },
1072
+ onMouseEnter: () => btnRef && (btnRef.style.backgroundColor = hoverColor),
1073
+ onMouseLeave: () => btnRef && (btnRef.style.backgroundColor = baseColor),
1074
+ };
1075
+ };
1076
+
1077
+ const primaryButtonProps = (text, onClick) => {
1078
+ const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.primary, theme.primaryHover, theme.primaryText);
1079
+ return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>{text}</button>;
1080
+ };
1081
+
1082
+ const secondaryButtonProps = (text, onClick) => {
1083
+ const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.secondary, theme.secondaryHover, theme.secondaryText);
1084
+ return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>{text}</button>;
1085
+ };
1086
+
1087
+ const destructiveButtonProps = (text, onClick) => {
1088
+ const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.destructive, theme.destructiveHover, theme.destructiveText);
1089
+ return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>{text}</button>;
1090
+ };
1091
+
1092
+ const defaultButtonProps = (text, onClick, additionalStyles = {}) => {
1093
+ const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.panelBg, theme.border, theme.textMuted);
1094
+ return <button ref={ref} style={{...style, border: `1px solid ${theme.border}`, ...additionalStyles}} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>{text}</button>;
1095
+ };
1096
+
1097
+ const iconButtonStyler = (baseColor, hoverColor, textColor) => {
1098
+ let btnRef;
1099
+ const iconBaseStyle = { ...baseButtonStyle, padding: '0.5rem 0.7rem', 'font-size': '1.5rem', 'line-height': '1', 'margin-right': '0' };
1100
+ return {
1101
+ ref: el => btnRef = el,
1102
+ style: { ...iconBaseStyle, background: baseColor, color: textColor, border: `1px solid ${theme.border}`},
1103
+ onMouseEnter: () => btnRef && (btnRef.style.backgroundColor = hoverColor),
1104
+ onMouseLeave: () => btnRef && (btnRef.style.backgroundColor = baseColor),
1105
+ };
1106
+ };
1107
+
1108
+ const inputStyle = {
1109
+ padding: '0.7rem 0.9rem',
1110
+ 'font-size': '1.05rem',
1111
+ border: `1px solid ${theme.inputBorder}`,
1112
+ 'border-radius': theme.borderRadius,
1113
+ flex: '1',
1114
+ 'margin-right': '0.5rem',
1115
+ 'font-family': theme.fontFamily,
1116
+ 'background-color': theme.inputBg,
1117
+ color: theme.text,
1118
+ outline: 'none',
1119
+ transition: 'border-color 0.2s, box-shadow 0.2s',
1120
+ 'letter-spacing': '0.5px',
1121
+ };
1122
+
1123
+ const modalInputStyle = {
1124
+ ...inputStyle,
1125
+ width: 'calc(100% - 22px)',
1126
+ 'margin-bottom': '20px',
1127
+ 'margin-right': '0',
1128
+ 'font-size': '1.1rem',
1129
+ };
1130
+
1131
+ const codeViewerBaseStyle = {
1132
+ width: '100%',
1133
+ fontFamily: theme.monospaceFontFamily,
1134
+ border: `1px solid ${theme.border}`,
1135
+ padding: '15px',
1136
+ boxSizing: 'border-box',
1137
+ flex: '1',
1138
+ marginBottom: '15px',
1139
+ minHeight: isMobileView() ? '250px' : '350px',
1140
+ resize: 'vertical',
1141
+ overflow: 'auto',
1142
+ backgroundColor: '#282c34',
1143
+ color: theme.text,
1144
+ borderRadius: theme.borderRadius,
1145
+ fontSize: '12px',
1146
+ };
1147
+
1148
+ const codeMirrorEditorStyle = {
1149
+ ...codeViewerBaseStyle,
1150
+ padding: '0px',
1151
+ };
1152
+
1153
+ return (
1154
+ <div style={{ 'font-size': '1.1rem', background: theme.bg, color: theme.text, 'min-height': '100vh', padding: '25px', 'box-sizing': 'border-box' }}>
1155
+ <NotificationContainer />
1156
+ <h2 style={{ color: theme.primary, 'font-size': '2.8rem', 'margin-bottom': '25px', 'text-align': 'center', 'letter-spacing': '1px' }}>
1157
+ 📁 ExoCore Explorer 📂
1158
+ </h2>
1159
+
1160
+ <Show when={status()}>
1161
+ <div class="status-box" style={{ 'background-color': theme.panelBg, border: `1px solid ${theme.border}`, color: theme.text, padding: '12px 18px', 'margin-bottom': '1.5rem', 'border-radius': theme.borderRadius, display: 'flex', 'align-items': 'center', 'justify-content': 'space-between', 'box-shadow': '0 2px 5px rgba(0,0,0,0.2)', 'font-size': '1.05rem' }}>
1162
+ {status()}
1163
+ {defaultButtonProps('Clear', () => setStatus(''), { padding: '0.2rem 0.5rem', 'margin-left': '10px', 'font-size': '0.9rem' })}
1164
+ </div>
1165
+ </Show>
1166
+
1167
+ <Show when={loading() && !(isMobileView() && selectedFile())}>
1168
+ <div style={{ 'margin-top': '1.5rem', color: theme.textMuted, 'font-size': '1.2rem', 'text-align': 'center' }}>Loading... ⏳ Please wait...</div>
1169
+ </Show>
1170
+
1171
+ <div class="main-content-flex" style={{ display: 'flex', 'margin-top': '1.5rem', gap: '25px', 'flex-wrap': (isMobileView() && selectedFile()) ? 'wrap' : 'nowrap' }}>
1172
+ <div class="file-list-panel" style={{ ...(isMobileView() && selectedFile() ? {display: 'none'} : {flex: '1'}), border: `1px solid ${theme.border}`, padding: '20px', background: theme.panelBg, 'min-width': '320px', color: theme.text, 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow }}>
1173
+ <h4 style={{ color: theme.primary, 'font-size': '1.5rem', 'margin-top': '0', 'margin-bottom': '1rem', 'border-bottom': `1px solid ${theme.border}`, 'padding-bottom': '0.5rem' }}>Controls</h4>
1174
+ <div style={{ 'margin-bottom': '0.8rem', display: 'flex', 'align-items': 'center', gap: '0.5rem' }}>
1175
+ <input style={inputStyle} placeholder="New file name..." value={newFileName()} onInput={e => setNewFileName(e.target.value)} onKeyPress={e => e.key === 'Enter' && createFile()} onFocus={e => e.target.style.borderColor = theme.inputFocusBorder} onBlur={e => e.target.style.borderColor = theme.inputBorder} />
1176
+ {(() => {
1177
+ const { ref, style, onMouseEnter, onMouseLeave } = iconButtonStyler(theme.panelBg, theme.border, theme.primary);
1178
+ return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={createFile} title="Create File">📄</button>;
1179
+ })()}
1180
+ </div>
1181
+ <div style={{ 'margin-bottom': '0.8rem', display: 'flex', 'align-items': 'center', gap: '0.5rem' }}>
1182
+ <input style={inputStyle} placeholder="New folder name..." value={newFolderName()} onInput={e => setNewFolderName(e.target.value)} onKeyPress={e => e.key === 'Enter' && createFolder()} onFocus={e => e.target.style.borderColor = theme.inputFocusBorder} onBlur={e => e.target.style.borderColor = theme.inputBorder} />
1183
+ {(() => {
1184
+ const { ref, style, onMouseEnter, onMouseLeave } = iconButtonStyler(theme.panelBg, theme.border, theme.primary);
1185
+ return <button ref={ref} style={style} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={createFolder} title="Create Folder">📁</button>;
1186
+ })()}
1187
+ </div>
1188
+ <div style={{ 'margin-bottom': '1.5rem' }}>
1189
+ {(() => {
1190
+ const { ref, style, onMouseEnter, onMouseLeave } = createButtonStyler(theme.primary, theme.primaryHover, theme.primaryText);
1191
+ return <label for="fileUpload" ref={ref} style={{...style, display: 'inline-block', width: '100%', 'box-sizing': 'border-box', 'text-align': 'center', 'margin-right': 0}} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>📤 Upload File</label>;
1192
+ })()}
1193
+ <input id="fileUpload" type="file" onChange={uploadFile} style={{display: 'none'}} />
1194
+ </div>
1195
+
1196
+ <h4 style={{ color: theme.primary, 'font-size': '1.5rem', 'margin-bottom': '1rem', 'border-bottom': `1px solid ${theme.border}`, 'padding-bottom': '0.5rem' }}>File System</h4>
1197
+ <div style={{ 'max-height': '450px', 'overflow-y': 'auto', border: `1px solid ${theme.border}`, padding: '10px', 'border-radius': theme.borderRadius, background: theme.inputBg }}>
1198
+ {renderFiles(files())}
1199
+ </div>
1200
+ <div style={{'margin-top': '1.5rem'}}>
1201
+ {secondaryButtonProps('Download All (Root) as ZIP 📦', handleDownloadAll)}
1202
+ </div>
1203
+ </div>
1204
+
1205
+ <div class="file-editor-panel" style={ isMobileView() && selectedFile() ? { position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(15, 23, 42, 0.9)', display: 'flex', 'align-items': 'center', 'justify-content': 'center', 'z-index': '1001', padding: '15px', 'box-sizing': 'border-box' } : { flex: '3.5', 'min-width': '0', display: selectedFile() ? 'flex' : 'block', 'flex-direction': 'column' } }>
1206
+ <Show when={selectedFile()} fallback={ !isMobileView() || (isMobileView() && !selectedFile()) ? <div style={{ border: `2px dashed ${theme.border}`, padding: '30px', 'text-align': 'center', background: theme.panelBg, color: theme.textMuted, height: '100%', display: 'flex', 'align-items': 'center', 'justify-content': 'center', 'border-radius': theme.borderRadius, 'font-size': '1.3rem', 'box-shadow': theme.shadow }}>Select a file to embark on an editing adventure! 🚀</div> : null }>
1207
+ <div style={ isMobileView() ? { background: theme.panelBg, padding: '20px', 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow, width: '100%', height: 'auto', 'max-height': 'calc(100vh - 40px)', display: 'flex', 'flex-direction': 'column', 'overflow-y': 'auto', color: theme.text, border: `1px solid ${theme.border}` } : { border: `1px solid ${theme.border}`, padding: '20px', background: theme.panelBg, height: '100%', display: 'flex', 'flex-direction': 'column', color: theme.text, 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow } }>
1208
+ <h3 style={{ 'margin-top': '0', color: theme.primary, 'font-size': '1.6rem', 'margin-bottom': '1rem', 'word-break': 'break-all' }}>
1209
+ Now Editing: {selectedFile()}
1210
+ </h3>
1211
+ <div ref={el => editorRef = el} style={codeMirrorEditorStyle}></div>
1212
+ <div style={{ 'text-align': 'right', 'margin-top': '10px', display: 'flex', 'justify-content': 'flex-end', gap: '0.5rem' }}>
1213
+ {primaryButtonProps('💾 Save', saveFile)}
1214
+ {destructiveButtonProps('❌ Close', closeFileEditor)}
1215
+ </div>
1216
+ </div>
1217
+ </Show>
1218
+ </div>
1219
+ </div>
1220
+
1221
+ <Show when={contextMenu().visible}>
1222
+ <div id="context-menu" style={{ position: 'fixed', top: `${contextMenu().y}px`, left: `${contextMenu().x}px`, background: theme.panelBg, border: `1px solid ${theme.border}`, padding: '0.4rem', 'z-index': '1000', 'box-shadow': '0 5px 15px rgba(0,0,0,0.5)', 'min-width': '170px', 'text-align': 'left', color: theme.text, 'border-radius': theme.borderRadius, transform: contextMenu().x > (window.innerWidth - 200) ? 'translateX(-100%)' : 'none' }}>
1223
+ {[
1224
+ { label: '✏️ Rename', action: handleRenameClick, show: () => true },
1225
+ { label: '📂 Open', action: handleOpenFolderFromContextMenu, show: () => contextMenu().file?.isDir },
1226
+ { label: '➕📄 Add New File', action: () => handleShowCreateItemModal(false), show: () => contextMenu().file?.isDir || !contextMenu().file },
1227
+ { label: '➕📁 Add New Folder', action: () => handleShowCreateItemModal(true), show: () => contextMenu().file?.isDir || !contextMenu().file },
1228
+ { label: '⬇️ Download', action: handleDownloadSelected, show: () => contextMenu().file && !contextMenu().file.isDir },
1229
+ {
1230
+ label: '🌀 Unzip Here',
1231
+ action: handleUnzipSelected,
1232
+ show: () => {
1233
+ const file = contextMenu().file;
1234
+ return file && !file.isDir && file.name.toLowerCase().endsWith('.zip');
1235
+ }
1236
+ },
1237
+ { label: '🗑️ Delete', action: handleDeleteSelected, show: () => contextMenu().file, color: theme.destructive },
1238
+ ].map(item => (
1239
+ <Show when={item.show()}>
1240
+ <div
1241
+ style={{ cursor: 'pointer', padding: '0.5rem 0.7rem', 'white-space': 'nowrap', color: item.color || theme.text, 'border-radius': '4px', transition: 'background-color 0.15s', 'font-size': '0.9rem' }}
1242
+ onClick={item.action}
1243
+ onMouseEnter={e => e.target.style.backgroundColor = theme.itemHoverBg}
1244
+ onMouseLeave={e => e.target.style.backgroundColor = 'transparent'}
1245
+ >
1246
+ {item.label}
1247
+ </div>
1248
+ </Show>
1249
+ ))}
1250
+ <Show when={contextMenu().file}>
1251
+ <div style={{ 'font-size': '0.8em', color: theme.textMuted, 'margin-top': '6px', 'border-top': `1px solid ${theme.border}`, 'padding-top': '6px' }}>
1252
+ {contextMenu().file.name} ({contextMenu().file.isDir ? 'Folder' : 'File'})
1253
+ </div>
1254
+ </Show>
1255
+ </div>
1256
+ </Show>
1257
+
1258
+ <Show when={renameContainerInfo().visible}>
1259
+ <div class="rename-modal-overlay" style={{ position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(15, 23, 42, 0.85)', display: 'flex', 'justify-content': 'center', 'align-items': 'center', 'z-index': '1002' }}>
1260
+ <div class="rename-modal-content" style={{ background: theme.panelBg, padding: '25px', 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow, 'text-align': 'center', 'min-width': '320px', 'max-width': '90%', 'box-sizing': 'border-box', position: 'relative', color: theme.text, border: `1px solid ${theme.border}` }} onClick={e => e.stopPropagation()}>
1261
+ <h3 style={{ color: theme.primary, 'margin-top': 0, 'margin-bottom': '20px', 'font-size': '1.5rem' }}>Rename "{renameContainerInfo().file?.name}"</h3>
1262
+ <input ref={el => renameInputRef = el} style={modalInputStyle} value={renameContainerInfo().newName} onInput={e => setRenameContainerInfo(prev => ({ ...prev, newName: e.target.value }))} onKeyPress={e => e.key === 'Enter' && performRename()} onFocus={e => e.target.style.borderColor = theme.inputFocusBorder} onBlur={e => e.target.style.borderColor = theme.inputBorder} />
1263
+ <div style={{ display: 'flex', 'justify-content': 'center', gap: '10px', 'margin-top': '10px' }}>
1264
+ {primaryButtonProps('✔️ Confirm', performRename)}
1265
+ {destructiveButtonProps('✖️ Cancel', cancelRename)}
1266
+ </div>
1267
+ </div>
1268
+ </div>
1269
+ </Show>
1270
+
1271
+ <Show when={createItemModalInfo().visible}>
1272
+ <div class="create-item-modal-overlay" style={{ position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', background: 'rgba(15, 23, 42, 0.85)', display: 'flex', 'justify-content': 'center', 'align-items': 'center', 'z-index': '1002' }}>
1273
+ <div class="create-item-modal-content" style={{ background: theme.panelBg, padding: '25px', 'border-radius': theme.borderRadius, 'box-shadow': theme.shadow, 'text-align': 'center', 'min-width': '360px', 'max-width': '90%', 'box-sizing': 'border-box', position: 'relative', color: theme.text, border: `1px solid ${theme.border}` }} onClick={e => e.stopPropagation()}>
1274
+ <h3 style={{ color: theme.primary, 'margin-top': 0, 'margin-bottom': '20px', 'font-size': '1.4rem' }}> Create New {createItemModalInfo().isDir ? 'Folder' : 'File'} in "{createItemModalInfo().parentPath || 'root'}" </h3>
1275
+ <input ref={el => createItemInputRef = el} style={modalInputStyle} placeholder={createItemModalInfo().isDir ? 'New folder name...' : 'New file name (e.g., script.js)'} value={createItemModalInfo().itemName} onInput={e => setCreateItemModalInfo(prev => ({ ...prev, itemName: e.target.value }))} onKeyPress={e => e.key === 'Enter' && performCreateItem()} onFocus={e => e.target.style.borderColor = theme.inputFocusBorder} onBlur={e => e.target.style.borderColor = theme.inputBorder} />
1276
+ <div style={{ display: 'flex', 'justify-content': 'center', gap: '10px', 'margin-top': '10px' }}>
1277
+ {primaryButtonProps('✔️ Create', performCreateItem)}
1278
+ {destructiveButtonProps('✖️ Cancel', cancelCreateItem)}
1279
+ </div>
1280
+ </div>
1281
+ </div>
1282
+ </Show>
1283
+
1284
+ </div>
1285
+ );
1286
+ }
1287
+
1288
+ render(() => <App />, document.getElementById('app'));
exocore-web/public/console.jsx ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, Show, For } from 'solid-js';
3
+
4
+ const FullscreenIcon = () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" /></svg>;
5
+ const ExitFullscreenIcon = () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" /></svg>;
6
+ const StartIcon = () => <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><path d="M8 5v14l11-7z"></path></svg>;
7
+ const RestartIcon = () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path></svg>;
8
+ const StopIcon = () => <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1"><rect x="6" y="6" width="12" height="12"></rect></svg>;
9
+
10
+ function App() {
11
+ const [loading, setLoading] = createSignal(true);
12
+ const [initialLoadComplete, setInitialLoadComplete] = createSignal(false);
13
+ const [status, setStatus] = createSignal('');
14
+ const [userData, setUserData] = createSignal(null);
15
+ const [logs, setLogs] = createSignal([]);
16
+ const [wsStatus, setWsStatus] = createSignal('Disconnected');
17
+ const [isFullScreen, setIsFullScreen] = createSignal(false);
18
+ const [siteLinkVisible, setSiteLinkVisible] = createSignal(false);
19
+ const [isAwaitingInput, setIsAwaitingInput] = createSignal(false);
20
+ const [inputValue, setInputValue] = createSignal('');
21
+
22
+ let ws, inputRef, consoleContainerRef, ansiUpInstance;
23
+ let logIdCounter = 0;
24
+
25
+ const getToken = () => localStorage.getItem('exocore-token') || '';
26
+ const getCookies = () => localStorage.getItem('exocore-cookies') || '';
27
+
28
+ async function fetchUserInfo() {
29
+ setLoading(true);
30
+ const token = getToken();
31
+ const cookies = getCookies();
32
+
33
+ if (!token || !cookies) {
34
+ setLoading(false);
35
+ setInitialLoadComplete(true);
36
+ window.location.href = '/private/server/exocore/web/public/login';
37
+ return;
38
+ }
39
+
40
+ try {
41
+ const res = await fetch('/private/server/exocore/web/userinfo', {
42
+ method: 'POST',
43
+ headers: { 'Content-Type': 'application/json' },
44
+ body: JSON.stringify({ token, cookies }),
45
+ });
46
+
47
+ if (!res.ok) {
48
+ let errorMsg = `Server error: ${res.status}`;
49
+ try {
50
+ const errorData = await res.json();
51
+ errorMsg = errorData.message || errorMsg;
52
+ } catch (parseError) {}
53
+ throw new Error(errorMsg);
54
+ }
55
+
56
+ const data = await res.json();
57
+
58
+ if (data.data?.user && data.data.user.verified === 'success') {
59
+ setUserData(data.data.user);
60
+ setStatus('');
61
+ } else {
62
+ setUserData(null);
63
+ setStatus(data.message || 'User verification failed. Redirecting...');
64
+ localStorage.removeItem('exocore-token');
65
+ localStorage.removeItem('exocore-cookies');
66
+ setTimeout(() => {
67
+ window.location.href = '/private/server/exocore/web/public/login';
68
+ }, 2500);
69
+ }
70
+ } catch (err) {
71
+ setUserData(null);
72
+ setStatus('Failed to fetch user info: ' + err.message + '. Redirecting...');
73
+ localStorage.removeItem('exocore-token');
74
+ localStorage.removeItem('exocore-cookies');
75
+ setTimeout(() => {
76
+ window.location.href = '/private/server/exocore/web/public/login';
77
+ }, 2500);
78
+ } finally {
79
+ setLoading(false);
80
+ setInitialLoadComplete(true);
81
+ }
82
+ }
83
+
84
+ const scrollToBottom = () => {
85
+ if (consoleContainerRef) {
86
+ requestAnimationFrame(() => {
87
+ consoleContainerRef.scrollTop = consoleContainerRef.scrollHeight;
88
+ });
89
+ }
90
+ };
91
+
92
+ function addLog(line, isSystemMessage = false) {
93
+ let htmlContent;
94
+ if (ansiUpInstance) {
95
+ htmlContent = ansiUpInstance.ansi_to_html(line);
96
+ } else {
97
+ const escapeHtml = (unsafe) => unsafe.replace(/[&<"']/g, (match) => ({ '&': '&amp;', '<': '&lt;', '"': '&quot;', "'": '&#039;' })[match] || match);
98
+ htmlContent = isSystemMessage ? `<span style="color: var(--system-message-color);">${escapeHtml(line)}</span>` : escapeHtml(line);
99
+ }
100
+
101
+ if (typeof line === 'string' && line.includes(window.origin)) {
102
+ setSiteLinkVisible(true);
103
+ }
104
+ const newLogEntry = { id: logIdCounter++, html: htmlContent, isSystem: isSystemMessage };
105
+ setLogs((prev) => [...prev, newLogEntry].slice(-250));
106
+ scrollToBottom();
107
+ }
108
+
109
+ function handleInputSubmit(e) {
110
+ if (e.key === 'Enter') {
111
+ e.preventDefault();
112
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
113
+ addLog('\x1b[31mError: WebSocket is not connected.\x1b[0m', true);
114
+ return;
115
+ }
116
+ const commandToSend = inputValue();
117
+ ws.send(JSON.stringify({ type: 'STDIN_INPUT', payload: commandToSend }));
118
+ addLog(`\x1b[38;5;39m> ${commandToSend}\x1b[0m`, true);
119
+ setIsAwaitingInput(false);
120
+ setInputValue('');
121
+ }
122
+ }
123
+
124
+ function sendCommand(endpoint) {
125
+ const commandName = endpoint.split('/').pop();
126
+ fetch(endpoint, { method: 'POST' })
127
+ .then((res) => {
128
+ if (!res.ok) {
129
+ addLog(`\x1b[31mERROR: Command '${commandName}' failed - HTTP ${res.status}\x1b[0m`, true);
130
+ } else {
131
+ addLog(`\x1b[32mSUCCESS: Command '${commandName}' sent.\x1b[0m`, true);
132
+ }
133
+ })
134
+ .catch((err) => {
135
+ addLog(`\x1b[31mERROR: Failed to send command '${commandName}': ${err.message}\x1b[0m`, true);
136
+ });
137
+ }
138
+
139
+ const handleStartCommand = () => {
140
+ setSiteLinkVisible(false);
141
+ setLogs([]);
142
+ addLog('INFO: Starting server...', true);
143
+ sendCommand('/private/server/exocore/web/start');
144
+ };
145
+ const handleRestartCommand = () => {
146
+ setSiteLinkVisible(false);
147
+ setLogs([]);
148
+ addLog('INFO: Restarting server...', true);
149
+ sendCommand('/private/server/exocore/web/restart');
150
+ };
151
+ const handleStopCommand = () => {
152
+ setSiteLinkVisible(false);
153
+ addLog('INFO: Stop command sent.', true);
154
+ sendCommand('/private/server/exocore/web/stop');
155
+ };
156
+
157
+ function toggleFullScreen() {
158
+ const el = document.querySelector('.console-wrapper');
159
+ if (!el) return;
160
+ if (!document.fullscreenElement) {
161
+ el.requestFullscreen().catch((err) => addLog('Error entering fullscreen: ' + err.message, true));
162
+ } else {
163
+ document.exitFullscreen();
164
+ }
165
+ }
166
+
167
+ onMount(() => {
168
+ const fontLink = document.createElement('link');
169
+ fontLink.href = 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&family=Fira+Code:wght@400;500&display=swap';
170
+ fontLink.rel = 'stylesheet';
171
+ document.head.appendChild(fontLink);
172
+
173
+ const ansiScript = document.createElement('script');
174
+ ansiScript.src = 'https://cdn.jsdelivr.net/npm/[email protected]/ansi_up.min.js';
175
+ ansiScript.onload = () => {
176
+ if (typeof AnsiUp !== 'undefined') {
177
+ ansiUpInstance = new AnsiUp();
178
+ ansiUpInstance.use_classes = false;
179
+ addLog('\x1b[32mINFO: ANSI color processing enabled.\x1b[0m', true);
180
+ }
181
+ };
182
+ document.head.appendChild(ansiScript);
183
+
184
+ fetchUserInfo();
185
+
186
+ const wsUrl = (window.location.protocol === 'https:' ? 'wss' : 'ws') + '://' + window.location.host + '/private/server/exocore/web/console';
187
+
188
+ function connectWebSocket() {
189
+ ws = new WebSocket(wsUrl);
190
+ ws.onopen = () => setWsStatus('Connected');
191
+ ws.onclose = () => {
192
+ setWsStatus('Disconnected');
193
+ setTimeout(connectWebSocket, 2000);
194
+ };
195
+ ws.onerror = () => setWsStatus('Error');
196
+ ws.onmessage = (e) => {
197
+ try {
198
+ const message = JSON.parse(e.data);
199
+ if (message?.type === 'INPUT_REQUIRED') {
200
+ addLog(message.payload || 'Input required:');
201
+ setIsAwaitingInput(true);
202
+ setTimeout(() => inputRef?.focus(), 50);
203
+ scrollToBottom();
204
+ }
205
+ } catch (error) {
206
+ if (typeof e.data === 'string') {
207
+ addLog(e.data.trim());
208
+ } else {
209
+ addLog(e.data);
210
+ }
211
+ }
212
+ };
213
+ }
214
+ connectWebSocket();
215
+
216
+ document.addEventListener('fullscreenchange', () => setIsFullScreen(!!document.fullscreenElement));
217
+ });
218
+
219
+ return (
220
+ <div class="main-wrapper">
221
+ <style>{`
222
+ :root {
223
+ --bg-primary: #111217; --bg-secondary: #1a1b23; --bg-tertiary: #0D0E12;
224
+ --text-primary: #e0e0e0; --text-secondary: #8a8f98;
225
+ --border-color: rgba(255, 255, 255, 0.1); --shadow-color: rgba(0, 0, 0, 0.5);
226
+ --font-body: 'Roboto', sans-serif; --font-console: 'Fira Code', monospace;
227
+ --radius-main: 16px; --radius-inner: 10px;
228
+ --btn-start-bg: #28a745; --btn-start-hover: #218838;
229
+ --btn-restart-bg: #007bff; --btn-restart-hover: #0069d9;
230
+ --btn-stop-bg: #dc3545; --btn-stop-hover: #c82333;
231
+ --success-color: #2ecc71; --warning-color: #f39c12; --error-color: #e74c3c;
232
+ --system-message-color: #3498db;
233
+ }
234
+ body { background-color: var(--bg-primary); color: var(--text-primary); font-family: var(--font-body); margin: 0; }
235
+ .main-wrapper { display: flex; justify-content: center; align-items: center; padding: 4vh 2vw; min-height: 100vh; }
236
+ .app-container { background: var(--bg-secondary); padding: 2rem; width: 100%; max-width: 800px; border-radius: var(--radius-main); border: 1px solid var(--border-color); box-shadow: 0 15px 40px var(--shadow-color); display: flex; flex-direction: column; gap: 1.5rem; }
237
+ .greeting-header { text-align: center; }
238
+ .greeting { font-size: 2.25rem; font-weight: 700; color: #fff; letter-spacing: -1px; }
239
+ .user-welcome { font-size: 1rem; color: var(--text-secondary); margin-top: 0.25rem; }
240
+ .console-wrapper { border-radius: var(--radius-inner); background: var(--bg-tertiary); box-shadow: inset 0 4px 15px rgba(0,0,0,0.4); overflow: hidden; display: flex; flex-direction: column; height: 450px; border: 1px solid var(--border-color); position: relative; }
241
+ .console-wrapper:fullscreen { width: 100vw; height: 100vh; border-radius: 0; border: none; }
242
+ .console-header { background: var(--bg-secondary); padding: 0.6rem 1rem; display: flex; align-items: center; border-bottom: 1px solid var(--border-color); position: relative; }
243
+ .console-header-dots { display: flex; gap: 8px; }
244
+ .console-header-dots span { width: 12px; height: 12px; border-radius: 50%; }
245
+ .console-header-dots .red-dot { background-color: #ff5f57; }
246
+ .console-header-dots .yellow-dot { background-color: #ffbd2e; }
247
+ .console-header-dots .green-dot { background-color: #28c940; }
248
+ .fullscreen-btn { position: absolute; top: 50%; right: 1rem; transform: translateY(-50%); background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px; border-radius: 4px; display: flex; }
249
+ .fullscreen-btn:hover { color: var(--text-primary); background-color: rgba(255,255,255,0.1); }
250
+ .console-container { flex-grow: 1; color: var(--text-primary); font-family: var(--font-console); font-size: 14px; line-height: 1.6; padding: 1rem; overflow-y: auto; white-space: pre-wrap; word-break: break-all; }
251
+ .input-prompt-line { display: flex; }
252
+ .input-prompt-line span:first-child { color: var(--accent-primary); margin-right: 0.5ch; }
253
+ .input-prompt-line input { flex-grow: 1; background: transparent; border: none; color: var(--text-primary); font-family: var(--font-console); font-size: 14px; outline: none; padding: 0; }
254
+ .controls { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center; }
255
+ .btn { display: flex; align-items: center; gap: 0.6rem; padding: 0.7rem 1.5rem; font-size: 0.95rem; color: #fff; border: none; border-radius: var(--radius-inner); cursor: pointer; transition: all 0.2s ease; font-weight: 500; }
256
+ .btn:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,0.3); }
257
+ .btn:active { transform: translateY(0); box-shadow: none; }
258
+ .btn.start-btn { background-color: var(--btn-start-bg); }
259
+ .btn.start-btn:hover { background-color: var(--btn-start-hover); }
260
+ .btn.restart-btn { background-color: var(--btn-restart-bg); }
261
+ .btn.restart-btn:hover { background-color: var(--btn-restart-hover); }
262
+ .btn.stop-btn { background-color: var(--btn-stop-bg); }
263
+ .btn.stop-btn:hover { background-color: var(--btn-stop-hover); }
264
+ `}</style>
265
+ <Show when={initialLoadComplete()} fallback={<div>Initializing...</div>}>
266
+ <Show when={userData()} fallback={<div>Redirecting to login...</div>}>
267
+ <div class="app-container">
268
+ <div class="greeting-header">
269
+ <h2 class="greeting">Exocore Console</h2>
270
+ <span class="user-welcome">Welcome, {userData()?.user || 'User'}</span>
271
+ </div>
272
+ <div class="console-wrapper">
273
+ <div class="console-header">
274
+ <div class="console-header-dots">
275
+ <span class="red-dot"></span><span class="yellow-dot"></span><span class="green-dot"></span>
276
+ </div>
277
+ <button class="fullscreen-btn" onClick={toggleFullScreen} title="Toggle Fullscreen">
278
+ <Show when={isFullScreen()} fallback={<FullscreenIcon />}>
279
+ <ExitFullscreenIcon />
280
+ </Show>
281
+ </button>
282
+ </div>
283
+ <div class="console-container" ref={consoleContainerRef} onClick={() => inputRef?.focus()}>
284
+ <For each={logs()}>{(log) => <div innerHTML={log.html}></div>}</For>
285
+ <Show when={isAwaitingInput()}>
286
+ <div class="input-prompt-line">
287
+ <span>&gt;</span>
288
+ <input ref={inputRef} type="text" value={inputValue()} onInput={(e) => setInputValue(e.currentTarget.value)} onKeyDown={handleInputSubmit} autofocus />
289
+ </div>
290
+ </Show>
291
+ </div>
292
+ </div>
293
+ <div class="controls">
294
+ <button class="btn start-btn" onClick={handleStartCommand}><StartIcon /> Start Server</button>
295
+ <button class="btn restart-btn" onClick={handleRestartCommand}><RestartIcon /> Restart Server</button>
296
+ <button class="btn stop-btn" onClick={handleStopCommand}><StopIcon /> Stop Server</button>
297
+ </div>
298
+ </div>
299
+ </Show>
300
+ </Show>
301
+ </div>
302
+ );
303
+ }
304
+
305
+ render(() => <App />, document.getElementById('app'));
exocore-web/public/dashboard.jsx ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, Show, For } from 'solid-js';
3
+
4
+ // --- Icons for new features ---
5
+ const BellIcon = () => <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>;
6
+ const MegaphoneIcon = () => <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 11.61V14a2 2 0 0 0 2 2h3l8 5V4l-8 5H5a2 2 0 0 0-2 2.39zM19.13 6.87a8.55 8.55 0 0 1 0 10.26"/></svg>;
7
+
8
+ function App() {
9
+ const [loading, setLoading] = createSignal(true);
10
+ const [status, setStatus] = createSignal('');
11
+ const [userData, setUserData] = createSignal(null);
12
+ const [globalNotifications, setGlobalNotifications] = createSignal({});
13
+ const [showUserNotifications, setShowUserNotifications] = createSignal(false);
14
+ const [showGlobalNotifications, setShowGlobalNotifications] = createSignal(false);
15
+
16
+ const getToken = () => localStorage.getItem('exocore-token') || '';
17
+ const getCookies = () => localStorage.getItem('exocore-cookies') || '';
18
+
19
+ async function fetchUserInfo() {
20
+ const token = getToken();
21
+ const cookies = getCookies();
22
+
23
+ if (!token || !cookies) {
24
+ window.location.href = '/private/server/exocore/web/public/login';
25
+ return;
26
+ }
27
+
28
+ try {
29
+ const res = await fetch('/private/server/exocore/web/userinfo', {
30
+ method: 'POST',
31
+ headers: { 'Content-Type': 'application/json' },
32
+ body: JSON.stringify({ token, cookies }),
33
+ });
34
+
35
+ const data = await res.json();
36
+
37
+ if (data.data?.user && data.data.user.verified === 'success') {
38
+ setUserData(data.data.user);
39
+ setGlobalNotifications(data.data.global?.notifications || {});
40
+ setStatus('');
41
+ } else {
42
+ window.location.href = '/private/server/exocore/web/public/login';
43
+ }
44
+ } catch (err) {
45
+ setStatus('Failed to fetch user info: ' + err.message);
46
+ } finally {
47
+ setLoading(false);
48
+ }
49
+ }
50
+
51
+ function timeAgo(dateString) {
52
+ const date = new Date(dateString);
53
+ const now = new Date();
54
+ const seconds = Math.floor((now - date) / 1000);
55
+ let interval = seconds / 86400;
56
+ if (interval > 1) return Math.floor(interval) + " days ago";
57
+ interval = seconds / 3600;
58
+ if (interval > 1) return Math.floor(interval) + " hours ago";
59
+ interval = seconds / 60;
60
+ if (interval > 1) return Math.floor(interval) + " minutes ago";
61
+ return "Just now";
62
+ }
63
+
64
+ onMount(() => {
65
+ const link = document.createElement('link');
66
+ link.href = 'https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap';
67
+ link.rel = 'stylesheet';
68
+ document.head.appendChild(link);
69
+
70
+ // Styles are now controlled by the <style> tag below
71
+ fetchUserInfo();
72
+ });
73
+
74
+ return (
75
+ <div class="page-wrapper-dark">
76
+ <style>
77
+ {`
78
+ /* --- Dark Theme Variables --- */
79
+ :root {
80
+ --bg-dark: #111217;
81
+ --card-bg-dark: #1a1b23;
82
+ --dropdown-bg-dark: #2a2c3b;
83
+ --text-primary-dark: #e0e0e0;
84
+ --text-secondary-dark: #8a8f98;
85
+ --accent-dark: #00aaff;
86
+ --border-dark: rgba(255, 255, 255, 0.1);
87
+ }
88
+
89
+ .page-wrapper-dark {
90
+ background-color: var(--bg-dark);
91
+ font-family: 'Patrick Hand', cursive;
92
+ padding: 3vh 2vw;
93
+ display: flex;
94
+ justify-content: center;
95
+ align-items: center;
96
+ min-height: 100vh;
97
+ box-sizing: border-box;
98
+ animation: fadeIn 1s ease forwards;
99
+ opacity: 0;
100
+ }
101
+ @keyframes fadeIn { to { opacity: 1; } }
102
+
103
+ .main-card-dark {
104
+ width: 100%;
105
+ max-width: 480px;
106
+ min-height: 320px;
107
+ background-color: var(--card-bg-dark);
108
+ border-radius: 16px;
109
+ border: 1px solid var(--border-dark);
110
+ box-shadow: 0 8px 24px rgba(0,0,0,0.3);
111
+ padding: 2rem;
112
+ text-align: center;
113
+ user-select: none;
114
+ color: var(--text-primary-dark);
115
+ }
116
+
117
+ .greeting-dark strong {
118
+ color: var(--accent-dark);
119
+ }
120
+
121
+ .info-text-dark {
122
+ color: var(--text-secondary-dark);
123
+ font-size: 1.2rem;
124
+ }
125
+
126
+ .info-text-dark strong {
127
+ color: var(--text-primary-dark);
128
+ font-weight: 700;
129
+ }
130
+
131
+ .status-box { font-family: inherit; margin-top: 1rem; padding: 0.75rem 1rem; border-radius: 6px; color: #f8d7da; background-color: rgba(220, 53, 69, 0.2); border: 1px solid rgba(220, 53, 69, 0.5); font-weight: 700; }
132
+
133
+ .card-header { display: flex; justify-content: flex-end; gap: 0.5rem; margin-bottom: 1rem; position: relative; }
134
+ .notification-btn { position: relative; background: none; border: none; cursor: pointer; padding: 5px; color: var(--text-secondary-dark); }
135
+ .notification-btn:hover { color: var(--text-primary-dark); }
136
+ .notification-count { position: absolute; top: 0; right: 0; background: #dc3545; color: white; border-radius: 50%; width: 16px; height: 16px; font-size: 11px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--card-bg-dark); }
137
+ .notification-dropdown { position: absolute; top: 120%; right: 0; width: 300px; background: var(--dropdown-bg-dark); border-radius: 8px; border: 1px solid var(--border-dark); box-shadow: 0 4px 12px rgba(0,0,0,0.2); z-index: 100; text-align: left; }
138
+ .notification-item { padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-dark); }
139
+ .notification-item:last-child { border-bottom: none; }
140
+ .notification-from { font-weight: 700; color: var(--text-primary-dark); }
141
+ .notification-message { margin: 0.25rem 0; color: var(--text-secondary-dark); }
142
+ .notification-date { font-size: 0.9rem; color: var(--text-secondary-dark); opacity: 0.7; }
143
+
144
+ .plans-link { display: inline-block; background-color: var(--accent-dark); color: white; padding: 10px 20px; border-radius: 8px; text-decoration: none; margin-top: 1.5rem; font-weight: 700; transition: background-color 0.2s, transform 0.2s; }
145
+ .plans-link:hover { background-color: #0088cc; transform: translateY(-2px); }
146
+ `}
147
+ </style>
148
+
149
+ <div class="main-card-dark">
150
+
151
+ <Show when={!loading()}
152
+ fallback={<p style={{ fontSize: '1.2rem', color: 'var(--text-secondary-dark)' }}>Loading user info...</p>}
153
+ >
154
+ <Show when={userData()}
155
+ fallback={<div class="status-box">{status() || 'Could not load user data.'}</div>}
156
+ >
157
+ <>
158
+ <div class="card-header">
159
+ <button class="notification-btn" title="Global Announcements" onClick={() => { setShowGlobalNotifications(p => !p); setShowUserNotifications(false); }}>
160
+ <MegaphoneIcon />
161
+ <Show when={Object.keys(globalNotifications()).length > 0}>
162
+ <span class="notification-count">{Object.keys(globalNotifications()).length}</span>
163
+ </Show>
164
+ </button>
165
+ <button class="notification-btn" title="Your Notifications" onClick={() => { setShowUserNotifications(p => !p); setShowGlobalNotifications(false); }}>
166
+ <BellIcon />
167
+ <Show when={userData().notification?.length > 0}>
168
+ <span class="notification-count">{userData().notification.length}</span>
169
+ </Show>
170
+ </button>
171
+
172
+ <Show when={showGlobalNotifications()}>
173
+ <div class="notification-dropdown">
174
+ <For each={Object.entries(globalNotifications())} fallback={<div class="notification-item">No announcements</div>}>
175
+ {([from, message]) => (
176
+ <div class="notification-item">
177
+ <p class="notification-from">From: {from}</p>
178
+ <p class="notification-message">{message}</p>
179
+ </div>
180
+ )}
181
+ </For>
182
+ </div>
183
+ </Show>
184
+
185
+ <Show when={showUserNotifications()}>
186
+ <div class="notification-dropdown">
187
+ <For each={userData().notification} fallback={<div class="notification-item">No notifications</div>}>
188
+ {(notif) => (
189
+ <div class="notification-item">
190
+ <p class="notification-from">From: {notif.from}</p>
191
+ <p class="notification-message">{notif.message}</p>
192
+ <p class="notification-date">{timeAgo(notif.date)}</p>
193
+ </div>
194
+ )}
195
+ </For>
196
+ </div>
197
+ </Show>
198
+ </div>
199
+
200
+ <p class="greeting-dark" style={{ fontSize: '2rem', marginBottom: '1.5rem' }}>
201
+ Hello, <strong>{userData().user}</strong>!
202
+ </p>
203
+ <p class="info-text-dark" style={{ marginBottom: '1rem' }}>
204
+ Level: <strong>{userData().level}</strong>
205
+ </p>
206
+ <p class="info-text-dark">
207
+ Days since joined: <strong>{userData().count_days}</strong>
208
+ </p>
209
+ <a href="/private/server/exocore/web/public/plans" class="plans-link">Manage Plan</a>
210
+
211
+ </>
212
+
213
+ </Show>
214
+ </Show>
215
+ <a href="https://www.facebook.com/share/15k6A3oWbR/" target="_blank" rel="noopener noreferrer" class="follow-link">
216
+ Follow Exocore on Facebook
217
+ </a>
218
+ </div>
219
+ </div>
220
+ );
221
+ }
222
+
223
+ render(() => <App />, document.getElementById('app'));
224
+
225
+ add
226
+ const planStylesConfig = {
227
+ "Core Access": {
228
+ textGrad1: '#D0A9F5', textGrad2: '#E8D4F7', cardGrad1: '#6A0DAD', cardGrad2: '#A74AC7',
229
+ cardBorder: '#4B0082', textColor: '#FFFFFF', iconFill: '#E8D4F7', glowColor: '#E0BBE4'
230
+ },
231
+ "Prime Core": {
232
+ textGrad1: '#FFEB3B', textGrad2: '#FFF59D', cardGrad1: '#FBC02D', cardGrad2: '#FFD700',
233
+ cardBorder: '#B98B00', textColor: '#1A1A1A', iconFill: '#424242', glowColor: '#FFFACD'
234
+ },
235
+ "Alpha Core": {
236
+ textGrad1: '#00BCD4', textGrad2: '#80DEEA', cardGrad1: '#03A9F4', cardGrad2: '#4FC3F7',
237
+ cardBorder: '#0277BD', textColor: '#FFFFFF', iconFill: '#B2EBF2', glowColor: '#80DEEA'
238
+ },
239
+ "EXO Elite": {
240
+ textGrad1: '#F44336', textGrad2: '#FF8A80', cardGrad1: '#D32F2F', cardGrad2: '#E57373',
241
+ cardBorder: '#9A0007', textColor: '#FFFFFF', iconFill: '#FFCDD2', glowColor: '#FF8A80'
242
+ },
243
+ "Hacker Core": {
244
+ textGrad1: '#4CAF50', textGrad2: '#A5D6A7', cardGrad1: '#388E3C', cardGrad2: '#66BB6A',
245
+ cardBorder: '#1B5E20', textColor: '#FFFFFF', iconFill: '#C8E6C9', glowColor: '#A5D6A7'
246
+ }
247
+ };
248
+ const defaultPlanStyle = {
249
+ textGrad1: '#B0BEC5', textGrad2: '#ECEFF1', cardGrad1: '#455A64', cardGrad2: '#607D8B',
250
+ cardBorder: '#263238', textColor: '#FFFFFF', iconFill: '#ECEFF1', glowColor: '#90A4AE'
251
+ };
exocore-web/public/devtools.js ADDED
The diff for this file is too large to render. See raw diff
 
exocore-web/public/eruda.js ADDED
@@ -0,0 +1 @@
 
 
1
+ (function(_0x57191a,_0x8b58c2){const _0x130d6b=_0x2ddc,_0x181071=_0x57191a();while(!![]){try{const _0x3ed2e2=-parseInt(_0x130d6b(0x2da,'HAN('))/0x1*(-parseInt(_0x130d6b(0x29f,'OYk)'))/0x2)+parseInt(_0x130d6b(0x357,'3cPF'))/0x3+parseInt(_0x130d6b(0x2c0,'BFeX'))/0x4*(parseInt(_0x130d6b(0x2bf,'g6r!'))/0x5)+parseInt(_0x130d6b(0x178,'IEeM'))/0x6+-parseInt(_0x130d6b(0x16d,'q)]c'))/0x7*(-parseInt(_0x130d6b(0x2a1,'(iQZ'))/0x8)+parseInt(_0x130d6b(0x259,'sry4'))/0x9+parseInt(_0x130d6b(0x25d,'RSw)'))/0xa*(-parseInt(_0x130d6b(0x2e5,'sry4'))/0xb);if(_0x3ed2e2===_0x8b58c2)break;else _0x181071['push'](_0x181071['shift']());}catch(_0x1e36c7){_0x181071['push'](_0x181071['shift']());}}}(_0x1ac5,0xbc38b));function _0x4d12(){const _0x19cfe2=_0x2ddc,_0x5031c8={'MLlUG':_0x19cfe2(0x334,'&]mB'),'SptDr':_0x19cfe2(0x1a6,'dxo&'),'aTNAh':function(_0x1b67df,_0x10904b){return _0x1b67df%_0x10904b;},'XEhtM':function(_0x6d6234,_0x423414){return _0x6d6234+_0x423414;},'WHHds':function(_0x386be4,_0x452570){return _0x386be4*_0x452570;},'txuoP':_0x19cfe2(0x2f4,'q)]c'),'PeuKY':function(_0x455235,_0x5284be){return _0x455235&_0x5284be;},'ZePvQ':function(_0x12d018,_0x4e6d45){return _0x12d018>>_0x4e6d45;},'wibgU':function(_0x42b6ae,_0x1fbad0){return _0x42b6ae&_0x1fbad0;},'SnsKv':_0x19cfe2(0x265,'(jW1'),'GMfMI':_0x19cfe2(0x193,'f69U'),'SYWAY':function(_0x2f6989,_0x4de265){return _0x2f6989<_0x4de265;},'hpSIj':_0x19cfe2(0x1d3,'T]PE'),'CmaFk':_0x19cfe2(0x29a,'A(6P'),'GXxQw':_0x19cfe2(0x174,'HAN('),'fEudV':function(_0x1cc008,_0x527938){return _0x1cc008(_0x527938);},'IDOTX':function(_0xe48415,_0x175c0c){return _0xe48415!==_0x175c0c;},'DqNsT':_0x19cfe2(0x302,'RSw)'),'stIst':_0x19cfe2(0x1c1,'BFeX'),'wZDHf':_0x19cfe2(0x185,'hOLQ'),'wwUVI':_0x19cfe2(0x28a,'7%2E'),'zqzAI':_0x19cfe2(0x25c,'RSw)'),'oUpLj':_0x19cfe2(0x20f,'(jW1'),'KHzgu':_0x19cfe2(0x1c6,'HAN('),'qTYpl':_0x19cfe2(0x2ea,'sWIA'),'VEbIs':_0x19cfe2(0x323,'MK#n'),'hjSfQ':_0x19cfe2(0x2b7,'5b5%'),'mEIlo':_0x19cfe2(0x23a,'A(6P'),'txhir':_0x19cfe2(0x19f,'(iQZ'),'FEQsX':_0x19cfe2(0x1f5,'sWIA'),'PAEHU':_0x19cfe2(0x27f,'cG81'),'PRKYo':_0x19cfe2(0x164,'Udpt'),'aZsYp':_0x19cfe2(0x106,'&g5L'),'lSWpb':_0x19cfe2(0x2ef,'A(6P'),'RsdeA':_0x19cfe2(0x109,'g6r!'),'JtYpP':_0x19cfe2(0x2a7,'vquI'),'fJPlZ':_0x19cfe2(0x1fa,'&]mB'),'oGpjc':_0x19cfe2(0x11d,'1kvD'),'sraqp':_0x19cfe2(0x1ef,'sry4'),'XZwVt':_0x19cfe2(0x188,')xp]'),'AVrBR':_0x19cfe2(0x367,'dxo&'),'CKiFA':_0x19cfe2(0x156,'OYk)'),'SMYtF':_0x19cfe2(0x1cb,'OYk)'),'nwhGl':_0x19cfe2(0x2a5,'Pa4!'),'hZaLk':_0x19cfe2(0x1c8,'g6r!'),'HMiIw':_0x19cfe2(0x1a3,'4wDp'),'hIpTi':_0x19cfe2(0x28f,'GAjn'),'FdcRl':_0x19cfe2(0x293,'vquI'),'OePZA':_0x19cfe2(0x14b,'Udpt'),'kvIvE':_0x19cfe2(0x241,'EK)a'),'CShby':_0x19cfe2(0x1ce,'HAN('),'tstvw':_0x19cfe2(0x341,'2yr0'),'gWnVW':_0x19cfe2(0x2dc,'4wDp'),'SZaXM':_0x19cfe2(0x223,'sWIA'),'tfgGd':_0x19cfe2(0x226,'g6r!'),'RAfrF':_0x19cfe2(0x150,'BFeX'),'OfvLI':function(_0x1f43c9){return _0x1f43c9();}},_0x54a63e=[_0x5031c8[_0x19cfe2(0x325,'g6r!')],_0x5031c8[_0x19cfe2(0x2bc,'[fcK')],_0x5031c8[_0x19cfe2(0x1b9,'rdr*')],_0x5031c8[_0x19cfe2(0x360,'f0xW')],_0x5031c8[_0x19cfe2(0x176,'Mage')],_0x5031c8[_0x19cfe2(0x166,'3cPF')],_0x5031c8[_0x19cfe2(0x36e,')xp]')],_0x5031c8[_0x19cfe2(0x18d,'q)]c')],_0x5031c8[_0x19cfe2(0x113,'49fL')],_0x5031c8[_0x19cfe2(0x314,'[fcK')],_0x5031c8[_0x19cfe2(0x2d7,'T]PE')],_0x5031c8[_0x19cfe2(0x2d2,'Kif$')],_0x5031c8[_0x19cfe2(0x1d2,'Kif$')],_0x5031c8[_0x19cfe2(0x2de,'q)]c')],_0x5031c8[_0x19cfe2(0x123,')xp]')],_0x5031c8[_0x19cfe2(0x1ae,'&g5L')],_0x5031c8[_0x19cfe2(0x264,'IEeM')],_0x5031c8[_0x19cfe2(0x35f,'f69U')],_0x5031c8[_0x19cfe2(0x248,'&g5L')],_0x5031c8[_0x19cfe2(0x2b0,'c3pP')],_0x5031c8[_0x19cfe2(0x315,'hOLQ')],_0x5031c8[_0x19cfe2(0x144,'sWIA')],_0x5031c8[_0x19cfe2(0x34e,'RSw)')],_0x5031c8[_0x19cfe2(0x276,'OYk)')],_0x5031c8[_0x19cfe2(0x168,'IEeM')],_0x5031c8[_0x19cfe2(0x304,'q)]c')],_0x5031c8[_0x19cfe2(0x219,'sWIA')],_0x5031c8[_0x19cfe2(0x104,'gE*p')],_0x5031c8[_0x19cfe2(0x173,')xp]')],_0x5031c8[_0x19cfe2(0x256,'q)]c')],_0x5031c8[_0x19cfe2(0x351,'RSw)')],_0x5031c8[_0x19cfe2(0x157,'A(6P')],_0x5031c8[_0x19cfe2(0x210,'(jW1')],_0x5031c8[_0x19cfe2(0x12c,'c3pP')],_0x5031c8[_0x19cfe2(0x2e0,'cWF!')],_0x5031c8[_0x19cfe2(0x190,'Pa4!')],_0x5031c8[_0x19cfe2(0x266,'HAN(')],_0x5031c8[_0x19cfe2(0x340,'f69U')]];return _0x4d12=function(){const _0x56c7d1=_0x19cfe2,_0x1163a8={'UDSqM':_0x5031c8[_0x56c7d1(0x322,'gE*p')],'nHdRm':_0x5031c8[_0x56c7d1(0x10f,'3cPF')],'PshRz':function(_0x158cec,_0x4e39dd){const _0x501506=_0x56c7d1;return _0x5031c8[_0x501506(0x330,'Kif$')](_0x158cec,_0x4e39dd);},'MzyZV':function(_0x2455af,_0x3e23c7){const _0x537e92=_0x56c7d1;return _0x5031c8[_0x537e92(0x1d4,'Udpt')](_0x2455af,_0x3e23c7);},'eAity':function(_0x1a61fd,_0x3ca3a2){const _0x2bbe97=_0x56c7d1;return _0x5031c8[_0x2bbe97(0x2c8,'GAjn')](_0x1a61fd,_0x3ca3a2);},'NlqNC':_0x5031c8[_0x56c7d1(0x122,'cG81')],'Rknbo':function(_0x1ae3f2,_0x894be9){const _0xb8680a=_0x56c7d1;return _0x5031c8[_0xb8680a(0x233,'GAjn')](_0x1ae3f2,_0x894be9);},'Qkmpn':function(_0x4595d1,_0x442347){const _0x25c5ea=_0x56c7d1;return _0x5031c8[_0x25c5ea(0x261,'IEeM')](_0x4595d1,_0x442347);},'zFWMk':function(_0x1fbc53,_0x23fbd7){const _0x1fa568=_0x56c7d1;return _0x5031c8[_0x1fa568(0x1f7,'8(X1')](_0x1fbc53,_0x23fbd7);},'shwAx':_0x5031c8[_0x56c7d1(0x2ec,'K4ZM')],'xMiXH':_0x5031c8[_0x56c7d1(0x131,'f0xW')],'fuKay':function(_0x5b9bf8,_0xfab91d){const _0x22be02=_0x56c7d1;return _0x5031c8[_0x22be02(0x10b,'sWIA')](_0x5b9bf8,_0xfab91d);},'mrRtr':function(_0x587577,_0x35927c){const _0x43732e=_0x56c7d1;return _0x5031c8[_0x43732e(0x36b,'&g5L')](_0x587577,_0x35927c);},'mhkmZ':_0x5031c8[_0x56c7d1(0x199,'f69U')],'XRQNY':_0x5031c8[_0x56c7d1(0x312,'T]PE')],'bkWby':_0x5031c8[_0x56c7d1(0x132,'1kvD')],'oYBLd':function(_0x47f0c4,_0x55cfec){const _0x123575=_0x56c7d1;return _0x5031c8[_0x123575(0x1ba,'Udpt')](_0x47f0c4,_0x55cfec);}};if(_0x5031c8[_0x56c7d1(0x1a5,'1kvD')](_0x5031c8[_0x56c7d1(0x30d,'RSw)')],_0x5031c8[_0x56c7d1(0x2d4,'MK#n')])){const _0x3348bc=_0x1163a8[_0x56c7d1(0x1d0,'GAjn')];let _0x330bdc='',_0x5b564e='';for(let _0x4a8a2e=0x0,_0x16ef0d,_0x84058,_0x5b3ad3=0x0;_0x84058=_0xa35c0f[_0x1163a8[_0x56c7d1(0x17c,'rdr*')]](_0x5b3ad3++);~_0x84058&&(_0x16ef0d=_0x1163a8[_0x56c7d1(0x21a,'&]mB')](_0x4a8a2e,0x4)?_0x1163a8[_0x56c7d1(0x30c,'gE*p')](_0x1163a8[_0x56c7d1(0x19a,'sWIA')](_0x16ef0d,0x40),_0x84058):_0x84058,_0x1163a8[_0x56c7d1(0x22e,'4wDp')](_0x4a8a2e++,0x4))?_0x330bdc+=_0x43cf70[_0x1163a8[_0x56c7d1(0x1e7,'8(X1')]](_0x1163a8[_0x56c7d1(0x25f,'5b5%')](0xff,_0x1163a8[_0x56c7d1(0x11a,'gE*p')](_0x16ef0d,_0x1163a8[_0x56c7d1(0x140,'Pa4!')](_0x1163a8[_0x56c7d1(0x347,'q)]c')](-0x2,_0x4a8a2e),0x6)))):0x0){_0x84058=_0x3348bc[_0x1163a8[_0x56c7d1(0x1bb,'KA*M')]](_0x84058);}for(let _0xadfccd=0x0,_0xe45da3=_0x330bdc[_0x1163a8[_0x56c7d1(0x253,'5b5%')]];_0x1163a8[_0x56c7d1(0x309,'vquI')](_0xadfccd,_0xe45da3);_0xadfccd++){_0x5b564e+=_0x1163a8[_0x56c7d1(0x337,'xLuB')]('%',_0x1163a8[_0x56c7d1(0x2d1,'4wDp')]('00',_0x330bdc[_0x1163a8[_0x56c7d1(0xfe,'5b5%')]](_0xadfccd)[_0x1163a8[_0x56c7d1(0x1cd,'g6r!')]](0x10))[_0x1163a8[_0x56c7d1(0x300,'&]mB')]](-0x2));}return _0x1163a8[_0x56c7d1(0x184,'GAjn')](_0xc5493a,_0x5b564e);}else return _0x54a63e;},_0x5031c8[_0x19cfe2(0x2d6,'Kif$')](_0x4d12);}function _0x2ddc(_0xe89eb6,_0xfc1056){const _0x1ac55e=_0x1ac5();return _0x2ddc=function(_0x2ddc5a,_0x3ae07f){_0x2ddc5a=_0x2ddc5a-0xfe;let _0x46e704=_0x1ac55e[_0x2ddc5a];if(_0x2ddc['OAOTcj']===undefined){var _0x105a12=function(_0x1bfe39){const _0x2c1575='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xb3b9c7='',_0x942569='';for(let _0x557c16=0x0,_0x4217d1,_0x168983,_0x1ed347=0x0;_0x168983=_0x1bfe39['charAt'](_0x1ed347++);~_0x168983&&(_0x4217d1=_0x557c16%0x4?_0x4217d1*0x40+_0x168983:_0x168983,_0x557c16++%0x4)?_0xb3b9c7+=String['fromCharCode'](0xff&_0x4217d1>>(-0x2*_0x557c16&0x6)):0x0){_0x168983=_0x2c1575['indexOf'](_0x168983);}for(let _0x444a38=0x0,_0x559903=_0xb3b9c7['length'];_0x444a38<_0x559903;_0x444a38++){_0x942569+='%'+('00'+_0xb3b9c7['charCodeAt'](_0x444a38)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x942569);};const _0x547a53=function(_0xe81db0,_0xc5493a){let _0xa35c0f=[],_0x43cf70=0x0,_0x36c7ce,_0x2654c1='';_0xe81db0=_0x105a12(_0xe81db0);let _0x12d109;for(_0x12d109=0x0;_0x12d109<0x100;_0x12d109++){_0xa35c0f[_0x12d109]=_0x12d109;}for(_0x12d109=0x0;_0x12d109<0x100;_0x12d109++){_0x43cf70=(_0x43cf70+_0xa35c0f[_0x12d109]+_0xc5493a['charCodeAt'](_0x12d109%_0xc5493a['length']))%0x100,_0x36c7ce=_0xa35c0f[_0x12d109],_0xa35c0f[_0x12d109]=_0xa35c0f[_0x43cf70],_0xa35c0f[_0x43cf70]=_0x36c7ce;}_0x12d109=0x0,_0x43cf70=0x0;for(let _0xd52399=0x0;_0xd52399<_0xe81db0['length'];_0xd52399++){_0x12d109=(_0x12d109+0x1)%0x100,_0x43cf70=(_0x43cf70+_0xa35c0f[_0x12d109])%0x100,_0x36c7ce=_0xa35c0f[_0x12d109],_0xa35c0f[_0x12d109]=_0xa35c0f[_0x43cf70],_0xa35c0f[_0x43cf70]=_0x36c7ce,_0x2654c1+=String['fromCharCode'](_0xe81db0['charCodeAt'](_0xd52399)^_0xa35c0f[(_0xa35c0f[_0x12d109]+_0xa35c0f[_0x43cf70])%0x100]);}return _0x2654c1;};_0x2ddc['XTbqHM']=_0x547a53,_0xe89eb6=arguments,_0x2ddc['OAOTcj']=!![];}const _0x40203a=_0x1ac55e[0x0],_0x512577=_0x2ddc5a+_0x40203a,_0x183a21=_0xe89eb6[_0x512577];return!_0x183a21?(_0x2ddc['CaNTSq']===undefined&&(_0x2ddc['CaNTSq']=!![]),_0x46e704=_0x2ddc['XTbqHM'](_0x46e704,_0x3ae07f),_0xe89eb6[_0x512577]=_0x46e704):_0x46e704=_0x183a21,_0x46e704;},_0x2ddc(_0xe89eb6,_0xfc1056);}function _0x1ac5(){const _0xdd3e53=['W71Jm8oKdq','nCkyj8k7ga','p8kUWOftnG','CmkxW6WNCCkzdCkpyLS8EJZcQCkIttT5tCkYW5RcIcrX','W4RdTCoCldxcLmorymo6W4DetCkwW6m','rSokW73cQbTuW442gWxcImknW6FcJCkK','WO0YW79yW7O','WQOoWOaJW6m','qCkxo8k5nW','WPBcLSk1Evi','etb/E8oo','WPVcGCkNAM0','W6pcQuVcPvq','B8ozxsG0','bdzismot','WP1ruCkgWQO','WRiGWOu/iq','EZjFW7FdOa','DSoStbyz','F8kHoCkBfCk2W4xdTCkpmSk/WOe','A8k9kCkApa','WPGDkalcPW','k8ktixjs','DComW6lcMGm','W40NWOGAs8oqWP9RWOBdPHBdV1PEW7lcHgDMb8k+W5Wi','WPVcMmoqdtS','kmo5WP8IWOm','WPVcGCk+DLa','W5BcO8kwWO13WQxcVCo9W7tcGCoyzhS','WOaxgt7cRW','WQLnbSoCka','ncvbwSov','n8k1WOuvWQxcM0pdQwtcUxxcOSoOcglcJSo0at1Ta8kguIVcICorCW','WRVdVwldU8oZC8onxmkctCkRWR/dLCkarCkWW5uZimooux4mW7dcICkEhCk0eefn','WQpcMcZcU8o7','WRrHrmky','pCkPWQubWOW','wbZcUhZcPa','zCo0W4qDW7a','WPe/fuFcK8k0FSoYxSoUW7LKWOeaWP0','a8kxWOzWBa','WRddM2hdOCo9','pCocW4LVWPnaW549eKBdQ8oSWRxcHvVdR3RdPmoso2RdJg/dOq','gmkxixj1','WQRdNmodW7zi','WOBdJgJdSmoW','WRJdHmo5yLO','rwNcV8ocka','fSkmnuLq','emkha8k3iG','qGTbr2G','WRHjamo+kW','WPtcTmkECu8','W5ZcNmkRE00','AazpW4VdNG','W4OqWRijua','W6alDvxcSxJdTc4','nSoWlhHSD20GWPtcOwLzxSoTjge','oMbIgHW','rmoNW5y4va','ySovW4WVW5pcJCo8zwFcGmo5W5nQsqj3nSopumkKW6vOCt8zW6zlWQu','smorFvFcUW','WPlcQSoiW5acW7hcTCk+W5hcPCouwMqpW4bPWOfDW5BcQqf+W4uk','W5dcO8kivMK','jCkJdCkvcq','WO3cJGJcL8o8','W4xcGLBcV1m','WPNdOmoNyfi','WPnVcSoiia','aCo7cmksiCklWO3dPCoAW5xdMmo6mJldQgu2WOb4WQjGj8oHWPKPW5ZdOSoL','WOm9WPG7dW','WOBcIYRcHCo/','lSk1WQHorG','WQddMMpdKmol','W5ZcICk3WR8qW4xdHCkGcmkQBa','WRZdS8oAW5iw','W6FdSSkbD00','WOL8zN/cLa','W4WqowBdJG','nCkdiCk5dW','WQmXWQKQW58','W67cKCkyANu','yCkklmkDfG','cu9hlH4','wSolW5VcUWO','WOGGW6XfW7y','WQa8WOeMW7q','WRXzxSkOWOq','WQ0ylXhcSW','qdDeueS','jgfNgHC','uCkdWQ8mW4S','WQDZWRukW7ZdImkKW5PrWO0','WR/cPgX0WOrbms4KB8kEm0G','WQRcHSk5r00','WPuUFmoLuq','W5f5lSoyoaLRa8klfX13mCoNjYe8WPVcTCoQmrTvCtqFWQ4qyCoIwW','WO8ka8oekfaXiG','EeJcMSoadW','WPz/wCksWQm','WQ3cT8kdz3i','WRlcOSkvBGm','DsbkW5RdHG','o8o/W5LmWRi','WRRcTmkHFrm','qCkajCkDpCk6W4W','mSkbWPzqCG','WOmyWPqLdq','W5P0qatcNSkrB8ozqG','z8kpkSkbka','WPjiBulcNa','WRZdKmoXW4f2','DSoKW4uTW7G','pCo4W69jWPa','o8o7W51UWRe','W5CLWOqSrq','iCk0WP9AeW','FCoTBH0+','kmowWOCDWOm','W4S4dKpdPq','WRzUq8k/WOq','W4NcTSkPtvK','WOmWqmo6va','W4FdLdC2W5S','W7einwldMq','WQJcNSkKeSkh','WQtdR1tdGSoO','W4H2W51xWQhcJ8o8W6HiWP9cfmoi','WPVcVSoKWPtdSG','W6qQqCoL','W67cRSkyrx0','a8osW4ecWONcMutdI2tcP1JcR8o9c3hcQCoPDH4+a8oHwhRcJCklBqS','WOBcGCogWPRdHq','WQOKW45j','xColW64gW7O','WPSzW7z3W4m','WPhcLIJcSmoc','WP3cJCkMC2S','E8ohEqGY','WR/dU8onW4be','pSkQhCkWha','WQpcKHlcSSo+','axjbsColWRqOF2XloviyWQrdDa','B8oCW6Knrq','FSk4WOa/W5pcJ0ZdOrldTCkTyCkmuSktihdcLKRdK8kvW5TRea','W47dT8oQW4e','W7HrmSoLgG','W6KIWR4exSoBWOTRWPldQG','WPVcPSksr0S','omkoWQ1Tia','WOG6FmoLDW','W7JdVG/cShxcVh/cIW','cSkwefHq','WO/cH1SyxW','dmk1gNbK','WPbqcSoRkN8c','kmoFWOeWWPe','WQnUi8oTkG','WPddVCoWW48XW7ZdO8oQ','zMJcMmodiq','W7DfyKhdJMaFWQLfWRbYWRJcUxFdVunAWO92zCkMWRXOD8oiDWGEWPmbwG','W6xdTSk5ga','mCkvghjI','W7jceCokt8kbWPOFW6e','WOldQSoTW5GqW7JdPSoNW7FdGmkd','W5NcHCk2W6fMW6NdU8k7ka','W5BdNCkOs0C','W6zum8oBoW','W6O6s8oEaq','WQFdUSkiWRldNSkOnxvYW6VcTefSW6JcPrJdMwtdKSoHWOZcHmo3WO5IW5DvWPWiW6xdUG','ntjtosX8y1RcJmkOBSoVgCoTyuJcJ8obWQZdMG','W7JcM0BcIK7cVh/cScVcQCkpvSkOE0pcUf7cIG','fmkxpmk5oq','iSoUndK','Dmo9W64pW7q','WORcQ8khqfu','WPaEW6DSW58','WQnUf8o/pa','sCojCK3cRG','r2FcLmoEhW','WP8bWP0kW7a','W47dISkqAx4','jCkyhCkWo8kPWRBdLCoEW6y','WQxcHY/cRmo/','vmofW6W/W4e','kCksjmkuBw9XW6xdNa','WRBcPSouWOxdPq','WPnfuCkAWPSoW6JcMeruW5pdMaZdRSkrW6yrWQW8','W4BdTIKoW5W','zmorwJ8P','ErrKxfq','W5nsaSo5nW','tG7cPhhcTW','WOmBWO4nha','fmk2WPXXrq','xmk+WPLmWQ1XW7mSmW','W6tdIwRdM8khWPZcJqFdQCk/W6a','WRFdNmo/W651','WQKWW5fZW4O','W6OLWPCYAG','FSo+qg3cJW','W6/dOmkOtvW','wSoHrmkBqa','W7KksmoHca','W409WO8MEG','WQOwWPqrW70','tCoiW5aQzG','WRlcSJZcKSoL','W6WrogNdKq','WQRdVSoeuLC','WQBdQSoTW785','f8k2WOH4rq','dCkrWObhpq','FWP7ywa','W6y3hfBdMa','WRhcKCk8uu8','WQhcOvGnwG','WOxcJZ7cHSoJ','W68uo2NdIq','WRxcRCk7hmkW','WRuQW54x','W5VcL8kdlv3dPG3cGmkzW6uWW6lcRwGKW6rjt8ooz3j0W7JcI0FcMsOfh8ovWOv4f8k8rXhcKYvOCqdcGCkDzColW4qkxSossSomCCoMpCkAW7dcG8o8yvlcJ8oyW5JcQchcUW','D8owW4D7F1JdGSoRWRu','WPtcPcNcSCov','DabNDKhdPshcJSkNomoy','W6hdSsSKW5q','mLDperq','W41skmoqgW','Emo9ESkKFa','dCkaWQzXqa','WQqAxmoozW','WPm/FSo1qW','WQtdOgq9','WR7cOgLWWOncmwK+AmkAa0KC','W45kkCo+kW','WOypw0pcU2tdUdH0W5hdGmkXad/dThJcUrJcKmo2W404eaydWPjfW50','WPldSmohW7iK','WRf1qSkbWOq','WP8GeYJcK8orB8kLyCkmW4r5WPfJW4a','bIX5zCoH','vCobW7qhrG','W6RdHamZW4e','WRZcN8oTmtekWPBcI2/dTcfJ','WRpdG8oLW58xW4/dUCoPW63cM8ouxW','WPmsWReahq','WOtcSNuAA0XHW5WNWQqicYRcPXXYmCo1kvZcVmoEDmoPyeNcMc8dWQpdSeJdOCoKj8ojemknimoXCuBdUJxcT8kYyfu5WOOXWPqwEIrDpu7dOSo2WRxcJSoaW78n','xmouW5atW78','i110gHq','bhDRjtGIEKVcHSkeyCon','WQlcV8ocWRpdHa','WPb2gCoMhq','WO9CcSohnq','a8kiWOD9la','FmoIW700W7a','WP3dJxxdMmoY','W4ldQmkJx3K','W7NdNCkhsf4','CSoEW64JW78','W4mqWQyuEa','y8ovEX4','WPTvoCoSkW','emkyfCkIiG','W5TQd8o6ka','W4Wxi0ldTda','dhjSdXC','W5/cKCkhuW','iSk8kCkUnG','oCkweLne','WOTCfmoAka','W4NcV3xcIhW','nSoZWPaXWQtdL8oXeXxcU8oyta','WR1BBCkYWOq','WPhdQCokFu0','W7Pld8ofoW','WPqlWQCnW74','WPnft8ktWODKWRdcUvqGW7ldJcZdGmkvW6ueWP8','WO3cRrBcGmop','WO7dMSojx2i','WOlcUmkYm8kP','o8kUWO5Xoq','vbhcQvxcVG','vColCetcNq','eCkekSk/ha','BCoArJ8X','yILrEua','W4RdLmotsftdJCk5WR9r','C8owCtaI','Dmoys1NcMW','za9txG','zw/cISoanW','WR09W6rTW64','wtjCFhy','WR0uW5LWW6m','WQKWxSoBua','WPhdN8oFCLW','WOBcG30nzxbZW6qzWOejjrdcMqTHcSoemrRcNSkFCCkKtGtcRa','WQFcN8k3AJq','gCo5W6v7WO0','WRaDkJ3cOa','WPeciJdcJa','W6/dGbCqW70','zxpcGSoa','WQaaWQqxkG','aSo9W5PnWRnQ','WOS8hHFcQW','W7exWQWhBW','i8kfavvk','W4lcKmkLpG','W4eMa2tdQa','ymoKW4pcVaC','iSkfiCk5jW','vCoXW442W7e','WPHCdCoQn1ydq8kFW7ZdPCokW4iBF0eHWR3dICkbW794WPZdQLjddLL9DZZdHfldM8kvWQBdHSo+WR7dPeaZW43dJmoVW5X7cCkYWRboiaG1oL3dOWpdK8kemSoiWPCvWP8','WPdcSwmprG','WRGldt3cTa','WPOfWO8anG','vCoyzmkuBq','WQybWQWsda','WQdcR8kKaG','WQFcMeCkAG','WRhdL8opW7mq','W4RdSSkKCNm','WOxcGSouWRxdIa','aJncvmoZ','x0VcLCo0aq','DeD/W7pdVSocaSkEuSkpW4L9WQnkr8o8WOHBw1C','DmoIW7yHW58','WPWHkshcSq','zvpcU8oRfa','oCkqgLnW','WPVcTSkOCwS','b0rTpai','W5vTmSo5bq','A8oPuCkkFa','rJXGW7tdHa','ESoxwaKw','W6C8tSoFkG','vJfhW6pdVq','W79Sm8o0pq','qSoeW7mKFW','u8kGW6T9W7NcQmoNyNNdSW','W7fFeCoSlG','WQXdECkJWPy','W4L0bCo4dq','WPJdSCkkra','fCoNemot','wSony8k1yq','W47dLSosndtcRmoSWP1MWPvbW4tcNW','WRlcLmoZgG','bSoEW4n9WQ4tW6Gpm3JdQ8krWR3dMMBdLgddJmkpp0RcT2/dIa','W7xdL8kcB2vHlWa','W7tdUJ8VW6u','WPKnWPOhW5y','WO9fWO4xlmk/hLe','dColWReRWPW','r37cQSo2fW','i8kPWRbFhq','hCksWQ0OWOe','pCoCW6PSWQ1+W6ydheBdR8ou','mCkbWOjZbW','WPe8kGpcQa','qSoUw3dcRa','C8kmCai','nSoZghzpAwPVWO3cKa','WQe8rmootW','WQKWW59qW6e','W4rZgCo1jW','W5NdVCk5B1O','WQOLW5XKW6m','kmoaW6TsWOm','W6mjySoEdG','WQL8xmkDWPy','CCoLBIS2','WPG1W5GeW7xdLSkJW5TiWR5IbCo3Fd7cO1/dJq','WOBcOxaByq','x8oCW4W8FG','WPZcISknz2G','WPtdNSoABMW','WOBdHehdVSoC','W5BdQmoGC2rVdWnosLrikqDWWP7cSIyeWPBcO10lvW','dCoMW7zbWQ4','WPlcR8oufbK','g8oGW4mNWP4xW7ydfNJdR8kxWQFdMGNdUhRcN8oaofddUZpdI0iUWPq1WPeBW54WnSkRuWpdQZNcMMOekw/dTGzhe2bkomk+pSo7k8klkSoXhmkLW7VcPZn1eNtcJW','jCkyhCkWna','WRSulZpcNq','W5y/aSon','z8onzmkcsa','ymodW5FcGYG','WQ/cL8ksshi','WR3cGeqXAG','lSoZW6O/','tmoAW7eJW5O','WRLrzehcPW','ESoHW6dcTce','fqzatSoa','WOtdN8oTW4jg','FSkgW6j5','BcnoW6ddHW','wKxcLSoHlCoRzCo8WO1tWPeaW6a6W4tcTKxdN8oXW49ItCkcba','WO3dUmoEv3u','W4/cKmkNseW','DexcQCoedW','WPhcS8ozEMddISkomSoJW6vXvSkkW5rNlmkhDa','W6pdJSkvDhO','WRrFn8ouea','WQFdLCovW4L1','rWb/ugy','imkEWPSjWP4','W7mhsmo3eG','WQhcSSkDxrK','WRBcT8kYF20','WOhcMdFcR8oV','tCkGW7CWW7uVW77cQmkoqHmiW5VdIW','imouWR8xWOi','zCo7FfBcQG','dIvurmos','WRaihtBcLG','WOq1WPKwW6q','WOtcQMej','WQNdHCosW4mn','W6KnECoboaKWa8kvBb0YnSoZodGGWQBcKConmrTUsXuXWQOh','WQZcRCkbsbq','hSkvWQXthq','WR7cMmkut3e','nSoYCuvqiM1Y','WR/cKmkpweW','hCoEW59VWR4','WQtcGSkaxMC','rCo+W5uSW6y','W4ZcV8kABhu','WOVcMu4uyG','WORcSCk2x2m','t07cKConaa','WOldJSoCW6TK','rG9gBgy','WQJcQSoQlGq','W6Tpjmo8oG','WORcI8oWWPVdUW','imkXWQn+qG','W4nbW69nDCoTb2HLWPmE','WRNdR2RdPSo3','WRaxdYtcSa','kCksWPLsEq','W60NWPu6','W6ddVrOnW6G','uSopW7FcGa8pW7LNl0a','ySo7W6edxG','WRFdMCoWqx4','ACoTzdOEBSkpWQ3cQrvodtnBWPTnsCk4Cc87W7SCWRBdMbBcK8kAFCoVm8owhmk+W5xcTxRdLCo2W6tcRSo3Du9wWR94eCorjmkCtSk1v8kHW5NdOCkBWQjvW74OW4OE','W4mWWQe0BW','W6NcNmkfr0m','WOdcUmouWR4','kCoOWOeWWQ0','WQlcKddcH8onWQJdVJBdK8oQW4xcISovC8oGW4n+jmoNW5ddQCkUW5XK','omkdjMPg','W4mQhgZdRq','WRRcLrJcRmoV','F8k8DSkBfmk5W5JdQ8k3v8oK','W77dM0tdRW','WQqOrSknqSk6W7O0W7dcKhRdVdxcGCk3WQW','WO/dPmoQW40g','zsTACLu','W4BcJCk1E1i','p8oOW69dWPe','p8kZWRHrnW','WROHW75MW50','t8oYzLlcQa','e8knWPqnWPy','umoUzGez','WPJcN8o+WO/dGa','WQTcwMdcJa','W7/dHYaYW5G','jCk1f3jt','uSoUCYWhfmkBW7lcNhbNwa1rWQjfu8kojGO9WOWHWRi','FCoLW6lcHcC','WRFcR8kCA3u','WOpcMmkul8k4','WRVcISkCBbq','WOfty2/cKa','WRJcGCkWvYi','F8oZW5VcHbq','xmklnSkGcq','vJm2CuOGBvhcJCk6qq','fSkaWRHSmG','WPNcVSojWPFdPq','WQxdSKpdG8o3','BSkAixi','wCkhnCkHia','W7Ous8o6cW','nCklWPH0CW','jCklWOnIxG','WRxcUmoYebG','W5XBlCobpq','W5ddT8o1l2dcKCoPotzQWP/dNCkQ','WQtcPCkrEuK','WPFdPCouBMW','WRBcO8kVEeS','ASoEW4CxW78','WQJcL8o2eZO','WOpcImo3WQddIG','W4JcR8kIuhC','WQRcSx0hyW','wSoqzq0b','a8oJW4HTWOfRW7q','Amo3W74AEW','W7uSWOuoBq','CCkpwq3cHK4YWQNdUKW','WO8AqSofEa','h8kFWQTifq','W7qEvmoei8o3x8oEW5mXWRNcLSkLvCoAW5qtgmkuW6BcGmkFWR/cPsVcM3BcQG','aSoVW4T/WRO','WPtcOmoEWOldGq','WRpcHmoUWQldOW','WONdUSoGW7qB','nebMaqG','xbRcJhpcUa','yCk2i8kxiq','WQpcL8ogWO7dNq','WONcLfuQxW','n8kokmk8aq','yw/cNCoHm8oN','Bb7cQLJcIa','Emo0W7FcQa','W5ddGCk1Av0','WOfSw8khWQO','DeqhW6BdRSkScmkptmkDW6v1WPH0r8o1WOG/yLuwAmoTW7tdQ8kIWPxdOW','zxRcOmoplq','WO0meqBcVq','z8kaWQCdW44','WPSwWOWPW4C','a8krWPCfWQa','p8kal8krlG','WRJcISk+W7b3WP3dUSkTd8kesCkfW4tdImoHqd3dVSk/oc/cVmo8W4xdLvexW68','o8kvWRCCWP0','WRz2tCkKWRy','WRhcK8kpyfa','ru5li3tdRgxcGmk9FW','F8ozdCkreSkNW7ddO8kQmSk/WRDJW5NcRCoh','WRdcHmkJsL4','aSkUiw5HBG','WOKjWRCIW5S','arrvtSojWPqPy2WTt3KiW418kZ0RjhbaWOZcL3/cMCoBW5hcVIdcRCkjWOHVW68MvaHfgqtcLmogbCoxnvxdLaZdVmk8WRpcUSkvdtBdMSkitwNcGNiltf0','WRv9q8kPWQK','W7Lvk8oVcG','Fc7cHwJcSW','bI9ozCo1','WO7cHCkkl8ks','W63dQ8kgA3u','WPqVBCoU','WPlcNb7cKSoF','h8ocW59RWQe','wSo/q8krxa','WRGwWRynkq','WPpdNwNdV8oX','WRvDg8ocaW','WO/cLCougqy','WPFdRSoTWRf3W6tcV8kGiCkEeCkvW6RdVCk+tt3cMSk6ottdKmo5W7/dSgS','W7O+hMddMG','C8oHW7ytW5S','wmo4At0g','WQFdLNRdLmoC','gCkPWROaWQS','WOxcQmk8tKG','vmodzxRcPq','uZHNW4ddMq','WQhdK8onW4mZW5m','WOdcRXtcU8o1WQJcKa3dPCk/W4hcKmo0DCkWW4zVpSo9W7/dMCkD','nrDOwSo3','trHeW6ddVW','arqCrCo0WR4jmhz/swKyW4j2kISib1vbWQ7cQMS','WRPSqKtcPge','mSoFWP5cCqddTmohWQxdJ8orW53dV3K','oCooW7vXWO4','aCodW75RWRjNW7KebHZdOq','WP7dQ8ooW7W5','lmoiWOe+WQq','WPDmzCovqSkNWPm0W73cSuVdRbddSSk6W6u','WR87W5vWW7Gv','mSoFW71gWQa','pSovWQj0FGJdLCoY','rsH/Cv7cScxcTSkar8k2umoAWR95W6hdGZmNnmkQW53cSxFcMtFcQHBcIdW','W48XWPqZra','W7BcR1/cV3q','W7aZcg3dLq','WQlcVCkYb8kbpJVdH8oPW5G','zSo4Dc0D','fMLxmsm','W67cRmkywha','WPZdLCoVW6fu','W549WOmuwW','WQiArColrW','WRvOwbBcOvJcSGHKW7hdMmkXgsFdVxS','gSkIbSkAaW','z0lcM8oqeq','axjpg8oHWR1OmhzQ','WP8bW5DaW5y','DSodFxpcIG','WOq9W4zVW60','w8o5W7qsW4a','W5ewWRCozq','gmkaWRPmoW','W5WkCmo9oa','WRZdNgRdOSoN','WRJcQ8ovcX0','rCk5WPOvW6O','p8kvWPWIqwhdUmoaWQFdN8ovW7BdM1NcOa','WOnhi8ozaG','WPS9ltRcJq','WRhcV8kOt2q','rgpcQ8obnW','mSkHgNPb','j8oLW4DUWRi','W5RdHq8MW7XjBGWauCkRgfuKWO3cTt/dVKBcGmoFW4hcLg5va8o2vmoKWPC','nSkxjNz3sdvOWOtcSJzMFmo/hZjKemkz','fmkaWOrDma','bmkBlCkYaa','WPtcRCkfmmk2','z8k2m8kkiW','WR8FtXhcLCkPtSo6q8klWQy','W61IWOjUW5ajFIWP','Fmk8WOK8W7W','WOBcHYpcPmoU','W4VdSCoyjJlcK8ovpSoHW7fGu8km','WOfTbCk4bx9vqSkuW4/cUCofW6idieyhW7VdSmkrW4zxWQ3dSwDU','WQJdKCo0W7Gm'];_0x1ac5=function(){return _0xdd3e53;};return _0x1ac5();}function _0x3ad8(_0x4f2db1,_0x3fb369){const _0x481be9=_0x2ddc,_0x48a5ca={'LcuLQ':function(_0x1c094d,_0x32ab94){return _0x1c094d%_0x32ab94;},'KJuid':function(_0x34e98d,_0x12ce0e){return _0x34e98d+_0x12ce0e;},'balwR':_0x481be9(0x148,'Fw8b'),'tlSyX':function(_0x22dc44,_0x33dbb3){return _0x22dc44%_0x33dbb3;},'OXrrf':_0x481be9(0x303,'Kif$'),'kJCfe':function(_0x2e9241,_0x4b9cce){return _0x2e9241===_0x4b9cce;},'eNlJi':_0x481be9(0x120,'(iQZ'),'sEPvZ':_0x481be9(0x202,'hZL['),'vvhfZ':function(_0x202133,_0x4612e1){return _0x202133(_0x4612e1);},'MtilP':function(_0xa2e6f6,_0xa84690){return _0xa2e6f6<_0xa84690;},'BCAIj':function(_0x4887f1,_0x59c4d1){return _0x4887f1!==_0x59c4d1;},'nhlbV':_0x481be9(0x34d,'2yr0'),'GkzkX':function(_0x3b5a2b,_0x3a87c6){return _0x3b5a2b<_0x3a87c6;},'dMJmm':function(_0x74ff11,_0x30c175){return _0x74ff11!==_0x30c175;},'cqfeo':_0x481be9(0x1bf,'2yr0'),'bvDom':function(_0x3e6b8f,_0x2c28c4){return _0x3e6b8f+_0x2c28c4;},'aALJm':function(_0x53dae4,_0x5a6131){return _0x53dae4!==_0x5a6131;},'iOKgB':_0x481be9(0x13b,'f69U'),'HBVHk':function(_0x33eb88,_0x118aa3){return _0x33eb88%_0x118aa3;},'KgWfV':function(_0x98b507,_0x3b0102){return _0x98b507+_0x3b0102;},'DTtGG':function(_0x1205e0,_0x896fac){return _0x1205e0%_0x896fac;},'qitYe':_0x481be9(0x2ee,'Mage'),'hRYYP':function(_0xf833c0,_0x24ef60){return _0xf833c0^_0x24ef60;},'XPROd':function(_0x4734d9,_0x37b5f7){return _0x4734d9%_0x37b5f7;},'KFvFm':function(_0x1aaa14,_0x459c3c){return _0x1aaa14+_0x459c3c;},'PFuOp':function(_0x3f92a0,_0x221f76,_0x2f4fdb){return _0x3f92a0(_0x221f76,_0x2f4fdb);},'EgwGJ':_0x481be9(0x111,'rdr*'),'gfAfm':_0x481be9(0x31c,'4wDp'),'UeCKh':_0x481be9(0x2a9,'dxo&'),'cLEOc':function(_0xd5daf,_0x2ee9f8){return _0xd5daf+_0x2ee9f8;},'ZHmCp':_0x481be9(0x35a,'&g5L'),'XVZOP':_0x481be9(0x23c,'EK)a'),'zYdTS':function(_0x5a925d,_0x2c2a17){return _0x5a925d(_0x2c2a17);},'QruDK':function(_0x3261ab,_0x568394){return _0x3261ab<_0x568394;},'nIXjl':function(_0xd892b0,_0x222ccb){return _0xd892b0%_0x222ccb;},'ZLSEZ':function(_0x55a69e,_0x1d038b){return _0x55a69e%_0x1d038b;},'mQgsS':_0x481be9(0x277,'sry4'),'UJJaY':_0x481be9(0x152,'Kif$'),'VPbXo':_0x481be9(0x2f1,'MK#n'),'LBtvk':_0x481be9(0x1cc,'hZL['),'cWCMt':function(_0x69175b,_0x8575ff){return _0x69175b*_0x8575ff;},'BxNDz':function(_0x52abc7,_0x13e3f9){return _0x52abc7&_0x13e3f9;},'GKNIp':function(_0x485e92,_0x594868){return _0x485e92>>_0x594868;},'bARhV':_0x481be9(0x212,'dxo&'),'JrpfF':_0x481be9(0x182,'g6r!'),'iHwhO':_0x481be9(0x221,'[fcK'),'OrAri':_0x481be9(0x364,'sWIA'),'PhTHf':function(_0x380261,_0x10cc0f){return _0x380261+_0x10cc0f;},'zIXCH':function(_0x39701f,_0xa4d725){return _0x39701f+_0xa4d725;},'FPcFJ':function(_0x192090,_0xb9b5ff){return _0x192090%_0xb9b5ff;},'gAtKK':function(_0x4ef68d,_0x3866e3){return _0x4ef68d^_0x3866e3;},'GojYe':_0x481be9(0x21f,'5b5%'),'pQxlR':_0x481be9(0x2df,'RSw)'),'lwYyh':_0x481be9(0x230,'1kvD'),'rGhrv':function(_0x1bd70a,_0x1c22f0){return _0x1bd70a-_0x1c22f0;},'CPrDn':function(_0x1b5aec,_0x5ead5c){return _0x1b5aec===_0x5ead5c;},'rbzTz':_0x481be9(0x1c5,'49fL'),'nXyVK':_0x481be9(0x15c,'hZL['),'XefRg':_0x481be9(0x32b,'g6r!'),'ouhEo':function(_0x27af43,_0xaeae09){return _0x27af43+_0xaeae09;},'eJayn':function(_0x26d6ac,_0x4022f1){return _0x26d6ac===_0x4022f1;},'xgppc':_0x481be9(0x1c0,'A(6P'),'HTibY':function(_0x5e77fb){return _0x5e77fb();}},_0x323ef2=_0x48a5ca[_0x481be9(0x14f,'bnq7')](_0x4d12);return _0x3ad8=function(_0x19efde,_0x39fbdc){const _0x58fad3=_0x481be9,_0xcff6a5={'RreeT':function(_0x1028ee,_0x47eb89,_0x3bbb71){const _0x1ce1e1=_0x2ddc;return _0x48a5ca[_0x1ce1e1(0x16a,'IEeM')](_0x1028ee,_0x47eb89,_0x3bbb71);},'Exlwf':_0x48a5ca[_0x58fad3(0x356,'cWF!')],'SCYyw':_0x48a5ca[_0x58fad3(0x207,'3cPF')],'AhWEv':_0x48a5ca[_0x58fad3(0x15a,'g6r!')],'IiXGp':function(_0x203672,_0x449bef){const _0x7c19da=_0x58fad3;return _0x48a5ca[_0x7c19da(0x313,'f0xW')](_0x203672,_0x449bef);},'FGaVA':function(_0x4f87bf,_0x4bae14){const _0x1088bf=_0x58fad3;return _0x48a5ca[_0x1088bf(0x24b,'EK)a')](_0x4f87bf,_0x4bae14);},'iKwgE':_0x48a5ca[_0x58fad3(0x1e1,'#mhK')],'toIQI':_0x48a5ca[_0x58fad3(0x203,'c3pP')],'HQPOI':_0x48a5ca[_0x58fad3(0x345,'dxo&')],'YEfvf':function(_0x582251,_0x55b8cd){const _0xc2706d=_0x58fad3;return _0x48a5ca[_0xc2706d(0x23b,'j7W$')](_0x582251,_0x55b8cd);},'kWsOj':function(_0x1e359d,_0x4d4e45){const _0x2a06e5=_0x58fad3;return _0x48a5ca[_0x2a06e5(0x263,'g6r!')](_0x1e359d,_0x4d4e45);},'QvqfH':function(_0x29fc21,_0xf4e049){const _0x4944a8=_0x58fad3;return _0x48a5ca[_0x4944a8(0x139,'MK#n')](_0x29fc21,_0xf4e049);},'vLaLU':function(_0x663363,_0x3b1e08){const _0x33f506=_0x58fad3;return _0x48a5ca[_0x33f506(0x2fd,'#mhK')](_0x663363,_0x3b1e08);},'ZPyqn':_0x48a5ca[_0x58fad3(0xff,'Udpt')],'ZPMcx':_0x48a5ca[_0x58fad3(0x172,'(jW1')],'PSXnB':function(_0x59c023,_0x4d21ce){const _0x48163c=_0x58fad3;return _0x48a5ca[_0x48163c(0x160,'Pa4!')](_0x59c023,_0x4d21ce);},'fvKMb':function(_0x121d54,_0x948014){const _0x55c148=_0x58fad3;return _0x48a5ca[_0x55c148(0x1b8,'Kif$')](_0x121d54,_0x948014);},'hbgwC':function(_0x4a86eb,_0x1da1bc){const _0x18b0f4=_0x58fad3;return _0x48a5ca[_0x18b0f4(0x275,'j7W$')](_0x4a86eb,_0x1da1bc);},'rrfhj':function(_0x3876e8,_0x24b691){const _0x48b388=_0x58fad3;return _0x48a5ca[_0x48b388(0x285,'1kvD')](_0x3876e8,_0x24b691);},'UUUYD':_0x48a5ca[_0x58fad3(0x143,'KA*M')],'osYzS':_0x48a5ca[_0x58fad3(0x194,'[fcK')],'ItCNO':_0x48a5ca[_0x58fad3(0x262,'2yr0')],'qLNVS':_0x48a5ca[_0x58fad3(0x165,'Fw8b')],'GJBuz':function(_0x44d856,_0x192e9d){const _0x2c05df=_0x58fad3;return _0x48a5ca[_0x2c05df(0x1d5,'q)]c')](_0x44d856,_0x192e9d);},'pQYWL':function(_0x5490fe,_0x20af5c){const _0x4c53f3=_0x58fad3;return _0x48a5ca[_0x4c53f3(0x33d,'&g5L')](_0x5490fe,_0x20af5c);},'YeaVq':function(_0x352e30,_0x589222){const _0x5eebb5=_0x58fad3;return _0x48a5ca[_0x5eebb5(0x1fd,'EK)a')](_0x352e30,_0x589222);},'tlQSu':function(_0x3b8fbb,_0x574ca4){const _0xbeaa37=_0x58fad3;return _0x48a5ca[_0xbeaa37(0x307,'dxo&')](_0x3b8fbb,_0x574ca4);},'QdAqd':function(_0x367aa2,_0x1b4e10){const _0x2087b6=_0x58fad3;return _0x48a5ca[_0x2087b6(0x2ce,'A(6P')](_0x367aa2,_0x1b4e10);},'WuCAi':function(_0x693f25,_0x1b9938){const _0x52d0bd=_0x58fad3;return _0x48a5ca[_0x52d0bd(0x316,'EK)a')](_0x693f25,_0x1b9938);},'tewXL':function(_0x2aa3ee,_0x5ab1ce){const _0x4be757=_0x58fad3;return _0x48a5ca[_0x4be757(0x14a,'gE*p')](_0x2aa3ee,_0x5ab1ce);},'jHhVV':_0x48a5ca[_0x58fad3(0x217,'1kvD')],'MznDM':_0x48a5ca[_0x58fad3(0x338,'cWF!')],'abgXb':_0x48a5ca[_0x58fad3(0x2f6,'&]mB')],'tdnEo':_0x48a5ca[_0x58fad3(0x2b1,'&g5L')],'cSEwp':function(_0x596e89,_0x11a248){const _0xbd1b7a=_0x58fad3;return _0x48a5ca[_0xbd1b7a(0x169,'49fL')](_0x596e89,_0x11a248);},'DjDPF':function(_0x312825,_0x51e862){const _0x4bc2b=_0x58fad3;return _0x48a5ca[_0x4bc2b(0x36a,'RSw)')](_0x312825,_0x51e862);},'Lmblo':function(_0x577fa6,_0x30f07a){const _0x3d300c=_0x58fad3;return _0x48a5ca[_0x3d300c(0x134,'1kvD')](_0x577fa6,_0x30f07a);},'SFUYK':function(_0x369c6e,_0x309dba){const _0x42e8a5=_0x58fad3;return _0x48a5ca[_0x42e8a5(0x290,'3cPF')](_0x369c6e,_0x309dba);},'xlUDG':function(_0x358168,_0x1d7ecd){const _0x4eb09a=_0x58fad3;return _0x48a5ca[_0x4eb09a(0x110,'MK#n')](_0x358168,_0x1d7ecd);},'UElHS':function(_0x59d118,_0x2e56cd){const _0x1e20f0=_0x58fad3;return _0x48a5ca[_0x1e20f0(0x2eb,'7%2E')](_0x59d118,_0x2e56cd);},'wNDNb':_0x48a5ca[_0x58fad3(0x1aa,'RSw)')],'dSvch':_0x48a5ca[_0x58fad3(0x318,'4wDp')]};if(_0x48a5ca[_0x58fad3(0x24f,'q)]c')](_0x48a5ca[_0x58fad3(0x159,'j7W$')],_0x48a5ca[_0x58fad3(0x35e,'bnq7')])){_0x19efde=_0x48a5ca[_0x58fad3(0x13e,'Mage')](_0x19efde,0xee);let _0x727d9d=_0x323ef2[_0x19efde];if(_0x48a5ca[_0x58fad3(0x2fb,'&g5L')](_0x3ad8[_0x48a5ca[_0x58fad3(0x308,'&]mB')]],undefined)){if(_0x48a5ca[_0x58fad3(0x271,'Udpt')](_0x48a5ca[_0x58fad3(0x2c5,'&g5L')],_0x48a5ca[_0x58fad3(0x183,'K4ZM')])){var _0x30402b=function(_0x32cbb2){const _0x1af3f7=_0x58fad3,_0x1a843a={'NWKSZ':function(_0x37d582,_0x458b52){const _0x4a8ecf=_0x2ddc;return _0xcff6a5[_0x4a8ecf(0x14c,'GAjn')](_0x37d582,_0x458b52);},'EzeQb':function(_0xe43d61,_0x1ced65){const _0x118618=_0x2ddc;return _0xcff6a5[_0x118618(0x348,'RSw)')](_0xe43d61,_0x1ced65);},'PzlFg':function(_0x326ab1,_0x22d716){const _0x101109=_0x2ddc;return _0xcff6a5[_0x101109(0x339,'xLuB')](_0x326ab1,_0x22d716);},'UxVEt':function(_0x528798,_0x26770a){const _0xb85b73=_0x2ddc;return _0xcff6a5[_0xb85b73(0x280,'Pa4!')](_0x528798,_0x26770a);},'dmyTQ':_0xcff6a5[_0x1af3f7(0x279,'T]PE')],'bUNRM':function(_0x13259c,_0x246302){const _0x20676c=_0x1af3f7;return _0xcff6a5[_0x20676c(0x243,'BFeX')](_0x13259c,_0x246302);},'hYHmS':_0xcff6a5[_0x1af3f7(0x2c9,'c3pP')],'Icibe':function(_0x26f1ad,_0x4bbe1b){const _0x599ba6=_0x1af3f7;return _0xcff6a5[_0x599ba6(0x2ab,'3cPF')](_0x26f1ad,_0x4bbe1b);},'FWqTN':_0xcff6a5[_0x1af3f7(0x299,'&]mB')],'rRyph':function(_0x42ae2f,_0x21e61d){const _0x716310=_0x1af3f7;return _0xcff6a5[_0x716310(0x29e,'dxo&')](_0x42ae2f,_0x21e61d);},'FHgAN':function(_0x460536,_0x37aca5){const _0x595857=_0x1af3f7;return _0xcff6a5[_0x595857(0x1fe,'f0xW')](_0x460536,_0x37aca5);},'TsXGO':function(_0x158b90,_0x20842a){const _0x3ff81b=_0x1af3f7;return _0xcff6a5[_0x3ff81b(0x1e5,'KA*M')](_0x158b90,_0x20842a);}};if(_0xcff6a5[_0x1af3f7(0x26c,'rdr*')](_0xcff6a5[_0x1af3f7(0x25b,'OYk)')],_0xcff6a5[_0x1af3f7(0x1a0,'cG81')])){const _0x24d27e=_0xcff6a5[_0x1af3f7(0x361,'cG81')];let _0x5f2898='',_0xfddc68='';for(let _0xf906c0=0x0,_0x13e2b2,_0x507c72,_0x125fe9=0x0;_0x507c72=_0x32cbb2[_0xcff6a5[_0x1af3f7(0x170,'KA*M')]](_0x125fe9++);~_0x507c72&&(_0x13e2b2=_0xcff6a5[_0x1af3f7(0x283,'hZL[')](_0xf906c0,0x4)?_0xcff6a5[_0x1af3f7(0x27a,'KA*M')](_0xcff6a5[_0x1af3f7(0x2fe,'GAjn')](_0x13e2b2,0x40),_0x507c72):_0x507c72,_0xcff6a5[_0x1af3f7(0x343,'sWIA')](_0xf906c0++,0x4))?_0x5f2898+=String[_0xcff6a5[_0x1af3f7(0x310,'BFeX')]](_0xcff6a5[_0x1af3f7(0x10e,'Fw8b')](0xff,_0xcff6a5[_0x1af3f7(0x26d,'g6r!')](_0x13e2b2,_0xcff6a5[_0x1af3f7(0x209,'Udpt')](_0xcff6a5[_0x1af3f7(0x1d1,'vquI')](-0x2,_0xf906c0),0x6)))):0x0){_0xcff6a5[_0x1af3f7(0x16c,'(jW1')](_0xcff6a5[_0x1af3f7(0x1dc,'f69U')],_0xcff6a5[_0x1af3f7(0x23e,'vquI')])?_0x507c72=_0x24d27e[_0xcff6a5[_0x1af3f7(0x342,'#mhK')]](_0x507c72):_0x5465b8[_0xcff6a5[_0x1af3f7(0x2d5,'BFeX')](_0x1a3617,0x100,_0xcff6a5[_0x1af3f7(0x197,'5b5%')])](_0x43d796[_0xcff6a5[_0x1af3f7(0x20a,'7%2E')](_0x1d80d7,0x112,_0xcff6a5[_0x1af3f7(0x1c7,'g6r!')])],_0x4fe824[_0xcff6a5[_0x1af3f7(0x229,'KA*M')](_0xbf4c6b,0xfd,_0xcff6a5[_0x1af3f7(0x128,'bnq7')])]);}for(let _0x22052d=0x0,_0x4c1848=_0x5f2898[_0xcff6a5[_0x1af3f7(0x2ad,'&]mB')]];_0xcff6a5[_0x1af3f7(0x2c7,')xp]')](_0x22052d,_0x4c1848);_0x22052d++){if(_0xcff6a5[_0x1af3f7(0x21e,'BFeX')](_0xcff6a5[_0x1af3f7(0x222,'rdr*')],_0xcff6a5[_0x1af3f7(0x245,'KA*M')])){let _0x533ddb=[],_0x19470e=0x0,_0x2cd404,_0x1b56db='';_0x472b02=_0x1a843a[_0x1af3f7(0x1e4,')xp]')](_0x5286b8,_0x137dcb);let _0x4cab3f;for(_0x4cab3f=0x0;_0x1a843a[_0x1af3f7(0x2f9,'#mhK')](_0x4cab3f,0x100);_0x4cab3f++){_0x533ddb[_0x4cab3f]=_0x4cab3f;}for(_0x4cab3f=0x0;_0x1a843a[_0x1af3f7(0x286,'Udpt')](_0x4cab3f,0x100);_0x4cab3f++){_0x19470e=_0x1a843a[_0x1af3f7(0x252,'c3pP')](_0x1a843a[_0x1af3f7(0x121,'4wDp')](_0x1a843a[_0x1af3f7(0x1f3,'T]PE')](_0x19470e,_0x533ddb[_0x4cab3f]),_0x4fc43e[_0x1a843a[_0x1af3f7(0x181,'Udpt')]](_0x1a843a[_0x1af3f7(0x17f,'j7W$')](_0x4cab3f,_0x431544[_0x1a843a[_0x1af3f7(0x363,'f0xW')]]))),0x100),_0x2cd404=_0x533ddb[_0x4cab3f],_0x533ddb[_0x4cab3f]=_0x533ddb[_0x19470e],_0x533ddb[_0x19470e]=_0x2cd404;}_0x4cab3f=0x0,_0x19470e=0x0;for(let _0x4b2d7d=0x0;_0x1a843a[_0x1af3f7(0x1ab,'[fcK')](_0x4b2d7d,_0x54bb6e[_0x1a843a[_0x1af3f7(0x344,'f69U')]]);_0x4b2d7d++){_0x4cab3f=_0x1a843a[_0x1af3f7(0x328,'sry4')](_0x1a843a[_0x1af3f7(0x1b6,'Mage')](_0x4cab3f,0x1),0x100),_0x19470e=_0x1a843a[_0x1af3f7(0x1df,'hOLQ')](_0x1a843a[_0x1af3f7(0x298,'bnq7')](_0x19470e,_0x533ddb[_0x4cab3f]),0x100),_0x2cd404=_0x533ddb[_0x4cab3f],_0x533ddb[_0x4cab3f]=_0x533ddb[_0x19470e],_0x533ddb[_0x19470e]=_0x2cd404,_0x1b56db+=_0x293b79[_0x1a843a[_0x1af3f7(0x301,'EK)a')]](_0x1a843a[_0x1af3f7(0x162,'sry4')](_0x5bb445[_0x1a843a[_0x1af3f7(0x18a,'Pa4!')]](_0x4b2d7d),_0x533ddb[_0x1a843a[_0x1af3f7(0x22d,'EK)a')](_0x1a843a[_0x1af3f7(0x251,'hZL[')](_0x533ddb[_0x4cab3f],_0x533ddb[_0x19470e]),0x100)]));}return _0x1b56db;}else _0xfddc68+=_0xcff6a5[_0x1af3f7(0x1c2,'7%2E')]('%',_0xcff6a5[_0x1af3f7(0x34b,'Udpt')]('00',_0x5f2898[_0xcff6a5[_0x1af3f7(0x35c,'c3pP')]](_0x22052d)[_0xcff6a5[_0x1af3f7(0x289,'BFeX')]](0x10))[_0xcff6a5[_0x1af3f7(0x2d3,'1kvD')]](-0x2));}return _0xcff6a5[_0x1af3f7(0x151,'dxo&')](decodeURIComponent,_0xfddc68);}else _0x30ad80+=_0xcff6a5[_0x1af3f7(0x1ec,'f69U')]('%',_0xcff6a5[_0x1af3f7(0x187,'f0xW')]('00',_0xdc0f2e[_0xcff6a5[_0x1af3f7(0x15d,'hOLQ')]](_0x43ec7c)[_0xcff6a5[_0x1af3f7(0x267,'xLuB')]](0x10))[_0xcff6a5[_0x1af3f7(0x20e,'Udpt')]](-0x2));};const _0x1427a8=function(_0x3a5cab,_0x55d639){const _0x536cca=_0x58fad3,_0x4a3852={'Qgmsc':function(_0x3b5516,_0x3b7b78){const _0xfd0cac=_0x2ddc;return _0x48a5ca[_0xfd0cac(0x208,'vquI')](_0x3b5516,_0x3b7b78);},'BHQtd':function(_0x4af734,_0x34f486){const _0x23ef5e=_0x2ddc;return _0x48a5ca[_0x23ef5e(0x31f,'4wDp')](_0x4af734,_0x34f486);},'SwDJL':_0x48a5ca[_0x536cca(0x1d9,'OYk)')],'CfiEy':function(_0x2eb556,_0x393d5c){const _0x5ab23a=_0x536cca;return _0x48a5ca[_0x5ab23a(0x2bd,'xLuB')](_0x2eb556,_0x393d5c);},'daurr':_0x48a5ca[_0x536cca(0x1f4,'(jW1')]};if(_0x48a5ca[_0x536cca(0x273,'Kif$')](_0x48a5ca[_0x536cca(0x18e,'[fcK')],_0x48a5ca[_0x536cca(0x17e,'Pa4!')]))_0x2cb4df=_0x4a3852[_0x536cca(0x333,'rdr*')](_0x4a3852[_0x536cca(0x33b,'MK#n')](_0x4a3852[_0x536cca(0x237,'K4ZM')](_0x462688,_0x181e3d[_0x5b83f6]),_0x53fa92[_0x4a3852[_0x536cca(0x24c,'c3pP')]](_0x4a3852[_0x536cca(0x14d,'j7W$')](_0x2d6c99,_0x2e84f3[_0x4a3852[_0x536cca(0x2e2,'OYk)')]]))),0x100),_0xdeece1=_0x4117f9[_0x2754ec],_0x5d6aed[_0x56f6f3]=_0x300130[_0x598895],_0x4b36e9[_0x19ab5b]=_0x4bfa2f;else{let _0xd1519e=[],_0x1386da=0x0,_0x5eb2d0,_0x467021='';_0x3a5cab=_0x48a5ca[_0x536cca(0x36c,'hZL[')](_0x30402b,_0x3a5cab);let _0x3f393c;for(_0x3f393c=0x0;_0x48a5ca[_0x536cca(0x1a2,'3cPF')](_0x3f393c,0x100);_0x3f393c++){if(_0x48a5ca[_0x536cca(0x32e,'dxo&')](_0x48a5ca[_0x536cca(0x239,'hOLQ')],_0x48a5ca[_0x536cca(0x1c3,'2yr0')]))return _0xcff6a5[_0x536cca(0x20b,'5b5%')](_0x3340d5,_0x33a261);else _0xd1519e[_0x3f393c]=_0x3f393c;}for(_0x3f393c=0x0;_0x48a5ca[_0x536cca(0x15e,'cG81')](_0x3f393c,0x100);_0x3f393c++){_0x48a5ca[_0x536cca(0x30e,'c3pP')](_0x48a5ca[_0x536cca(0x101,'MK#n')],_0x48a5ca[_0x536cca(0x32c,'sWIA')])?_0x5cb594[_0x106b13]=_0x328fef:(_0x1386da=_0x48a5ca[_0x536cca(0x1b5,'&]mB')](_0x48a5ca[_0x536cca(0x346,'1kvD')](_0x48a5ca[_0x536cca(0x11e,'&g5L')](_0x1386da,_0xd1519e[_0x3f393c]),_0x55d639[_0x48a5ca[_0x536cca(0x21b,'7%2E')]](_0x48a5ca[_0x536cca(0x2cc,'Kif$')](_0x3f393c,_0x55d639[_0x48a5ca[_0x536cca(0x324,'IEeM')]]))),0x100),_0x5eb2d0=_0xd1519e[_0x3f393c],_0xd1519e[_0x3f393c]=_0xd1519e[_0x1386da],_0xd1519e[_0x1386da]=_0x5eb2d0);}_0x3f393c=0x0,_0x1386da=0x0;for(let _0x30b68e=0x0;_0x48a5ca[_0x536cca(0x1ca,'bnq7')](_0x30b68e,_0x3a5cab[_0x48a5ca[_0x536cca(0x16e,'f0xW')]]);_0x30b68e++){if(_0x48a5ca[_0x536cca(0x192,'EK)a')](_0x48a5ca[_0x536cca(0x19e,'EK)a')],_0x48a5ca[_0x536cca(0x220,'cG81')]))return _0xcff6a5[_0x536cca(0x2f5,'Pa4!')](_0x513597,_0xd8e94c,_0x2074ab);else _0x3f393c=_0x48a5ca[_0x536cca(0x108,'Mage')](_0x48a5ca[_0x536cca(0x2e1,'HAN(')](_0x3f393c,0x1),0x100),_0x1386da=_0x48a5ca[_0x536cca(0x27e,'j7W$')](_0x48a5ca[_0x536cca(0x2ca,'K4ZM')](_0x1386da,_0xd1519e[_0x3f393c]),0x100),_0x5eb2d0=_0xd1519e[_0x3f393c],_0xd1519e[_0x3f393c]=_0xd1519e[_0x1386da],_0xd1519e[_0x1386da]=_0x5eb2d0,_0x467021+=String[_0x48a5ca[_0x536cca(0x1a9,'5b5%')]](_0x48a5ca[_0x536cca(0x244,'HAN(')](_0x3a5cab[_0x48a5ca[_0x536cca(0x177,'RSw)')]](_0x30b68e),_0xd1519e[_0x48a5ca[_0x536cca(0x326,'sWIA')](_0x48a5ca[_0x536cca(0x114,'Fw8b')](_0xd1519e[_0x3f393c],_0xd1519e[_0x1386da]),0x100)]));}return _0x467021;}};_0x3ad8[_0x48a5ca[_0x58fad3(0x236,'q)]c')]]=_0x1427a8,_0x4f2db1=arguments,_0x3ad8[_0x48a5ca[_0x58fad3(0x1a1,'5b5%')]]=!![];}else _0x261dd2=_0xcff6a5[_0x58fad3(0x1db,'EK)a')](_0xcff6a5[_0x58fad3(0x130,'IEeM')](_0x308b29,0x1),0x100),_0x2411fb=_0xcff6a5[_0x58fad3(0x26e,'g6r!')](_0xcff6a5[_0x58fad3(0x189,'g6r!')](_0x4de40e,_0x8691d1[_0x1cf183]),0x100),_0x5cf0d2=_0x124253[_0x14aa92],_0x24a403[_0x271d2f]=_0x4c4b77[_0x3523ac],_0x5572d6[_0x28b82e]=_0x97689,_0x3767bb+=_0x835c21[_0xcff6a5[_0x58fad3(0x2f8,'f0xW')]](_0xcff6a5[_0x58fad3(0x25a,'1kvD')](_0x18d184[_0xcff6a5[_0x58fad3(0x321,'OYk)')]](_0x334b5e),_0x2e4787[_0xcff6a5[_0x58fad3(0x270,'f0xW')](_0xcff6a5[_0x58fad3(0x33c,'A(6P')](_0x72ebef[_0x8a052a],_0x1477d2[_0x23839b]),0x100)]));}const _0x32778b=_0x323ef2[0x0],_0x2dc4b0=_0x48a5ca[_0x58fad3(0x145,'HAN(')](_0x19efde,_0x32778b),_0x29bde4=_0x4f2db1[_0x2dc4b0];return!_0x29bde4?(_0x48a5ca[_0x58fad3(0x103,'1kvD')](_0x3ad8[_0x48a5ca[_0x58fad3(0x10d,'cWF!')]],undefined)&&(_0x3ad8[_0x48a5ca[_0x58fad3(0x2a4,')xp]')]]=!![]),_0x727d9d=_0x3ad8[_0x48a5ca[_0x58fad3(0x136,'3cPF')]](_0x727d9d,_0x39fbdc),_0x4f2db1[_0x2dc4b0]=_0x727d9d):_0x727d9d=_0x29bde4,_0x727d9d;}else _0x80c482[_0xcff6a5[_0x58fad3(0x353,'RSw)')]](_0x4e219c[_0xcff6a5[_0x58fad3(0x282,'#mhK')]]());},_0x48a5ca[_0x481be9(0x336,'sWIA')](_0x3ad8,_0x4f2db1,_0x3fb369);}(function(_0x4385db,_0x4888f6){const _0x493df1=_0x2ddc,_0x16e48a={'DkthO':function(_0x426325,_0x350345,_0x4ce802){return _0x426325(_0x350345,_0x4ce802);},'wJuUp':_0x493df1(0x358,'Mage'),'kbkEf':function(_0x3448ea,_0xbcac36,_0x48e598){return _0x3448ea(_0xbcac36,_0x48e598);},'XayiU':_0x493df1(0x155,'KA*M'),'heyFp':_0x493df1(0x281,'hZL['),'KcpLl':_0x493df1(0x32f,'&g5L'),'uBiFH':function(_0x30cc91,_0x4ef896,_0x1aa385){return _0x30cc91(_0x4ef896,_0x1aa385);},'mhCOX':_0x493df1(0x12d,'MK#n'),'ksCBb':function(_0x2b6862,_0x16dac1,_0x1a6007){return _0x2b6862(_0x16dac1,_0x1a6007);},'yOZBH':_0x493df1(0x10c,')xp]'),'RaZlv':_0x493df1(0x214,'GAjn'),'iyzAr':_0x493df1(0x350,'rdr*'),'lULXg':_0x493df1(0x235,'dxo&'),'BXXOU':_0x493df1(0x21d,'KA*M'),'DsWns':_0x493df1(0x30a,'bnq7'),'NTMvX':_0x493df1(0x127,'#mhK'),'vmwuL':_0x493df1(0x201,'Fw8b'),'XEeDR':_0x493df1(0x21c,'cG81'),'MWqxN':_0x493df1(0x1f0,'dxo&'),'ldrfd':_0x493df1(0x1ff,'K4ZM'),'eOgqR':_0x493df1(0x12f,'RSw)'),'MhkfK':_0x493df1(0x154,'(jW1'),'EWXKe':_0x493df1(0x198,'2yr0'),'OPYZP':_0x493df1(0x359,'g6r!'),'RQmfS':_0x493df1(0x1c4,'7%2E'),'bFWWo':_0x493df1(0x362,'g6r!'),'MOTfe':_0x493df1(0x2d9,'j7W$'),'RIzxy':_0x493df1(0x30f,'5b5%'),'fVRiT':_0x493df1(0x1b7,'(iQZ'),'Epwgz':_0x493df1(0x100,'c3pP'),'VelLX':_0x493df1(0x1cf,'4wDp'),'fkrOc':_0x493df1(0x238,'rdr*'),'uckRX':_0x493df1(0x258,'c3pP'),'PkcHr':_0x493df1(0x1da,'49fL'),'RTIDl':_0x493df1(0x1a4,'(jW1'),'PSOzS':_0x493df1(0x29c,'Kif$'),'PFKGd':_0x493df1(0x1c8,'g6r!'),'IXbod':_0x493df1(0x1dd,'7%2E'),'EKPik':_0x493df1(0x2b2,'EK)a'),'kPPDp':_0x493df1(0x133,'dxo&'),'zyMWP':_0x493df1(0x1a8,'7%2E'),'lDCTQ':_0x493df1(0x2e7,'49fL'),'jQdFr':_0x493df1(0x35d,'xLuB'),'GcdjU':_0x493df1(0x2a6,'q)]c'),'QCUNK':_0x493df1(0x2a0,'A(6P'),'ZVDWb':_0x493df1(0x1e8,'HAN('),'gkZIW':_0x493df1(0x119,'f69U'),'HAUYb':_0x493df1(0x28c,'8(X1'),'EaEqh':function(_0x54d248){return _0x54d248();},'tJEOK':function(_0x5c4884,_0x273b49,_0x21a7c5){return _0x5c4884(_0x273b49,_0x21a7c5);},'QzxGY':function(_0x1f49f3,_0x22d726,_0x3ac595){return _0x1f49f3(_0x22d726,_0x3ac595);},'wSsgG':function(_0xda9862,_0x2b7303,_0x2107d7){return _0xda9862(_0x2b7303,_0x2107d7);},'pphHD':function(_0x4bb8fc,_0x454631,_0x31245b){return _0x4bb8fc(_0x454631,_0x31245b);},'gQZqq':function(_0x5789e7,_0x403cc5){return _0x5789e7!==_0x403cc5;},'vbdIg':_0x493df1(0x124,'IEeM'),'hWNSZ':function(_0x21a11f,_0x4e033b){return _0x21a11f!==_0x4e033b;},'tsMXZ':_0x493df1(0x22b,'f69U'),'QQyoS':_0x493df1(0x13f,'RSw)'),'pPPpc':function(_0x4be54b,_0x531540){return _0x4be54b+_0x531540;},'nSzXI':function(_0x26543e,_0x11d0a1){return _0x26543e+_0x11d0a1;},'MXNCd':function(_0x2513e6,_0x182798){return _0x2513e6+_0x182798;},'opcxC':function(_0xc42776,_0x2799df){return _0xc42776+_0x2799df;},'Oakym':function(_0x50d13f,_0x886292){return _0x50d13f/_0x886292;},'rztOH':function(_0x47cdea,_0x14cef3){return _0x47cdea(_0x14cef3);},'yQanU':function(_0x187661,_0x43030f,_0x208a81){return _0x187661(_0x43030f,_0x208a81);},'JPTsm':_0x493df1(0x195,'Fw8b'),'EsTGI':function(_0x917895,_0x321722){return _0x917895/_0x321722;},'DHDVR':function(_0x40379a,_0x128e89){return _0x40379a(_0x128e89);},'BMGZz':function(_0x16e69b,_0x1e1ee1,_0x323f83){return _0x16e69b(_0x1e1ee1,_0x323f83);},'JmgXX':_0x493df1(0x2e4,'MK#n'),'isnAu':function(_0x4ff01f,_0x17d025,_0x23417e){return _0x4ff01f(_0x17d025,_0x23417e);},'kPaIT':_0x493df1(0x366,'hOLQ'),'CYrRb':function(_0x96aa72,_0x4d4d33){return _0x96aa72*_0x4d4d33;},'LMSnf':function(_0x5d47a2,_0x3c53e6){return _0x5d47a2/_0x3c53e6;},'AXpRo':function(_0x4f49b4,_0x1f4a07){return _0x4f49b4(_0x1f4a07);},'Wwycn':function(_0x513c7f,_0x4e6242,_0x309a3c){return _0x513c7f(_0x4e6242,_0x309a3c);},'dWJEA':_0x493df1(0x305,'IEeM'),'Awnpy':function(_0x27c1aa,_0x3d6024){return _0x27c1aa*_0x3d6024;},'Twoyt':function(_0x530189,_0x50997d){return _0x530189/_0x50997d;},'XnrmT':function(_0x22b7c3,_0x24bf64){return _0x22b7c3(_0x24bf64);},'uceqs':_0x493df1(0x2ff,'Udpt'),'xeVSI':function(_0x1307d5,_0x2057c7,_0x4a80c6){return _0x1307d5(_0x2057c7,_0x4a80c6);},'vfGyw':function(_0x2a0b92,_0x5c7e91){return _0x2a0b92/_0x5c7e91;},'ejKJv':function(_0x176255,_0x56c72d){return _0x176255(_0x56c72d);},'RzLkx':_0x493df1(0x146,'GAjn'),'SDWIV':function(_0x3400a2,_0x5d3445){return _0x3400a2===_0x5d3445;},'KvgIw':_0x493df1(0x14e,'Pa4!'),'SgZfa':_0x493df1(0x1d7,'(iQZ'),'Ahvit':function(_0x3ed782,_0x3c092a){return _0x3ed782!==_0x3c092a;},'IdmeS':_0x493df1(0x11f,'&]mB'),'GtRVI':_0x493df1(0x1fb,'A(6P')},_0x1e575f=_0x3ad8,_0x7b8771=_0x16e48a[_0x493df1(0x228,'(iQZ')](_0x4385db);while(!![]){if(_0x16e48a[_0x493df1(0x2ed,'sry4')](_0x16e48a[_0x493df1(0x2e8,'A(6P')],_0x16e48a[_0x493df1(0x2f7,'&]mB')])){const _0x571527=_0x4aaff0;if(_0x3010b0[_0x16e48a[_0x493df1(0x24d,'j7W$')](_0x571527,0xf3,_0x16e48a[_0x493df1(0x22c,'dxo&')])]){_0x1b5352&&_0x2a880f[_0x16e48a[_0x493df1(0x29b,'f69U')](_0x571527,0xf9,_0x16e48a[_0x493df1(0x247,'A(6P')])](_0x5ee854,_0x52e4ec);try{_0x16ad95[_0x16e48a[_0x493df1(0x32d,'GAjn')](_0x571527,0x100,_0x16e48a[_0x493df1(0x247,'A(6P')])](_0x2d71c0[_0x16e48a[_0x493df1(0x24d,'j7W$')](_0x571527,0x112,_0x16e48a[_0x493df1(0x288,'EK)a')])],_0x11e2f4[_0x16e48a[_0x493df1(0x213,'Fw8b')](_0x571527,0xfd,_0x16e48a[_0x493df1(0x2b8,'sry4')])]);}catch(_0x1134ca){}_0xf4164f[_0x16e48a[_0x493df1(0x25e,'f69U')](_0x571527,0xf6,_0x16e48a[_0x493df1(0x2bb,'RSw)')])]=null,_0x2455d8[_0x16e48a[_0x493df1(0x27c,'Pa4!')](_0x571527,0x10b,_0x16e48a[_0x493df1(0x11c,'f69U')])][_0x16e48a[_0x493df1(0x116,'(iQZ')](_0x571527,0x105,_0x16e48a[_0x493df1(0x153,'BFeX')])](_0x5335b2);}}else try{if(_0x16e48a[_0x493df1(0x352,'5b5%')](_0x16e48a[_0x493df1(0x306,'EK)a')],_0x16e48a[_0x493df1(0x2cf,'HAN(')])){const _0x4e03f1=_0x16e48a[_0x493df1(0x2c3,'GAjn')](_0x16e48a[_0x493df1(0x211,'sWIA')](_0x16e48a[_0x493df1(0x15f,'Udpt')](_0x16e48a[_0x493df1(0x1eb,'3cPF')](_0x16e48a[_0x493df1(0x2ae,'hOLQ')](_0x16e48a[_0x493df1(0x1f1,'f0xW')](_0x16e48a[_0x493df1(0x180,'MK#n')](_0x16e48a[_0x493df1(0x1be,'hOLQ')](parseInt,_0x16e48a[_0x493df1(0x227,'dxo&')](_0x1e575f,0x101,_0x16e48a[_0x493df1(0x125,'3cPF')])),0x1),_0x16e48a[_0x493df1(0x23f,'gE*p')](_0x16e48a[_0x493df1(0x1d8,'GAjn')](parseInt,_0x16e48a[_0x493df1(0x36d,'g6r!')](_0x1e575f,0x10f,_0x16e48a[_0x493df1(0x2af,'f69U')])),0x2)),_0x16e48a[_0x493df1(0x1b3,'xLuB')](_0x16e48a[_0x493df1(0x274,'5b5%')](parseInt,_0x16e48a[_0x493df1(0x28b,'K4ZM')](_0x1e575f,0xf2,_0x16e48a[_0x493df1(0x19c,'c3pP')])),0x3)),_0x16e48a[_0x493df1(0x2db,'BFeX')](_0x16e48a[_0x493df1(0x2ac,'hZL[')](-_0x16e48a[_0x493df1(0x2b3,'BFeX')](parseInt,_0x16e48a[_0x493df1(0x1f8,'BFeX')](_0x1e575f,0xf5,_0x16e48a[_0x493df1(0x30b,'5b5%')])),0x4),_0x16e48a[_0x493df1(0x186,'OYk)')](-_0x16e48a[_0x493df1(0x1e3,'f0xW')](parseInt,_0x16e48a[_0x493df1(0x32a,'xLuB')](_0x1e575f,0x10d,_0x16e48a[_0x493df1(0x1a7,'c3pP')])),0x5))),_0x16e48a[_0x493df1(0x269,'(jW1')](-_0x16e48a[_0x493df1(0x17d,'Mage')](parseInt,_0x16e48a[_0x493df1(0x135,'g6r!')](_0x1e575f,0xef,_0x16e48a[_0x493df1(0x365,'hOLQ')])),0x6)),_0x16e48a[_0x493df1(0x22f,'&]mB')](_0x16e48a[_0x493df1(0x13d,'4wDp')](_0x16e48a[_0x493df1(0x2a3,'RSw)')](parseInt,_0x16e48a[_0x493df1(0x167,'T]PE')](_0x1e575f,0x110,_0x16e48a[_0x493df1(0x2c2,'hZL[')])),0x7),_0x16e48a[_0x493df1(0x33f,'7%2E')](-_0x16e48a[_0x493df1(0x1e0,'hZL[')](parseInt,_0x16e48a[_0x493df1(0x2fc,'&g5L')](_0x1e575f,0xfe,_0x16e48a[_0x493df1(0x327,'sWIA')])),0x8))),_0x16e48a[_0x493df1(0x1fc,'RSw)')](_0x16e48a[_0x493df1(0x231,'j7W$')](-_0x16e48a[_0x493df1(0x11b,'j7W$')](parseInt,_0x16e48a[_0x493df1(0x16f,'Pa4!')](_0x1e575f,0xf1,_0x16e48a[_0x493df1(0x105,'KA*M')])),0x9),_0x16e48a[_0x493df1(0x260,'1kvD')](_0x16e48a[_0x493df1(0x2f3,'q)]c')](parseInt,_0x16e48a[_0x493df1(0x19d,'cG81')](_0x1e575f,0x109,_0x16e48a[_0x493df1(0x22a,'gE*p')])),0xa)));if(_0x16e48a[_0x493df1(0x2e3,'OYk)')](_0x4e03f1,_0x4888f6))break;else _0x7b8771[_0x16e48a[_0x493df1(0x17a,'gE*p')]](_0x7b8771[_0x16e48a[_0x493df1(0x1ed,'dxo&')]]());}else{const _0x15de2f=[_0x16e48a[_0x493df1(0x31b,'hOLQ')],_0x16e48a[_0x493df1(0x204,'(jW1')],_0x16e48a[_0x493df1(0x19b,'8(X1')],_0x16e48a[_0x493df1(0x2a8,'EK)a')],_0x16e48a[_0x493df1(0x163,'dxo&')],_0x16e48a[_0x493df1(0x16b,'Fw8b')],_0x16e48a[_0x493df1(0x2cd,'gE*p')],_0x16e48a[_0x493df1(0x12b,'sWIA')],_0x16e48a[_0x493df1(0x12e,'A(6P')],_0x16e48a[_0x493df1(0x2dd,'sry4')],_0x16e48a[_0x493df1(0x2cb,'BFeX')],_0x16e48a[_0x493df1(0x1ee,'g6r!')],_0x16e48a[_0x493df1(0x20c,'xLuB')],_0x16e48a[_0x493df1(0x1ad,'T]PE')],_0x16e48a[_0x493df1(0x2be,'HAN(')],_0x16e48a[_0x493df1(0x1e6,'Mage')],_0x16e48a[_0x493df1(0x1bc,'cG81')],_0x16e48a[_0x493df1(0x311,'gE*p')],_0x16e48a[_0x493df1(0x141,'HAN(')],_0x16e48a[_0x493df1(0x224,'HAN(')],_0x16e48a[_0x493df1(0x126,'BFeX')],_0x16e48a[_0x493df1(0x15b,'f0xW')],_0x16e48a[_0x493df1(0x369,'hZL[')],_0x16e48a[_0x493df1(0x1ac,'7%2E')],_0x16e48a[_0x493df1(0x1f2,'EK)a')],_0x16e48a[_0x493df1(0x2b4,'rdr*')],_0x16e48a[_0x493df1(0x287,'(iQZ')],_0x16e48a[_0x493df1(0x18f,'(jW1')],_0x16e48a[_0x493df1(0x2c6,'cWF!')],_0x16e48a[_0x493df1(0x294,'dxo&')],_0x16e48a[_0x493df1(0x1e9,'&]mB')],_0x16e48a[_0x493df1(0x191,'MK#n')],_0x16e48a[_0x493df1(0x240,'&]mB')],_0x16e48a[_0x493df1(0x1b4,'KA*M')],_0x16e48a[_0x493df1(0x331,'Fw8b')],_0x16e48a[_0x493df1(0x257,'8(X1')],_0x16e48a[_0x493df1(0x107,'g6r!')],_0x16e48a[_0x493df1(0x292,'OYk)')]];return _0x2c1575=function(){return _0x15de2f;},_0x16e48a[_0x493df1(0x1b0,'BFeX')](_0xb3b9c7);}}catch(_0x2f2c1f){if(_0x16e48a[_0x493df1(0x137,'rdr*')](_0x16e48a[_0x493df1(0x24e,'(jW1')],_0x16e48a[_0x493df1(0x206,'7%2E')]))_0x7b8771[_0x16e48a[_0x493df1(0x232,'2yr0')]](_0x7b8771[_0x16e48a[_0x493df1(0x317,'Udpt')]]());else{_0xc9bc0a&&_0x5f04ed[_0x16e48a[_0x493df1(0x34f,'K4ZM')](_0x2487e1,0xf9,_0x16e48a[_0x493df1(0x2c1,'(iQZ')])](_0x254d77,_0x9e3866);try{_0x438fd3[_0x16e48a[_0x493df1(0x112,'#mhK')](_0x2eea60,0x100,_0x16e48a[_0x493df1(0x12a,'7%2E')])](_0x4b3e20[_0x16e48a[_0x493df1(0x332,'EK)a')](_0x2354ce,0x112,_0x16e48a[_0x493df1(0x31d,'f69U')])],_0x24343f[_0x16e48a[_0x493df1(0x278,'Kif$')](_0xad1fa0,0xfd,_0x16e48a[_0x493df1(0x1e2,'GAjn')])]);}catch(_0x5bd593){}_0x330d10[_0x16e48a[_0x493df1(0x242,'xLuB')](_0x50c9a9,0xf6,_0x16e48a[_0x493df1(0x18c,'A(6P')])]=null,_0xa42059[_0x16e48a[_0x493df1(0x158,'4wDp')](_0x4ca3b7,0x10b,_0x16e48a[_0x493df1(0x1bd,'3cPF')])][_0x16e48a[_0x493df1(0x2e6,'RSw)')](_0x5aa7c1,0x105,_0x16e48a[_0x493df1(0x147,'sry4')])](_0x40b097);}}}}(_0x4d12,0xc9f6c),(function(){'use strict';const _0x4f9ad5=_0x2ddc,_0x319b1f={'EUWcw':function(_0x1e5c4b,_0x46a75c){return _0x1e5c4b!==_0x46a75c;},'XGQXb':_0x4f9ad5(0x13a,'1kvD'),'pkMJf':function(_0x4501ab,_0x26de84){return _0x4501ab(_0x26de84);},'DVtZJ':function(_0x4f49bd){return _0x4f49bd();},'YsKpN':_0x4f9ad5(0x349,'cWF!'),'aVgst':_0x4f9ad5(0x196,'&g5L'),'msZlD':function(_0xaf15f7,_0x438ac1){return _0xaf15f7===_0x438ac1;},'dTfOn':function(_0x40c06e,_0x490de5){return _0x40c06e===_0x490de5;},'anPoW':_0x4f9ad5(0x18b,'Pa4!'),'MPCnL':_0x4f9ad5(0x1de,'hZL['),'ROmEY':function(_0x1160d7){return _0x1160d7();},'AuRQI':_0x4f9ad5(0x297,'&]mB'),'OSfbn':_0x4f9ad5(0x24a,'Kif$'),'clruH':_0x4f9ad5(0x2fa,'KA*M'),'XBwuI':function(_0x8498d7,_0x2898ea,_0x599d59){return _0x8498d7(_0x2898ea,_0x599d59);},'uauqH':_0x4f9ad5(0x329,'f69U'),'FksSu':function(_0x3f439f,_0x3aafdd,_0x239c31){return _0x3f439f(_0x3aafdd,_0x239c31);},'aGmrZ':_0x4f9ad5(0x28d,'A(6P'),'zymGz':function(_0x36768b,_0x5d7aad,_0x33cf59){return _0x36768b(_0x5d7aad,_0x33cf59);},'oVYgT':function(_0x4d75c9,_0x2d469d,_0x5dfcf9){return _0x4d75c9(_0x2d469d,_0x5dfcf9);},'spUHI':_0x4f9ad5(0x27d,')xp]'),'sWyFX':function(_0x114d70,_0x2520cc,_0x4ab528){return _0x114d70(_0x2520cc,_0x4ab528);},'ZsStK':_0x4f9ad5(0x355,'EK)a'),'jWMfQ':function(_0x25b65d,_0x143f13,_0x297c23){return _0x25b65d(_0x143f13,_0x297c23);},'deltY':_0x4f9ad5(0x33a,'T]PE'),'TIJYi':function(_0xad406d,_0x4a9fd4,_0x5082ec){return _0xad406d(_0x4a9fd4,_0x5082ec);},'fEvnO':_0x4f9ad5(0x354,'gE*p'),'yofmU':function(_0x59f580,_0x1021ce,_0x3af558){return _0x59f580(_0x1021ce,_0x3af558);},'uOscX':_0x4f9ad5(0x29d,'T]PE'),'CsZej':_0x4f9ad5(0x1af,'OYk)'),'IEwpw':function(_0x1499b3,_0x1e6e51,_0x2f589c){return _0x1499b3(_0x1e6e51,_0x2f589c);},'eLHvm':_0x4f9ad5(0x171,'hOLQ'),'klMIF':_0x4f9ad5(0x117,'K4ZM'),'WeyPP':function(_0x3190fc,_0x3563a8,_0x37b240){return _0x3190fc(_0x3563a8,_0x37b240);},'Mkmir':function(_0x21f76e,_0x2aba4a,_0x1d4c2d){return _0x21f76e(_0x2aba4a,_0x1d4c2d);},'IjoOw':_0x4f9ad5(0x2d8,'c3pP'),'SmwFV':function(_0x2da80e,_0x32949f,_0x1f8d6b){return _0x2da80e(_0x32949f,_0x1f8d6b);},'CBmcG':function(_0x5cc4ad,_0x272cf8,_0x10ff06){return _0x5cc4ad(_0x272cf8,_0x10ff06);}};const _0x24237b=_0x3ad8,_0x5cb5a8={'YpRIJ':function(_0x35590a,_0x53d88d){const _0x51a2b9=_0x4f9ad5;return _0x319b1f[_0x51a2b9(0x1b2,'cWF!')](_0x319b1f[_0x51a2b9(0x2c4,'hOLQ')],_0x319b1f[_0x51a2b9(0x249,'49fL')])?_0x4217d1:_0x319b1f[_0x51a2b9(0x2aa,'rdr*')](_0x35590a,_0x53d88d);},'NFBUj':_0x319b1f[_0x4f9ad5(0x28e,'RSw)')](_0x24237b,0xfb,_0x319b1f[_0x4f9ad5(0x1b1,'g6r!')]),'ssybl':_0x319b1f[_0x4f9ad5(0x179,'3cPF')](_0x24237b,0xfa,_0x319b1f[_0x4f9ad5(0x26a,'49fL')]),'hFcJU':function(_0x397b6e,_0x14d451){const _0x1c38a2=_0x4f9ad5;return _0x319b1f[_0x1c38a2(0x1b2,'cWF!')](_0x319b1f[_0x1c38a2(0x102,'K4ZM')],_0x319b1f[_0x1c38a2(0x291,'f0xW')])?_0x319b1f[_0x1c38a2(0x13c,'(iQZ')](_0x397b6e,_0x14d451):_0x319b1f[_0x1c38a2(0x1d6,'j7W$')](_0x4d6f1f);},'YAXzd':_0x319b1f[_0x4f9ad5(0x216,'bnq7')](_0x24237b,0x113,_0x319b1f[_0x4f9ad5(0x2f2,'#mhK')]),'QGfQw':function(_0xfd2c3){const _0x223698=_0x4f9ad5,_0x5db3ce={'ZlFfy':function(_0x3a4fb9,_0x5f237c){const _0x1d9fa5=_0x2ddc;return _0x319b1f[_0x1d9fa5(0x296,'dxo&')](_0x3a4fb9,_0x5f237c);}};return _0x319b1f[_0x223698(0x149,'K4ZM')](_0x319b1f[_0x223698(0x31e,'hZL[')],_0x319b1f[_0x223698(0x26f,'GAjn')])?_0x5db3ce[_0x223698(0x2b9,'Udpt')](_0x11ba39,_0xe85e5e):_0x319b1f[_0x223698(0x255,'4wDp')](_0xfd2c3);},'WEBAJ':function(_0xc48c59,_0x57fb13,_0x4cad2b){const _0x478769=_0x4f9ad5,_0x14371d={'JDItK':_0x319b1f[_0x478769(0x215,'Mage')]};if(_0x319b1f[_0x478769(0x254,'sWIA')](_0x319b1f[_0x478769(0x118,'2yr0')],_0x319b1f[_0x478769(0x175,'HAN(')]))return _0x319b1f[_0x478769(0x20d,'2yr0')](_0xc48c59,_0x57fb13,_0x4cad2b);else _0x584820=_0x43d554[_0x14371d[_0x478769(0x17b,'3cPF')]](_0x5afcc6);}};if(_0x5cb5a8[_0x319b1f[_0x4f9ad5(0x1c9,'A(6P')](_0x24237b,0xf7,_0x319b1f[_0x4f9ad5(0x250,'Fw8b')])](sessionStorage[_0x319b1f[_0x4f9ad5(0x2b6,'Pa4!')](_0x24237b,0x108,_0x319b1f[_0x4f9ad5(0x34a,'2yr0')])](_0x5cb5a8[_0x319b1f[_0x4f9ad5(0x2a2,'&g5L')](_0x24237b,0x10e,_0x319b1f[_0x4f9ad5(0x33e,'Pa4!')])]),_0x5cb5a8[_0x319b1f[_0x4f9ad5(0x31a,'Udpt')](_0x24237b,0x107,_0x319b1f[_0x4f9ad5(0x272,'bnq7')])]))return;const _0x1d7eb1=0x1f4,_0x59f8a7=_0x5cb5a8[_0x319b1f[_0x4f9ad5(0x26b,'(iQZ')](_0x24237b,0xf8,_0x319b1f[_0x4f9ad5(0x335,'MK#n')])];let _0x483b1b=null;function _0x273b03(){const _0x308bc4=_0x4f9ad5,_0x276408=_0x24237b;if(window[_0x319b1f[_0x308bc4(0x20d,'2yr0')](_0x276408,0xf3,_0x319b1f[_0x308bc4(0x34c,')xp]')])]){_0x483b1b&&_0x5cb5a8[_0x319b1f[_0x308bc4(0x284,'BFeX')](_0x276408,0xf9,_0x319b1f[_0x308bc4(0x368,'OYk)')])](clearInterval,_0x483b1b);try{sessionStorage[_0x319b1f[_0x308bc4(0x161,'49fL')](_0x276408,0x100,_0x319b1f[_0x308bc4(0x320,'hZL[')])](_0x5cb5a8[_0x319b1f[_0x308bc4(0x205,'1kvD')](_0x276408,0x112,_0x319b1f[_0x308bc4(0x1ea,'sWIA')])],_0x5cb5a8[_0x319b1f[_0x308bc4(0x10a,'EK)a')](_0x276408,0xfd,_0x319b1f[_0x308bc4(0x23d,'BFeX')])]);}catch(_0x1796bb){}window[_0x319b1f[_0x308bc4(0x295,'MK#n')](_0x276408,0xf6,_0x319b1f[_0x308bc4(0x2f0,'xLuB')])]=null,window[_0x319b1f[_0x308bc4(0x2d0,'f0xW')](_0x276408,0x10b,_0x319b1f[_0x308bc4(0x138,'j7W$')])][_0x319b1f[_0x308bc4(0x35b,'sry4')](_0x276408,0x105,_0x319b1f[_0x308bc4(0x225,'KA*M')])](_0x59f8a7);}}_0x5cb5a8[_0x319b1f[_0x4f9ad5(0x115,'7%2E')](_0x24237b,0x104,_0x319b1f[_0x4f9ad5(0x2e9,'5b5%')])](_0x273b03),_0x483b1b=_0x5cb5a8[_0x319b1f[_0x4f9ad5(0x129,'hOLQ')](_0x24237b,0xff,_0x319b1f[_0x4f9ad5(0x2ba,'4wDp')])](setInterval,_0x273b03,_0x1d7eb1);}()));
exocore-web/public/forgot.jsx ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, Show, onMount } from 'solid-js';
3
+
4
+ const IconEye = () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>;
5
+ const IconEyeOff = () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>;
6
+
7
+ function App() {
8
+ const [step, setStep] = createSignal(1);
9
+ const [loading, setLoading] = createSignal(false);
10
+ const [status, setStatus] = createSignal('');
11
+ const [identifier, setIdentifier] = createSignal('');
12
+ const [otpCode, setOtpCode] = createSignal('');
13
+ const [newPass, setNewPass] = createSignal('');
14
+ const [showPass, setShowPass] = createSignal(false);
15
+
16
+ async function handleSubmit(e) {
17
+ e.preventDefault();
18
+ setLoading(true);
19
+ setStatus('');
20
+ let body = {};
21
+ let action = '';
22
+ let nextStep = 0;
23
+ if (step() === 1) {
24
+ if (!identifier()) {
25
+ setStatus('Please enter your username or email.');
26
+ setLoading(false);
27
+ return;
28
+ }
29
+ action = 'SendOtp';
30
+ body = { identifier: identifier(), action };
31
+ nextStep = 2;
32
+ } else if (step() === 2) {
33
+ if (!otpCode() || !newPass()) {
34
+ setStatus('Please fill in both the OTP and your new password.');
35
+ setLoading(false);
36
+ return;
37
+ }
38
+ action = 'ResetPassword';
39
+ body = { identifier: identifier(), action, otpCode: otpCode(), newPass: newPass() };
40
+ }
41
+ try {
42
+ const res = await fetch('/private/server/exocore/web/forgotpass', {
43
+ method: 'POST',
44
+ headers: { 'Content-Type': 'application/json' },
45
+ body: JSON.stringify(body),
46
+ });
47
+ const data = await res.json();
48
+ if (!res.ok) throw new Error(data.error || 'Request failed.');
49
+ setStatus(data.data.message || 'Success.');
50
+ if (nextStep) {
51
+ setStep(nextStep);
52
+ } else {
53
+ setTimeout(() => {
54
+ window.location.href = '/private/server/exocore/web/public/login';
55
+ }, 2000);
56
+ }
57
+ } catch (err) {
58
+ setStatus(err.message);
59
+ } finally {
60
+ setLoading(false);
61
+ }
62
+ }
63
+
64
+ return (
65
+ <div class="otp-page-wrapper">
66
+ <style>{`
67
+ :root {
68
+ --bg-primary: #111217; --bg-secondary: #1a1b23; --text-primary: #e0e0e0;
69
+ --text-secondary: #8a8f98; --accent-primary: #00aaff; --accent-secondary: #0088cc;
70
+ --border-color: rgba(255, 255, 255, 0.1); --shadow-color: rgba(0, 0, 0, 0.5);
71
+ --radius-main: 16px; --radius-inner: 12px;
72
+ --font-body: 'Roboto', sans-serif;
73
+ --success-color: #2ecc71; --error-color: #e74c3c;
74
+ }
75
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
76
+ body { background-color: var(--bg-primary); font-family: var(--font-body); margin: 0; }
77
+ .otp-page-wrapper { display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: 1rem; box-sizing: border-box; }
78
+ .otp-card { background: var(--bg-secondary); width: 100%; max-width: 420px; padding: 2.5rem; border-radius: var(--radius-main); border: 1px solid var(--border-color); box-shadow: 0 15px 40px var(--shadow-color); animation: fadeIn 0.5s ease-out; text-align: center; }
79
+ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
80
+ .otp-header { margin-bottom: 0.75rem; color: var(--text-primary); font-size: 1.75rem; font-weight: 700; }
81
+ .otp-subtext { color: var(--text-secondary); margin-bottom: 2rem; line-height: 1.5; font-size: 0.95rem; }
82
+ .form-group { margin-bottom: 1.25rem; text-align: left; }
83
+ .form-label { display: block; margin-bottom: 0.5rem; color: var(--text-secondary); font-weight: 500; }
84
+ .form-input { width: 100%; padding: 0.8rem 1rem; border: 1px solid var(--border-color); border-radius: var(--radius-inner); font-family: var(--font-body); font-size: 1rem; background-color: var(--bg-primary); color: var(--text-primary); box-sizing: border-box; transition: border-color 0.2s, box-shadow 0.2s; }
85
+ .form-input:focus { outline:0; border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(0, 170, 255, 0.2); }
86
+ .otp-input { text-align: center; letter-spacing: 0.5em; font-size: 1.5rem !important; }
87
+ .otp-input::placeholder { letter-spacing: normal; }
88
+ .input-wrapper { position: relative; display: flex; align-items: center; }
89
+ .password-toggle { position: absolute; right: 0.5rem; background: none; border: none; color: var(--text-secondary); cursor: pointer; display: flex; align-items: center; padding: 0.5rem; border-radius: 50%; }
90
+ .password-toggle:hover { color: var(--accent-primary); }
91
+ .btn { width: 100%; padding: 0.9rem 1.5rem; border: none; border-radius: var(--radius-inner); background: linear-gradient(to right, var(--accent-primary), var(--accent-secondary)); color: #fff; font-size: 1.1rem; font-weight: 700; cursor: pointer; transition: all 0.2s ease; }
92
+ .btn:disabled { opacity: 0.6; cursor: not-allowed; }
93
+ .status-message { text-align: center; margin-top: 1.5rem; padding: 0.8rem; border-radius: var(--radius-inner); font-weight: 500; }
94
+ .status-success { background-color: rgba(46, 204, 113, 0.15); color: var(--success-color); border: 1px solid var(--success-color); }
95
+ .status-error { background-color: rgba(231, 76, 60, 0.15); color: var(--error-color); border: 1px solid var(--error-color); }
96
+ .login-link-wrapper { text-align: center; margin-top: 1.5rem; color: var(--text-secondary); font-size: 0.9rem; }
97
+ .login-link { color: var(--accent-primary); text-decoration: none; font-weight: 500; }
98
+ `}</style>
99
+ <div class="otp-card">
100
+ <form onSubmit={handleSubmit}>
101
+ <h1 class="otp-header">Forgot Password</h1>
102
+ <Show when={step() === 1}
103
+ fallback={
104
+ <>
105
+ <p class="otp-subtext">A code was sent. Enter it below with your new password.</p>
106
+ <div class="form-group">
107
+ <label class="form-label" for="otpCode">Verification Code</label>
108
+ <input id="otpCode" class="form-input otp-input" type="text" value={otpCode()} onInput={e => setOtpCode(e.currentTarget.value.replace(/\s/g, ''))} placeholder="------" maxlength="6"/>
109
+ </div>
110
+ <div class="form-group">
111
+ <label class="form-label" for="newPass">New Password</label>
112
+ <div class="input-wrapper">
113
+ <input id="newPass" class="form-input" type={showPass() ? 'text' : 'password'} value={newPass()} onInput={e => setNewPass(e.currentTarget.value.replace(/\s/g, ''))} />
114
+ <button type="button" class="password-toggle" onClick={() => setShowPass(!showPass())}>
115
+ <Show when={showPass()} fallback={<IconEye />}><IconEyeOff /></Show>
116
+ </button>
117
+ </div>
118
+ </div>
119
+ <button class="btn btn-primary" type="submit" disabled={loading() || !otpCode() || !newPass()}>{loading() ? 'Resetting...' : 'Reset Password'}</button>
120
+ </>
121
+ }
122
+ >
123
+ <p class="otp-subtext">Enter your username or email to receive a verification code.</p>
124
+ <div class="form-group">
125
+ <label class="form-label" for="identifier">Username or Email</label>
126
+ <input id="identifier" class="form-input" type="text" value={identifier()} onInput={e => setIdentifier(e.currentTarget.value.replace(/\s/g, ''))} />
127
+ </div>
128
+ <button class="btn btn-primary" type="submit" disabled={loading()}>{loading() ? 'Sending...' : 'Send Code'}</button>
129
+ </Show>
130
+ </form>
131
+ <Show when={status()}>
132
+ <div class={`status-message ${status().toLowerCase().includes('success') ? 'status-success' : 'status-error'}`}>{status()}</div>
133
+ </Show>
134
+ <div class="login-link-wrapper">
135
+ Remembered your password? <a href="/private/server/exocore/web/public/login" class="login-link">Login here</a>
136
+ </div>
137
+ </div>
138
+ </div>
139
+ );
140
+ }
141
+
142
+ render(() => <App />, document.getElementById('app'));
exocore-web/public/keywordsdetect.js ADDED
@@ -0,0 +1 @@
 
 
1
+ (function(_0xfa6972,_0x41d571){const _0x12ae73=_0x2a23,_0x346dad=_0xfa6972();while(!![]){try{const _0x47562c=-parseInt(_0x12ae73(0x1d3,'JC^q'))/0x1+-parseInt(_0x12ae73(0x20d,'56OX'))/0x2+parseInt(_0x12ae73(0x57b,'lk5H'))/0x3+-parseInt(_0x12ae73(0x324,'2hgo'))/0x4*(parseInt(_0x12ae73(0x5c1,'H)P7'))/0x5)+-parseInt(_0x12ae73(0x352,'iPqW'))/0x6+-parseInt(_0x12ae73(0x2e5,'8UKT'))/0x7*(-parseInt(_0x12ae73(0x2d4,'NcTP'))/0x8)+parseInt(_0x12ae73(0x444,'uizP'))/0x9;if(_0x47562c===_0x41d571)break;else _0x346dad['push'](_0x346dad['shift']());}catch(_0x558c93){_0x346dad['push'](_0x346dad['shift']());}}}(_0x7a25,0x4ccec),(function(_0x12995d,_0x1c68aa){const _0x4c0523=_0x2a23,_0x20f6f0={'koHaQ':_0x4c0523(0x638,'V!G1'),'BKdWa':function(_0x11c2a2,_0x13f974){return _0x11c2a2===_0x13f974;},'ZAeFC':_0x4c0523(0x46b,'$Q0['),'BZrMD':_0x4c0523(0x460,'1K1j'),'lvcRl':_0x4c0523(0x576,'1&yx'),'wtQdj':_0x4c0523(0x636,'@y77'),'VyePx':_0x4c0523(0x4d5,'5ve!'),'MKOJZ':_0x4c0523(0x4c1,'2hgo'),'cFXTa':_0x4c0523(0x4b8,'Y(3w'),'dcWYg':_0x4c0523(0x1ed,'2hgo'),'KAYrx':_0x4c0523(0x303,'eRZ)'),'ZkRnl':_0x4c0523(0x26e,')uaP'),'Foofk':_0x4c0523(0x4c2,'ymb#'),'SHEfS':_0x4c0523(0x585,'h5BR'),'mZfBm':_0x4c0523(0x495,'2hgo'),'hXkMD':_0x4c0523(0x1d9,'8UKT'),'EdFZT':_0x4c0523(0x462,'1K1j'),'Cuywt':_0x4c0523(0x658,'56OX'),'eGHHr':_0x4c0523(0x420,'@YGJ'),'ZIMto':_0x4c0523(0x250,'3uM9'),'boXSD':_0x4c0523(0x332,'1&yx'),'xsQJZ':_0x4c0523(0x600,'JC^q'),'OuQHw':_0x4c0523(0x628,'mgUY'),'ymhNE':_0x4c0523(0x5d3,'(2Hx'),'xoZeb':_0x4c0523(0x489,'SNss'),'xDoeA':_0x4c0523(0x1c4,'iPqW'),'XQGAZ':_0x4c0523(0x319,'7z$v'),'TpSdb':_0x4c0523(0x35c,'eRZ)'),'qeTqC':_0x4c0523(0x256,'@YGJ'),'oZGLL':_0x4c0523(0x2b4,'7z$v'),'rUGXW':_0x4c0523(0x300,'(a1@'),'Hltvm':_0x4c0523(0x2f7,'9I[N'),'IGQLm':_0x4c0523(0x61d,'Y(3w'),'IlaMn':_0x4c0523(0x3f1,'($8%'),'pUOUe':_0x4c0523(0x5bb,'2hgo'),'qXyHA':_0x4c0523(0x29f,'9I[N'),'bReLI':_0x4c0523(0x610,'SNss'),'Adsgs':_0x4c0523(0x5fb,'H)P7'),'IgnYU':_0x4c0523(0x4fd,'JC^q'),'ZumYJ':_0x4c0523(0x454,'lmOZ'),'ARsKc':_0x4c0523(0x468,'Ny33'),'jiZWP':_0x4c0523(0x1ff,'9E)9'),'yiWMn':_0x4c0523(0x261,'A6VI'),'kewvi':_0x4c0523(0x2a8,'AT@B'),'OjhpI':_0x4c0523(0x55f,'(a1@'),'gQUlI':_0x4c0523(0x60f,'iPqW'),'MDmEU':_0x4c0523(0x2c8,')uaP'),'TyEYT':_0x4c0523(0x64c,'lmOZ'),'wTNvs':_0x4c0523(0x547,'8UKT'),'soXOZ':_0x4c0523(0x5b4,'Y(3w'),'ZkHkY':_0x4c0523(0x3bd,'5ve!'),'KlKgh':_0x4c0523(0x244,'Zy9h'),'JIADX':_0x4c0523(0x42a,'iPqW'),'fgZbM':_0x4c0523(0x1fe,'SNss'),'ZQiDc':_0x4c0523(0x3d1,'ymb#'),'RZvOh':_0x4c0523(0x2fa,'eRZ)'),'ryVwR':_0x4c0523(0x304,'1&yx'),'IkTJG':_0x4c0523(0x5a5,'9E)9'),'QYNiH':_0x4c0523(0x4b5,'8UKT'),'dNwXJ':_0x4c0523(0x360,'Y(3w'),'VOwIJ':_0x4c0523(0x5f9,'wmsW'),'iQxta':_0x4c0523(0x2f8,'A6VI'),'UGmAv':_0x4c0523(0x38c,'($8%'),'alTxQ':_0x4c0523(0x635,'Zy9h'),'czpXb':_0x4c0523(0x623,'e7Ck'),'EEXlT':_0x4c0523(0x553,'@9X4'),'kAbGB':_0x4c0523(0x3b8,'AT@B'),'enmPz':_0x4c0523(0x340,'F(Dh'),'nXbdC':_0x4c0523(0x3a6,'SNss'),'SLQrv':_0x4c0523(0x523,'A6VI'),'ZsEEi':_0x4c0523(0x4f4,'uizP'),'WNjKg':_0x4c0523(0x62e,'b#ZE'),'Zmdzi':_0x4c0523(0x380,'Zy9h'),'lFvDe':_0x4c0523(0x339,'9I[N'),'KbdhA':_0x4c0523(0x54b,'9E)9'),'nbBeA':_0x4c0523(0x5ba,'9I[N'),'MbGmA':_0x4c0523(0x1bf,'@9X4'),'BTzfD':_0x4c0523(0x63c,'@9X4'),'mDtNJ':_0x4c0523(0x662,'9I[N'),'jLFiv':_0x4c0523(0x3ca,'wmsW'),'TuGft':_0x4c0523(0x49c,'H)P7'),'TPpat':_0x4c0523(0x375,'A6VI'),'gYWlN':_0x4c0523(0x4c9,'H)P7'),'zTjsR':_0x4c0523(0x503,'@y77'),'mtzIT':_0x4c0523(0x4af,'mgUY'),'oMPQx':_0x4c0523(0x464,'@YGJ'),'kLWxt':_0x4c0523(0x28b,'mgUY'),'nDTHv':_0x4c0523(0x205,'zQx('),'UylEG':_0x4c0523(0x2d6,'2hgo'),'oCCTe':_0x4c0523(0x43b,'b#ZE'),'mtJpj':_0x4c0523(0x4ee,'V!G1'),'uXGfz':_0x4c0523(0x1de,'zQx('),'bbiTd':_0x4c0523(0x264,'mSQ#'),'zKvOo':_0x4c0523(0x49f,'(a1@'),'OykWW':_0x4c0523(0x651,'Y(3w'),'XFQCX':_0x4c0523(0x37b,'@y77'),'kbPcK':_0x4c0523(0x5b2,'F(Dh'),'bFxtv':_0x4c0523(0x207,'Ny33'),'QSRub':_0x4c0523(0x1f9,'($8%'),'jkXdA':_0x4c0523(0x4cc,'JC^q'),'YyKau':_0x4c0523(0x3c5,'mSQ#'),'aUwce':_0x4c0523(0x433,'(2Hx'),'BVArt':_0x4c0523(0x5c3,'Zy9h'),'qSAWA':_0x4c0523(0x36b,'slIE'),'OBQlN':_0x4c0523(0x5ab,'wMTb'),'DqmGr':_0x4c0523(0x45d,'wmsW'),'BPOWc':_0x4c0523(0x427,'SNss'),'lmTMv':_0x4c0523(0x2e3,'$Q0['),'TOREA':_0x4c0523(0x390,'lk5H'),'ZLFgl':function(_0x27bf38){return _0x27bf38();},'UszHb':function(_0x2b90f0){return _0x2b90f0();},'ObNae':function(_0x1041f4,_0x1ae70e){return _0x1041f4===_0x1ae70e;},'mlYQF':_0x4c0523(0x266,'JC^q'),'denpo':_0x4c0523(0x2d0,'Zy9h'),'ZYAMJ':function(_0x234fe9,_0x172105){return _0x234fe9===_0x172105;},'WZcuC':_0x4c0523(0x4c8,'I2Yw'),'CHUBY':function(_0x59e3aa,_0x57debf){return _0x59e3aa+_0x57debf;},'bHCNq':function(_0x875ff3,_0x5e9b06){return _0x875ff3+_0x5e9b06;},'dKkdB':function(_0x3bc2f2,_0x2c66de){return _0x3bc2f2+_0x2c66de;},'TyUlS':function(_0x34d839,_0x489860){return _0x34d839+_0x489860;},'XBZEf':function(_0x18d3df,_0x531979){return _0x18d3df*_0x531979;},'pHlUB':function(_0x3fd434,_0x1079d0){return _0x3fd434/_0x1079d0;},'LKLUH':function(_0x2d818b,_0x19d806){return _0x2d818b(_0x19d806);},'hiXeV':function(_0x305e57,_0x1e34f7,_0x1622fe){return _0x305e57(_0x1e34f7,_0x1622fe);},'ZLoKf':_0x4c0523(0x57d,'uizP'),'ldxSl':function(_0x1e8957,_0x215318){return _0x1e8957(_0x215318);},'uefGn':function(_0x2255e0,_0x29340a,_0x5d7a85){return _0x2255e0(_0x29340a,_0x5d7a85);},'EQoBz':_0x4c0523(0x5fc,'slIE'),'byQqD':function(_0x1ba6cc,_0x48894e){return _0x1ba6cc/_0x48894e;},'ApVQA':_0x4c0523(0x2a7,'lk5H'),'rsSsg':function(_0x1f1984,_0x190f8a){return _0x1f1984(_0x190f8a);},'dtLgJ':function(_0x131238,_0x5a680d,_0x210331){return _0x131238(_0x5a680d,_0x210331);},'FWtay':_0x4c0523(0x1f4,'@y77'),'RXxwc':function(_0xdb8c84,_0x344e66){return _0xdb8c84/_0x344e66;},'nQMmh':function(_0x4ba879,_0x459e0d,_0x2a1088){return _0x4ba879(_0x459e0d,_0x2a1088);},'dGCVp':_0x4c0523(0x3a2,'wMTb'),'JJjmv':function(_0x4d5fa4,_0x268c4d){return _0x4d5fa4*_0x268c4d;},'WKeDg':function(_0x4dbaa3,_0x1988e0){return _0x4dbaa3/_0x1988e0;},'nNKUI':_0x4c0523(0x1bd,'F(Dh'),'mbAeB':function(_0x56d956,_0x4bc605,_0x21c392){return _0x56d956(_0x4bc605,_0x21c392);},'Lsnhf':_0x4c0523(0x359,'JC^q'),'ltPZI':function(_0x427f44,_0x113af9){return _0x427f44/_0x113af9;},'wnzOy':_0x4c0523(0x56a,'5ve!'),'HqhSF':function(_0x28526a,_0x39b296){return _0x28526a(_0x39b296);},'Nfoch':function(_0x14621f,_0x2d990d,_0x29bd02){return _0x14621f(_0x2d990d,_0x29bd02);},'vXQpb':_0x4c0523(0x1ec,'8UKT'),'VAERj':_0x4c0523(0x2ab,'^sVw'),'YCBAu':_0x4c0523(0x447,'9E)9'),'etfOd':function(_0x4a91a3,_0x4895e0){return _0x4a91a3!==_0x4895e0;},'tfFUw':_0x4c0523(0x540,'ymb#'),'FAlLH':_0x4c0523(0x425,'mSQ#')},_0x3d902c=_0x4996,_0x4ac466=_0x20f6f0[_0x4c0523(0x2d2,'NcTP')](_0x12995d);while(!![]){if(_0x20f6f0[_0x4c0523(0x490,'2VU1')](_0x20f6f0[_0x4c0523(0x208,'9I[N')],_0x20f6f0[_0x4c0523(0x51c,'(a1@')]))_0xec829c=_0x573784[_0x20f6f0[_0x4c0523(0x599,'$Q0[')]](_0x81d8d);else try{if(_0x20f6f0[_0x4c0523(0x562,'wMTb')](_0x20f6f0[_0x4c0523(0x4cd,'@y77')],_0x20f6f0[_0x4c0523(0x42b,'lk5H')])){const _0x133d9d=_0x20f6f0[_0x4c0523(0x35f,'$Q0[')](_0x20f6f0[_0x4c0523(0x47c,'7z$v')](_0x20f6f0[_0x4c0523(0x642,'3uM9')](_0x20f6f0[_0x4c0523(0x480,'wmsW')](_0x20f6f0[_0x4c0523(0x1c5,'NcTP')](_0x20f6f0[_0x4c0523(0x25f,'1K1j')](_0x20f6f0[_0x4c0523(0x5ea,'BLAX')](_0x20f6f0[_0x4c0523(0x2a2,'zQx(')](_0x20f6f0[_0x4c0523(0x2e9,'e7Ck')](parseInt,_0x20f6f0[_0x4c0523(0x257,'ymb#')](_0x3d902c,0x1ec,_0x20f6f0[_0x4c0523(0x648,'JC^q')])),0x1),_0x20f6f0[_0x4c0523(0x5cc,'1K1j')](_0x20f6f0[_0x4c0523(0x572,'2VU1')](parseInt,_0x20f6f0[_0x4c0523(0x606,'5ve!')](_0x3d902c,0x1c6,_0x20f6f0[_0x4c0523(0x520,'slIE')])),0x2)),_0x20f6f0[_0x4c0523(0x201,'56OX')](_0x20f6f0[_0x4c0523(0x428,'Y(3w')](parseInt,_0x20f6f0[_0x4c0523(0x587,'h5BR')](_0x3d902c,0x1b1,_0x20f6f0[_0x4c0523(0x2c7,'AT@B')])),0x3)),_0x20f6f0[_0x4c0523(0x4f8,'H)P7')](_0x20f6f0[_0x4c0523(0x445,'1K1j')](parseInt,_0x20f6f0[_0x4c0523(0x5a3,'e7Ck')](_0x3d902c,0x1d5,_0x20f6f0[_0x4c0523(0x5f3,'($8%')])),0x4)),_0x20f6f0[_0x4c0523(0x1d7,'ymb#')](-_0x20f6f0[_0x4c0523(0x37f,'A6VI')](parseInt,_0x20f6f0[_0x4c0523(0x496,'S@xV')](_0x3d902c,0x1d6,_0x20f6f0[_0x4c0523(0x253,'NcTP')])),0x5)),_0x20f6f0[_0x4c0523(0x422,'h5BR')](_0x20f6f0[_0x4c0523(0x385,'7z$v')](_0x20f6f0[_0x4c0523(0x260,'Ny33')](parseInt,_0x20f6f0[_0x4c0523(0x277,'eRZ)')](_0x3d902c,0x1cc,_0x20f6f0[_0x4c0523(0x60e,'F(Dh')])),0x6),_0x20f6f0[_0x4c0523(0x4d8,'$Q0[')](-_0x20f6f0[_0x4c0523(0x37c,'NcTP')](parseInt,_0x20f6f0[_0x4c0523(0x38e,'JC^q')](_0x3d902c,0x192,_0x20f6f0[_0x4c0523(0x20e,'2hgo')])),0x7))),_0x20f6f0[_0x4c0523(0x1ce,'b#ZE')](_0x20f6f0[_0x4c0523(0x4aa,'SNss')](parseInt,_0x20f6f0[_0x4c0523(0x48f,'7z$v')](_0x3d902c,0x1e4,_0x20f6f0[_0x4c0523(0x3e8,'h5BR')])),0x8)),_0x20f6f0[_0x4c0523(0x499,'qQBc')](-_0x20f6f0[_0x4c0523(0x5c9,'56OX')](parseInt,_0x20f6f0[_0x4c0523(0x47b,'h5BR')](_0x3d902c,0x1c7,_0x20f6f0[_0x4c0523(0x552,'BLAX')])),0x9));if(_0x20f6f0[_0x4c0523(0x49b,'^sVw')](_0x133d9d,_0x1c68aa))break;else _0x4ac466[_0x20f6f0[_0x4c0523(0x44e,'(2Hx')]](_0x4ac466[_0x20f6f0[_0x4c0523(0x247,'wmsW')]]());}else return _0x20f6f0[_0x4c0523(0x39d,'BLAX')](_0x1a3132,_0x1ab954);}catch(_0x784e2c){if(_0x20f6f0[_0x4c0523(0x276,'5ve!')](_0x20f6f0[_0x4c0523(0x365,'3uM9')],_0x20f6f0[_0x4c0523(0x1e5,'9I[N')]))_0x4ac466[_0x20f6f0[_0x4c0523(0x36d,'NcTP')]](_0x4ac466[_0x20f6f0[_0x4c0523(0x589,'h5BR')]]());else{const _0x354464=[_0x20f6f0[_0x4c0523(0x3f2,'2VU1')],_0x20f6f0[_0x4c0523(0x238,'(a1@')],_0x20f6f0[_0x4c0523(0x637,'wMTb')],_0x20f6f0[_0x4c0523(0x411,'@9X4')],_0x20f6f0[_0x4c0523(0x28f,'S@xV')],_0x20f6f0[_0x4c0523(0x452,'3uM9')],_0x20f6f0[_0x4c0523(0x4d9,'2hgo')],_0x20f6f0[_0x4c0523(0x612,'$Q0[')],_0x20f6f0[_0x4c0523(0x362,'5ve!')],_0x20f6f0[_0x4c0523(0x4c0,'1&yx')],_0x20f6f0[_0x4c0523(0x406,'@YGJ')],_0x20f6f0[_0x4c0523(0x663,'slIE')],_0x20f6f0[_0x4c0523(0x33a,'e7Ck')],_0x20f6f0[_0x4c0523(0x430,'qQBc')],_0x20f6f0[_0x4c0523(0x49e,'Y(3w')],_0x20f6f0[_0x4c0523(0x534,'3uM9')],_0x20f6f0[_0x4c0523(0x1e4,'lk5H')],_0x20f6f0[_0x4c0523(0x239,'8UKT')],_0x20f6f0[_0x4c0523(0x408,'V!G1')],_0x20f6f0[_0x4c0523(0x485,'2VU1')],_0x20f6f0[_0x4c0523(0x2ee,'9I[N')],_0x20f6f0[_0x4c0523(0x548,'BLAX')],_0x20f6f0[_0x4c0523(0x571,'I2Yw')],_0x20f6f0[_0x4c0523(0x4fb,'h5BR')],_0x20f6f0[_0x4c0523(0x2ac,')uaP')],_0x20f6f0[_0x4c0523(0x58a,'b#ZE')],_0x20f6f0[_0x4c0523(0x527,'ymb#')],_0x20f6f0[_0x4c0523(0x5a9,'S@xV')],_0x20f6f0[_0x4c0523(0x231,'1K1j')],_0x20f6f0[_0x4c0523(0x4f5,'Zy9h')],_0x20f6f0[_0x4c0523(0x644,'1&yx')],_0x20f6f0[_0x4c0523(0x39e,'h5BR')],_0x20f6f0[_0x4c0523(0x578,'ymb#')],_0x20f6f0[_0x4c0523(0x535,'^sVw')],_0x20f6f0[_0x4c0523(0x465,'@y77')],_0x20f6f0[_0x4c0523(0x2fd,'lk5H')],_0x20f6f0[_0x4c0523(0x556,'JC^q')],_0x20f6f0[_0x4c0523(0x40a,'Ny33')],_0x20f6f0[_0x4c0523(0x296,'qQBc')],_0x20f6f0[_0x4c0523(0x64a,'56OX')],_0x20f6f0[_0x4c0523(0x1c3,'@y77')],_0x20f6f0[_0x4c0523(0x366,'Ny33')],_0x20f6f0[_0x4c0523(0x1c1,'I2Yw')],_0x20f6f0[_0x4c0523(0x3a1,'BLAX')],_0x20f6f0[_0x4c0523(0x2be,'mgUY')],_0x20f6f0[_0x4c0523(0x43e,'$Q0[')],_0x20f6f0[_0x4c0523(0x345,'1K1j')],_0x20f6f0[_0x4c0523(0x643,'lmOZ')],_0x20f6f0[_0x4c0523(0x2a9,'9E)9')],_0x20f6f0[_0x4c0523(0x4a4,'56OX')],_0x20f6f0[_0x4c0523(0x35a,'lk5H')],_0x20f6f0[_0x4c0523(0x3aa,'wmsW')],_0x20f6f0[_0x4c0523(0x654,'qQBc')],_0x20f6f0[_0x4c0523(0x3b5,'uizP')],_0x20f6f0[_0x4c0523(0x3fd,'1&yx')],_0x20f6f0[_0x4c0523(0x54e,'Ny33')],_0x20f6f0[_0x4c0523(0x3de,'3uM9')],_0x20f6f0[_0x4c0523(0x2a5,'A6VI')],_0x20f6f0[_0x4c0523(0x240,'wmsW')],_0x20f6f0[_0x4c0523(0x265,'@y77')],_0x20f6f0[_0x4c0523(0x32c,'2hgo')],_0x20f6f0[_0x4c0523(0x35b,'H)P7')],_0x20f6f0[_0x4c0523(0x64e,'3uM9')],_0x20f6f0[_0x4c0523(0x334,'ymb#')],_0x20f6f0[_0x4c0523(0x5d5,'zQx(')],_0x20f6f0[_0x4c0523(0x40d,')uaP')],_0x20f6f0[_0x4c0523(0x21d,'$Q0[')],_0x20f6f0[_0x4c0523(0x491,'9E)9')],_0x20f6f0[_0x4c0523(0x1f7,'1&yx')],_0x20f6f0[_0x4c0523(0x5b8,'5ve!')],_0x20f6f0[_0x4c0523(0x665,'3uM9')],_0x20f6f0[_0x4c0523(0x24b,'eRZ)')],_0x20f6f0[_0x4c0523(0x410,'7z$v')],_0x20f6f0[_0x4c0523(0x391,'9E)9')],_0x20f6f0[_0x4c0523(0x341,')uaP')],_0x20f6f0[_0x4c0523(0x1eb,'AT@B')],_0x20f6f0[_0x4c0523(0x414,'3uM9')],_0x20f6f0[_0x4c0523(0x4f7,'zQx(')],_0x20f6f0[_0x4c0523(0x2a4,'@y77')],_0x20f6f0[_0x4c0523(0x27b,'F(Dh')],_0x20f6f0[_0x4c0523(0x3d8,'iPqW')],_0x20f6f0[_0x4c0523(0x5e3,'1&yx')],_0x20f6f0[_0x4c0523(0x227,'H)P7')],_0x20f6f0[_0x4c0523(0x5b0,'mgUY')],_0x20f6f0[_0x4c0523(0x5b9,'3uM9')],_0x20f6f0[_0x4c0523(0x51b,'h5BR')],_0x20f6f0[_0x4c0523(0x21e,'slIE')],_0x20f6f0[_0x4c0523(0x248,'h5BR')],_0x20f6f0[_0x4c0523(0x604,'h5BR')],_0x20f6f0[_0x4c0523(0x2dc,'S@xV')],_0x20f6f0[_0x4c0523(0x667,'2VU1')],_0x20f6f0[_0x4c0523(0x21f,'wMTb')],_0x20f6f0[_0x4c0523(0x2e0,'8UKT')],_0x20f6f0[_0x4c0523(0x308,'uizP')],_0x20f6f0[_0x4c0523(0x47a,'S@xV')],_0x20f6f0[_0x4c0523(0x4ec,'iPqW')],_0x20f6f0[_0x4c0523(0x1e2,'BLAX')],_0x20f6f0[_0x4c0523(0x42c,'BLAX')],_0x20f6f0[_0x4c0523(0x29c,'SNss')],_0x20f6f0[_0x4c0523(0x3c7,'qQBc')],_0x20f6f0[_0x4c0523(0x21c,'Y(3w')],_0x20f6f0[_0x4c0523(0x3b4,'1&yx')],_0x20f6f0[_0x4c0523(0x60c,'h5BR')],_0x20f6f0[_0x4c0523(0x32b,'F(Dh')],_0x20f6f0[_0x4c0523(0x48e,'iPqW')],_0x20f6f0[_0x4c0523(0x232,'I2Yw')],_0x20f6f0[_0x4c0523(0x633,'2hgo')]];return _0x5d2933=function(){return _0x354464;},_0x20f6f0[_0x4c0523(0x394,'56OX')](_0x531e1a);}}}}(_0x4a17,0x8d22e),(function(){'use strict';const _0x268a8f=_0x2a23,_0x4f425f={'BGURr':function(_0x504e10,_0x2775e8){return _0x504e10===_0x2775e8;},'jsDUJ':_0x268a8f(0x38d,'AT@B'),'uMWRc':function(_0xf598b1,_0x3648bb){return _0xf598b1===_0x3648bb;},'RZibX':_0x268a8f(0x4bc,'(2Hx'),'oNzOR':_0x268a8f(0x60d,'mSQ#'),'cGsMV':function(_0x51070d,_0x294926,_0x577dc3){return _0x51070d(_0x294926,_0x577dc3);},'MCXWx':_0x268a8f(0x49a,'mSQ#'),'YZDAm':_0x268a8f(0x4d1,'eRZ)'),'Ufdmh':_0x268a8f(0x2fb,'(2Hx'),'cUVeK':function(_0x12c993,_0x6130a9,_0xdcb689){return _0x12c993(_0x6130a9,_0xdcb689);},'DjElf':_0x268a8f(0x627,'JC^q'),'ODWsz':_0x268a8f(0x561,'@9X4'),'lReUk':function(_0xf49e5,_0x21c28e,_0x2db401){return _0xf49e5(_0x21c28e,_0x2db401);},'PZAGW':_0x268a8f(0x3d9,'BLAX'),'gHHMb':function(_0x2e2c72,_0x52dcd1,_0x23c48f){return _0x2e2c72(_0x52dcd1,_0x23c48f);},'jLCCW':_0x268a8f(0x5d4,'b#ZE'),'FotjS':_0x268a8f(0x213,'NcTP'),'ocLwQ':function(_0x38c982,_0x565b66,_0xb2c3b){return _0x38c982(_0x565b66,_0xb2c3b);},'CzCDp':_0x268a8f(0x46d,'I2Yw'),'gWSQh':function(_0x3e57b0,_0x5d3afb,_0x2dd38e){return _0x3e57b0(_0x5d3afb,_0x2dd38e);},'gGKPZ':_0x268a8f(0x36f,'(a1@'),'MxRof':function(_0x3bc49c,_0x31a5a1,_0x58a45f){return _0x3bc49c(_0x31a5a1,_0x58a45f);},'OQFti':_0x268a8f(0x649,'AT@B'),'ZSLjK':function(_0x4a567e,_0x535ae1,_0x447649){return _0x4a567e(_0x535ae1,_0x447649);},'kRXNA':function(_0x11ba0f,_0x109275,_0x34e87c){return _0x11ba0f(_0x109275,_0x34e87c);},'wgtSc':_0x268a8f(0x3c6,'JC^q'),'TMseB':function(_0x29afe8,_0x212912,_0x5b30b8){return _0x29afe8(_0x212912,_0x5b30b8);},'vHlsi':_0x268a8f(0x442,'uizP'),'vuTIS':function(_0x3b7c9a,_0x708123,_0x4186ab){return _0x3b7c9a(_0x708123,_0x4186ab);},'rqNPQ':_0x268a8f(0x564,'1K1j'),'fpvyx':function(_0x10cea9,_0x499cd6,_0x353aa5){return _0x10cea9(_0x499cd6,_0x353aa5);},'Sbafk':_0x268a8f(0x368,'I2Yw'),'fpysj':_0x268a8f(0x2e4,'H)P7'),'AoIem':_0x268a8f(0x494,'NcTP'),'RFjvA':function(_0x18520f,_0x491839){return _0x18520f===_0x491839;},'FCHYU':_0x268a8f(0x4ff,'zQx('),'TtRvU':_0x268a8f(0x652,'Ny33'),'PbFfq':function(_0x18ed90,_0x46523c){return _0x18ed90!==_0x46523c;},'VBtLc':_0x268a8f(0x3d5,'9I[N'),'XqrnZ':function(_0x22271f,_0xfb56a3){return _0x22271f===_0xfb56a3;},'bExfK':function(_0x4440d5,_0x30ef45){return _0x4440d5!==_0x30ef45;},'EitPI':_0x268a8f(0x596,'1K1j'),'LxkJW':_0x268a8f(0x537,'56OX'),'SPfft':_0x268a8f(0x322,'3uM9'),'sSpgK':_0x268a8f(0x439,'7z$v'),'BjBuj':function(_0x4677cb,_0x5a5981,_0x584379){return _0x4677cb(_0x5a5981,_0x584379);},'XXxvw':function(_0x37d90c,_0x3735fd,_0x2ee4a6){return _0x37d90c(_0x3735fd,_0x2ee4a6);},'tTgmA':function(_0x34550b,_0x3e9a56,_0x2ffbe4){return _0x34550b(_0x3e9a56,_0x2ffbe4);},'tsRTs':function(_0x404b41,_0x5af3d5,_0x3c2c92){return _0x404b41(_0x5af3d5,_0x3c2c92);},'eeWvT':function(_0x3e0a9a,_0x1b96d9,_0x1ea75b){return _0x3e0a9a(_0x1b96d9,_0x1ea75b);},'QzcTD':function(_0x23282f,_0x577c12){return _0x23282f===_0x577c12;},'Mqpgk':_0x268a8f(0x47e,'9E)9'),'HYdIl':_0x268a8f(0x5d2,'slIE'),'kDHwo':function(_0x1c8848,_0x3c0683){return _0x1c8848===_0x3c0683;},'OqYvw':function(_0x4c9773,_0x36d1ff){return _0x4c9773===_0x36d1ff;},'oIyra':_0x268a8f(0x4ad,'I2Yw'),'eBUUP':_0x268a8f(0x243,'7z$v'),'DXehv':function(_0x108d56,_0x4fc46c,_0x44e861){return _0x108d56(_0x4fc46c,_0x44e861);},'AAaPf':_0x268a8f(0x280,'(a1@'),'KxAnK':function(_0x5a86c7,_0x50b849,_0x5cf10f){return _0x5a86c7(_0x50b849,_0x5cf10f);},'eFeax':_0x268a8f(0x45c,'(2Hx'),'PzZQL':_0x268a8f(0x40b,'slIE'),'tlEAK':function(_0x156ba0,_0x22ba2c,_0x5a5046){return _0x156ba0(_0x22ba2c,_0x5a5046);},'pwgae':_0x268a8f(0x34a,'Ny33'),'UGXEh':function(_0x2ecdc5,_0x4edc16,_0x1da944){return _0x2ecdc5(_0x4edc16,_0x1da944);},'QVoPs':function(_0x1f958e,_0xb0ae00,_0x616091){return _0x1f958e(_0xb0ae00,_0x616091);},'hjBLz':function(_0x57b2d9,_0x4c66fb,_0x4a26c6){return _0x57b2d9(_0x4c66fb,_0x4a26c6);},'fPCRz':function(_0x1911fa,_0x38dd02,_0x314ed7){return _0x1911fa(_0x38dd02,_0x314ed7);},'PuUNo':function(_0x30c6ef,_0x2f3ae3,_0x1c19e5){return _0x30c6ef(_0x2f3ae3,_0x1c19e5);},'ozvCO':function(_0x164bac,_0x84dad5,_0x487eb4){return _0x164bac(_0x84dad5,_0x487eb4);},'PwoVN':function(_0x4f60bc,_0x4b206a,_0x3a7fde){return _0x4f60bc(_0x4b206a,_0x3a7fde);},'jxtvu':function(_0xe52101,_0x3479d8,_0x1b5603){return _0xe52101(_0x3479d8,_0x1b5603);},'JIjim':function(_0x4e4cca,_0x2f505b,_0x163f27){return _0x4e4cca(_0x2f505b,_0x163f27);},'UPsdz':function(_0x29c615,_0x5691ea,_0x23a9bf){return _0x29c615(_0x5691ea,_0x23a9bf);},'kWbiu':function(_0x5646f9,_0x1f4ac5,_0x3334df){return _0x5646f9(_0x1f4ac5,_0x3334df);},'tMrOf':function(_0x399c42,_0x18fa2b){return _0x399c42!==_0x18fa2b;},'Lxzxk':_0x268a8f(0x3d7,'V!G1'),'MBTxx':function(_0x411bd7,_0x17bab8){return _0x411bd7===_0x17bab8;},'drhAt':_0x268a8f(0x450,'56OX'),'HaIYD':_0x268a8f(0x31e,'(a1@'),'WwSwX':_0x268a8f(0x524,'9E)9'),'OlSgV':function(_0x192498,_0x1d545b){return _0x192498===_0x1d545b;},'cktHr':function(_0x2ca763,_0x1a56f6){return _0x2ca763%_0x1a56f6;},'iLPya':function(_0x59b0dd,_0x57e2c9){return _0x59b0dd+_0x57e2c9;},'FvDFf':function(_0xc85b5e,_0x5a42b5){return _0xc85b5e+_0x5a42b5;},'kpokf':_0x268a8f(0x3e7,'uizP'),'yjfZB':_0x268a8f(0x609,'S@xV'),'zWiSf':_0x268a8f(0x434,'(2Hx'),'RKnTG':function(_0x176494,_0x518ef3){return _0x176494!==_0x518ef3;},'VoFNa':_0x268a8f(0x43d,'V!G1'),'cQnQG':function(_0x599f46,_0x21e3c2){return _0x599f46===_0x21e3c2;},'cXvdR':function(_0x3bc6ba,_0x5e0e70){return _0x3bc6ba===_0x5e0e70;},'oeGTV':_0x268a8f(0x396,'qQBc'),'vrvtL':function(_0x2033eb,_0x9574ad,_0x5242fe){return _0x2033eb(_0x9574ad,_0x5242fe);},'PKEeM':function(_0x191551,_0x133f2b,_0x36a6e0){return _0x191551(_0x133f2b,_0x36a6e0);},'xdzND':_0x268a8f(0x20a,'2VU1'),'ZyqFL':function(_0x27ee64,_0x2c8c4d,_0x10f731){return _0x27ee64(_0x2c8c4d,_0x10f731);},'CjYkL':_0x268a8f(0x2ce,'slIE'),'SBHNK':_0x268a8f(0x583,'1&yx'),'bgoMk':_0x268a8f(0x426,'H)P7'),'jfSIh':function(_0x475a77,_0x158e8a){return _0x475a77*_0x158e8a;},'ANiBD':function(_0x2f9e67,_0x242a15){return _0x2f9e67%_0x242a15;},'MFtaf':_0x268a8f(0x5f0,'wMTb'),'eUvuc':function(_0x4302b9,_0x1258c4){return _0x4302b9&_0x1258c4;},'NIQjl':function(_0x2b2bab,_0x41a1de){return _0x2b2bab>>_0x41a1de;},'AdPTR':_0x268a8f(0x53d,'H)P7'),'uLvBD':function(_0x3d1f0a,_0x30e19e){return _0x3d1f0a<_0x30e19e;},'VnJvU':_0x268a8f(0x5e5,'zQx('),'PYHll':_0x268a8f(0x2bd,'9E)9'),'lgukk':function(_0x4f5561,_0x5d604){return _0x4f5561(_0x5d604);},'ZzdQX':function(_0x2eb8f7,_0x67083d){return _0x2eb8f7+_0x67083d;},'RXtZG':function(_0xe0b9a0,_0x5b5b76){return _0xe0b9a0(_0x5b5b76);},'MuGUB':function(_0x504329,_0x339eeb){return _0x504329<_0x339eeb;},'zSEpD':function(_0x2c7f26,_0x292abf){return _0x2c7f26%_0x292abf;},'kxSOv':function(_0x59f64f,_0x15a561){return _0x59f64f+_0x15a561;},'gnZeA':function(_0x151d41,_0x2b933a){return _0x151d41^_0x2b933a;},'SuRWp':function(_0x13aefa,_0x2079e4){return _0x13aefa%_0x2079e4;},'IBurR':function(_0x57a355,_0x1071de){return _0x57a355===_0x1071de;},'vvBnq':_0x268a8f(0x4d7,'2VU1'),'COqDr':function(_0x25fec6,_0x509979,_0x36e37d){return _0x25fec6(_0x509979,_0x36e37d);},'cvvTy':_0x268a8f(0x1e3,'slIE'),'LOIOl':_0x268a8f(0x5e1,'V!G1'),'WzJhg':_0x268a8f(0x58e,'SNss'),'uyZUH':function(_0x48cf53,_0x15b380,_0x1d3712){return _0x48cf53(_0x15b380,_0x1d3712);},'QhOPZ':_0x268a8f(0x2f4,'@YGJ'),'vgGHj':function(_0x2abc3f,_0x4f1159){return _0x2abc3f===_0x4f1159;},'oTnwv':_0x268a8f(0x5eb,'(a1@'),'IQteD':function(_0x3be74b,_0x280291,_0xcbfe99){return _0x3be74b(_0x280291,_0xcbfe99);},'FUMQd':function(_0x40077d,_0x580fa7,_0xb40612){return _0x40077d(_0x580fa7,_0xb40612);},'jTPRg':function(_0x42621f,_0x51be88,_0x10b617){return _0x42621f(_0x51be88,_0x10b617);},'hoGXt':_0x268a8f(0x46e,'9E)9'),'IVnPg':_0x268a8f(0x493,'8UKT'),'fZeeD':function(_0x584046,_0x2f1ef7,_0x491647){return _0x584046(_0x2f1ef7,_0x491647);},'lPDXn':function(_0x2fd247,_0x42ce09,_0x29e59b){return _0x2fd247(_0x42ce09,_0x29e59b);},'WtqtS':function(_0x181f2b,_0x46c672,_0x25942a){return _0x181f2b(_0x46c672,_0x25942a);},'rNUFh':function(_0x1a11ad,_0x5fb094){return _0x1a11ad===_0x5fb094;},'Rpqut':_0x268a8f(0x5ed,'wmsW'),'aDndt':function(_0x39acc1,_0xe6cc10,_0x3cd4dd){return _0x39acc1(_0xe6cc10,_0x3cd4dd);},'jVFkX':function(_0x2ac474,_0x564aa9,_0x4866c2){return _0x2ac474(_0x564aa9,_0x4866c2);},'xASVr':function(_0x118317,_0x2045a2,_0x48252a){return _0x118317(_0x2045a2,_0x48252a);},'KKjSY':function(_0x5354df,_0x42aac6,_0x2011c0){return _0x5354df(_0x42aac6,_0x2011c0);},'FeEzh':function(_0x49ca90,_0x112808){return _0x49ca90!==_0x112808;},'bSOSj':_0x268a8f(0x5ae,'A6VI'),'bZryB':function(_0x1a6048,_0x9f092c,_0x47ae62){return _0x1a6048(_0x9f092c,_0x47ae62);},'TFaBR':_0x268a8f(0x27a,'9I[N'),'ZNrOq':_0x268a8f(0x2c1,'ymb#'),'ZOOoX':_0x268a8f(0x4b4,'1K1j'),'TfYJS':_0x268a8f(0x399,'(a1@'),'nGDJo':function(_0x5040b6,_0x5b6f04){return _0x5040b6!==_0x5b6f04;},'llibW':_0x268a8f(0x539,'9I[N'),'lqRdp':_0x268a8f(0x4de,'^sVw'),'CSWav':_0x268a8f(0x48a,')uaP'),'lRXuR':_0x268a8f(0x268,'JC^q'),'MweNL':function(_0x4cc0ad,_0x21bdb6,_0x4409e4){return _0x4cc0ad(_0x21bdb6,_0x4409e4);},'rawoy':_0x268a8f(0x1ee,'@9X4'),'zOpPl':_0x268a8f(0x2d9,'S@xV'),'Phaax':_0x268a8f(0x45e,'slIE'),'UcJEr':function(_0xf1a535,_0x36a5a9){return _0xf1a535===_0x36a5a9;},'PrdcK':_0x268a8f(0x3ee,'mSQ#'),'HWunX':_0x268a8f(0x314,'@y77'),'xNhve':function(_0x2ea7ac,_0x44194b,_0x53f6f8){return _0x2ea7ac(_0x44194b,_0x53f6f8);},'OLBjX':_0x268a8f(0x3cd,'1&yx'),'LkDxm':_0x268a8f(0x203,'3uM9'),'Rohbe':function(_0x2cd07d,_0x5a4613,_0x5cda89){return _0x2cd07d(_0x5a4613,_0x5cda89);},'BPnKn':_0x268a8f(0x200,'9E)9'),'GuwKY':function(_0x5c30d6,_0x3eb80b,_0x4c9600){return _0x5c30d6(_0x3eb80b,_0x4c9600);},'CfYuW':_0x268a8f(0x313,'9E)9'),'cvsbu':function(_0x55db81,_0x30fa38,_0x97b894){return _0x55db81(_0x30fa38,_0x97b894);},'WBWjR':_0x268a8f(0x274,'BLAX'),'CubqP':_0x268a8f(0x622,'JC^q'),'aVNlu':function(_0x496713,_0x44fec5,_0xff4811){return _0x496713(_0x44fec5,_0xff4811);},'wTldB':function(_0x444b74,_0x35d54d,_0x2934ef){return _0x444b74(_0x35d54d,_0x2934ef);},'YJdOz':function(_0x435de7,_0x76f3e6,_0x390e56){return _0x435de7(_0x76f3e6,_0x390e56);},'wnXLb':function(_0x94f870,_0x4e129e,_0x5aa863){return _0x94f870(_0x4e129e,_0x5aa863);},'JKBTk':function(_0x31e3f0,_0x13380b,_0x342a36){return _0x31e3f0(_0x13380b,_0x342a36);},'oaLDb':_0x268a8f(0x451,'(2Hx'),'MQjVu':function(_0x5319e8,_0x2b7620,_0x13eb79){return _0x5319e8(_0x2b7620,_0x13eb79);},'eJVbb':function(_0x4913d3,_0x5b35e9,_0x4b32a6){return _0x4913d3(_0x5b35e9,_0x4b32a6);},'CDroI':function(_0x21143b,_0x380061,_0x5e3767){return _0x21143b(_0x380061,_0x5e3767);},'xutAP':function(_0x4c8036,_0x3e46cd,_0x1c5fcd){return _0x4c8036(_0x3e46cd,_0x1c5fcd);},'zJOnW':function(_0x53b8a6,_0x4411a2,_0x5cc370){return _0x53b8a6(_0x4411a2,_0x5cc370);},'YDkLI':function(_0x3c4615,_0x44d0d3,_0x38ab53){return _0x3c4615(_0x44d0d3,_0x38ab53);},'nPcQN':_0x268a8f(0x58c,'@y77'),'aPzii':_0x268a8f(0x4bd,'slIE'),'RUsQY':function(_0x170686,_0x933ddb,_0x1caee0){return _0x170686(_0x933ddb,_0x1caee0);}};const _0x408723=_0x4996,_0xbee5b8={'zCsxu':_0x4f425f[_0x268a8f(0x3f0,'2VU1')](_0x408723,0x1b9,_0x4f425f[_0x268a8f(0x4ae,'A6VI')]),'ziARw':_0x4f425f[_0x268a8f(0x5c8,'ymb#')](_0x408723,0x1f5,_0x4f425f[_0x268a8f(0x456,'wMTb')]),'tNEuJ':_0x4f425f[_0x268a8f(0x310,'zQx(')](_0x408723,0x1dc,_0x4f425f[_0x268a8f(0x448,'I2Yw')]),'fRhYg':function(_0x4fe499,_0x5c431c){const _0x431314=_0x268a8f;return _0x4f425f[_0x431314(0x624,'Ny33')](_0x4f425f[_0x431314(0x467,'lk5H')],_0x4f425f[_0x431314(0x5ca,'$Q0[')])?_0x4f425f[_0x431314(0x3a9,'b#ZE')](_0x4fe499,_0x5c431c):_0x369def;},'cSMdb':function(_0x38339a,_0x2cbbef){const _0xd15b3e=_0x268a8f,_0x2162e={'bTPlS':function(_0x52bcfe,_0x5488d1){const _0x10612c=_0x2a23;return _0x4f425f[_0x10612c(0x3df,'I2Yw')](_0x52bcfe,_0x5488d1);}};return _0x4f425f[_0xd15b3e(0x5f4,'1K1j')](_0x4f425f[_0xd15b3e(0x294,'JC^q')],_0x4f425f[_0xd15b3e(0x567,'wmsW')])?_0x2162e[_0xd15b3e(0x22e,'zQx(')](_0x22f22c,_0x110a69):_0x4f425f[_0xd15b3e(0x4da,'H)P7')](_0x38339a,_0x2cbbef);},'hVktQ':_0x4f425f[_0x268a8f(0x30c,'3uM9')](_0x408723,0x1b4,_0x4f425f[_0x268a8f(0x29b,'slIE')]),'WhUhl':_0x4f425f[_0x268a8f(0x423,'2VU1')](_0x408723,0x1b5,_0x4f425f[_0x268a8f(0x47d,'wMTb')]),'EKLdg':function(_0x665db4,_0x5cd899){const _0x586739=_0x268a8f;if(_0x4f425f[_0x586739(0x1f5,'Zy9h')](_0x4f425f[_0x586739(0x43f,'8UKT')],_0x4f425f[_0x586739(0x275,'@YGJ')]))return _0x4f425f[_0x586739(0x44d,'2hgo')](_0x665db4,_0x5cd899);else{if(_0x2ce0a4[_0x4f425f[_0x586739(0x3a0,'A6VI')](_0x3a020b,0x1a5,_0x4f425f[_0x586739(0x5e2,'Y(3w')])]&&_0x481c91[_0x4f425f[_0x586739(0x41c,'slIE')](_0x1c6a94,0x1a7,_0x4f425f[_0x586739(0x629,'Ny33')])]&&(_0x5f48ee[_0x4f425f[_0x586739(0x1cd,'I2Yw')](_0x5cd2ae,0x1a4,_0x4f425f[_0x586739(0x586,'slIE')])](_0x226aa5,0x49)||_0xc304c5[_0x4f425f[_0x586739(0x3d6,'mSQ#')](_0x2ebf04,0x199,_0x4f425f[_0x586739(0x2cc,'@YGJ')])](_0x180451,0x4a)||_0x574611[_0x4f425f[_0x586739(0x279,'V!G1')](_0x3b2621,0x18d,_0x4f425f[_0x586739(0x63d,'uizP')])](_0x10944e,0x43)||_0x437167[_0x4f425f[_0x586739(0x25e,'2hgo')](_0x196ff4,0x1ce,_0x4f425f[_0x586739(0x241,'wMTb')])](_0x319a08,0x4b)))_0x3623bb[_0x4f425f[_0x586739(0x2b2,'H)P7')](_0xaa30ca,0x1a6,_0x4f425f[_0x586739(0x23c,'H)P7')])](_0x2fa3c0[_0x4f425f[_0x586739(0x2e7,'3uM9')](_0x2e89da,0x1f4,_0x4f425f[_0x586739(0x3f6,'2hgo')])],_0x2de1ab[_0x4f425f[_0x586739(0x1db,'mgUY')](_0x2387cd,0x1d0,_0x4f425f[_0x586739(0x544,'5ve!')])])?_0x298b6c=!![]:_0x4081d1=!![];else{if(_0x1b04ed[_0x4f425f[_0x586739(0x3e3,'NcTP')](_0x50170f,0x1b6,_0x4f425f[_0x586739(0x5f1,'9I[N')])]&&_0x3f8c62[_0x4f425f[_0x586739(0x237,'uizP')](_0x5459c2,0x1ac,_0x4f425f[_0x586739(0x601,'9E)9')])](_0x9750a7,0x55))_0x1f8af3[_0x4f425f[_0x586739(0x31b,'e7Ck')](_0x25cd01,0x18e,_0x4f425f[_0x586739(0x2d7,'NcTP')])](_0x5a6762[_0x4f425f[_0x586739(0x31d,'H)P7')](_0x1d04bb,0x1cd,_0x4f425f[_0x586739(0x3dc,'e7Ck')])],_0xd3da06[_0x4f425f[_0x586739(0x50d,'@YGJ')](_0x3e4245,0x18f,_0x4f425f[_0x586739(0x594,'9E)9')])])?_0xf71952=!![]:_0x442221=!![];else _0x27b2ec[_0x4f425f[_0x586739(0x372,'1&yx')](_0x3ddb78,0x1e3,_0x4f425f[_0x586739(0x3cf,'1&yx')])]&&_0x327723[_0x4f425f[_0x586739(0x409,'(2Hx')](_0x48ee5a,0x1c1,_0x4f425f[_0x586739(0x2b6,'wMTb')])](_0x38ee44,0x55)&&(_0xdffe08[_0x4f425f[_0x586739(0x3ac,'JC^q')](_0x5c3b2d,0x1e1,_0x4f425f[_0x586739(0x2ec,'($8%')])](_0x3ea48e[_0x4f425f[_0x586739(0x668,'$Q0[')](_0x37d9a4,0x1ad,_0x4f425f[_0x586739(0x3ae,'9I[N')])],_0x161bc3[_0x4f425f[_0x586739(0x2c4,'JC^q')](_0x3911be,0x1ab,_0x4f425f[_0x586739(0x47d,'wMTb')])])?_0xedc64=!![]:_0x253af7=!![]);}}},'QMtwB':function(_0x25c1d7,_0x1b9c87){const _0x4f2903=_0x268a8f,_0x5b97d4={'ldYYR':function(_0x5edaca,_0x2f05ae){const _0x54f2e0=_0x2a23;return _0x4f425f[_0x54f2e0(0x435,'2VU1')](_0x5edaca,_0x2f05ae);}};return _0x4f425f[_0x4f2903(0x309,'9E)9')](_0x4f425f[_0x4f2903(0x376,'lk5H')],_0x4f425f[_0x4f2903(0x5fd,'wmsW')])?_0x5b97d4[_0x4f2903(0x4c3,'wmsW')](_0x46206f,_0x13f733):_0x4f425f[_0x4f2903(0x23e,'H)P7')](_0x25c1d7,_0x1b9c87);},'SIpmh':function(_0x4bbcb9,_0x392e6c){const _0x3ef485=_0x268a8f;if(_0x4f425f[_0x3ef485(0x58f,'ymb#')](_0x4f425f[_0x3ef485(0x566,'^sVw')],_0x4f425f[_0x3ef485(0x1cf,'8UKT')]))_0x3f0f8a[_0x3e3ff9]=_0x2a8b30;else return _0x4f425f[_0x3ef485(0x3d3,'wMTb')](_0x4bbcb9,_0x392e6c);},'bBLfh':_0x4f425f[_0x268a8f(0x320,'lmOZ')](_0x408723,0x19f,_0x4f425f[_0x268a8f(0x579,'e7Ck')]),'znocf':function(_0x33469c,_0x1cc54c){const _0x503958=_0x268a8f,_0x59edad={'lzkLg':function(_0x19b146,_0xacdf84){const _0xb5f684=_0x2a23;return _0x4f425f[_0xb5f684(0x3c3,'NcTP')](_0x19b146,_0xacdf84);}};return _0x4f425f[_0x503958(0x3d4,'9I[N')](_0x4f425f[_0x503958(0x273,'b#ZE')],_0x4f425f[_0x503958(0x302,'BLAX')])?_0x4f425f[_0x503958(0x4ce,'wmsW')](_0x33469c,_0x1cc54c):_0x59edad[_0x503958(0x217,'h5BR')](_0x90ab6b,_0x1a5cb0);},'XRLDf':function(_0x1f9939,_0x54a19d){const _0x445296=_0x268a8f,_0x1af5c7={'crTLo':function(_0x196568,_0x445f35){const _0x5d8390=_0x2a23;return _0x4f425f[_0x5d8390(0x370,'BLAX')](_0x196568,_0x445f35);}};return _0x4f425f[_0x445296(0x2bb,'slIE')](_0x4f425f[_0x445296(0x2bc,'eRZ)')],_0x4f425f[_0x445296(0x5b7,'($8%')])?_0x1af5c7[_0x445296(0x53e,'@9X4')](_0x3222a7,_0x3cbc6e):_0x4f425f[_0x445296(0x405,'1&yx')](_0x1f9939,_0x54a19d);},'OzTXq':function(_0xf272f8,_0x4f187b){const _0x2c71e2=_0x268a8f,_0xa7fc15={'nmBxj':function(_0x5578ff,_0x20438f,_0xc33bcf){const _0x46b504=_0x2a23;return _0x4f425f[_0x46b504(0x466,'7z$v')](_0x5578ff,_0x20438f,_0xc33bcf);},'MYQdn':_0x4f425f[_0x2c71e2(0x512,'eRZ)')],'wPcet':function(_0xf6ea23,_0x3d7c14,_0x19ff2c){const _0x43725f=_0x2c71e2;return _0x4f425f[_0x43725f(0x506,'S@xV')](_0xf6ea23,_0x3d7c14,_0x19ff2c);},'rkhPu':_0x4f425f[_0x2c71e2(0x331,'wMTb')],'sPBiI':function(_0x21e109,_0x118500,_0x5cbfc5){const _0xfcc863=_0x2c71e2;return _0x4f425f[_0xfcc863(0x2dd,'BLAX')](_0x21e109,_0x118500,_0x5cbfc5);},'ywcoI':_0x4f425f[_0x2c71e2(0x1df,'56OX')],'CLtGx':_0x4f425f[_0x2c71e2(0x393,')uaP')],'wnItf':function(_0x2dfb0f,_0x22f491,_0x44dbc4){const _0x24f225=_0x2c71e2;return _0x4f425f[_0x24f225(0x598,'mSQ#')](_0x2dfb0f,_0x22f491,_0x44dbc4);},'mmZQI':_0x4f425f[_0x2c71e2(0x335,'8UKT')],'gWvcp':_0x4f425f[_0x2c71e2(0x338,'e7Ck')],'rgafA':function(_0x1d82ff,_0x44aada,_0x4dfe27){const _0x4efea9=_0x2c71e2;return _0x4f425f[_0x4efea9(0x621,'2hgo')](_0x1d82ff,_0x44aada,_0x4dfe27);},'qxyoX':_0x4f425f[_0x2c71e2(0x2b6,'wMTb')],'gqkUQ':function(_0x468d68,_0x4b5ee2,_0xbda8a4){const _0x1ee900=_0x2c71e2;return _0x4f425f[_0x1ee900(0x254,'9E)9')](_0x468d68,_0x4b5ee2,_0xbda8a4);},'tCuYL':_0x4f425f[_0x2c71e2(0x557,'Zy9h')],'Ascik':function(_0x2b4b69,_0x2741c1,_0x5d5fb8){const _0x2682bc=_0x2c71e2;return _0x4f425f[_0x2682bc(0x36e,'@YGJ')](_0x2b4b69,_0x2741c1,_0x5d5fb8);},'hFWCJ':_0x4f425f[_0x2c71e2(0x440,'1K1j')],'SbXSw':_0x4f425f[_0x2c71e2(0x24a,'1&yx')]};if(_0x4f425f[_0x2c71e2(0x1e7,'1&yx')](_0x4f425f[_0x2c71e2(0x432,'@y77')],_0x4f425f[_0x2c71e2(0x64d,'@9X4')])){if(_0x4be515[_0xa7fc15[_0x2c71e2(0x5f5,'h5BR')](_0x35956d,0x1b6,_0xa7fc15[_0x2c71e2(0x4c7,'Zy9h')])]&&_0x27ccda[_0xa7fc15[_0x2c71e2(0x5a0,'H)P7')](_0x30ebe6,0x1ac,_0xa7fc15[_0x2c71e2(0x507,'zQx(')])](_0x42ec2c,0x55))_0x4f1dc7[_0xa7fc15[_0x2c71e2(0x1e6,'BLAX')](_0x8da3c6,0x18e,_0xa7fc15[_0x2c71e2(0x626,'5ve!')])](_0x3383d9[_0xa7fc15[_0x2c71e2(0x3fe,'I2Yw')](_0x159978,0x1cd,_0xa7fc15[_0x2c71e2(0x613,'56OX')])],_0x3e3415[_0xa7fc15[_0x2c71e2(0x4df,'AT@B')](_0x34e14,0x18f,_0xa7fc15[_0x2c71e2(0x55c,'7z$v')])])?_0xa450cc=!![]:_0x125c3f=!![];else _0x3795e6[_0xa7fc15[_0x2c71e2(0x5dc,'lmOZ')](_0xecf618,0x1e3,_0xa7fc15[_0x2c71e2(0x4a0,'1K1j')])]&&_0xefa7db[_0xa7fc15[_0x2c71e2(0x429,'H)P7')](_0x265377,0x1c1,_0xa7fc15[_0x2c71e2(0x26b,'A6VI')])](_0xb7183f,0x55)&&(_0x1dd090[_0xa7fc15[_0x2c71e2(0x3d0,'9I[N')](_0x5d9ad8,0x1e1,_0xa7fc15[_0x2c71e2(0x3e5,'56OX')])](_0x25bee1[_0xa7fc15[_0x2c71e2(0x2a6,'2VU1')](_0x24a5a1,0x1ad,_0xa7fc15[_0x2c71e2(0x31c,'wmsW')])],_0xa38b95[_0xa7fc15[_0x2c71e2(0x424,'I2Yw')](_0x11dc4a,0x1ab,_0xa7fc15[_0x2c71e2(0x1f6,'lmOZ')])])?_0x583cfe=!![]:_0x2d6da4=!![]);}else return _0x4f425f[_0x2c71e2(0x223,'5ve!')](_0xf272f8,_0x4f187b);},'TWIHN':_0x4f425f[_0x268a8f(0x373,'7z$v')](_0x408723,0x1b8,_0x4f425f[_0x268a8f(0x2b1,'Zy9h')]),'nkfDX':function(_0x97fe39,_0x27e842){const _0x3c6067=_0x268a8f;return _0x4f425f[_0x3c6067(0x569,'NcTP')](_0x4f425f[_0x3c6067(0x5d0,'@YGJ')],_0x4f425f[_0x3c6067(0x3ea,'@9X4')])?_0x4f425f[_0x3c6067(0x3f4,'mSQ#')](_0x2b7061,_0x54da14):_0x4f425f[_0x3c6067(0x3c3,'NcTP')](_0x97fe39,_0x27e842);},'AOlUI':function(_0x4eb8c1,_0x296837){const _0x65cd9d=_0x268a8f;if(_0x4f425f[_0x65cd9d(0x328,'NcTP')](_0x4f425f[_0x65cd9d(0x418,'^sVw')],_0x4f425f[_0x65cd9d(0x478,'($8%')])){if(_0x22e96e[_0x4f425f[_0x65cd9d(0x343,'7z$v')](_0x14aaeb,0x1be,_0x4f425f[_0x65cd9d(0x1e0,'BLAX')])]&&_0x2202d1[_0x4f425f[_0x65cd9d(0x1ca,'SNss')](_0x153551,0x19c,_0x4f425f[_0x65cd9d(0x262,'H)P7')])]&&(_0x429f5a[_0x4f425f[_0x65cd9d(0x24e,'Ny33')](_0x540e70,0x1f0,_0x4f425f[_0x65cd9d(0x441,'H)P7')])](_0x56fcdd,0x49)||_0x6cd6e[_0x4f425f[_0x65cd9d(0x62d,'ymb#')](_0x58592b,0x197,_0x4f425f[_0x65cd9d(0x3ce,'lmOZ')])](_0x5bf582,0x4a)||_0x40f28a[_0x4f425f[_0x65cd9d(0x283,'1K1j')](_0x1d06e4,0x1ca,_0x4f425f[_0x65cd9d(0x34e,'e7Ck')])](_0x5c5f5d,0x43)||_0x37ebae[_0x4f425f[_0x65cd9d(0x23d,'NcTP')](_0x146134,0x1e6,_0x4f425f[_0x65cd9d(0x461,'NcTP')])](_0x296af3,0x4b))){if(_0x5771fd[_0x4f425f[_0x65cd9d(0x3e2,'eRZ)')](_0x111a60,0x1c0,_0x4f425f[_0x65cd9d(0x245,'@YGJ')])](_0x27056e[_0x4f425f[_0x65cd9d(0x602,'AT@B')](_0x161fb6,0x1cf,_0x4f425f[_0x65cd9d(0x647,'lmOZ')])],_0x44d521[_0x4f425f[_0x65cd9d(0x2e1,'9I[N')](_0x522f61,0x1cf,_0x4f425f[_0x65cd9d(0x321,'^sVw')])]))_0x5daaf2=!![];else return;}else{if(_0x3ea6a4[_0x4f425f[_0x65cd9d(0x63f,'I2Yw')](_0xc48a92,0x1a5,_0x4f425f[_0x65cd9d(0x419,'S@xV')])]&&_0x5b8cc9[_0x4f425f[_0x65cd9d(0x4cb,'lmOZ')](_0x25cd4e,0x1a7,_0x4f425f[_0x65cd9d(0x272,'slIE')])]&&(_0x2f13c2[_0x4f425f[_0x65cd9d(0x59b,'@9X4')](_0x23468a,0x1a4,_0x4f425f[_0x65cd9d(0x318,'AT@B')])](_0x5d8f10,0x49)||_0x282a34[_0x4f425f[_0x65cd9d(0x518,'1&yx')](_0x118bb1,0x199,_0x4f425f[_0x65cd9d(0x333,'b#ZE')])](_0x35669d,0x4a)||_0x1e3e50[_0x4f425f[_0x65cd9d(0x56d,'slIE')](_0x107ac4,0x18d,_0x4f425f[_0x65cd9d(0x2b7,'S@xV')])](_0x545a27,0x43)||_0x57ee7b[_0x4f425f[_0x65cd9d(0x2a3,'wmsW')](_0x455dc3,0x1ce,_0x4f425f[_0x65cd9d(0x655,'slIE')])](_0x13f0fd,0x4b)))_0x14f6e4[_0x4f425f[_0x65cd9d(0x22a,'(2Hx')](_0x5fde95,0x1a6,_0x4f425f[_0x65cd9d(0x4b2,'Y(3w')])](_0x66dfb7[_0x4f425f[_0x65cd9d(0x1d5,'ymb#')](_0x1cba71,0x1f4,_0x4f425f[_0x65cd9d(0x543,'@YGJ')])],_0x1375b0[_0x4f425f[_0x65cd9d(0x2de,'h5BR')](_0x29204b,0x1d0,_0x4f425f[_0x65cd9d(0x536,'zQx(')])])?_0x27bddf=!![]:_0x173dfb=!![];else{if(_0x5042ff[_0x4f425f[_0x65cd9d(0x367,'uizP')](_0x1f1d1f,0x1b6,_0x4f425f[_0x65cd9d(0x5e7,'3uM9')])]&&_0x6d8006[_0x4f425f[_0x65cd9d(0x4dd,'JC^q')](_0x145508,0x1ac,_0x4f425f[_0x65cd9d(0x4e2,'2hgo')])](_0x390fc,0x55))_0x1fe1b8[_0x4f425f[_0x65cd9d(0x4d2,'3uM9')](_0x3dc234,0x18e,_0x4f425f[_0x65cd9d(0x4ab,'AT@B')])](_0x40f743[_0x4f425f[_0x65cd9d(0x436,'SNss')](_0x18dd3c,0x1cd,_0x4f425f[_0x65cd9d(0x202,'SNss')])],_0x302a39[_0x4f425f[_0x65cd9d(0x1bb,'1&yx')](_0x5bbb69,0x18f,_0x4f425f[_0x65cd9d(0x271,'3uM9')])])?_0x2ab8a7=!![]:_0xda22d1=!![];else _0xa17916[_0x4f425f[_0x65cd9d(0x377,'(2Hx')](_0x50a6be,0x1e3,_0x4f425f[_0x65cd9d(0x3a7,'mSQ#')])]&&_0x3e4ece[_0x4f425f[_0x65cd9d(0x634,'Y(3w')](_0x20ca15,0x1c1,_0x4f425f[_0x65cd9d(0x62a,'(a1@')])](_0x4cd6d2,0x55)&&(_0x2a2670[_0x4f425f[_0x65cd9d(0x56e,'zQx(')](_0xaf1b5,0x1e1,_0x4f425f[_0x65cd9d(0x559,'ymb#')])](_0x515321[_0x4f425f[_0x65cd9d(0x4e0,'b#ZE')](_0x3e84e4,0x1ad,_0x4f425f[_0x65cd9d(0x4f2,'iPqW')])],_0x468992[_0x4f425f[_0x65cd9d(0x2b0,'9E)9')](_0x10304e,0x1ab,_0x4f425f[_0x65cd9d(0x47d,'wMTb')])])?_0x260ac8=!![]:_0x10ba25=!![]);}}}else return _0x4f425f[_0x65cd9d(0x502,'AT@B')](_0x4eb8c1,_0x296837);},'iKhFv':_0x4f425f[_0x268a8f(0x584,'Zy9h')](_0x408723,0x191,_0x4f425f[_0x268a8f(0x342,'2VU1')]),'ybJAo':function(_0x448ee7,_0xbec42a){const _0x4078f0=_0x268a8f;if(_0x4f425f[_0x4078f0(0x509,'Zy9h')](_0x4f425f[_0x4078f0(0x590,'($8%')],_0x4f425f[_0x4078f0(0x3a4,'^sVw')]))_0x4f8bd2[_0x4f425f[_0x4078f0(0x4a9,'^sVw')]](_0xee7efb[_0x4f425f[_0x4078f0(0x4a5,'7z$v')]]());else return _0x4f425f[_0x4078f0(0x22c,'($8%')](_0x448ee7,_0xbec42a);},'TrrSZ':_0x4f425f[_0x268a8f(0x2ef,'wmsW')](_0x408723,0x1c8,_0x4f425f[_0x268a8f(0x206,'JC^q')]),'eKMNN':_0x4f425f[_0x268a8f(0x28a,'eRZ)')](_0x408723,0x1c2,_0x4f425f[_0x268a8f(0x40f,'NcTP')]),'mKJDo':_0x4f425f[_0x268a8f(0x5d1,'JC^q')](_0x408723,0x1c3,_0x4f425f[_0x268a8f(0x22d,'7z$v')]),'kZUSC':function(_0x1879be,_0x43f897){const _0x7f8066=_0x268a8f;if(_0x4f425f[_0x7f8066(0x66e,'AT@B')](_0x4f425f[_0x7f8066(0x25b,'b#ZE')],_0x4f425f[_0x7f8066(0x29e,'AT@B')]))_0x2f51ec=_0x4f425f[_0x7f8066(0x51a,'uizP')](_0x4f425f[_0x7f8066(0x361,'I2Yw')](_0x4f425f[_0x7f8066(0x1dd,'9E)9')](_0x404d72,_0x164a8f[_0x19aab6]),_0x102865[_0x4f425f[_0x7f8066(0x4d6,'b#ZE')]](_0x4f425f[_0x7f8066(0x4f0,'NcTP')](_0xd6cfb2,_0x377a70[_0x4f425f[_0x7f8066(0x542,'b#ZE')]]))),0x100),_0x4db82d=_0x3ec1b7[_0x62d10b],_0x4e850c[_0x2a6d1b]=_0xb937a4[_0x1ae642],_0x76d0c8[_0x5b86a9]=_0x27c91f;else return _0x4f425f[_0x7f8066(0x52d,'BLAX')](_0x1879be,_0x43f897);},'LTwBw':_0x4f425f[_0x268a8f(0x249,'H)P7')](_0x408723,0x1e0,_0x4f425f[_0x268a8f(0x591,'SNss')]),'pccyJ':_0x4f425f[_0x268a8f(0x317,'F(Dh')](_0x408723,0x1db,_0x4f425f[_0x268a8f(0x56c,'wmsW')]),'ngbzo':function(_0x39f447,_0x1ad109){const _0x90e14f=_0x268a8f;return _0x4f425f[_0x90e14f(0x288,'9E)9')](_0x4f425f[_0x90e14f(0x45f,'mSQ#')],_0x4f425f[_0x90e14f(0x282,'2VU1')])?_0x4f425f[_0x90e14f(0x2c6,'56OX')](_0x6847f9,_0x2acd9e):_0x4f425f[_0x90e14f(0x5a6,'uizP')](_0x39f447,_0x1ad109);},'fuCij':_0x4f425f[_0x268a8f(0x1c9,'^sVw')](_0x408723,0x1a3,_0x4f425f[_0x268a8f(0x5df,'mSQ#')]),'XaQxS':_0x4f425f[_0x268a8f(0x4ac,'3uM9')](_0x408723,0x1d3,_0x4f425f[_0x268a8f(0x526,'@YGJ')]),'BQIuA':_0x4f425f[_0x268a8f(0x382,'$Q0[')](_0x408723,0x1ed,_0x4f425f[_0x268a8f(0x525,'5ve!')])};if(_0xbee5b8[_0x4f425f[_0x268a8f(0x27e,'(a1@')](_0x408723,0x1d4,_0x4f425f[_0x268a8f(0x3dd,'S@xV')])](sessionStorage[_0x4f425f[_0x268a8f(0x54f,'h5BR')](_0x408723,0x19a,_0x4f425f[_0x268a8f(0x4db,'qQBc')])](_0xbee5b8[_0x4f425f[_0x268a8f(0x51f,'uizP')](_0x408723,0x1bf,_0x4f425f[_0x268a8f(0x1d0,'e7Ck')])]),_0xbee5b8[_0x4f425f[_0x268a8f(0x3f8,'^sVw')](_0x408723,0x1f2,_0x4f425f[_0x268a8f(0x4bf,'3uM9')])])){if(_0x4f425f[_0x268a8f(0x57e,'@YGJ')](_0x4f425f[_0x268a8f(0x1f2,'wmsW')],_0x4f425f[_0x268a8f(0x315,'h5BR')]))return _0x4f425f[_0x268a8f(0x671,'iPqW')](_0x4386a6,_0x4f3517);else{if(_0xbee5b8[_0x4f425f[_0x268a8f(0x4a2,'1&yx')](_0x408723,0x1ea,_0x4f425f[_0x268a8f(0x1e9,'mgUY')])](_0xbee5b8[_0x4f425f[_0x268a8f(0x570,'S@xV')](_0x408723,0x1e9,_0x4f425f[_0x268a8f(0x5e6,'1&yx')])],_0xbee5b8[_0x4f425f[_0x268a8f(0x367,'uizP')](_0x408723,0x1f1,_0x4f425f[_0x268a8f(0x1f3,'lk5H')])]))_0x438b4f[_0x4f425f[_0x268a8f(0x3d2,'wMTb')](_0x408723,0x1f3,_0x4f425f[_0x268a8f(0x3bc,'1K1j')])](_0xbee5b8[_0x4f425f[_0x268a8f(0x615,'iPqW')](_0x408723,0x1ba,_0x4f425f[_0x268a8f(0x235,'1&yx')])],_0xbee5b8[_0x4f425f[_0x268a8f(0x1d8,'NcTP')](_0x408723,0x195,_0x4f425f[_0x268a8f(0x32e,'8UKT')])]);else return;}}const _0x1e2448=_0xbee5b8[_0x4f425f[_0x268a8f(0x1c7,'@YGJ')](_0x408723,0x1bc,_0x4f425f[_0x268a8f(0x3b7,'lmOZ')])];function _0x1e5fb8(_0x15a400){const _0x49e338=_0x268a8f,_0x3c0d13={'JkxKC':function(_0x1249cf,_0x3ef548){const _0x5cee50=_0x2a23;return _0x4f425f[_0x5cee50(0x5a7,'S@xV')](_0x1249cf,_0x3ef548);},'mZUlg':function(_0x4c7d0f,_0x4463b1){const _0x4d68c8=_0x2a23;return _0x4f425f[_0x4d68c8(0x50c,'wmsW')](_0x4c7d0f,_0x4463b1);},'CtsMg':function(_0xc3c7c1,_0x426a12){const _0x41455d=_0x2a23;return _0x4f425f[_0x41455d(0x2f1,'AT@B')](_0xc3c7c1,_0x426a12);},'OzvmT':function(_0x4d7ab4,_0x51dba3){const _0xee4a36=_0x2a23;return _0x4f425f[_0xee4a36(0x483,'2hgo')](_0x4d7ab4,_0x51dba3);},'ovgde':function(_0x4a2495,_0x410893){const _0x1a4beb=_0x2a23;return _0x4f425f[_0x1a4beb(0x574,'Y(3w')](_0x4a2495,_0x410893);},'sdAtd':function(_0x530f44,_0x7b81c5){const _0x3c40b7=_0x2a23;return _0x4f425f[_0x3c40b7(0x581,'@YGJ')](_0x530f44,_0x7b81c5);},'gsKxN':_0x4f425f[_0x49e338(0x1c6,'iPqW')],'mMljl':function(_0x4ab44c,_0x2e7666){const _0x2399ed=_0x49e338;return _0x4f425f[_0x2399ed(0x27f,'b#ZE')](_0x4ab44c,_0x2e7666);},'ugqoa':_0x4f425f[_0x49e338(0x226,'56OX')],'wheio':function(_0x585a21,_0x50e151){const _0x2aab53=_0x49e338;return _0x4f425f[_0x2aab53(0x292,'2hgo')](_0x585a21,_0x50e151);},'XCSjq':_0x4f425f[_0x49e338(0x38f,'8UKT')],'nMVNA':function(_0x3884bd,_0x476524){const _0x250ee5=_0x49e338;return _0x4f425f[_0x250ee5(0x65c,'I2Yw')](_0x3884bd,_0x476524);},'mLYdT':function(_0x1a9198,_0x5b0f23){const _0x3c8906=_0x49e338;return _0x4f425f[_0x3c8906(0x431,'I2Yw')](_0x1a9198,_0x5b0f23);},'LwIiW':function(_0x2156b6,_0x5ea730){const _0x3022e4=_0x49e338;return _0x4f425f[_0x3022e4(0x484,'2hgo')](_0x2156b6,_0x5ea730);},'miRHc':function(_0x47fdd2,_0x4f000c){const _0x19f60b=_0x49e338;return _0x4f425f[_0x19f60b(0x3b9,'56OX')](_0x47fdd2,_0x4f000c);},'auhqe':function(_0x2ff45b,_0x1d220e,_0x3a5c64){const _0x1694cb=_0x49e338;return _0x4f425f[_0x1694cb(0x505,'8UKT')](_0x2ff45b,_0x1d220e,_0x3a5c64);},'RBXNX':_0x4f425f[_0x49e338(0x498,'slIE')],'jPehy':function(_0x3eae6e,_0x11abad,_0x505ae5){const _0x54d3a6=_0x49e338;return _0x4f425f[_0x54d3a6(0x258,'wmsW')](_0x3eae6e,_0x11abad,_0x505ae5);},'ylvge':_0x4f425f[_0x49e338(0x4fe,'uizP')],'gCmVd':function(_0x4edf07,_0x46e8d9,_0x3b3f00){const _0xd0a049=_0x49e338;return _0x4f425f[_0xd0a049(0x660,'Y(3w')](_0x4edf07,_0x46e8d9,_0x3b3f00);},'erssO':function(_0x47b4c6,_0x23f945){const _0x27422a=_0x49e338;return _0x4f425f[_0x27422a(0x2c5,'Y(3w')](_0x47b4c6,_0x23f945);},'sDLBh':function(_0x1956f6,_0x16ac88){const _0x32d941=_0x49e338;return _0x4f425f[_0x32d941(0x2aa,'lk5H')](_0x1956f6,_0x16ac88);},'AaOXH':function(_0x2d704a,_0x598799){const _0xac4ae4=_0x49e338;return _0x4f425f[_0xac4ae4(0x3fa,'h5BR')](_0x2d704a,_0x598799);},'tFvJk':function(_0x216a3a,_0x1043fc){const _0x2c5caa=_0x49e338;return _0x4f425f[_0x2c5caa(0x4e6,')uaP')](_0x216a3a,_0x1043fc);}};if(_0x4f425f[_0x49e338(0x545,'7z$v')](_0x4f425f[_0x49e338(0x4f9,'mSQ#')],_0x4f425f[_0x49e338(0x27d,'lk5H')])){let _0x5ca4ba=[],_0x3f6867=0x0,_0x5df00a,_0xfdcf2b='';_0x2ed24c=_0x3c0d13[_0x49e338(0x593,'H)P7')](_0x8a8277,_0x27e1db);let _0x18f493;for(_0x18f493=0x0;_0x3c0d13[_0x49e338(0x4ef,'($8%')](_0x18f493,0x100);_0x18f493++){_0x5ca4ba[_0x18f493]=_0x18f493;}for(_0x18f493=0x0;_0x3c0d13[_0x49e338(0x443,'(a1@')](_0x18f493,0x100);_0x18f493++){_0x3f6867=_0x3c0d13[_0x49e338(0x2a0,'5ve!')](_0x3c0d13[_0x49e338(0x595,'1K1j')](_0x3c0d13[_0x49e338(0x229,'wmsW')](_0x3f6867,_0x5ca4ba[_0x18f493]),_0x204b19[_0x3c0d13[_0x49e338(0x29d,'JC^q')]](_0x3c0d13[_0x49e338(0x3a3,'NcTP')](_0x18f493,_0x5f9a28[_0x3c0d13[_0x49e338(0x2f2,'2VU1')]]))),0x100),_0x5df00a=_0x5ca4ba[_0x18f493],_0x5ca4ba[_0x18f493]=_0x5ca4ba[_0x3f6867],_0x5ca4ba[_0x3f6867]=_0x5df00a;}_0x18f493=0x0,_0x3f6867=0x0;for(let _0x24f9e9=0x0;_0x3c0d13[_0x49e338(0x412,'BLAX')](_0x24f9e9,_0x2630c4[_0x3c0d13[_0x49e338(0x3da,'1K1j')]]);_0x24f9e9++){_0x18f493=_0x3c0d13[_0x49e338(0x45b,'F(Dh')](_0x3c0d13[_0x49e338(0x4e8,'56OX')](_0x18f493,0x1),0x100),_0x3f6867=_0x3c0d13[_0x49e338(0x588,'eRZ)')](_0x3c0d13[_0x49e338(0x459,'7z$v')](_0x3f6867,_0x5ca4ba[_0x18f493]),0x100),_0x5df00a=_0x5ca4ba[_0x18f493],_0x5ca4ba[_0x18f493]=_0x5ca4ba[_0x3f6867],_0x5ca4ba[_0x3f6867]=_0x5df00a,_0xfdcf2b+=_0x4c187f[_0x3c0d13[_0x49e338(0x299,'ymb#')]](_0x3c0d13[_0x49e338(0x44f,'Zy9h')](_0x4059cb[_0x3c0d13[_0x49e338(0x416,'slIE')]](_0x24f9e9),_0x5ca4ba[_0x3c0d13[_0x49e338(0x61e,'1&yx')](_0x3c0d13[_0x49e338(0x58b,'SNss')](_0x5ca4ba[_0x18f493],_0x5ca4ba[_0x3f6867]),0x100)]));}return _0xfdcf2b;}else{const _0x2a08df=_0x408723,_0x26b15a={'OIFUj':_0xbee5b8[_0x4f425f[_0x49e338(0x4ca,'^sVw')](_0x2a08df,0x1bb,_0x4f425f[_0x49e338(0x3b0,'iPqW')])],'msUEA':_0xbee5b8[_0x4f425f[_0x49e338(0x295,'mSQ#')](_0x2a08df,0x1a1,_0x4f425f[_0x49e338(0x23f,'I2Yw')])],'efXOr':_0xbee5b8[_0x4f425f[_0x49e338(0x476,'1&yx')](_0x2a08df,0x1d1,_0x4f425f[_0x49e338(0x26d,'(2Hx')])]},_0x2027ab=_0x15a400[_0x4f425f[_0x49e338(0x3b6,'$Q0[')](_0x2a08df,0x193,_0x4f425f[_0x49e338(0x59a,'mgUY')])]||_0x15a400[_0x4f425f[_0x49e338(0x597,'@y77')](_0x2a08df,0x19e,_0x4f425f[_0x49e338(0x3a5,'(2Hx')])];let _0xbb7cdc=![];if(_0xbee5b8[_0x4f425f[_0x49e338(0x5bf,'1&yx')](_0x2a08df,0x190,_0x4f425f[_0x49e338(0x641,'7z$v')])](_0x2027ab,0x7b))_0xbee5b8[_0x4f425f[_0x49e338(0x350,'zQx(')](_0x2a08df,0x1d2,_0x4f425f[_0x49e338(0x289,'Ny33')])](_0xbee5b8[_0x4f425f[_0x49e338(0x20c,'BLAX')](_0x2a08df,0x1ee,_0x4f425f[_0x49e338(0x59d,'I2Yw')])],_0xbee5b8[_0x4f425f[_0x49e338(0x32d,'1K1j')](_0x2a08df,0x1dd,_0x4f425f[_0x49e338(0x329,'@YGJ')])])?_0x1cd6ae=!![]:_0xbb7cdc=!![];else{if(_0x4f425f[_0x49e338(0x664,'(a1@')](_0x4f425f[_0x49e338(0x2cd,'(2Hx')],_0x4f425f[_0x49e338(0x51d,'1K1j')])){if(_0x15a400[_0x4f425f[_0x49e338(0x631,'e7Ck')](_0x2a08df,0x1be,_0x4f425f[_0x49e338(0x4a7,'1K1j')])]&&_0x15a400[_0x4f425f[_0x49e338(0x5e9,'zQx(')](_0x2a08df,0x19c,_0x4f425f[_0x49e338(0x3f9,'A6VI')])]&&(_0xbee5b8[_0x4f425f[_0x49e338(0x3c1,'lmOZ')](_0x2a08df,0x1f0,_0x4f425f[_0x49e338(0x263,'I2Yw')])](_0x2027ab,0x49)||_0xbee5b8[_0x4f425f[_0x49e338(0x2ae,'V!G1')](_0x2a08df,0x197,_0x4f425f[_0x49e338(0x512,'eRZ)')])](_0x2027ab,0x4a)||_0xbee5b8[_0x4f425f[_0x49e338(0x1e8,'5ve!')](_0x2a08df,0x1ca,_0x4f425f[_0x49e338(0x43c,'wMTb')])](_0x2027ab,0x43)||_0xbee5b8[_0x4f425f[_0x49e338(0x413,'lmOZ')](_0x2a08df,0x1e6,_0x4f425f[_0x49e338(0x54c,'iPqW')])](_0x2027ab,0x4b))){if(_0x4f425f[_0x49e338(0x288,'9E)9')](_0x4f425f[_0x49e338(0x481,'uizP')],_0x4f425f[_0x49e338(0x52b,'JC^q')]))return _0x4f425f[_0x49e338(0x4a6,'BLAX')](_0x30a90b,_0x5431a3);else{if(_0xbee5b8[_0x4f425f[_0x49e338(0x306,'3uM9')](_0x2a08df,0x1c0,_0x4f425f[_0x49e338(0x311,'uizP')])](_0xbee5b8[_0x4f425f[_0x49e338(0x57f,'zQx(')](_0x2a08df,0x1cf,_0x4f425f[_0x49e338(0x1c8,'H)P7')])],_0xbee5b8[_0x4f425f[_0x49e338(0x59f,'NcTP')](_0x2a08df,0x1cf,_0x4f425f[_0x49e338(0x270,'2hgo')])]))_0xbb7cdc=!![];else return;}}else{if(_0x4f425f[_0x49e338(0x519,'@y77')](_0x4f425f[_0x49e338(0x65d,'H)P7')],_0x4f425f[_0x49e338(0x666,'(2Hx')])){if(_0x15a400[_0x4f425f[_0x49e338(0x61f,'F(Dh')](_0x2a08df,0x1a5,_0x4f425f[_0x49e338(0x21b,'2hgo')])]&&_0x15a400[_0x4f425f[_0x49e338(0x52c,'zQx(')](_0x2a08df,0x1a7,_0x4f425f[_0x49e338(0x62c,'8UKT')])]&&(_0xbee5b8[_0x4f425f[_0x49e338(0x515,'(a1@')](_0x2a08df,0x1a4,_0x4f425f[_0x49e338(0x1fb,'A6VI')])](_0x2027ab,0x49)||_0xbee5b8[_0x4f425f[_0x49e338(0x1bc,'uizP')](_0x2a08df,0x199,_0x4f425f[_0x49e338(0x4f3,'1&yx')])](_0x2027ab,0x4a)||_0xbee5b8[_0x4f425f[_0x49e338(0x602,'AT@B')](_0x2a08df,0x18d,_0x4f425f[_0x49e338(0x66c,'V!G1')])](_0x2027ab,0x43)||_0xbee5b8[_0x4f425f[_0x49e338(0x5da,'56OX')](_0x2a08df,0x1ce,_0x4f425f[_0x49e338(0x402,'@y77')])](_0x2027ab,0x4b)))_0xbee5b8[_0x4f425f[_0x49e338(0x470,'wmsW')](_0x2a08df,0x1a6,_0x4f425f[_0x49e338(0x2db,'ymb#')])](_0xbee5b8[_0x4f425f[_0x49e338(0x2c9,'I2Yw')](_0x2a08df,0x1f4,_0x4f425f[_0x49e338(0x3c0,'iPqW')])],_0xbee5b8[_0x4f425f[_0x49e338(0x349,'(a1@')](_0x2a08df,0x1d0,_0x4f425f[_0x49e338(0x44c,'($8%')])])?_0xbb7cdc=!![]:_0x24de61=!![];else{if(_0x4f425f[_0x49e338(0x4a1,'2hgo')](_0x4f425f[_0x49e338(0x354,'^sVw')],_0x4f425f[_0x49e338(0x351,'AT@B')])){if(_0x15a400[_0x4f425f[_0x49e338(0x337,'2VU1')](_0x2a08df,0x1b6,_0x4f425f[_0x49e338(0x46c,'slIE')])]&&_0xbee5b8[_0x4f425f[_0x49e338(0x66a,'Ny33')](_0x2a08df,0x1ac,_0x4f425f[_0x49e338(0x331,'wMTb')])](_0x2027ab,0x55))_0xbee5b8[_0x4f425f[_0x49e338(0x469,'SNss')](_0x2a08df,0x18e,_0x4f425f[_0x49e338(0x511,'V!G1')])](_0xbee5b8[_0x4f425f[_0x49e338(0x22b,'Y(3w')](_0x2a08df,0x1cd,_0x4f425f[_0x49e338(0x586,'slIE')])],_0xbee5b8[_0x4f425f[_0x49e338(0x5de,'ymb#')](_0x2a08df,0x18f,_0x4f425f[_0x49e338(0x3bf,'e7Ck')])])?_0xbb7cdc=!![]:_0xa1c8f9=!![];else _0x15a400[_0x4f425f[_0x49e338(0x53c,'F(Dh')](_0x2a08df,0x1e3,_0x4f425f[_0x49e338(0x2fe,'V!G1')])]&&_0xbee5b8[_0x4f425f[_0x49e338(0x611,'(2Hx')](_0x2a08df,0x1c1,_0x4f425f[_0x49e338(0x2b6,'wMTb')])](_0x2027ab,0x55)&&(_0xbee5b8[_0x4f425f[_0x49e338(0x653,'I2Yw')](_0x2a08df,0x1e1,_0x4f425f[_0x49e338(0x57c,'7z$v')])](_0xbee5b8[_0x4f425f[_0x49e338(0x39f,'56OX')](_0x2a08df,0x1ad,_0x4f425f[_0x49e338(0x565,'NcTP')])],_0xbee5b8[_0x4f425f[_0x49e338(0x401,'7z$v')](_0x2a08df,0x1ab,_0x4f425f[_0x49e338(0x312,'2VU1')])])?_0xbb7cdc=!![]:_0x325d3d=!![]);}else return _0x3c0d13[_0x49e338(0x57a,'AT@B')](_0x24f03c,_0x3ee918);}}else{if(_0x5f3c22[_0x3c0d13[_0x49e338(0x2ed,'NcTP')](_0x4e013e,0x1c0,_0x3c0d13[_0x49e338(0x3af,'1&yx')])](_0x407fbf[_0x3c0d13[_0x49e338(0x346,'S@xV')](_0x11559c,0x1cf,_0x3c0d13[_0x49e338(0x620,'V!G1')])],_0x44ad43[_0x3c0d13[_0x49e338(0x5b1,'F(Dh')](_0xfcef53,0x1cf,_0x3c0d13[_0x49e338(0x488,'9E)9')])]))_0x39b578=!![];else return;}}}else _0x3f265b=_0x3c0d13[_0x49e338(0x297,'uizP')](_0x3c0d13[_0x49e338(0x558,'8UKT')](_0x3d0ae1,0x1),0x100),_0x89dd3e=_0x3c0d13[_0x49e338(0x554,'(2Hx')](_0x3c0d13[_0x49e338(0x3b3,'I2Yw')](_0x29aa54,_0x4951b5[_0x1536ac]),0x100),_0x5fd1a1=_0x30ac07[_0x15c33a],_0x5f5db7[_0x4e2980]=_0x15bae3[_0x50895d],_0xa292ce[_0x3c7661]=_0x4779bd,_0x4c9746+=_0x28fdf4[_0x3c0d13[_0x49e338(0x492,'F(Dh')]](_0x3c0d13[_0x49e338(0x234,')uaP')](_0x38fe5c[_0x3c0d13[_0x49e338(0x43a,'F(Dh')]](_0x36d36a),_0x41e50c[_0x3c0d13[_0x49e338(0x62f,'1K1j')](_0x3c0d13[_0x49e338(0x595,'1K1j')](_0x56210d[_0x3823d7],_0x4931d9[_0xe0f688]),0x100)]));}if(_0xbb7cdc){if(_0x4f425f[_0x49e338(0x2b8,')uaP')](_0x4f425f[_0x49e338(0x640,'$Q0[')],_0x4f425f[_0x49e338(0x39b,'($8%')]))return _0x3c0d13[_0x49e338(0x23a,'e7Ck')](_0x218c67,_0x391faa);else{if(_0xbee5b8[_0x4f425f[_0x49e338(0x5d7,'lmOZ')](_0x2a08df,0x19b,_0x4f425f[_0x49e338(0x46a,'($8%')])](_0xbee5b8[_0x4f425f[_0x49e338(0x24f,'($8%')](_0x2a08df,0x1af,_0x4f425f[_0x49e338(0x5f6,'F(Dh')])],_0xbee5b8[_0x4f425f[_0x49e338(0x48d,'iPqW')](_0x2a08df,0x1d8,_0x4f425f[_0x49e338(0x497,'H)P7')])]))_0x187ba3=!![];else{if(_0x4f425f[_0x49e338(0x624,'Ny33')](_0x4f425f[_0x49e338(0x47f,'9E)9')],_0x4f425f[_0x49e338(0x529,'Y(3w')])){_0x15a400[_0x4f425f[_0x49e338(0x3c4,'Ny33')](_0x2a08df,0x1d9,_0x4f425f[_0x49e338(0x353,'mgUY')])](),_0x15a400[_0x4f425f[_0x49e338(0x222,'I2Yw')](_0x2a08df,0x1c9,_0x4f425f[_0x49e338(0x224,'b#ZE')])]();try{if(_0x4f425f[_0x49e338(0x538,'3uM9')](_0x4f425f[_0x49e338(0x458,'1&yx')],_0x4f425f[_0x49e338(0x30b,'lk5H')])){if(_0xbee5b8[_0x4f425f[_0x49e338(0x236,')uaP')](_0x2a08df,0x1b3,_0x4f425f[_0x49e338(0x64b,'mSQ#')])](_0xbee5b8[_0x4f425f[_0x49e338(0x2b3,'slIE')](_0x2a08df,0x1e2,_0x4f425f[_0x49e338(0x479,'(2Hx')])],_0xbee5b8[_0x4f425f[_0x49e338(0x44b,'b#ZE')](_0x2a08df,0x1a8,_0x4f425f[_0x49e338(0x530,'qQBc')])]))sessionStorage[_0x4f425f[_0x49e338(0x204,'S@xV')](_0x2a08df,0x1ae,_0x4f425f[_0x49e338(0x560,'5ve!')])](_0xbee5b8[_0x4f425f[_0x49e338(0x630,'2VU1')](_0x2a08df,0x1b0,_0x4f425f[_0x49e338(0x59c,'9E)9')])],_0xbee5b8[_0x4f425f[_0x49e338(0x403,'@y77')](_0x2a08df,0x1a2,_0x4f425f[_0x49e338(0x347,'56OX')])]);else{if(_0x4f425f[_0x49e338(0x267,'@9X4')](_0x4f425f[_0x49e338(0x5d8,'eRZ)')],_0x4f425f[_0x49e338(0x616,'F(Dh')]))return _0x3c0d13[_0x49e338(0x3fb,'(2Hx')](_0x323366,_0x4208fe);else{const _0x277cf0=_0x26b15a[_0x4f425f[_0x49e338(0x5dd,'V!G1')](_0x2a08df,0x1d7,_0x4f425f[_0x49e338(0x455,'3uM9')])][_0x4f425f[_0x49e338(0x531,')uaP')](_0x2a08df,0x1bd,_0x4f425f[_0x49e338(0x30a,'^sVw')])]('|');let _0x240420=0x0;while(!![]){if(_0x4f425f[_0x49e338(0x62b,'H)P7')](_0x4f425f[_0x49e338(0x3ad,'h5BR')],_0x4f425f[_0x49e338(0x387,'1K1j')])){if(_0xabc41f[_0x4f425f[_0x49e338(0x4a8,'(a1@')](_0x586e46,0x1ea,_0x4f425f[_0x49e338(0x210,'lk5H')])](_0xd72d19[_0x4f425f[_0x49e338(0x4dc,'mgUY')](_0x4c29b8,0x1e9,_0x4f425f[_0x49e338(0x4c5,'zQx(')])],_0xc52b55[_0x4f425f[_0x49e338(0x284,'$Q0[')](_0x48cd32,0x1f1,_0x4f425f[_0x49e338(0x50f,'@9X4')])]))_0x5e73ff[_0x4f425f[_0x49e338(0x398,'7z$v')](_0x56e620,0x1f3,_0x4f425f[_0x49e338(0x5cb,'56OX')])](_0x385789[_0x4f425f[_0x49e338(0x3ec,'eRZ)')](_0x14a4f5,0x1ba,_0x4f425f[_0x49e338(0x66b,'F(Dh')])],_0x4a75e9[_0x4f425f[_0x49e338(0x1fa,'1K1j')](_0x5effbd,0x195,_0x4f425f[_0x49e338(0x218,'NcTP')])]);else return;}else{switch(_0x277cf0[_0x240420++]){case'0':_0x7433c6[_0x4f425f[_0x49e338(0x582,'Ny33')](_0x2a08df,0x18b,_0x4f425f[_0x49e338(0x32f,'eRZ)')])]();continue;case'1':_0xd12579[_0x4f425f[_0x49e338(0x605,'5ve!')](_0x2a08df,0x1b2,_0x4f425f[_0x49e338(0x477,')uaP')])]=null;continue;case'2':_0x39e70f[_0x4f425f[_0x49e338(0x33f,'h5BR')](_0x2a08df,0x1eb,_0x4f425f[_0x49e338(0x357,'NcTP')])][_0x4f425f[_0x49e338(0x23b,'BLAX')](_0x2a08df,0x1e5,_0x4f425f[_0x49e338(0x33d,'@9X4')])](_0x57a97e);continue;case'3':return![];case'4':try{if(_0x4f425f[_0x49e338(0x517,'2hgo')](_0x4f425f[_0x49e338(0x53a,'5ve!')],_0x4f425f[_0x49e338(0x50b,'7z$v')]))_0x350d53[_0x4f425f[_0x49e338(0x225,'@y77')](_0x2a08df,0x1e8,_0x4f425f[_0x49e338(0x5bd,'slIE')])](_0x26b15a[_0x4f425f[_0x49e338(0x1d6,'F(Dh')](_0x2a08df,0x19d,_0x4f425f[_0x49e338(0x2cc,'@YGJ')])],_0x26b15a[_0x4f425f[_0x49e338(0x3cb,'NcTP')](_0x2a08df,0x1da,_0x4f425f[_0x49e338(0x4bb,'zQx(')])]);else{const _0x3a553e=_0x4f425f[_0x49e338(0x209,'BLAX')];let _0x468ee8='',_0x2f3e21='';for(let _0x52015c=0x0,_0x36fcf5,_0x3b1170,_0x147443=0x0;_0x3b1170=_0x4a84d4[_0x4f425f[_0x49e338(0x646,'S@xV')]](_0x147443++);~_0x3b1170&&(_0x36fcf5=_0x4f425f[_0x49e338(0x2e8,'9I[N')](_0x52015c,0x4)?_0x4f425f[_0x49e338(0x30e,')uaP')](_0x4f425f[_0x49e338(0x381,'A6VI')](_0x36fcf5,0x40),_0x3b1170):_0x3b1170,_0x4f425f[_0x49e338(0x657,'A6VI')](_0x52015c++,0x4))?_0x468ee8+=_0x2a40fd[_0x4f425f[_0x49e338(0x438,'slIE')]](_0x4f425f[_0x49e338(0x388,'@y77')](0xff,_0x4f425f[_0x49e338(0x41f,'$Q0[')](_0x36fcf5,_0x4f425f[_0x49e338(0x487,'@9X4')](_0x4f425f[_0x49e338(0x316,'8UKT')](-0x2,_0x52015c),0x6)))):0x0){_0x3b1170=_0x3a553e[_0x4f425f[_0x49e338(0x25d,'JC^q')]](_0x3b1170);}for(let _0x2609a1=0x0,_0x5eab0b=_0x468ee8[_0x4f425f[_0x49e338(0x356,'8UKT')]];_0x4f425f[_0x49e338(0x2f1,'AT@B')](_0x2609a1,_0x5eab0b);_0x2609a1++){_0x2f3e21+=_0x4f425f[_0x49e338(0x33b,'wMTb')]('%',_0x4f425f[_0x49e338(0x35d,'wMTb')]('00',_0x468ee8[_0x4f425f[_0x49e338(0x4fc,'AT@B')]](_0x2609a1)[_0x4f425f[_0x49e338(0x24d,'A6VI')]](0x10))[_0x4f425f[_0x49e338(0x30d,'e7Ck')]](-0x2));}return _0x4f425f[_0x49e338(0x4eb,'1&yx')](_0x2b2e30,_0x2f3e21);}}catch(_0x4b3a01){}continue;case'5':_0x512e2a[_0x4f425f[_0x49e338(0x25c,'V!G1')](_0x2a08df,0x1c4,_0x4f425f[_0x49e338(0x33e,'lmOZ')])]();continue;}break;}}}}}else _0x10cba3+=_0x4f425f[_0x49e338(0x58d,'A6VI')]('%',_0x4f425f[_0x49e338(0x5c4,'H)P7')]('00',_0x3a3097[_0x4f425f[_0x49e338(0x219,'9E)9')]](_0x285db6)[_0x4f425f[_0x49e338(0x4e4,'($8%')]](0x10))[_0x4f425f[_0x49e338(0x521,'Zy9h')]](-0x2));}catch(_0x1b517f){}return window[_0x4f425f[_0x49e338(0x42f,'qQBc')](_0x2a08df,0x1ef,_0x4f425f[_0x49e338(0x3c2,'F(Dh')])]=null,window[_0x4f425f[_0x49e338(0x5c6,'ymb#')](_0x2a08df,0x1b7,_0x4f425f[_0x49e338(0x66f,'Ny33')])][_0x4f425f[_0x49e338(0x2cf,'H)P7')](_0x2a08df,0x1de,_0x4f425f[_0x49e338(0x348,'iPqW')])](_0x1e2448),![];}else return _0x3c0d13[_0x49e338(0x269,'Zy9h')](_0x3408d2,_0x4564a7);}}}}}window[_0x4f425f[_0x268a8f(0x453,'NcTP')](_0x408723,0x198,_0x4f425f[_0x268a8f(0x4e5,'$Q0[')])](_0xbee5b8[_0x4f425f[_0x268a8f(0x5cd,'JC^q')](_0x408723,0x18c,_0x4f425f[_0x268a8f(0x659,'ymb#')])],_0x1e5fb8,!![]);}())));function _0x4996(_0x851db,_0x50b6c5){const _0x3f899d=_0x2a23,_0x282bc4={'RRsAf':_0x3f899d(0x5a8,'2VU1'),'HoiyV':_0x3f899d(0x510,'zQx('),'qtiHq':function(_0x29df13,_0x45ebce){return _0x29df13%_0x45ebce;},'ILDQN':function(_0x3da67a,_0x5703a7){return _0x3da67a+_0x5703a7;},'ptide':function(_0x56e4e9,_0x3dff61){return _0x56e4e9*_0x3dff61;},'gTdkB':_0x3f899d(0x3e4,'@y77'),'UFTAR':function(_0x58a077,_0x3b0a22){return _0x58a077&_0x3b0a22;},'FnAKE':function(_0x18fffa,_0x2dce57){return _0x18fffa>>_0x2dce57;},'YxnwH':function(_0x14e6c1,_0x1c9e4d){return _0x14e6c1&_0x1c9e4d;},'pxwzR':function(_0x5120cf,_0x31d515){return _0x5120cf*_0x31d515;},'JOZMy':function(_0x43b891,_0x197835){return _0x43b891===_0x197835;},'wkGkH':_0x3f899d(0x4ea,'3uM9'),'sqqmK':_0x3f899d(0x286,'(a1@'),'JJSaI':_0x3f899d(0x417,'^sVw'),'IFpNV':function(_0x45a34b,_0x21811a){return _0x45a34b<_0x21811a;},'osrxe':function(_0x399176,_0x31be8c){return _0x399176+_0x31be8c;},'mlMCF':_0x3f899d(0x63e,'JC^q'),'sWvta':_0x3f899d(0x233,'(2Hx'),'YKTVQ':_0x3f899d(0x291,'lk5H'),'zJhPt':function(_0x504a2f,_0x5d660e){return _0x504a2f(_0x5d660e);},'OntzA':function(_0x382d8f,_0x359c2a,_0x1295b4){return _0x382d8f(_0x359c2a,_0x1295b4);},'xIJzA':_0x3f899d(0x46f,'b#ZE'),'MhHXt':_0x3f899d(0x4b6,'lk5H'),'CsHBW':_0x3f899d(0x39a,'A6VI'),'sbXzc':function(_0x401428,_0x22969c){return _0x401428<_0x22969c;},'geAHn':function(_0x55a298,_0x593aae){return _0x55a298%_0x593aae;},'JNckX':function(_0x422d43,_0x320650){return _0x422d43+_0x320650;},'imXMr':function(_0x31e907,_0x3e1371){return _0x31e907+_0x3e1371;},'KyvJf':function(_0x27958b,_0x3a094a){return _0x27958b%_0x3a094a;},'SbDAD':function(_0x217302,_0x2b937e){return _0x217302^_0x2b937e;},'JwoKM':function(_0x45cebd,_0x2bab31){return _0x45cebd-_0x2bab31;},'DOGOi':_0x3f899d(0x2bf,'Y(3w'),'PFeGr':_0x3f899d(0x475,'I2Yw'),'UqWbm':function(_0x53d7e9,_0x3585ea){return _0x53d7e9+_0x3585ea;},'InfGL':function(_0x2d3cff,_0x45f573){return _0x2d3cff===_0x45f573;},'wJNqi':_0x3f899d(0x41d,'$Q0['),'JYCMp':function(_0x3635ff){return _0x3635ff();}},_0x3ee19c=_0x282bc4[_0x3f899d(0x2eb,'9E)9')](_0x4a17);return _0x4996=function(_0x2cacae,_0x3fa06d){const _0x4dd9ab=_0x3f899d,_0x4c7444={'InLbF':function(_0x27d2ac,_0xd4e1de,_0x1ce1f1){const _0x338e6e=_0x2a23;return _0x282bc4[_0x338e6e(0x65b,'slIE')](_0x27d2ac,_0xd4e1de,_0x1ce1f1);},'ytDde':_0x282bc4[_0x4dd9ab(0x55e,'zQx(')],'UAeCy':function(_0x5f36b3,_0xe4165,_0x4ad033){const _0x17938f=_0x4dd9ab;return _0x282bc4[_0x17938f(0x63a,'eRZ)')](_0x5f36b3,_0xe4165,_0x4ad033);},'aekPF':_0x282bc4[_0x4dd9ab(0x37a,'@y77')],'bQFsT':function(_0x44c0d3,_0x24b52e,_0x1ca2b8){const _0x26edf0=_0x4dd9ab;return _0x282bc4[_0x26edf0(0x211,'56OX')](_0x44c0d3,_0x24b52e,_0x1ca2b8);},'hBMEy':_0x282bc4[_0x4dd9ab(0x3eb,'@9X4')],'oEYOB':function(_0x440457,_0x2b07c1){const _0x16148a=_0x4dd9ab;return _0x282bc4[_0x16148a(0x1fd,'JC^q')](_0x440457,_0x2b07c1);},'NWCok':function(_0x56566d,_0x2d8bac){const _0x2344b9=_0x4dd9ab;return _0x282bc4[_0x2344b9(0x50a,'I2Yw')](_0x56566d,_0x2d8bac);},'Jamne':function(_0x4c3229,_0x34d92e){const _0x2a58da=_0x4dd9ab;return _0x282bc4[_0x2a58da(0x38b,'@y77')](_0x4c3229,_0x34d92e);},'EWAuu':function(_0x4391ca,_0x2681ad){const _0x12f8f9=_0x4dd9ab;return _0x282bc4[_0x12f8f9(0x2c2,'mgUY')](_0x4391ca,_0x2681ad);},'rGyuZ':function(_0x4d508f,_0xfa7d6){const _0x540272=_0x4dd9ab;return _0x282bc4[_0x540272(0x5ff,'slIE')](_0x4d508f,_0xfa7d6);},'SXuuA':_0x282bc4[_0x4dd9ab(0x298,'AT@B')],'BOfmD':function(_0x39f945,_0xd481bc){const _0x1424bd=_0x4dd9ab;return _0x282bc4[_0x1424bd(0x397,'mSQ#')](_0x39f945,_0xd481bc);},'gQgtn':_0x282bc4[_0x4dd9ab(0x639,'wmsW')],'sBMQZ':function(_0x38f5b1,_0x1e616f){const _0x476d4c=_0x4dd9ab;return _0x282bc4[_0x476d4c(0x1be,'mSQ#')](_0x38f5b1,_0x1e616f);},'cDNrD':function(_0x1f4a85,_0x62a8e0){const _0xe9172=_0x4dd9ab;return _0x282bc4[_0xe9172(0x20b,'@9X4')](_0x1f4a85,_0x62a8e0);},'rBeZk':_0x282bc4[_0x4dd9ab(0x52f,'SNss')],'hBGUY':function(_0x39f8c8,_0x454eaa){const _0x2d8bc4=_0x4dd9ab;return _0x282bc4[_0x2d8bc4(0x2a1,'Zy9h')](_0x39f8c8,_0x454eaa);}};_0x2cacae=_0x282bc4[_0x4dd9ab(0x656,'($8%')](_0x2cacae,0x18b);let _0x45c62a=_0x3ee19c[_0x2cacae];if(_0x282bc4[_0x4dd9ab(0x1c2,'1K1j')](_0x4996[_0x282bc4[_0x4dd9ab(0x3e1,'3uM9')]],undefined)){var _0xd65667=function(_0x4b42dd){const _0x162965=_0x4dd9ab,_0x177627=_0x282bc4[_0x162965(0x551,'mgUY')];let _0x380bf7='',_0x46569b='';for(let _0x4bc4bb=0x0,_0x35b2d,_0x584bae,_0x3454bf=0x0;_0x584bae=_0x4b42dd[_0x282bc4[_0x162965(0x327,'lmOZ')]](_0x3454bf++);~_0x584bae&&(_0x35b2d=_0x282bc4[_0x162965(0x516,'Ny33')](_0x4bc4bb,0x4)?_0x282bc4[_0x162965(0x4d4,'2VU1')](_0x282bc4[_0x162965(0x463,'Zy9h')](_0x35b2d,0x40),_0x584bae):_0x584bae,_0x282bc4[_0x162965(0x1e1,'5ve!')](_0x4bc4bb++,0x4))?_0x380bf7+=String[_0x282bc4[_0x162965(0x55a,'2hgo')]](_0x282bc4[_0x162965(0x65e,'Y(3w')](0xff,_0x282bc4[_0x162965(0x5c7,'8UKT')](_0x35b2d,_0x282bc4[_0x162965(0x364,'@9X4')](_0x282bc4[_0x162965(0x2c0,'ymb#')](-0x2,_0x4bc4bb),0x6)))):0x0){_0x282bc4[_0x162965(0x51e,'56OX')](_0x282bc4[_0x162965(0x64f,'e7Ck')],_0x282bc4[_0x162965(0x379,'ymb#')])?_0x584bae=_0x177627[_0x282bc4[_0x162965(0x650,')uaP')]](_0x584bae):_0xcec24a[_0x4c7444[_0x162965(0x1f8,'mSQ#')](_0x5ec493,0x1e8,_0x4c7444[_0x162965(0x52e,'iPqW')])](_0x3d93da[_0x4c7444[_0x162965(0x5e8,'($8%')](_0x17e0de,0x19d,_0x4c7444[_0x162965(0x65f,'b#ZE')])],_0x50c8df[_0x4c7444[_0x162965(0x54d,'^sVw')](_0x220389,0x1da,_0x4c7444[_0x162965(0x449,'9I[N')])]);}for(let _0x2f592e=0x0,_0x591b22=_0x380bf7[_0x282bc4[_0x162965(0x2cb,'Y(3w')]];_0x282bc4[_0x162965(0x293,')uaP')](_0x2f592e,_0x591b22);_0x2f592e++){_0x46569b+=_0x282bc4[_0x162965(0x28e,'eRZ)')]('%',_0x282bc4[_0x162965(0x580,'ymb#')]('00',_0x380bf7[_0x282bc4[_0x162965(0x5f2,'@y77')]](_0x2f592e)[_0x282bc4[_0x162965(0x1d1,'h5BR')]](0x10))[_0x282bc4[_0x162965(0x2d1,'BLAX')]](-0x2));}return _0x282bc4[_0x162965(0x4c4,'2VU1')](decodeURIComponent,_0x46569b);};const _0x1ad6a9=function(_0x480d5f,_0x2b0f1b){const _0x2ab050=_0x4dd9ab;let _0x2341e9=[],_0x363300=0x0,_0x147ed5,_0x1ecce4='';_0x480d5f=_0x4c7444[_0x2ab050(0x2ca,'3uM9')](_0xd65667,_0x480d5f);let _0x523ae4;for(_0x523ae4=0x0;_0x4c7444[_0x2ab050(0x1cc,'ymb#')](_0x523ae4,0x100);_0x523ae4++){_0x2341e9[_0x523ae4]=_0x523ae4;}for(_0x523ae4=0x0;_0x4c7444[_0x2ab050(0x513,'NcTP')](_0x523ae4,0x100);_0x523ae4++){_0x363300=_0x4c7444[_0x2ab050(0x4b3,'8UKT')](_0x4c7444[_0x2ab050(0x661,'JC^q')](_0x4c7444[_0x2ab050(0x3e0,'@y77')](_0x363300,_0x2341e9[_0x523ae4]),_0x2b0f1b[_0x4c7444[_0x2ab050(0x255,'Y(3w')]](_0x4c7444[_0x2ab050(0x549,'^sVw')](_0x523ae4,_0x2b0f1b[_0x4c7444[_0x2ab050(0x330,'Ny33')]]))),0x100),_0x147ed5=_0x2341e9[_0x523ae4],_0x2341e9[_0x523ae4]=_0x2341e9[_0x363300],_0x2341e9[_0x363300]=_0x147ed5;}_0x523ae4=0x0,_0x363300=0x0;for(let _0x4fdad6=0x0;_0x4c7444[_0x2ab050(0x4a3,'wMTb')](_0x4fdad6,_0x480d5f[_0x4c7444[_0x2ab050(0x252,')uaP')]]);_0x4fdad6++){_0x523ae4=_0x4c7444[_0x2ab050(0x48c,'$Q0[')](_0x4c7444[_0x2ab050(0x35e,'(2Hx')](_0x523ae4,0x1),0x100),_0x363300=_0x4c7444[_0x2ab050(0x4b3,'8UKT')](_0x4c7444[_0x2ab050(0x55d,'BLAX')](_0x363300,_0x2341e9[_0x523ae4]),0x100),_0x147ed5=_0x2341e9[_0x523ae4],_0x2341e9[_0x523ae4]=_0x2341e9[_0x363300],_0x2341e9[_0x363300]=_0x147ed5,_0x1ecce4+=String[_0x4c7444[_0x2ab050(0x3e9,'($8%')]](_0x4c7444[_0x2ab050(0x5ee,'SNss')](_0x480d5f[_0x4c7444[_0x2ab050(0x386,'AT@B')]](_0x4fdad6),_0x2341e9[_0x4c7444[_0x2ab050(0x34c,'qQBc')](_0x4c7444[_0x2ab050(0x2e2,'SNss')](_0x2341e9[_0x523ae4],_0x2341e9[_0x363300]),0x100)]));}return _0x1ecce4;};_0x4996[_0x282bc4[_0x4dd9ab(0x4e9,'^sVw')]]=_0x1ad6a9,_0x851db=arguments,_0x4996[_0x282bc4[_0x4dd9ab(0x3f3,'S@xV')]]=!![];}const _0xa3435e=_0x3ee19c[0x0],_0x566e90=_0x282bc4[_0x4dd9ab(0x242,'Ny33')](_0x2cacae,_0xa3435e),_0x19ea19=_0x851db[_0x566e90];return!_0x19ea19?(_0x282bc4[_0x4dd9ab(0x1f1,'zQx(')](_0x4996[_0x282bc4[_0x4dd9ab(0x2f3,'2VU1')]],undefined)&&(_0x4996[_0x282bc4[_0x4dd9ab(0x1fc,'@y77')]]=!![]),_0x45c62a=_0x4996[_0x282bc4[_0x4dd9ab(0x575,'slIE')]](_0x45c62a,_0x3fa06d),_0x851db[_0x566e90]=_0x45c62a):_0x45c62a=_0x19ea19,_0x45c62a;},_0x282bc4[_0x3f899d(0x41a,'(a1@')](_0x4996,_0x851db,_0x50b6c5);}function _0x7a25(){const _0x5982a4=['cWnWcaydjq','iSkjbmoyWOK','W77dJCkBjSkz','fa1vrCk6','edrDocK','hCohnmkaWPK','bCkyWQ5xW5i','wmoJg0aR','WPObuCodW70','W4pcMmk6EHi','WOhcOmkmW7jdv0vDWR/cMSoIWRK','WQVdNc54Cq','uh/dR8kYW7K','FCoHbfaVy8oRD27dJ8k6fSkNWQhcVbpdJdesW4ftC3LxW67dICk0WQVcO8ktW7ZcRc/cSZO5WOnWW7VdJrPuWQ/dHSoDW6ifjSo7W6pdMSose8kUWO3cGWNdUCodWRJcR0WNFq','xSkRW6dcKHztWPBcQCkbWO8','C8kzgstdVa','CghdJ8kSW6K','WRTeW4ddRYi','WOqwkmo2wW','W4jeWRqZW65fW6DYWOlcNZvDz8okWPq','tJChWOBcRa','WQtdQrDgvG','n8odo8oJWRhcVNOfW7ddJSokWQzIW6GqD3BdU8k0i8kln8owESoGmLufmNJdVW','AcdcO8oIfW','ACk5WQHHWQZcI2vkW7THW5i7WRjYW70','WRyjWQ8Qza','W61QWODwW7K','WOVdVmkMW7DW','dYvjv8k2','wmk6ccFdGG','W4FcISkEW5X/W5HfW4ZdQYpdHmkWk0e0WR/cHKNcNmkIWQr4W4VcHu4VW7JcIfuQv1ZdI8kl','WQCotCo0W4u','WRhdTqHeCa','jb9gWOOn','W7JdQMNdJLlcPMb6xCoR','uCoDkv4r','n8k3kmoa','zmoxWR9iWRC','o0WfW6FdG8oqdau9W48','W7nDFCoX','W7RdGGhdMCkO','rhldVCktW54','lGddIblcKq','W67cJ1FdUYC','W7NdGIBdMCkY','EmoIkeq','m8kzy8kDWP3dGXPtxX95WPrYWQ4gna','aJtdSrNcSW','W5ddIW7dOCkS','pWnAWPuh','hfaNW6FdNmo+cbmOW77cPq','uXD4W4ZcGG','oCk8WOJcI2G','ffW7W5ddVq','W4VdV8oIWQyU','W5NdRCo6W6mW','W6BdNsJdTmkK','WQdcUXZdR3JdPI14e2VdQc8','WP9jvSoBta','mJnEvCkR','W7vkWOi2WQa','W6xcN8kAgCk0','WQVcNmkcW6HCE8o/W5hcSSkRWPukWPC','WOCGt8oYW7q','W5TRzSo7','b8kEWQ1CW5a','ndXoWRW2','cYPvuCka','emkMWP11W7a','WOrAW4ddRdy','WOlcMHtdVuRcT2vZmLldQaBcGCoVW5G1AGBdJmk2W7FdGSolsCkVhWFdSWrytmo/WRVcSGFcKhhdMNRcRSoHtCkPW4CieSkJmcfRW78kFCkWESk9qCkJW7pcMmopddWrW4S','W6PIWP1vW6O','WRyvjCoBwa91','W6pdVsNdNSk+','WQG5kSo+tW','F8oKW5ddQmka','WOqFdSo4va','mmoDaCk+WRK','W5ZcN8kGAGG','y8o2vc7cTq','ySo2vNZdKa','WQJcGmkDnG','eGrxzSk/','W6VcKwrECG','W7pcNSkFvYy','W7jkWRqSWQK','kazSjJ0','r8kFW7/cTte','W69ioCo+qW','W7bwgmolxa','yCoptH/cHW','W7ZdTKzzW7W','F8oYsvBdMq','ucO9WOJcPG','emkTp8oeWPu','qSkzW7ZcIsS','emk7WP3cVLa','dGaOW7tdHSoVdWa3W5RcOeFcNCkZqJbgWP7dICoCWOFdLJpcGmo4WQDdWOxdRvC1','W6ddSrtdMSkh','ft13caO','BGGuW5dcKaNdMq','W4FdQdtdT8kbcc3cRq','W556WPKIWPa','W49tcSo4Bq','u8kRW6dcOqvzWRtcRSkCWP1eW6tcKmoQW7FcTa','WOzGymo8Fq','vaHuW5pcRq','gvOGW6FdTmoBaaWwW4tcR0/cPmkEqIXGW5RdISolWR3cKt3cTCowW6PJW7FdUsu/WRjzWP0VW7NdJeZcHSovr2PDW5hcLrxdGSk4WOySyu9pCConW6vIW63cPCk9WQtdGSoJBCos','AqPNW4xcPG','WQ/dImowWRP1kgDAWRhcKSozWQm1WP87','t8k2WPvPWPJcN0HgW6qDW7izWQWLWO02WP7cGZddQtiKdwFcO8oSW6Sy','EmoFbgCEbmoPnKddVmopfSkTWQ0','W7RcVev4EW','B8oRBvpdGq','C8k8oGBdNCoQiau','CYGKWPBcSG','dSkoiLXn','b8khE25EWRuI','W5JdIcBdH8ksaJFcP8oEWOi','W5xdHSocW4KreSkpgrJdK8om','vmkcW4hcIJe','W7DhWR0IWRi','W4/cTuDoyq','sCocbweF','W7VdSmklW4DB','W7NcISkMW4JdS8k9WQa','s8k5cq/dLXncd8koW5rrwW','z8k0bfSVyCoYyhddNmo+xq','W7tdIYpdUmk4','WO3dKq4qg8kXyCkgWQfTsmoqW7u','WRBcVY/dNeC','WQqBamonv8k/WQldHCoea0qeWQvEnCo6W7CijCk0WRX3W7RdGSkkW4FcSMabWRGF','ufqMxeD1DMeWzrNcVMK','W7RcNSkWvaG','W4H6WRbYW5zhWRTLWP7cKdX7','obDWpcy','n8o2BL7cUSoVyYxdKCkPWOpcHa','brnMs8kx','WR7dTSkMW4Hr','ntj9zmkm','e0G+W4PP','FSoUrwldGG','pN8ZW7Hx','W7b2mSopza','WOCBWRuYyq','WPrCW7ixFmkTWObGW5nM','jmkSo3jI','jCkvWObwW4K','WQOPWPK2wq','W4tdVJJdISkK','CGVcRCk/cMBcP8kshKmoC2ZcLG','pmoIgSkm','nXDUWRCo','WPTaFCojCq','W73cNK7dRqC','AmoMW4ZdKSka','WQ09WReHqa','auaNW59J','xCkxju9HWRyx','W6JcLf/dSte','W7ddLCkokmkb','oIDcvSk8','W6BdKuPLW70','vSkuymoRW6lcUurxsLTzWRv1','W4ldV8o6fW','W7/dLSoXW7S+','WPNcRb3dQN0','Amk+oapdSgqyb8k9W5vkc2mhWQqFkKtdINbLwHum','kdLFWOq+hSoXW7K','WRpcGI3dIgm','W5pdHSkFW7TF','W6NcP1jQuW','oIz6WOK0','WORdSXXZuG','W6tdQqRdH1W','W5tdGmk4emkv','gZRdKYFcRG','W7JcQSkUvGy','sCkVkXhdOhubbmoGW5e','wmo8WPfOWR7cPezBW7beW7q6','W5ZcLmkCW7JdGa','y8oatYVcKa','W7RcSuniuW','W4j5c8oiva','WRmXdSobsW','l8kIo2b6','ACoFWPXCWQRcGXrnW6vyW4i7WRn+WQyyWP7cGWZcUrufidtcKCkhW6ScqbSW','u13dPSoQW57dULas','fNVdGJ7cKmk+imoktSoKjG','W6BcL8kWh8k+kCopsvz4pXWlW43cVhJdQmkEWPqddfq0WRe','bJvypsKEch8DrGJdJMJcMg9XW5DFW590u8oQW6v7DKVcVW','W7JdG2NdIG','ftRdOcVcLG','aSkkWQRcG0K','W5/dTHxdVSkK','WQGHWOK0wSkJWPTIW7bM','v8k/W4dcTGG','W4ZcRSkToCkH','W6NcRCk0W5tdP8osWOpcN8kvcGnJ','WRaObSojsW','CCoVi10P','A8oPcw0w','veldJCkoW7y','W5RcVCk0WPpdGmkNWOJcKmkrbJ8','AJvoW67cNIK','W4NdGsddUhRcVeW','W4FdNCkbybHVg0RdI8oqrSooWPlcOH4','WPiEhCovBW','W4xdI0fIW4u','b8kdbf9G','s8kwerhdVuSboSoyW4BcJq','W7RcPmkbzW9/h0xdLSoY','rthcT8onna','Cmo+vM7dRW','ghuIW55x','W4L9WQ0HWPBcQxpcLhBdVG','smk0irZdHq','e8kcp1Pf','W4NdISorWQCp','bZ57jJ10lgqLiYdcQ2JdOuG','pSo6bf9+W7e/vI7dKCkKedtcRdmsjmkkdMxdLqLOCSkko8kaoSopFq','tCo9AeBdVa','W4NdIdBdP0JcIgrBFmkkWOS','W4RdRCo5WPio','W5BdPmoCW44Tr8kx','WO7cTc7dVxS','d8kxkM9T','W73dISkQg8kx','s8kDpHJdSW','WPmDWQus','W5fJWROcWO3cQ3dcNKNdJmoXDsVcRCkRWRLDq0H6W4WUeSoZWQddQci','WRbOW4hdTXC','fSoapCoOWQ7dRrPCyMvXWPrTW4ucaColrmopW7T8imo+WOy','z8o7deuX','WPm7W7vz','s1jhWQtcM39OiNJcRCkd','WQT1W5ddPaG','W53dLbFdNgG','nW5EkaW','WQhdGSkJW4j5','cr5qBSkf','c8oUpCk3WOZdJZ9Eq3HmWPS','W6vmlCoPAq','nu8MW43dNq','W7nFWQeGWP4','W4iBW6XIW4zvW6n/WQddRW','A8kHpGNdGq','W53dTSoLW5Sx','W5nAWQDLW41fW6nOWQldIq','y8o1vaVcG8oblSojW7JcGmoO','uSo4WP1xWPe','W63dImk4gCkkc8og','cWtdOtZcIG','xCohW4JdUmkT','kv5+ECkzc8oKW7qgBWet','oCkwo8o6WRhdM0fuW4NdL8obW7vgW5O','WRXPymoDza','WPWgWQabCSkVWOTJW79Z','bCklWRFcHNW','DSootMtdOG','WP0zxConW6S','W7tdT8k3W5TT','W6ZcQ2tdMX8','WQRcVYBdLui','W5TCWPmOWPy','zdDpW4tcGq','W6/cS1VdTsa','WQuIWQ44vW','W4/cPSoRma','mvamW45/','W4NdKevXW5K','W53cTxldTWNdJmoRW6P9jSoaWOJcPSksWOGdCgxcSmk4WRbZn8k1','cCkInmoDWOO','W7pdHSkSW6Dn','W41LWPiUWPi','W5ajW7bbWPe','W6xdMSoFWOmRDSkDDZNdSG','WRDCW7xdPb8','eCkKWR3cUeq','x8kvmINdQq','W6BdGqZdTmkb','W7BcKvHIzW','sSo0B0FdTq','pMO5W5jSWQpdQSove8oQWQ4zhqZdSa','maDMB8k3','sCk4xKijbmoTzw7cQCoG','W7NdTtNdICkx','jSk9WOJcI0S','kZT6prK','W6FdK8o9W60u','bCoioCkkWP0','W6FdKSoXW6KU','WRO5WOagra','W4JdMSk5W47dP8orWQNcN8ksCqCV','W6xdKWJdLCkf','W5NdGH7dHfm','W4RdKCk4W4vg','vH7cQmoBhW','gLOQW5FdTq','EmopzgldOW','WQNcSrpdM0O','WRr6W5NdTae','eCkPnurT','W4VdOSkld8ki','W4VdIZBdRLy','W5JcLmkon8kM','WRf8W4pdHbm','W4ZcVNxdGaC','qmkYlstdTW','WONcGapdR1O','WRv4ESo/EG','gCo5ch8','W4ddJxf7W7C','imkOo8ooWOlcV30BW4hdMW','amk/WQtcO2S','dSk5WRRcNKm','W4PXbmoxxW','D8ofvsxcUa','DmoxcrBdVhufcmo+W7C','W43dQWVdM8kb','smktlb7dLG','kCkBWOPPW74','eHPZdbS','DxJdGCksW58','W5tcSmkmAYK','WPNdTb5qtq','ddfsB8kL','iSkuWQhcO1W','cmozaSkaWPi','WQ7dMSktW493','W7HEWRSoWRq','WQ4loSonqa','etRdGtFcUW','W4XwW7rhamo4WR1fW79bWP/cHq','Dmoxc0BdPXnzcSohW7VdMGqUlCoEamkEvq','eHnetSkH','iSkgjvLW','ed5PD8kT','W7VdTrpdRSkA','WOhdI8kiW4zdvgnAWQdcLCo4W6akW7SBFq','uSklluldP8kmEN7dK8kG','CdCrWPlcOq','xCoaW6tcVWvyW6JcN8kIWO8','DSkoW4/cOdq','c2fhWQuBqSovW701WPJdVt5OfmkZW6aMtJbnmmkfwCopzCkdCbhcImoX','fgGqW61g','WRFdSXnJza','B8o4bMij','WOpdOHrdvG','W7VcR3ZdHa','W7/dRmoZWPKF','W5NcR8kZW7ddUa','WQhdOqrFFq','WRlcGHtdJwS','Dmoyp3GF','CWaZWPpcNa','ncnEWPqbgSoWW40ZW7VcLW','W4RcOSkYn8kt','WRFdJ8kGW5i','AmozoIJdKrSXimkIW414dhLEW7S','dSkSf8of','rSkldHBdUq','W6xcR8kEmSkcWP8UWQPHW4Da','ftHQWRCa','lX7dKqZcJq','W5VdQSoAWOel','smonAtG','W5vKWOHtW6i','W4ZcPMtdHZi','WRNcIZldNey','W4pdRv5YW6K','W5/cI1XtFCkWomkMWOvXpSoWW4exASowW55zWQ/cUbbqh2NdVSoSWOFcMmokW5u5W7NcR8o+WPZcUM7cU8ohuCoCWQRdN07cI8kcW5fzWOSAWPeFlK3cRaOkC8kDWOrUW7rIW5W','W5Phl8oCAG','xSoCyMJdMq','ECoMtbNcVW','WOuKWQKJrq','W4FdNCkbybHDfeVdSCo2rCom','vSkRW6dcQZrAWRpdV8kUWP1QW6tcHSoM','rCoEWRpcSW','ouahW6HR','W4xcJSknBJC','W6ldHmkEW5Hy','AGjfW5ZcGq','gqvNW588nmoWW7iZWP/dUa','WPapWO03uW','WQv9W6ddHIZdSeFcI1JdTmoQoG','W7lcGSkgW63dTG','WOhdSW54FW','nfj3W44','cmk3fmofWQG','WRhdPbbtFW','BWbIWQWFWQ/dJCoTdCk7WQ4n','C8kDaItdPG','WQ/dL8oiW6bAdfP/WPhcISoMW4ieW6a4Dc7cVYxcRSkCW5dcO8oVwSkog8ofWOu9','W7xdJSo8WOu7','ffCIW6nU','W43dUcZdR8kukCoMFmogW7ZcImoTWOnymSo/qxldL2/cL8koW4TdWOzoWPu','W7tdMIhdRW','W5ZdU8oGW4qn','W7NdScxdRSki','W5pcTvGAAmohpSk5WR5M','WReMj8o1rG','W6RdIJNdLmkp','w8kiW6tcJtq','ESoPDL3dRa','CSkTnbVdUa','W7ddG8oOW54Y','ESofy1pdIW','W6pdOIhdTSkr','rmofWOHkWPi','uSklAY/dOCkCEJZdK8kg','WOxdOqLrusy5W5y5tG','c8kAWRJcH2C','DCoij10x','mmolc8kqWOG','xmodAGRcSW','iLmWW4nT','dXLUjcO','W7ZdVCorW6eZ','mIRdSYNcPW','AZVcLmoFcW','W5JdG8oVW4CE','W7pcIMroFa','WOuNqmowW7y','pGjCWPWF','WPhdNWTvzG','tqeSWPdcJW','W7jRgCocCq','lCk+WOBcO3W','AYFcLCo/cKJcVCkw','W5a8W41UWRi','WPVcNa3dL2S','W4qVW5j9WRi','WPr6zmo/DG','W63dVYVdGx0','WQldKCkQW7D7','W7TVWPODWPi','WQBdGHrIrW','ccfxlIK','W4RdPXpdSSkv','icPbpWW','iSkLWQtcUNm','fWhdHrtcIq','BSouWR9cWQO','WQDEW4pdHWG','WOWcFmo1','W7D4W6XIW5fvW6nKWR3dQZW8','pCk7WO13W4S','W7fhWQuUWPa','ga3dSbZcTG','WRiFd8oTra','bYDcdXW','WOxcIa7dQKu','FSoVW4RdHSkj','W4jpemo5ANJcJCk0W7ldICoyc8o/CtlcJGdcIw/dSCoxW7VcOtu','xCouthpdPa','WR9xW4BdIGm','W77cJhvCqa','W4FdRCk+W6z4W7OzW5hdVYtdVSk3k28WWRtcHI3dLCkGWPb4W4/dOL5eW7JcLvaDBW','W6tdIsz0W5GrWRK','W4qPW6zyWRq','W43dPYpdQCkZ','vCkDW5ZcKay','W6hdJCoCW5Kh','hCktW5zhW6hdTrXYkMGGW58','kG9jzCky','fqpdGtJcGq','W4i2W6veWRi','vmkCkrNdJq','hSo6o8kjWR0','W6FdKmkVhSkh','WR4kWPeNyW','u8k8crNdQW','W5rhc8o2Dq','WP5lW6ZdTGK','t8ojtxFdPSkRtSkC','iYX1prG','gmkjWPBcR2C','W53dK2PZW6byWOv9sCk2hmkX','z8o9EHZcTW','WQGQWQmWAq','i8k+kmoYWQ0','WPPEW7a1','W5rVWQLlW6O','WRhdNcLyy0XRWQ4vBmk8WPDzWQBdQKL7WOzaWRrWWRi','ESocF2RdQq','r8k2fcddGq','tZlcNmoAna','W5O1W6TOWPTiW7xcG8oykeRcKI80W4TRB8k1W7RdJXpcNCo0W4zfaa','W5FcRCocW500B8kKiHVdSG','t8kzcY3dPq','W6FdM8kOW6Xm','W6/dGqNdSSk7','iCoejSkkWPi','WQlcHqfd','c8kZWRbbW4u','E8o4cwuC','ESoaW6tdP8k6','WQ/dISktW6bDmL4rWQhcICozWQa','W6FdOCkVmCkK','W6JcG8kmW5i','pCkDp2TD','rGhcNSodlW','W6ZdNCo5WR8C','W7/dRHZdQxq','b8ogjSksWQK','WP/cNrxdOW','dSkclv5z','lLCfW43dSa','W7rndmoovq','rmowrfldHq','WRWTWQOfzSo3W4bLW7zuWQ7cSa','W4BdIZ3dQuhcQM0','W7OTW5f6WPy','ymkAW43cGcm','WR1RW4pdLH8','x8o4W5BdLmkz','FLqyWQtcHLfOEvRdN8kjWOtcLsVcSs8mW5C4frVdJCksW7u','W4tcKCkmhmkw','W5dcNLTqEq','FCoAW47dUSkj','ucLfW5NcKG','WOOmnmoABN97WRfyW5pcRr8','W6NdH8osWRii','xmkfgatdSG','W6O+W7fIWOW','WQ00WQGrAq','W6hdKuPEW64','rmkwkcBdQq','WPzFrmoDuq','W6xcMSkfeSkr','gIvcASk/','W7RcQ8kctGGBi0ddRSo6Fq','W4tdQGpdO8kh','W4NcKCkIyIO','WPGDWOOlFW','W7lcOCkHaSkX','W4JdM8oNW7VdHCkQWRxcN8kbrGujWO/cKWr8uwFdMCkwW6FdGZugWPlcSG','uCo2guCS','W7nlWPTaW4u','lb5GWQuo','kstdSbhcUq','wSozrq7cOG','B8o0Cv3dUW','ouSGW6RdUG','W5FcN8kkWQy','W5/cPSo5Amk2WRStWOHXW51xWQVdGHHZ','ASktW4pcJqS','W73dHCoHWRqS','yKxdUSk3','W7SPW4zTWOa','cZPGWQG0','W4ldS8krlCkw','W6ldUCoEWOuS','w8kVW6NcJYC','W5HnWQvpW4u','bsvCibW','W7ZdKIFdMSk7','WP1wjmogW4xdOmomf0VdQa','WPSgWPSzza','tmo/WRbvWQW','srr3W7RcKa','W6uDW4rwWRi','W40PW6v2WPi','nt0Jcs4FlhGLittcK33cUKzLW5ztW7nwx8ouW6uSDJhcSSoRWRpcPmkpyKrBDq','W67dQJ/dNCkm','qCo5W5RdPmky','q8kuW6lcHtC','usezWOlcNW','W5RdMCoCW5GizW','mH5MESkC','nd9Gz8kw','vISxWQZcKG','WPaPWQO/AW','WQSJWRiwCW','W6hdOmo7W7S2','gx4dW4TD','W4NcHSkEamkw','W7qQW4TpWPn+W5tcPmoak1FcRG','fmkdWQhcINa','W7/dUCkfW7bT','W7JdN8o6W40p','dSk2WRXiW44','CbZcQmo8dG','W7FcQG7cGq','btPhpby','W4nFWO9YW6q','WOVdUHjGzq','W7ZdKXRdT8kH','W7NdJaZdVfO','WPVcK1hcI8oYsCkDsSolW5VcLmkMWPK','W64VW6jdWPu','Amk+wYJdKa8Cmmk9WRnTb3jsWQaGkLNdTxrkuJvfeZNdK2igC8kWWPlcMZK1','W6BdSsBdI8kQ','W6pdPSorWPuSk8kfW6hcJSk0WQCQWRLTW6hdNmo0nmkSWQ/cLLVcUCkiq8kW','vYn1W4hcUG','W63dGqhdQgG','kcPsq8kz','CWHNW6/cKa','WQBdPsfBDq','WPaKhSowrW','WQjyW7pdTJq','WRFdOCkmW5rd','W4RcQCkhW7NdMa','W6pcQSkKuGu','q8onvxJdUbH3amkvhmoXdCkoamkMaquCa1lcUI/cU1W','mtGJta','W4/dImkxW5bof1W','bHvACSkzcCoIW74','W7FdTmkuW7jn','W7ZcHCkRW7tdGG','W7zfWPKqWPi','ur9OW47cGsldGdyifa','ESkHW4JcQYi','W7hcPw9+uG','W4JdLqJdJSkM','W5dcM8koW7tdHW','iJJdGt/cTG','WRmgCSo8W7q','W73cUSk+e8kt','dv8YW6ZdSa','d3inW7ldUa','lSk6WPya','bCk9WQlcT0u','W43cNmoAWPi6E8k5W6VcS8oFWQmcWOm/WPK','W7VcHSk7W5JdVCkNWOJcI8kryGK','xmkmkwBdVSkEsSktWPSMmKe','WQ/cRmkvWRjSdfPNWQhdR8oc','yCoeW5FdGmk7W7hcQCkfW7lcJSkC','rrxcRSoQ','CmomWOHcWPO','W5VdJ8oiWRyE','W7ldRSkWd8kB','rqq+WOtcJW','W4tcL2RdQhtcIgrOrSoD','W6ddS8kSn8kz','WP7dIs18yW','ESoXWOJdM8kwW6VcOa','WRtcTXpdVxVcGML2da3dRWNcO8okW6C0AYFdLmkjW6FdRCokqW','W5imW5bvWQ0','W5VdHmkDW5fK','at5/kIKCk285DHFcMg7cUKzu','WQTRzSoTrG','ySk+W6hcKbm','qLJdQmk+W4u','W7BdMSoPWRuD','W4NdTSk4W7bv','W6PxWP0PWRy','W6uoW4vQWRW','W5RcO1ldJJxdHmkZW59QhCoJWOdcImkCWQH8vulcJ8k5WPrO','nGjCWQiR','WOrkq8o9Fq','hKG6W7ddUW','bCkYW6RcIW','F8oFEdNcGa','WRWmnSoqsa','WPldVSk0W4P8','kSkjpwvG','W53cKmkSpmk/','WP0SomogW4ldG8ofleFdRgRdOtO5lSoCk3BcKSk5W7ZcJseyBCkJWOtdQ8oMW5u','z8kQWRZcHqDKWRpdV8kaWQXAW7q','W7D2WOCQWRW','kqJdPr7cIq','od5ybZu','W5ZdJtddQK0','WODGW5hdJZm','W77cGfldSde','yKFdRSk+W5G','W6hdTCk0W7vH','W7CaW6vHWPi','c8k0bGNdIc4r','WPldGbZdTuRcGM10da7dOsZcU8k3W7mZteddU8o2W7tdLSo+vCkCnI3dKG','WPHawmoPsCkAWQldGSoDAeboWQvEo8oHW6OrbmkUWOeqW5/cKSkTW6ZdPa','W5FcQ1xdRrm','W53dRrldSmkL','g8k0WRz0W7i','W6zim8ovCW','lCk8iK1B','ASkPaq3dTG','W4juhmoVta','WRVdSSk+W6Hy','r8opW5JdR8ke','WPv+W7pdKqS','wCojWRvvWQC','WONcUXZdLhJdPLfZdhFdKa','imohf8k2WR0','bYnjBmkA','WO/dV8ktW5b3','W4FcISoZW5XGW5jIW5pdJX/dGSkI','gxWTW6FdPq','W4XgWRK2WRm','W7tdLSkWW4xdP8k0WQ3cN8kqyqCJ','W5DuWRmhWRC','v8ocWQ58WPW','W4FcI8kFW694WOnaWPRdQJy','emkth8oeWRW','W7xcIh/dLXi','WQusjmopra','lmkGihjmWReFyq','W64AW4zbWPS','o00HW7ldGq','WR4qrCoXW78','C8oGW6RdOCki','W7DQemoSvq','BabfW6hcKW','aMmsW5Hc','ymkwiqtdOa','W7JdKsJdUgO','WRL8W7xcKG','ntWNdI4pkgKAvGZdKW','r8klpqddJG','FCoKW5hdISkR','W59iWRaKWQi','W5BdPSoEW6C1','ks9wWQue','W5RcHSk5jmkJ','eCorDKBcGbyCbmo7W67dUdy','rIO7WQJcKG','qeddUmkQW4K','oX3dNsJcLmk8dCogwCo/EuCPnqOa','WOhdSSkbW5Lw','W6BdRcldLCkB','W6FdKmkcuGH+feZdSCoIwW','WRywWRfs','W5ddOSo6WPu1','aWfafs8','uCoDW7RdPSk+W47cPSkaW73cNq','Emo4WRPdWPS','BaRcI8oAiG','v8ovvhxdKq','W6xcOCoRW48bsmkDcXJdJmo3WRVdQMG','kmkFWOlcL2S','vConnLGa','nG3dVXFcMG','gmkdpSoJWQ4','W6tdMSkAW6Py','WPLkW6pdKWW','WPXxqCoTuq','g8kwWR/cJW','vSoaWPjuWPK','w8o+FJ4yW7zfDX3cLSkbcJC','W5ddTIldMmkNnrlcKCoFW4xcRq','W5ORW65PWO0yW6NcG8obn1dcGbbsW6XO','W7/dOsxdRCkP','kCkjWQ9bW6m','W6tdJMNdGq','WQFdVbfKvW','hweaW7hdSa','WRFcTqtdVg0','WPOwqSoRW6m','W7RdVspdGmkr','ESojF0hdPSkPuSkC','W5ZdQmoZWOG4','vqhcRmoIfq','sSoduZ/cVW','nq1wA8kg','q8oesJdcOG','wCo9EGZcM8kukSokW7JdPCkxtG','W5VdKZpdJmkK','ACobW5fMWRtdTeGcW6r5W4b0','W4BdGSomW68rASohdsVdKmo0W6S','r8oXsLddUq','W7CEWO1LW5foW4zLWPJdIYn3ECkDW4OmWQapbxz8t3SnWQqhaCoEWOjhbt4MWOBdMIVdRsNcG0Osomo8Bu9TwWRdUcNdHCkYW4tdU3XavuKmW5K/W7uHW7nsW5rGySotESk3B1j8tdCTWORdK8omWOX+W6eqAvr2lSkUWOPWzCoIDq','yCoCvuZdMq','wComA2hdVq','uwDYW63cUHNdUJelfIhcL8khxslcIsdcO8oLW6dcTmolW6vuDM1yW7voWOxdSvi4WOqhWPCcoLGPWPfSrcldS3hdTmopW7ZdPCkwhHFdLf46xLqTW7ZcVCkDWOmufCo9W7FcVtTzWPXrWPnCW68pWQ9WyqtdTmoWWPaPyMVcVdz6u8k9x1v6','WOPQaSoACx9/WRbbW7FcHq','WP0OCSoHW6S','W5VcRSk9jmkw','W4HPk8o0FG','A8o5Db3cTq','WQ/dICowW6bdlNj6WPFcISoIWQeGW49bDrJdOr3dQ8kIW5/dV8k/sSoy','W6FcQvFdUHldG8otWOLki8oNW63cGCov','ACojqYdcUa','W6VcTKnnySk8oSktWOuvwSoU','W7RcT8kyiCkp','WPimWOawCW','WRxdNSktW6jY','W43cNSkmWRu9f8k7W6BcHSkTWP8','xSkAW4NcGXm','AmoBwYJdKaudimkTW41P','W7yEW6vbWRi','axuqW75d','CahcPCoUpG','xmkpefu','W4hdUMrAW4K','WQ0Rx8oOW64','W6pcHhJcVq','pSoWz2G','W57cTxH6qa','WQ4Xj8o7DHv0WPf5W4ZcLq','WPddUIjHvq','WPqWlCo0tW','nemGW5PG','Amo9DuJdPW','WRxdObnAFq','hCooWQLN','W4tdRqZdLCkV','ruFdMSkOW6u','sdlcJmoJhW','W7JdKmkgoYvVg13dM8oe','W7ZdI35JW4y','DSo0WR9tWQ4','eCoGbCkiWRG','jYNdQd/cJG','W5/dGSkkmSkqWP8UWQzHW5LVW73dKL4','WPKEWRCksq','WO0UkmoAAG','W4ZcJmk+W5RdMW','WRhcUI/dL3C','rSkLjHtdIa','D3dcQCkZaMlcUmkeoWm','ACobWO5MWRFcN0GEW6r5W6OO','mSk3WPpcMM4','WPlcQZBdJM4','WQf3qCoHDG','rColBMFdUW','W4/cVMBdHqK','W5/dGCklaCkaW4qVW4n1W7C','l3qKW5zj','fSkPgSo3WQ/cV30IW6/dQSoyWPO','WQKQWQ03sq','W6v4o8o7xG','ACk0bhSVbCoIz3hdImoG','W5/dK8k1W7jT','W41PWQewWRK','BmkNfaBdIG','W7dcP3ddOXq','pSkpggb7','W7hdKrldKCkz','WRHMW77dJaG','W6NdRN1+W7GYW5DWsSkygmkmjXpcHComErC/Ah0C','WRe2W6uk','zmkrla7dRW','W53dLSogW4erASk4iGtdKmoWWRq','WQuAW6tdHJBdSeFdI0RdVmkk','jdNcNtNcHmkaimoWz8o7','W67dLrFdTmkA','WQOFWRuHwW','W4ddNuFcOa','W5ZcVN/dKdu','WPxcSbVdQKy','W7JcN8k0W6NdOq','iYv6ySkzB8odW5GhCYaji3a','s8o3WQrqWRu','BmoiWPrZWRW','W73cQ8kNW5RdUW','W77cN8kPW4xdQa','W6NdLKr1W6q','W4RdI8kAc8kQ','rmk6fbNdVG','WPVdVtbS','W7vzl8o1rW','WOVcQt/dVfK','W69OWReOWRi','vtjbW6/cGq','W4hdPCksW5zN','nmkEWOxcVgK','FmoREX3cJa','W5tdS8kBW7bg','zSofW7NdG8kN','W4BdGYZdImks','AmoEBqxcLCoejmo9W6ZcVSoluq','l3OJW4bJ','lMigW4BdNW','WPbfvSoCxCkKWQ7dG8outW','WQOYnSo2wa','W47cPfjZqq','lSkYkCoMWOC','aSkigmowWRe','DCoHW7tdJ8ko','m2e3W4ldPW','W6JdJ2nBW5W','eSokf8kUWRq','gw4nW6/dPa','W57cI1WBrCoxoSkMWOuwD8oAW5TpAa','iNKMW4xdKG','qH9NW4BcGW','W4xdSKTMW5G','DwpdOSk6W6RdV2eJumokiG','CmkQoZ/dUG','z8kPW7pcGH8XWRpcJ8kaW4OiW7O','s3tdOSktW7q','sSo7z1xdLW','WOWMl8oTzq','AW7cSmobeW','W7RdPqFdQ8k7','WPhcGshdRN0','nSkdWRhcI34','W4FdNCorrcPIiKVdVSobq8o5WO7dSrFdPwpdOCohW7hdTSkvW5/dG0ZcOa','rCo5W4JdPSkKWPVcOSkGW6JdImkalG','WOeOFCo2W5u','xSo2qY/cGq','AmoCDbhcRG','W41Xcmo8Dq','WRVcIqxdT3u','dmkZWPzcW4m','DSkdWQlcVvb+zG','W6BdICkel8k2','At3cKSockW','WQHAW7NdVc8','W63dKHtdKG','wWWnWOxcSa','W4ywW6X8WQa','xCk7W6ddKIboWQJcQCkqW48dW6pcJ8o2','W6xdRYNdSmkV','WOebC8onW40','nSkpaCoWWOW','WPhdHtv7uW','W4VcIu/dSqC','W73dUmkOW7fL','W4xdVapdR3hcTMaHFmoZWPldTgvtW6m','W5hdQaBdI8ky','FLxdP8k4W4NcOa','xKJdS8kNW5y','sXn4W57cKG','W6ddIY3dTNG','eKWQW4xdV8oFnqCSW73cQ1y','W5xdNd7dVSka','zCo0z1pdHhO','C8k9fdRdMW','wSouuf3dPa','hCoQWPfaW6xcV0a6m30j','rSkBnbZdIG','WPCwjSouvW','d1yBW4/dSW','mSkdWPdcH0m','W4tdJ1z8W4q','aqv1hZ84','W4FdNmkBmIDbg3hdRSkdzq','W57dSCorW78Q','eaP1cZ8','sCk6grBdUhufrSoyW5NdRXeTuCoF','W43dSCoyWQqU','WRJdMH5sDq','oI51v8kM','W7RcHSk6e8kG','tSkpmt7dKW','BCkCmcddJG','o8kaWPFcNK4','q8oDCG/cVq','sbJdVSodfNlcVmkgdIbzDhtcPg/cGwCTmJuMpGNcJmkCWQJcLCoXW7NcPG','wXlcGCoZcW','dxuuW5hdSG','W4dcN8kgvre','W6ddPYpdSSkY','W7VdNtNdKSkW','WQyWF8oOW5u','dSk+bhjN','aCkvoCkRWQNdIInExfO','w8oiWPTKWOu','W6VdV8klh8kW','qmoKrg7dNa','WRNdT8kUW6z5','W5nCp8o8tq','oZDqlbm','WPrOCCof','W6ZdKsRdGv4','W4uCbCkCl8o9W7RdHCoAuu0FWPm','W7jndCoPqq','dtrDabK','q8kqW6lcGcy','aSkPWPhcQNO','W7FcRmksW7NdIq','W5ZdG8kqgCki','imo1n8kYWQ0','W7RcIundEq','sSkJoX7dOW','sqNcG8ozeG','W45KWOLpW4a','k0WLW7e','tX3cRCoh','W53dT8ktW7v1','W53dKZldQ8kW','W4JdSN7dTXxcMCoVW4v5oSoGWRNcUCoNWQGxCgxdJ8k6WP98BCkpW7CsWPmplCorW5VdMZa0','W6JdMmkMW7fR','smogWPj2WPq','aNWTW7pdGa','WO/cLb7dU3G','WQuvCmobW6K','WR06B8oPW5G','hSkLkMng','vt3cOSoE','lhBdNqtcLmk8E8oWFSon','W5ddTqRdNq','W5ZdRfrEW44','W7igmCocuapcJCkgW53dR8kNoSoKbbldPJpcKM/dTSopW5lcQc4','W7NdMJRdRSkp','W5DVB8o5Cq/cPCkMW5xdSSo7BSoQieZcIIdcTe7cPmokWOdcOZSwW4a','W5bDWRzLW6q','cCk0W45aW7VcNHWde1SOWPK','Bmo+zYtcNW','WOGjvCoqW6y','W7ddMmo/WOqN','WQv/W5VdGGdcM0pcLuZdHq','W6BcNCk9sGW','W7dcQx5MrG','FSoPAhhdPKjoj8krhCoUgW','W7xdOq7dT8kM','ySktWOxcJa','E8kAW5RcPXS','eCklASkp','lr7dTGxcRq','W5ZcRaVdSbBcP8oVW6zvl8oqWRC','daW+W7POW6RdOCozdmkFWOyO','y8oNA3tdVG','uCohW4/dGCkG','cCkuWRpcPML5','WQNcSr3dSei','W48QW5LzWOG','W7dcNK1rqq','Fd7cSmoFaq','BtjWW6RcOq','WPm6i8oAsq','WQGRvmoRW70','wmo+WOD2WPC','ASk6W4JcKdy','ASk2W7NcQsm','iWBdSrpcSG','WPTcCmo2AG','vCooAwtdGa','rCk9ktZdHa','zCkucb3dMa','aeSsW4NdIW','W4JcNLrTCW','jmkUjSoHWOu','sCkuW73cGtC','W4FcP8kzybv/hX/dRSoNvmoD','WOS+W5b5','imk4WOf3W48','xSo8BfNdRq','CSk1lcxdGW','yCkZdcldKW','WQikt8oaW5O','n1OnW6ldTa','y8k0W5RcLcq','mCkohgby','WPBdQCknW49m','W7VdKWBdLmkn','sCkwdsFdL2LcdG','AafTW6tcGG','nIT1lYW','W4hdVdNdOmk1','v8kCiXRdQq','W7pcSeDx','xvldH8k+W5G','iWb7wb1+c2i','W4FdRmoKW7DbW6zfW4ldVGxdImk3nue0WQVcHLBdV8kGWOzdWPxcM3eTW53cJ34M','W7FdSCoVW7ys','W43cL2RdR37cPMb3xSo7','W6DPkmo5vG','tCkGoqRdQa','WQtcJqddKNy','CmozWR1QWPy','efuDW75h','WOicxSo8W4G','WRhdQtbszG','W6v8c8opDG','W5VdSt7dOxG','DKldOCkEW4K','W5ZcO8kLvHC','W4FcP8kojCk+','W6JdICkOW75/','oCkGWRdcU3G','wSossvxdQW','wqiAWP3cUGW0EgZcTmkjWPdcJ3xcLtGsW4eBeZNdIq','W77cLvpdNmkknCopCSocW7G','W68TW5LMWPS','W5JdMCoQW68r','WRldUCkkW61X','W4LglSk7','WPFdI8kiWRbwiLPvWPRcNG','W7BdVSkpW7S','CSoRW6FdMJSWwCo9mmooCZO','W4ddUmogWP4ZsmkDicxdJConWRVdOYeoxYPKWO4KW4v2B8o8','gxSOW6hdHSkjcISOW6hcIKdcHmkN','navJWOmBjSkSW70VWPpdGdu','hZbvWOuB','CYZcKCoNeW','W7ZdNIFdMSkh','w8o5W5fHWRRcOuH8W59S','W4pdNSk9W5Le','WRNcKYxdT0m','AmoBbc/dHX8yiCkyW6jsdhTyWQi','fvjzm8kzBSkzW7qyuqeCorflW6X6tq','lsRdQWtcKq','aNiRW5pdPq','dcXwWQea','WPhdGbJdGvNcKML/mNBcTaNcOmocW5XQFZ/dSCkHW5ddKCkeqa','W61WWO5LW68','jSkdWPBcHx0','nt8JdISHld4LrWNcIa','ux/dUmkBW48','W4xcL3ddVG4','WQHyWO8qyCo4WObdW4ToWOi','wCo2yr3cLq','gt/dGdpcMq','x8o6fLO+','EhhdRCkLW4W','jSo5W63cTG','W6tdQmk7W5jU','W7xcIvTftq','mxqhW5ldNW','AmopbeiVyCoIygRcP8o+sW','d8oDpCkXWR0','muKLW5ldHq','q8owzhpdRW','xmkOnbJdOq','fYbdpX0','vCkSoGZdSG','AHCcWRpcHG','WRqwWOaDEG','C1ldG8k6W7K','W7/cMmkbjCkX','mCo9iCk+WQe','W6lcSSkqwXu','wmkPjXZdMG','z8k3W6/cGGzAWRFcP8kaW4TCW6pcJSomW4JcGYVdNHBdSrSlW4xdPG','W6RcIh1FFW','r8o/yfhdOW','W6O6W7rEWOG','W5RcG8kWW4tdLCkrWO3cQa','ne8XW71k','qNBdRmkyW48','W4hdI8knW7vv','WO/cNWldSKq','qCkLoWhdHG','CCoZW7FdJCkf','W77dTCkZcCkLfCoIsgmdoYG/W7RcGtK','W5hcVgjftq','W4RdIXtdT8kX','W43cNCotWRuGpmo4W6BcJ8kGWRu','CmkbiHpdMW','WQFcKJldTuK','WQqAvSoTsCo+WRJdImoNa0a6WP8mBW','W6HfWQT3W6W','uSoWpr/dNCoQxYVdSCksWQhcTq','nHPkWPK6','eIv4odW','W7ZdTvb+W54','x8oDWPvFWPNcN0HtW4Pk','WQuyi8oCya','W6pcHSkNoSkX','WQHAW7aBqmktWOrGW6KXWRa','WOnAumopEW','kIzgWQy4','v8kakJRdSW','omkDmfRdP8kADCoSW6dcU8onxCkO','W4xcTmkCkCkV','wCkAnqVcN8oylCoSW77dQCoerSkEW7JcJ8kFESohW7BcSSkpW5hdH8kejSoPWOddTvWLW5O','WR4fyCo0W6K','WQJdRCkYW417','xGHyW7/cNq','lJ1KWQa5','WRRdNCkqW4vW','W5rKWQ1oW6C','mSkXWORcLgK','WOyiu8oDW6e','ddVdTqJcGq','iCkoWQfQW6K','uwCtW6RcUWldM2SdpZa','amk6mCoeWOa','pZ5TWOinaW','W4VdT8kAcmkB','uCotW7/dHSkC','W6FdTYpdKmkO','shZcJmoOnhlcUmkqkbm','W7/dKJBdMNC','WOnBW73dRrq','vmkQjdVdRW','WOVcKJxdLvu','BCo0DaZcHa','WPbgq8oMBa','WRmygmoXvW','W4VdGdFdVfy','W69QmmoTua','exymW5rw','WOLNEmoasq','W7pdIIldSCkS','W7bWWPDTW60','W59KWPaoWRS','xmkon0ldT8k6ACkBWQPAbLnOWPZdLxG','DCkwW57cQcy','sSokdMGQ','e8kgWR1LW4u','mWnfCCkn','W6BcIhidbcOAWRaZsmkuWOu','W6JdM8oBW6m3','iCkvWPbgW5hcHry','WPCbWOyRrq','cqz/WPq2','WOddUIHICW','wSkxbXhdLq','W7FcVmknAb0','ACkwaXJdMa','W4GQW5LIWPS','W7tcMCkCytroeq','WPLjW6ddGqq','W5pdICkLW4HB','y2JdSmkxW7W','gJL4WPOF','f1CVW5Xz','W77dU8kyW7va','W7RcM8kMW7BdPq','uSoNk1iv','W77cNmkQrGS','dmkOghX9'];_0x7a25=function(){return _0x5982a4;};return _0x7a25();}function _0x2a23(_0x2ba89b,_0x5098c5){const _0x7a25da=_0x7a25();return _0x2a23=function(_0x2a23e2,_0x12849d){_0x2a23e2=_0x2a23e2-0x1bb;let _0x55ffcf=_0x7a25da[_0x2a23e2];if(_0x2a23['WfPEFW']===undefined){var _0x3a1e9f=function(_0x234403){const _0x4f8bd2='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xee7efb='',_0x522600='';for(let _0x138740=0x0,_0x218c67,_0x391faa,_0x52a8c1=0x0;_0x391faa=_0x234403['charAt'](_0x52a8c1++);~_0x391faa&&(_0x218c67=_0x138740%0x4?_0x218c67*0x40+_0x391faa:_0x391faa,_0x138740++%0x4)?_0xee7efb+=String['fromCharCode'](0xff&_0x218c67>>(-0x2*_0x138740&0x6)):0x0){_0x391faa=_0x4f8bd2['indexOf'](_0x391faa);}for(let _0xaadf06=0x0,_0x46206f=_0xee7efb['length'];_0xaadf06<_0x46206f;_0xaadf06++){_0x522600+='%'+('00'+_0xee7efb['charCodeAt'](_0xaadf06)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x522600);};const _0x3c43dd=function(_0x13f733,_0x40b6f5){let _0x5e7360=[],_0x22f22c=0x0,_0x110a69,_0x183d97='';_0x13f733=_0x3a1e9f(_0x13f733);let _0x576c64;for(_0x576c64=0x0;_0x576c64<0x100;_0x576c64++){_0x5e7360[_0x576c64]=_0x576c64;}for(_0x576c64=0x0;_0x576c64<0x100;_0x576c64++){_0x22f22c=(_0x22f22c+_0x5e7360[_0x576c64]+_0x40b6f5['charCodeAt'](_0x576c64%_0x40b6f5['length']))%0x100,_0x110a69=_0x5e7360[_0x576c64],_0x5e7360[_0x576c64]=_0x5e7360[_0x22f22c],_0x5e7360[_0x22f22c]=_0x110a69;}_0x576c64=0x0,_0x22f22c=0x0;for(let _0x2b7061=0x0;_0x2b7061<_0x13f733['length'];_0x2b7061++){_0x576c64=(_0x576c64+0x1)%0x100,_0x22f22c=(_0x22f22c+_0x5e7360[_0x576c64])%0x100,_0x110a69=_0x5e7360[_0x576c64],_0x5e7360[_0x576c64]=_0x5e7360[_0x22f22c],_0x5e7360[_0x22f22c]=_0x110a69,_0x183d97+=String['fromCharCode'](_0x13f733['charCodeAt'](_0x2b7061)^_0x5e7360[(_0x5e7360[_0x576c64]+_0x5e7360[_0x22f22c])%0x100]);}return _0x183d97;};_0x2a23['DFgHti']=_0x3c43dd,_0x2ba89b=arguments,_0x2a23['WfPEFW']=!![];}const _0x70414e=_0x7a25da[0x0],_0x591ed1=_0x2a23e2+_0x70414e,_0x3cf193=_0x2ba89b[_0x591ed1];return!_0x3cf193?(_0x2a23['pMKdgT']===undefined&&(_0x2a23['pMKdgT']=!![]),_0x55ffcf=_0x2a23['DFgHti'](_0x55ffcf,_0x12849d),_0x2ba89b[_0x591ed1]=_0x55ffcf):_0x55ffcf=_0x3cf193,_0x55ffcf;},_0x2a23(_0x2ba89b,_0x5098c5);}function _0x4a17(){const _0x234e4d=_0x2a23,_0x64430c={'UqtRj':_0x234e4d(0x41b,'2VU1'),'Iollg':_0x234e4d(0x4c6,'1&yx'),'NhxMu':_0x234e4d(0x285,'JC^q'),'OoiMB':_0x234e4d(0x1f0,'AT@B'),'xXxlA':_0x234e4d(0x603,'9I[N'),'zDnpQ':_0x234e4d(0x60b,'SNss'),'AlvMa':_0x234e4d(0x625,'b#ZE'),'yebZy':_0x234e4d(0x555,'wMTb'),'DnpYO':_0x234e4d(0x5a1,'S@xV'),'rZyXJ':_0x234e4d(0x2d8,'lk5H'),'Pfdlg':_0x234e4d(0x1d4,'iPqW'),'lxlyS':_0x234e4d(0x52a,'@YGJ'),'KIpkJ':_0x234e4d(0x5af,'qQBc'),'ntCET':_0x234e4d(0x36c,')uaP'),'yeeYx':_0x234e4d(0x389,'8UKT'),'krEUM':_0x234e4d(0x618,'H)P7'),'aRFmL':_0x234e4d(0x4f1,'lk5H'),'QTYwC':_0x234e4d(0x5f7,'wMTb'),'AvypF':_0x234e4d(0x29a,'SNss'),'FGnCM':_0x234e4d(0x2ea,'S@xV'),'MatxK':_0x234e4d(0x50e,'S@xV'),'MIhgh':_0x234e4d(0x40e,'9E)9'),'CnsCL':_0x234e4d(0x3b2,'wMTb'),'YIXHW':_0x234e4d(0x514,'(2Hx'),'VZEEN':_0x234e4d(0x20f,'8UKT'),'oYImg':_0x234e4d(0x563,'2VU1'),'AShSH':_0x234e4d(0x37d,'wMTb'),'QdXWE':_0x234e4d(0x4b0,'NcTP'),'BEwFd':_0x234e4d(0x5ce,'JC^q'),'JIdBe':_0x234e4d(0x56f,'2VU1'),'wYxLT':_0x234e4d(0x532,'SNss'),'CYxmC':_0x234e4d(0x550,'Zy9h'),'jvYWW':_0x234e4d(0x37e,'Y(3w'),'BdXdQ':_0x234e4d(0x3ff,'SNss'),'KEXfy':_0x234e4d(0x5ef,'iPqW'),'ejEKa':_0x234e4d(0x212,'NcTP'),'aIVcd':_0x234e4d(0x65a,'5ve!'),'vgEto':_0x234e4d(0x55b,'3uM9'),'hmJgo':_0x234e4d(0x221,'BLAX'),'SpSyM':_0x234e4d(0x5ac,'5ve!'),'PwgSQ':_0x234e4d(0x2e6,'ymb#'),'oIceF':_0x234e4d(0x5aa,'8UKT'),'qKkob':_0x234e4d(0x220,'qQBc'),'dnobo':_0x234e4d(0x1ea,'zQx('),'TxdMH':_0x234e4d(0x3ba,'@9X4'),'GiyBz':_0x234e4d(0x24c,'1K1j'),'dhZjU':_0x234e4d(0x5bc,'5ve!'),'nnIhK':_0x234e4d(0x3f5,'^sVw'),'rYIUW':_0x234e4d(0x358,'SNss'),'dUpKk':_0x234e4d(0x34b,'H)P7'),'HDais':_0x234e4d(0x415,'(a1@'),'fvmOU':_0x234e4d(0x472,'56OX'),'IGCMq':_0x234e4d(0x4b9,'2VU1'),'SzITB':_0x234e4d(0x39c,'h5BR'),'VDlDx':_0x234e4d(0x4e3,'9E)9'),'eYCra':_0x234e4d(0x307,'H)P7'),'PPEQK':_0x234e4d(0x216,'($8%'),'hNlQd':_0x234e4d(0x3ab,'AT@B'),'tciOC':_0x234e4d(0x3c9,'Ny33'),'Ptsjx':_0x234e4d(0x336,'3uM9'),'yuXPJ':_0x234e4d(0x400,'eRZ)'),'Sajvb':_0x234e4d(0x614,'e7Ck'),'dswKs':_0x234e4d(0x326,'uizP'),'cZKOi':_0x234e4d(0x59e,'2VU1'),'YaJCE':_0x234e4d(0x33c,'3uM9'),'qtQyw':_0x234e4d(0x4e7,'9I[N'),'wCMJY':_0x234e4d(0x3b1,'(2Hx'),'gObTp':_0x234e4d(0x56b,'b#ZE'),'jdxSg':_0x234e4d(0x2f6,'lk5H'),'oGkLZ':_0x234e4d(0x3c8,'Y(3w'),'MOVfS':_0x234e4d(0x383,'S@xV'),'ldauR':_0x234e4d(0x63b,'ymb#'),'ViUpc':_0x234e4d(0x5b3,'slIE'),'NBvGg':_0x234e4d(0x60a,'(a1@'),'RSpRq':_0x234e4d(0x4fa,'wMTb'),'dzJlc':_0x234e4d(0x38a,'lmOZ'),'txcDY':_0x234e4d(0x4f6,'qQBc'),'aNdhh':_0x234e4d(0x4be,'wMTb'),'CnMcR':_0x234e4d(0x5f8,'^sVw'),'MWcoO':_0x234e4d(0x5a2,'slIE'),'rprBw':_0x234e4d(0x31a,'9E)9'),'uOEjV':_0x234e4d(0x5c0,'uizP'),'wzjCv':_0x234e4d(0x30f,'lmOZ'),'HzAVS':_0x234e4d(0x471,'lmOZ'),'jAdzq':_0x234e4d(0x5fa,'V!G1'),'oMmHG':_0x234e4d(0x608,'9I[N'),'OmTbK':_0x234e4d(0x2ba,'H)P7'),'LfnsG':_0x234e4d(0x26f,'Y(3w'),'LUXJA':_0x234e4d(0x355,'wmsW'),'LgDMA':_0x234e4d(0x619,'F(Dh'),'xHdWh':_0x234e4d(0x290,'h5BR'),'kftda':_0x234e4d(0x632,'Zy9h'),'ntwjd':_0x234e4d(0x1da,'qQBc'),'SEgTx':_0x234e4d(0x3f7,'9E)9'),'YUPVL':_0x234e4d(0x251,'mSQ#'),'WllXx':_0x234e4d(0x278,'8UKT'),'KYtAv':_0x234e4d(0x54a,'5ve!'),'tfvQe':_0x234e4d(0x384,'h5BR'),'vyOWQ':_0x234e4d(0x26a,'BLAX'),'FZrQQ':_0x234e4d(0x49d,'3uM9'),'DoQWi':_0x234e4d(0x4ba,'zQx('),'FrDQK':_0x234e4d(0x61b,'(a1@'),'PFBCc':_0x234e4d(0x325,'1&yx'),'zkGZk':_0x234e4d(0x1dc,'9E)9'),'nQdZH':_0x234e4d(0x2f9,'8UKT'),'XeLez':_0x234e4d(0x5e4,'2hgo'),'hQHev':_0x234e4d(0x392,'2hgo'),'xReTA':function(_0x3acaaa){return _0x3acaaa();}},_0xcbf65=[_0x64430c[_0x234e4d(0x3cc,'JC^q')],_0x64430c[_0x234e4d(0x4d3,'($8%')],_0x64430c[_0x234e4d(0x228,'Y(3w')],_0x64430c[_0x234e4d(0x3be,'3uM9')],_0x64430c[_0x234e4d(0x26c,'2hgo')],_0x64430c[_0x234e4d(0x457,'2VU1')],_0x64430c[_0x234e4d(0x1c0,'I2Yw')],_0x64430c[_0x234e4d(0x1ef,'2hgo')],_0x64430c[_0x234e4d(0x2f5,'I2Yw')],_0x64430c[_0x234e4d(0x4e1,'SNss')],_0x64430c[_0x234e4d(0x5ec,'V!G1')],_0x64430c[_0x234e4d(0x28d,'($8%')],_0x64430c[_0x234e4d(0x246,'e7Ck')],_0x64430c[_0x234e4d(0x53b,'SNss')],_0x64430c[_0x234e4d(0x2f0,'7z$v')],_0x64430c[_0x234e4d(0x25a,'2hgo')],_0x64430c[_0x234e4d(0x645,'e7Ck')],_0x64430c[_0x234e4d(0x573,'lk5H')],_0x64430c[_0x234e4d(0x4cf,'5ve!')],_0x64430c[_0x234e4d(0x61a,'A6VI')],_0x64430c[_0x234e4d(0x5cf,'F(Dh')],_0x64430c[_0x234e4d(0x5b6,'e7Ck')],_0x64430c[_0x234e4d(0x474,'eRZ)')],_0x64430c[_0x234e4d(0x27c,'(2Hx')],_0x64430c[_0x234e4d(0x3e6,'2VU1')],_0x64430c[_0x234e4d(0x446,'H)P7')],_0x64430c[_0x234e4d(0x482,'$Q0[')],_0x64430c[_0x234e4d(0x230,'mgUY')],_0x64430c[_0x234e4d(0x508,'8UKT')],_0x64430c[_0x234e4d(0x669,'1&yx')],_0x64430c[_0x234e4d(0x45a,'7z$v')],_0x64430c[_0x234e4d(0x5fe,'I2Yw')],_0x64430c[_0x234e4d(0x5c2,'SNss')],_0x64430c[_0x234e4d(0x2da,'(a1@')],_0x64430c[_0x234e4d(0x1cb,'BLAX')],_0x64430c[_0x234e4d(0x522,'e7Ck')],_0x64430c[_0x234e4d(0x344,'eRZ)')],_0x64430c[_0x234e4d(0x3ef,'b#ZE')],_0x64430c[_0x234e4d(0x5d6,'uizP')],_0x64430c[_0x234e4d(0x546,'SNss')],_0x64430c[_0x234e4d(0x2df,'Ny33')],_0x64430c[_0x234e4d(0x395,'(2Hx')],_0x64430c[_0x234e4d(0x568,'lmOZ')],_0x64430c[_0x234e4d(0x66d,'(a1@')],_0x64430c[_0x234e4d(0x323,')uaP')],_0x64430c[_0x234e4d(0x40c,'mgUY')],_0x64430c[_0x234e4d(0x2b5,'JC^q')],_0x64430c[_0x234e4d(0x214,'Y(3w')],_0x64430c[_0x234e4d(0x541,'H)P7')],_0x64430c[_0x234e4d(0x301,'V!G1')],_0x64430c[_0x234e4d(0x592,'e7Ck')],_0x64430c[_0x234e4d(0x32a,'1K1j')],_0x64430c[_0x234e4d(0x437,'NcTP')],_0x64430c[_0x234e4d(0x670,'lmOZ')],_0x64430c[_0x234e4d(0x3bb,'JC^q')],_0x64430c[_0x234e4d(0x371,'2VU1')],_0x64430c[_0x234e4d(0x215,'NcTP')],_0x64430c[_0x234e4d(0x369,'wMTb')],_0x64430c[_0x234e4d(0x500,'iPqW')],_0x64430c[_0x234e4d(0x1d2,'wmsW')],_0x64430c[_0x234e4d(0x421,'2hgo')],_0x64430c[_0x234e4d(0x617,'lk5H')],_0x64430c[_0x234e4d(0x34f,'Y(3w')],_0x64430c[_0x234e4d(0x4ed,'eRZ)')],_0x64430c[_0x234e4d(0x2ff,'mgUY')],_0x64430c[_0x234e4d(0x305,')uaP')],_0x64430c[_0x234e4d(0x363,'wmsW')],_0x64430c[_0x234e4d(0x281,'F(Dh')],_0x64430c[_0x234e4d(0x48b,'@YGJ')],_0x64430c[_0x234e4d(0x2c3,'JC^q')],_0x64430c[_0x234e4d(0x404,'1K1j')],_0x64430c[_0x234e4d(0x577,'uizP')],_0x64430c[_0x234e4d(0x2d3,'(a1@')],_0x64430c[_0x234e4d(0x2fc,'wMTb')],_0x64430c[_0x234e4d(0x5d9,'JC^q')],_0x64430c[_0x234e4d(0x5b5,'9E)9')],_0x64430c[_0x234e4d(0x486,'($8%')],_0x64430c[_0x234e4d(0x259,')uaP')],_0x64430c[_0x234e4d(0x22f,'BLAX')],_0x64430c[_0x234e4d(0x2d5,')uaP')],_0x64430c[_0x234e4d(0x42e,'AT@B')],_0x64430c[_0x234e4d(0x31f,'Ny33')],_0x64430c[_0x234e4d(0x473,'$Q0[')],_0x64430c[_0x234e4d(0x3a8,'wMTb')],_0x64430c[_0x234e4d(0x4d0,'^sVw')],_0x64430c[_0x234e4d(0x34d,'eRZ)')],_0x64430c[_0x234e4d(0x5a4,'1K1j')],_0x64430c[_0x234e4d(0x374,'slIE')],_0x64430c[_0x234e4d(0x4b1,')uaP')],_0x64430c[_0x234e4d(0x28c,'AT@B')],_0x64430c[_0x234e4d(0x42d,'ymb#')],_0x64430c[_0x234e4d(0x533,'Ny33')],_0x64430c[_0x234e4d(0x21a,'$Q0[')],_0x64430c[_0x234e4d(0x3fc,'NcTP')],_0x64430c[_0x234e4d(0x287,')uaP')],_0x64430c[_0x234e4d(0x2ad,'zQx(')],_0x64430c[_0x234e4d(0x3ed,'2VU1')],_0x64430c[_0x234e4d(0x504,'7z$v')],_0x64430c[_0x234e4d(0x41e,'qQBc')],_0x64430c[_0x234e4d(0x5ad,'($8%')],_0x64430c[_0x234e4d(0x378,'@y77')],_0x64430c[_0x234e4d(0x607,'^sVw')],_0x64430c[_0x234e4d(0x61c,'lk5H')],_0x64430c[_0x234e4d(0x53f,'V!G1')],_0x64430c[_0x234e4d(0x2b9,')uaP')],_0x64430c[_0x234e4d(0x44a,'V!G1')],_0x64430c[_0x234e4d(0x3db,'1&yx')]];return _0x4a17=function(){return _0xcbf65;},_0x64430c[_0x234e4d(0x2af,'lk5H')](_0x4a17);}
exocore-web/public/login.jsx ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, Show } from 'solid-js';
3
+
4
+ const IconEye = () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>;
5
+ const IconEyeOff = () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>;
6
+
7
+ function App() {
8
+ const [loading, setLoading] = createSignal(false);
9
+ const [status, setStatus] = createSignal('');
10
+ const [form, setForm] = createSignal({ user: '', pass: '' });
11
+ const [showPass, setShowPass] = createSignal(false);
12
+ const [ready, setReady] = createSignal(false);
13
+
14
+ function LoggedAlready() {
15
+ const token = localStorage.getItem('exocore-token');
16
+ const cookies = localStorage.getItem('exocore-cookies');
17
+ if (token && cookies) {
18
+ fetch('/private/server/exocore/web/userinfo', {
19
+ method: 'POST',
20
+ headers: { 'Content-Type': 'application/json' },
21
+ body: JSON.stringify({ token, cookies }),
22
+ })
23
+ .then((res) => {
24
+ if (!res.ok) { return res.json().then((errData) => { throw new Error(errData.message || `HTTP error! status: ${res.status}`); }).catch(() => { throw new Error(`HTTP error! status: ${res.status}`); }); }
25
+ return res.json();
26
+ })
27
+ .then((data) => {
28
+ const user = data.data?.user;
29
+ if (user) {
30
+ if (!user.verified) {
31
+ window.location.href = '/private/server/exocore/web/public/otp';
32
+ } else {
33
+ window.location.href = '/private/server/exocore/web/public/dashboard';
34
+ }
35
+ }
36
+ })
37
+ .catch((err) => {
38
+ console.warn('Auto-check failed:', err.message);
39
+ });
40
+ }
41
+ }
42
+
43
+ onMount(() => {
44
+ setReady(true);
45
+ LoggedAlready();
46
+ setInterval(LoggedAlready, 2000);
47
+ });
48
+
49
+ async function handleLogin() {
50
+ setLoading(true);
51
+ setStatus('');
52
+ const userValue = form().user;
53
+ const passValue = form().pass;
54
+ if (!userValue || !passValue) {
55
+ setStatus('Username and password cannot be empty.');
56
+ setLoading(false);
57
+ return;
58
+ }
59
+ try {
60
+ const res = await fetch('/private/server/exocore/web/login', {
61
+ method: 'POST',
62
+ headers: { 'Content-Type': 'application/json' },
63
+ body: JSON.stringify({ user: userValue, pass: passValue }),
64
+ });
65
+ const data = await res.json();
66
+ if (!res.ok) { throw new Error(data.message || `Login HTTP error! status: ${res.status}`); }
67
+ if (data.success && data.data?.status === 'success') {
68
+ const { token, cookies } = data.data;
69
+ localStorage.setItem('exocore-token', token);
70
+ localStorage.setItem('exocore-cookies', JSON.stringify(cookies));
71
+ setStatus('Login successful! Redirecting...');
72
+ LoggedAlready();
73
+ } else {
74
+ setStatus(data.message || 'Login failed.');
75
+ }
76
+ } catch (err) {
77
+ setStatus(err.message);
78
+ }
79
+ setLoading(false);
80
+ }
81
+
82
+ const handleKeyPress = (e) => {
83
+ if (e.key === 'Enter') {
84
+ handleLogin();
85
+ }
86
+ };
87
+
88
+ return (
89
+ <Show when={ready()}>
90
+ <div class="login-page-wrapper">
91
+ <style>{`
92
+ :root {
93
+ --bg-primary: #111217; --bg-secondary: #1a1b23; --text-primary: #e0e0e0;
94
+ --text-secondary: #8a8f98; --accent-primary: #00aaff; --accent-secondary: #0088cc;
95
+ --border-color: rgba(255, 255, 255, 0.1); --shadow-color: rgba(0, 0, 0, 0.5);
96
+ --radius-main: 16px; --radius-inner: 12px;
97
+ --font-body: 'Roboto', sans-serif;
98
+ --success-color: #2ecc71; --error-color: #e74c3c;
99
+ }
100
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
101
+ body { background-color: var(--bg-primary); font-family: var(--font-body); margin: 0; }
102
+ .login-page-wrapper { display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: 2rem; box-sizing: border-box; }
103
+ .login-card { background: var(--bg-secondary); width: 100%; max-width: 420px; padding: 3rem; border-radius: var(--radius-main); border: 1px solid var(--border-color); box-shadow: 0 15px 40px var(--shadow-color); animation: fadeIn 0.5s ease-out; }
104
+ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
105
+ .login-header { text-align: center; margin-bottom: 2.5rem; color: var(--text-primary); font-size: 2rem; font-weight: 700; }
106
+ .form-group { margin-bottom: 1.5rem; }
107
+ .form-label { display: block; margin-bottom: 0.5rem; color: var(--text-secondary); font-weight: 500; }
108
+ .input-wrapper { position: relative; }
109
+ .form-input { width: 100%; padding: 0.9rem 1rem; border: 1px solid var(--border-color); border-radius: var(--radius-inner); font-family: var(--font-body); font-size: 1rem; background-color: var(--bg-primary); color: var(--text-primary); box-sizing: border-box; transition: border-color 0.2s, box-shadow 0.2s; }
110
+ .form-input:focus { outline:0; border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(0, 170, 255, 0.2); }
111
+ .password-toggle { position: absolute; right: 1rem; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 0.25rem; display: flex; align-items: center; }
112
+ .password-toggle:hover { color: var(--accent-primary); }
113
+ .login-btn { width: 100%; padding: 0.9rem 1.5rem; border: none; border-radius: var(--radius-inner); background: linear-gradient(to right, var(--accent-primary), var(--accent-secondary)); color: #fff; font-size: 1.1rem; font-weight: 700; cursor: pointer; transition: all 0.2s ease; }
114
+ .login-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 170, 255, 0.2); }
115
+ .login-btn:disabled { opacity: 0.6; cursor: not-allowed; }
116
+ .status-message { text-align: center; margin-top: 1.5rem; padding: 0.8rem; border-radius: var(--radius-inner); font-weight: 500; }
117
+ .status-success { background-color: rgba(46, 204, 113, 0.15); color: var(--success-color); border: 1px solid var(--success-color); }
118
+ .status-error { background-color: rgba(231, 76, 60, 0.15); color: var(--error-color); border: 1px solid var(--error-color); }
119
+ .links-wrapper { text-align: center; margin-top: 2rem; color: var(--text-secondary); }
120
+ .form-link { color: var(--accent-primary); text-decoration: none; font-weight: 500; }
121
+ .form-link:hover { text-decoration: underline; color: var(--accent-secondary); }
122
+ .links-separator { margin: 0 0.5rem; }
123
+ `}</style>
124
+ <div class="login-card">
125
+ <h1 class="login-header">Exocore Login</h1>
126
+ <div class="form-group">
127
+ <label class="form-label" for="username">Username or Email</label>
128
+ <input id="username" class="form-input" type="text" value={form().user} onInput={(e) => setForm(f => ({ ...f, user: e.currentTarget.value.replace(/\s/g, '') }))} onKeyPress={handleKeyPress} />
129
+ </div>
130
+ <div class="form-group">
131
+ <label class="form-label" for="password">Password</label>
132
+ <div class="input-wrapper">
133
+ <input id="password" class="form-input" type={showPass() ? 'text' : 'password'} value={form().pass} onInput={(e) => setForm(f => ({ ...f, pass: e.currentTarget.value.replace(/\s/g, '') }))} onKeyPress={handleKeyPress} />
134
+ <button type="button" class="password-toggle" onClick={() => setShowPass(!showPass())}>
135
+ <Show when={showPass()} fallback={<IconEye />}>
136
+ <IconEyeOff />
137
+ </Show>
138
+ </button>
139
+ </div>
140
+ </div>
141
+ <button class="login-btn" onClick={handleLogin} disabled={loading() || !form().user || !form().pass}>
142
+ {loading() ? 'Logging in...' : 'Login'}
143
+ </button>
144
+ <Show when={status()}>
145
+ <div class={`status-message ${status().includes('successful') ? 'status-success' : 'status-error'}`}>
146
+ {status()}
147
+ </div>
148
+ </Show>
149
+ <div class="links-wrapper">
150
+ <a href="/private/server/exocore/web/public/forgot-password" class="form-link">Forgot Password?</a>
151
+ <span class="links-separator">&bull;</span>
152
+ <a href="/private/server/exocore/web/public/register" class="form-link">Register here</a>
153
+ </div>
154
+ </div>
155
+ </div>
156
+ </Show>
157
+ );
158
+ }
159
+
160
+ render(() => <App />, document.getElementById('app'));
exocore-web/public/otp.jsx ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, Show } from 'solid-js';
3
+
4
+ function App() {
5
+ const [loading, setLoading] = createSignal(false);
6
+ const [status, setStatus] = createSignal('');
7
+ const [otp, setOtp] = createSignal('');
8
+ const [sendDisabled, setSendDisabled] = createSignal(false);
9
+ const [countdown, setCountdown] = createSignal(30);
10
+
11
+ const getToken = () => localStorage.getItem('exocore-token') || '';
12
+ const getCookies = () => localStorage.getItem('exocore-cookies') || '';
13
+
14
+ function AlreadyOtp() {
15
+ const token = getToken();
16
+ const cookies = getCookies();
17
+ if (token && cookies) {
18
+ fetch('/private/server/exocore/web/userinfo', {
19
+ method: 'POST',
20
+ headers: { 'Content-Type': 'application/json' },
21
+ body: JSON.stringify({ token, cookies }),
22
+ })
23
+ .then((res) => res.json())
24
+ .then((res) => {
25
+ const user = res.data?.user;
26
+ if (user && user.verified === 'success') {
27
+ window.location.href = '/private/server/exocore/web/public/dashboard';
28
+ }
29
+ })
30
+ .catch((err) => {
31
+ console.warn('Auto-check failed:', err.message);
32
+ });
33
+ } else {
34
+ window.location.href = '/private/server/exocore/web/public/login';
35
+ }
36
+ }
37
+
38
+ onMount(() => {
39
+ const otpCheckInterval = setInterval(AlreadyOtp, 3000);
40
+ });
41
+
42
+ async function sendOTP() {
43
+ setLoading(true);
44
+ setStatus('');
45
+ setSendDisabled(true);
46
+ setCountdown(30);
47
+ const token = getToken();
48
+ const cookies = getCookies();
49
+ if (!token || !cookies) {
50
+ setStatus('Authentication details not found. Please log in again.');
51
+ setLoading(false);
52
+ setSendDisabled(false);
53
+ return;
54
+ }
55
+ try {
56
+ const res = await fetch('/private/server/exocore/web/otp', {
57
+ method: 'POST',
58
+ headers: { 'Content-Type': 'application/json' },
59
+ body: JSON.stringify({ token, cookies, action: 'sent' }),
60
+ });
61
+ const data = await res.json();
62
+ if (data.status === 'success') {
63
+ setStatus(data.data?.message || 'OTP sent successfully!');
64
+ startCountdown();
65
+ } else {
66
+ setStatus(data.data?.message || data.message || 'Could not send OTP.');
67
+ setSendDisabled(false);
68
+ }
69
+ } catch (err) {
70
+ setStatus(err.message);
71
+ setSendDisabled(false);
72
+ }
73
+ setLoading(false);
74
+ }
75
+
76
+ async function submitOTP() {
77
+ setLoading(true);
78
+ setStatus('');
79
+ const token = getToken();
80
+ const cookies = getCookies();
81
+ if (!token || !cookies) {
82
+ setStatus('Authentication details not found. Please log in again.');
83
+ setLoading(false);
84
+ return;
85
+ }
86
+ if (!otp()) {
87
+ setStatus('Please enter the OTP.');
88
+ setLoading(false);
89
+ return;
90
+ }
91
+ try {
92
+ const res = await fetch('/private/server/exocore/web/otp', {
93
+ method: 'POST',
94
+ headers: { 'Content-Type': 'application/json' },
95
+ body: JSON.stringify({ token, cookies, otp: otp(), action: 'submit' }),
96
+ });
97
+ const data = await res.json();
98
+ if (data.status === 'success') {
99
+ setStatus(data.data?.message || 'OTP verified successfully! Redirecting...');
100
+ setTimeout(AlreadyOtp, 1000);
101
+ } else {
102
+ setStatus(data.data?.message || data.message || 'Invalid OTP.');
103
+ }
104
+ } catch (err) {
105
+ setStatus(err.message);
106
+ }
107
+ setLoading(false);
108
+ }
109
+
110
+ function startCountdown() {
111
+ let timeLeft = 30;
112
+ setCountdown(timeLeft);
113
+ const interval = setInterval(() => {
114
+ timeLeft--;
115
+ setCountdown(timeLeft);
116
+ if (timeLeft <= 0) {
117
+ clearInterval(interval);
118
+ setSendDisabled(false);
119
+ setCountdown(30);
120
+ }
121
+ }, 1000);
122
+ }
123
+
124
+ const handleKeyPress = (e) => {
125
+ if (e.key === 'Enter') {
126
+ submitOTP();
127
+ }
128
+ };
129
+
130
+ return (
131
+ <div class="otp-page-wrapper">
132
+ <style>{`
133
+ :root {
134
+ --bg-primary: #111217; --bg-secondary: #1a1b23; --text-primary: #e0e0e0;
135
+ --text-secondary: #8a8f98; --accent-primary: #00aaff; --accent-secondary: #0088cc;
136
+ --border-color: rgba(255, 255, 255, 0.1); --shadow-color: rgba(0, 0, 0, 0.5);
137
+ --radius-main: 16px; --radius-inner: 12px;
138
+ --font-body: 'Roboto', sans-serif;
139
+ --success-color: #2ecc71; --error-color: #e74c3c;
140
+ }
141
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
142
+
143
+ body { background-color: var(--bg-primary); font-family: var(--font-body); margin: 0; }
144
+ .otp-page-wrapper { display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: 2rem; box-sizing: border-box; }
145
+ .otp-card { background: var(--bg-secondary); width: 100%; max-width: 450px; padding: 3rem; border-radius: var(--radius-main); border: 1px solid var(--border-color); box-shadow: 0 15px 40px var(--shadow-color); animation: fadeIn 0.5s ease-out; text-align: center; }
146
+ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
147
+
148
+ .otp-header { margin-bottom: 1rem; color: var(--text-primary); font-size: 2rem; font-weight: 700; }
149
+ .otp-subtext { color: var(--text-secondary); margin-bottom: 2.5rem; line-height: 1.6; }
150
+
151
+ .form-group { margin-bottom: 1.5rem; text-align: left; }
152
+ .form-label { display: block; margin-bottom: 0.5rem; color: var(--text-secondary); font-weight: 500; }
153
+ .otp-input { width: 100%; padding: 1rem; border: 1px solid var(--border-color); border-radius: var(--radius-inner); font-family: var(--font-body); font-size: 1.5rem; background-color: var(--bg-primary); color: var(--text-primary); box-sizing: border-box; transition: border-color 0.2s, box-shadow 0.2s; text-align: center; letter-spacing: 0.5em; }
154
+ .otp-input:focus { outline:0; border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(0, 170, 255, 0.2); }
155
+ .otp-input::placeholder { letter-spacing: normal; }
156
+
157
+ .btn { width: 100%; padding: 0.9rem 1.5rem; border: none; border-radius: var(--radius-inner); color: #fff; font-size: 1.1rem; font-weight: 700; cursor: pointer; transition: all 0.2s ease; }
158
+ .btn:disabled { opacity: 0.6; cursor: not-allowed; }
159
+ .btn-primary { background: linear-gradient(to right, var(--accent-primary), var(--accent-secondary)); }
160
+ .btn-primary:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 170, 255, 0.2); }
161
+ .btn-secondary { background: var(--bg-tertiary); color: var(--text-secondary); border: 1px solid var(--border-color); }
162
+ .btn-secondary:hover:not(:disabled) { background-color: var(--border-color); color: var(--text-primary); }
163
+
164
+ .status-message { text-align: center; margin-top: 1.5rem; padding: 0.8rem; border-radius: var(--radius-inner); font-weight: 500; }
165
+ .status-success { background-color: rgba(46, 204, 113, 0.15); color: var(--success-color); border: 1px solid var(--success-color); }
166
+ .status-error { background-color: rgba(231, 76, 60, 0.15); color: var(--error-color); border: 1px solid var(--error-color); }
167
+ `}</style>
168
+ <div class="otp-card">
169
+ <h1 class="otp-header">Account Verification</h1>
170
+ <p class="otp-subtext">A verification code may be sent to your email. Please enter it below.</p>
171
+
172
+ <div class="form-group">
173
+ <label class="form-label" for="otpInput">Verification Code</label>
174
+ <input id="otpInput" class="otp-input" type="text" value={otp()} onInput={(e) => setOtp(e.currentTarget.value)} onKeyPress={handleKeyPress} placeholder="------" maxlength="6"/>
175
+ </div>
176
+
177
+ <button class="btn btn-primary" style={{"margin-bottom": "1rem"}} onClick={submitOTP} disabled={loading() || !otp() || otp().length < 6}>
178
+ {loading() ? 'Verifying...' : 'Verify Account'}
179
+ </button>
180
+
181
+ <button class="btn btn-secondary" onClick={sendOTP} disabled={loading() || sendDisabled()}>
182
+ {sendDisabled() ? `Resend in ${countdown()}s` : 'Send New Code'}
183
+ </button>
184
+
185
+ <Show when={status()}>
186
+ <div class={`status-message ${status().includes('Success') ? 'status-success' : 'status-error'}`}>
187
+ {status()}
188
+ </div>
189
+ </Show>
190
+ </div>
191
+ </div>
192
+ );
193
+ }
194
+
195
+ render(() => <App />, document.getElementById('app'));
exocore-web/public/panel.html ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Panel Login</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ display: flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ min-height: 100vh;
14
+ background-color: #f0f2f5; /* Light grey background */
15
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16
+ }
17
+ .login-container {
18
+ background-color: #ffffff;
19
+ padding: 35px;
20
+ border-radius: 10px;
21
+ box-shadow: 0 5px 20px rgba(0,0,0,0.1);
22
+ width: 100%;
23
+ max-width: 420px;
24
+ }
25
+ .login-container h2 {
26
+ margin-bottom: 25px;
27
+ text-align: center;
28
+ color: #333;
29
+ font-weight: 600;
30
+ }
31
+ .form-control:focus {
32
+ border-color: #0d6efd;
33
+ box-shadow: 0 0 0 0.2rem rgba(13,110,253,.25);
34
+ }
35
+ .btn-primary {
36
+ background-color: #0d6efd;
37
+ border-color: #0d6efd;
38
+ transition: background-color 0.2s;
39
+ }
40
+ .btn-primary:hover {
41
+ background-color: #0b5ed7;
42
+ border-color: #0a58ca;
43
+ }
44
+ .alert {
45
+ margin-top: 20px;
46
+ font-size: 0.9rem;
47
+ border-radius: 6px;
48
+ }
49
+ label {
50
+ font-weight: 500;
51
+ color: #555;
52
+ }
53
+ </style>
54
+ </head>
55
+ <body>
56
+ <div class="login-container">
57
+ <h2>Panel Login</h2>
58
+ <form id="loginForm">
59
+ <div class="mb-3">
60
+ <label for="username" class="form-label">Username</label>
61
+ <input type="text" class="form-control" id="username" name="user" required>
62
+ </div>
63
+ <div class="mb-4">
64
+ <label for="password" class="form-label">Password</label>
65
+ <input type="password" class="form-control" id="password" name="pass" required>
66
+ </div>
67
+ <button type="submit" class="btn btn-primary w-100 py-2">Login</button>
68
+ </form>
69
+ <div id="message" class="alert d-none mt-3" role="alert"></div>
70
+ </div>
71
+
72
+ <script>
73
+ const loginForm = document.getElementById('loginForm');
74
+ const messageDiv = document.getElementById('message');
75
+
76
+ loginForm.addEventListener('submit', async (event) => {
77
+ event.preventDefault();
78
+ messageDiv.classList.add('d-none');
79
+ messageDiv.textContent = '';
80
+ messageDiv.className = 'alert d-none mt-3'; // Reset classes
81
+
82
+ const formData = new FormData(loginForm);
83
+ const data = Object.fromEntries(formData.entries());
84
+
85
+ try {
86
+ const response = await fetch('/private/server/exocore/web/panel', {
87
+ method: 'POST',
88
+ headers: {
89
+ 'Content-Type': 'application/json',
90
+ },
91
+ body: JSON.stringify(data),
92
+ });
93
+
94
+ const result = await response.json();
95
+
96
+ if (response.ok && result.status === 'success') {
97
+ messageDiv.textContent = result.message || 'Login successful!';
98
+ messageDiv.classList.add('alert-success');
99
+ localStorage.setItem('panelLogin', 'success');
100
+ window.location.href = "/private/server/exocore/web/public/login"
101
+ console.log('Login status saved to localStorage: panelLogin = success');
102
+ } else {
103
+ messageDiv.textContent = result.message || `Login failed (Status: ${response.status})`;
104
+ messageDiv.classList.add('alert-danger');
105
+ }
106
+ } catch (error) {
107
+ console.error('Login submission error:', error);
108
+ messageDiv.textContent = 'An error occurred while trying to log in. Please check the console and try again.';
109
+ messageDiv.classList.add('alert-danger');
110
+ }
111
+ messageDiv.classList.remove('d-none');
112
+ });
113
+ </script>
114
+ </body>
115
+ </html>
exocore-web/public/plans.jsx ADDED
@@ -0,0 +1,418 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, For, Show } from 'solid-js';
3
+
4
+ const PixelIcon = ({ color }) => (
5
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="24" height="24" style={{ "image-rendering": "pixelated", fill: color || "currentColor" }}>
6
+ <path d="M2 0H14V2H16V14H14V16H2V14H0V2H2V0ZM4 4V12H12V4H4Z" />
7
+ <path d="M6 6H10V10H6V6Z" />
8
+ </svg>
9
+ );
10
+
11
+ const planStylesConfig = {
12
+ "Core Access": {
13
+ textGrad1: '#D0A9F5', textGrad2: '#E8D4F7', cardGrad1: '#6A0DAD', cardGrad2: '#A74AC7',
14
+ cardBorder: '#4B0082', textColor: '#FFFFFF', iconFill: '#E8D4F7', glowColor: '#E0BBE4'
15
+ },
16
+ "Prime Core": {
17
+ textGrad1: '#FFEB3B', textGrad2: '#FFF59D', cardGrad1: '#FBC02D', cardGrad2: '#FFD700',
18
+ cardBorder: '#B98B00', textColor: '#1A1A1A', iconFill: '#424242', glowColor: '#FFFACD'
19
+ },
20
+ "Alpha Core": {
21
+ textGrad1: '#00BCD4', textGrad2: '#80DEEA', cardGrad1: '#03A9F4', cardGrad2: '#4FC3F7',
22
+ cardBorder: '#0277BD', textColor: '#FFFFFF', iconFill: '#B2EBF2', glowColor: '#80DEEA'
23
+ },
24
+ "EXO Elite": {
25
+ textGrad1: '#F44336', textGrad2: '#FF8A80', cardGrad1: '#D32F2F', cardGrad2: '#E57373',
26
+ cardBorder: '#9A0007', textColor: '#FFFFFF', iconFill: '#FFCDD2', glowColor: '#FF8A80'
27
+ },
28
+ "Hacker Core": {
29
+ textGrad1: '#4CAF50', textGrad2: '#A5D6A7', cardGrad1: '#388E3C', cardGrad2: '#66BB6A',
30
+ cardBorder: '#1B5E20', textColor: '#FFFFFF', iconFill: '#C8E6C9', glowColor: '#A5D6A7'
31
+ }
32
+ };
33
+ const defaultPlanStyle = {
34
+ textGrad1: '#B0BEC5', textGrad2: '#ECEFF1', cardGrad1: '#455A64', cardGrad2: '#607D8B',
35
+ cardBorder: '#263238', textColor: '#FFFFFF', iconFill: '#ECEFF1', glowColor: '#90A4AE'
36
+ };
37
+
38
+ const countryCurrencyMap = {
39
+ "Afghanistan": "AFN", "Albania": "ALL", "Algeria": "DZD", "Angola": "AOA",
40
+ "Argentina": "ARS", "Armenia": "AMD", "Australia": "AUD", "Austria": "EUR", "Azerbaijan": "AZN",
41
+ "Bahamas": "BSD", "Bahrain": "BHD", "Bangladesh": "BDT", "Barbados": "BBD", "Belarus": "BYN",
42
+ "Belgium": "EUR", "Belize": "BZD", "Benin": "XOF", "Bhutan": "BTN", "Bolivia": "BOB",
43
+ "Bosnia and Herzegovina": "BAM", "Botswana": "BWP", "Brazil": "BRL", "Brunei": "BND",
44
+ "Bulgaria": "BGN", "Burkina Faso": "XOF", "Burundi": "BIF", "Cambodia": "KHR", "Cameroon": "XAF",
45
+ "Canada": "CAD", "Cape Verde": "CVE", "Central African Republic": "XAF", "Chad": "XAF",
46
+ "Chile": "CLP", "China": "CNY", "Colombia": "COP", "Comoros": "KMF", "Congo, Dem. Rep.": "CDF",
47
+ "Congo, Rep.": "XAF", "Costa Rica": "CRC", "Cote d'Ivoire": "XOF", "Croatia": "EUR",
48
+ "Cuba": "CUP", "Cyprus": "EUR", "Czech Republic": "CZK", "Denmark": "DKK", "Djibouti": "DJF",
49
+ "Dominican Republic": "DOP", "Ecuador": "USD", "Egypt": "EGP", "El Salvador": "USD",
50
+ "Equatorial Guinea": "XAF", "Eritrea": "ERN", "Estonia": "EUR", "Eswatini": "SZL", "Ethiopia": "ETB",
51
+ "Fiji": "FJD", "Finland": "EUR", "France": "EUR", "Gabon": "XAF", "Gambia": "GMD",
52
+ "Georgia": "GEL", "Germany": "EUR", "Ghana": "GHS", "Greece": "EUR", "Guatemala": "GTQ",
53
+ "Guinea": "GNF", "Guinea-Bissau": "XOF", "Guyana": "GYD", "Haiti": "HTG", "Honduras": "HNL",
54
+ "Hong Kong": "HKD", "Hungary": "HUF", "Iceland": "ISK", "India": "INR", "Indonesia": "IDR",
55
+ "Iran": "IRR", "Iraq": "IQD", "Ireland": "EUR", "Israel": "ILS", "Italy": "EUR", "Jamaica": "JMD",
56
+ "Japan": "JPY", "Jordan": "JOD", "Kazakhstan": "KZT", "Kenya": "KES", "Kiribati": "AUD",
57
+ "Korea, North": "KPW", "Korea, South": "KRW", "Kuwait": "KWD", "Kyrgyzstan": "KGS", "Laos": "LAK",
58
+ "Latvia": "EUR", "Lebanon": "LBP", "Lesotho": "LSL", "Liberia": "LRD", "Libya": "LYD",
59
+ "Liechtenstein": "CHF", "Lithuania": "EUR", "Luxembourg": "EUR", "Macao": "MOP", "Madagascar": "MGA",
60
+ "Malawi": "MWK", "Malaysia": "MYR", "Maldives": "MVR", "Mali": "XOF", "Malta": "EUR",
61
+ "Mauritania": "MRU", "Mauritius": "MUR", "Mexico": "MXN", "Micronesia": "USD", "Moldova": "MDL",
62
+ "Monaco": "EUR", "Mongolia": "MNT", "Montenegro": "EUR", "Morocco": "MAD", "Mozambique": "MZN",
63
+ "Myanmar": "MMK", "Namibia": "NAD", "Nauru": "AUD", "Nepal": "NPR", "Netherlands": "EUR",
64
+ "New Zealand": "NZD", "Nicaragua": "NIO", "Niger": "XOF", "Nigeria": "NGN", "North Macedonia": "MKD",
65
+ "Norway": "NOK", "Oman": "OMR", "Pakistan": "PKR", "Palau": "USD", "Panama": "PAB",
66
+ "Papua New Guinea": "PGK", "Paraguay": "PYG", "Peru": "PEN", "Philippines": "PHP",
67
+ "Poland": "PLN", "Portugal": "EUR", "Puerto Rico": "USD", "Qatar": "QAR", "Romania": "RON",
68
+ "Russia": "RUB", "Rwanda": "RWF", "Samoa": "WST", "San Marino": "EUR", "Sao Tome and Principe": "STN",
69
+ "Saudi Arabia": "SAR", "Senegal": "XOF", "Serbia": "RSD", "Seychelles": "SCR", "Sierra Leone": "SLL",
70
+ "Singapore": "SGD", "Slovakia": "EUR", "Slovenia": "EUR", "Solomon Islands": "SBD", "Somalia": "SOS",
71
+ "South Africa": "ZAR", "South Sudan": "SSP", "Spain": "EUR", "Sri Lanka": "LKR", "Sudan": "SDG",
72
+ "Suriname": "SRD", "Sweden": "SEK", "Switzerland": "CHF", "Syria": "SYP", "Taiwan": "TWD",
73
+ "Tajikistan": "TJS", "Tanzania": "TZS", "Thailand": "THB", "Timor-Leste": "USD", "Togo": "XOF",
74
+ "Tonga": "TOP", "Trinidad and Tobago": "TTD", "Tunisia": "TND", "Turkey": "TRY", "Turkmenistan": "TMT",
75
+ "Tuvalu": "AUD", "Uganda": "UGX", "Ukraine": "UAH", "United Arab Emirates": "AED",
76
+ "United Kingdom": "GBP", "United States": "USD", "Uruguay": "UYU", "Uzbekistan": "UZS",
77
+ "Vanuatu": "VUV", "Venezuela": "VES", "Vietnam": "VND", "Yemen": "YER", "Zambia": "ZMW", "Zimbabwe": "ZWL"
78
+ };
79
+
80
+ const currencySymbolsMap = {
81
+ "AFN": "؋", "ALL": "L", "DZD": "د.ج", "AOA": "Kz", "ARS": "$", "AMD": "֏", "AUD": "A$",
82
+ "AZN": "₼", "BSD": "B$", "BHD": ".د.ب", "BDT": "৳", "BBD": "Bds$", "BYN": "Br", "EUR": "€",
83
+ "BZD": "BZ$", "XOF": "CFA", "BTN": "Nu.", "BOB": "Bs.", "BAM": "KM", "BWP": "P", "BRL": "R$",
84
+ "BND": "B$", "BGN": "лв", "BIF": "FBu", "KHR": "៛", "XAF": "FCFA", "CAD": "C$", "CVE": "Esc",
85
+ "CLP": "CLP$", "CNY": "¥", "COP": "COL$", "KMF": "CF", "CDF": "FC", "CRC": "₡", "CUP": "$MN",
86
+ "CZK": "Kč", "DKK": "kr.", "DJF": "Fdj", "DOP": "RD$", "USD": "$", "EGP": "E£", "ERN": "Nfk",
87
+ "SZL": "L", "ETB": "Br", "FJD": "FJ$", "GMD": "D", "GEL": "₾", "GHS": "₵", "GTQ": "Q",
88
+ "GNF": "FG", "GYD": "G$", "HTG": "G", "HNL": "L", "HKD": "HK$", "HUF": "Ft", "ISK": "kr",
89
+ "INR": "₹", "IDR": "Rp", "IRR": "﷼", "IQD": "ع.د", "ILS": "₪", "JMD": "J$", "JPY": "¥",
90
+ "JOD": "JD", "KZT": "₸", "KES": "KSh", "KPW": "₩", "KRW": "₩", "KWD": "KD", "KGS": "сом",
91
+ "LAK": "₭", "LBP": "ل.ل", "LSL": "M", "LRD": "L$", "LYD": "LD", "CHF": "Fr.", "MOP": "MOP$",
92
+ "MGA": "Ar", "MWK": "MK", "MYR": "RM", "MVR": ".ރ", "MRU": "UM", "MUR": "₨", "MXN": "Mex$",
93
+ "MDL": "L", "MNT": "₮", "MAD": "د.م.", "MZN": "MT", "MMK": "K", "NAD": "N$", "NPR": "₨",
94
+ "NZD": "NZ$", "NIO": "C$", "NGN": "₦", "MKD": "ден", "NOK": "kr", "OMR": "﷼", "PKR": "₨",
95
+ "PAB": "B/.", "PGK": "K", "PYG": "₲", "PEN": "S/.", "PHP": "₱", "PLN": "zł", "QAR": "﷼",
96
+ "RON": "lei", "RUB": "₽", "RWF": "RF", "WST": "WS$", "STN": "Db", "SAR": "﷼", "RSD": "дин.",
97
+ "SCR": "₨", "SLL": "Le", "SGD": "S$", "SBD": "SI$", "SOS": "Sh.So.", "ZAR": "R", "SSP": "£",
98
+ "LKR": "Rs", "SDG": "ج.س.", "SRD": "$", "SEK": "kr", "SYP": "£S", "TWD": "NT$", "TJS": "ЅМ",
99
+ "TZS": "TSh", "THB": "฿", "TOP": "T$", "TTD": "TT$", "TND": "د.ت", "TRY": "₺", "TMT": "m",
100
+ "UGX": "USh", "UAH": "₴", "AED": "د.إ", "GBP": "£", "UYU": "$U", "UZS": "сўм", "VUV": "VT",
101
+ "VES": "Bs.S.", "VND": "₫", "YER": "﷼", "ZMW": "ZK", "ZWL": "$"
102
+ };
103
+
104
+ function App() {
105
+ const [loading, setLoading] = createSignal(true);
106
+ const [status, setStatus] = createSignal('');
107
+ const [userData, setUserData] = createSignal(null);
108
+ const [plans, setPlans] = createSignal([]);
109
+ const [initialLoadComplete, setInitialLoadComplete] = createSignal(false);
110
+
111
+ const [targetCurrency, setTargetCurrency] = createSignal('USD');
112
+ const [exchangeRate, setExchangeRate] = createSignal(1);
113
+ const [currencySymbol, setCurrencySymbol] = createSignal('$');
114
+
115
+ const getToken = () => localStorage.getItem('exocore-token') || '';
116
+ const getCookies = () => localStorage.getItem('exocore-cookies') || '';
117
+
118
+ async function fetchExchangeRatesForUser(countryName) {
119
+ const currencyCode = countryCurrencyMap[countryName] || 'USD';
120
+ const symbol = currencySymbolsMap[currencyCode] || (currencyCode + ' ');
121
+
122
+ setTargetCurrency(currencyCode);
123
+ setCurrencySymbol(symbol);
124
+
125
+ if (currencyCode === 'USD') {
126
+ setExchangeRate(1);
127
+ return;
128
+ }
129
+ try {
130
+ const response = await fetch(`https://api.frankfurter.app/latest?from=USD&to=${currencyCode}`);
131
+ if (!response.ok) throw new Error(`API error: ${response.status}`);
132
+ const data = await response.json();
133
+ if (data.rates && data.rates[currencyCode]) {
134
+ setExchangeRate(data.rates[currencyCode]);
135
+ } else {
136
+ setExchangeRate(1); setTargetCurrency('USD'); setCurrencySymbol('$');
137
+ }
138
+ } catch (error) {
139
+ setStatus('Could not load local currency. Displaying prices in USD.');
140
+ setExchangeRate(1); setTargetCurrency('USD'); setCurrencySymbol('$');
141
+ }
142
+ }
143
+
144
+ async function fetchPlans() {
145
+ try {
146
+ const proxiedUrl = `https://api.allorigins.win/raw?url=${encodeURIComponent('https://pastebin.com/raw/zddjxUGr')}`;
147
+ const res = await fetch(proxiedUrl);
148
+ if (!res.ok) throw new Error(`Failed to fetch plans: ${res.status}`);
149
+ const data = await res.json();
150
+ if (Array.isArray(data)) {
151
+ setPlans(data);
152
+ } else {
153
+ setPlans([]);
154
+ }
155
+ } catch (err) {
156
+ setStatus('Failed to load subscription plans. Please try refreshing.');
157
+ setPlans([]);
158
+ }
159
+ }
160
+
161
+ async function fetchUserInfo() {
162
+ setLoading(true); setStatus('');
163
+ const token = getToken(); const cookies = getCookies();
164
+
165
+ if (!token || !cookies) {
166
+ setLoading(false); setInitialLoadComplete(true);
167
+ window.location.href = '/private/server/exocore/web/public/login'; return;
168
+ }
169
+ try {
170
+ const res = await fetch('/private/server/exocore/web/userinfo', {
171
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
172
+ body: JSON.stringify({ token, cookies }),
173
+ });
174
+ if (!res.ok) {
175
+ let errorMsg = `Server error: ${res.status}`;
176
+ try { const errorData = await res.json(); errorMsg = errorData.message || errorMsg; } catch (e) {}
177
+ throw new Error(errorMsg);
178
+ }
179
+ const data = await res.json();
180
+
181
+ if (data.data?.user && data.data.user.verified === 'success') {
182
+ setUserData(data.data.user);
183
+ setStatus('');
184
+ if (data.data.user.country) {
185
+ await fetchExchangeRatesForUser(data.data.user.country);
186
+ } else {
187
+ setTargetCurrency('USD'); setExchangeRate(1); setCurrencySymbol('$');
188
+ }
189
+ await fetchPlans();
190
+ } else {
191
+ setUserData(null); setPlans([]);
192
+ setStatus(data.message || 'User verification failed. Redirecting to login...');
193
+ localStorage.removeItem('exocore-token'); localStorage.removeItem('exocore-cookies');
194
+ setTimeout(() => { window.location.href = '/private/server/exocore/web/public/login'; }, 2500);
195
+ }
196
+ } catch (err) {
197
+ setUserData(null); setPlans([]);
198
+ setStatus('Failed to fetch user info: ' + (err.message || 'Unknown error') + '. Redirecting...');
199
+ localStorage.removeItem('exocore-token'); localStorage.removeItem('exocore-cookies');
200
+ setTimeout(() => { window.location.href = '/private/server/exocore/web/public/login'; }, 2500);
201
+ } finally {
202
+ setLoading(false); setInitialLoadComplete(true);
203
+ }
204
+ }
205
+
206
+ onMount(() => {
207
+ const fontLink = document.createElement('link');
208
+ fontLink.href = 'https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400;700&display=swap';
209
+ fontLink.rel = 'stylesheet';
210
+ document.head.appendChild(fontLink);
211
+
212
+ document.body.style.margin = '0';
213
+ document.body.style.fontFamily = "'Pixelify Sans', sans-serif";
214
+ document.body.style.background = 'linear-gradient(160deg, #1A073C 0%, #2C0F3A 50%, #4A1B4D 100%)';
215
+ document.body.style.color = '#EAEAEA';
216
+ document.body.style.setProperty('image-rendering', 'pixelated', 'important');
217
+ document.body.style.setProperty('-webkit-font-smoothing', 'none', 'important');
218
+ document.body.style.setProperty('font-smooth', 'never', 'important');
219
+
220
+ fetchUserInfo();
221
+ });
222
+
223
+ const handleBuyClick = () => {
224
+ window.location.href = 'https://www.facebook.com/share/16TsfAhA3z/';
225
+ };
226
+
227
+ return (
228
+ <div class="main-container">
229
+ <style>
230
+ {`
231
+ * {
232
+ image-rendering: pixelated !important;
233
+ -ms-interpolation-mode: nearest-neighbor !important;
234
+ -webkit-font-smoothing: none !important;
235
+ font-smooth: never !important;
236
+ box-sizing: border-box;
237
+ }
238
+ body, input, button, textarea, select {
239
+ font-family: 'Pixelify Sans', sans-serif !important;
240
+ }
241
+ .main-container {
242
+ padding: 2vh 2vw; display: flex; flex-direction: column;
243
+ justify-content: center; align-items: center; min-height: 100vh;
244
+ animation: fadeIn 0.7s 0.1s ease forwards; opacity: 0;
245
+ }
246
+ @keyframes fadeIn { to { opacity: 1; } }
247
+ .greeting {
248
+ font-size: 2.3rem; font-weight: 700; color: #00EFFF;
249
+ margin-bottom: 1.5rem; text-shadow: 2px 2px 0px #110522;
250
+ letter-spacing: 1px;
251
+ }
252
+ .status-box {
253
+ margin-bottom: 1rem; padding: 10px 15px; border-radius: 2px;
254
+ color: #FEE2E2; background-color: #7F1D1D; border: 2px solid #5F1212;
255
+ box-shadow: 2px 2px 0px #400A0A; font-weight: 700;
256
+ max-width: 500px; width: 90%; text-align: center;
257
+ font-size: 0.8rem; line-height: 1.3; letter-spacing: 0.5px;
258
+ }
259
+ .loading-text {
260
+ font-size: 1.2rem; color: #909090; font-weight: 700; letter-spacing: 0.5px;
261
+ }
262
+ .content-box {
263
+ width: 100%; max-width: 860px; min-height: 350px;
264
+ background-color: rgba(10, 2, 20, 0.9);
265
+ border-radius: 3px; border: 2px solid #2A0B4A;
266
+ box-shadow: 3px 3px 0px #0A0314;
267
+ padding: 1.5rem; text-align: center; user-select: none;
268
+ }
269
+ .plans-outer-container { width: 100%; }
270
+ .plans-container {
271
+ display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
272
+ gap: 1.3rem; width: 100%; margin-top: 1rem;
273
+ }
274
+ .plan-card {
275
+ display: flex; align-items: flex-start; padding: 12px;
276
+ border-radius: 3px; border: 2px solid var(--card-border);
277
+ color: var(--card-text);
278
+ background: linear-gradient(145deg, var(--card-grad1), var(--card-grad2));
279
+ animation: cardGlow 2.5s infinite alternate;
280
+ transition: transform 0.15s ease-out;
281
+ }
282
+ @keyframes cardGlow {
283
+ from { box-shadow: 2px 2px 0px var(--card-border), 0 0 4px 0px var(--glow-color); }
284
+ to { box-shadow: 2px 2px 0px var(--card-border), 0 0 14px 3px var(--glow-color); }
285
+ }
286
+ .plan-icon-area {
287
+ margin-right: 10px; flex-shrink: 0; padding-top: 2px;
288
+ width: 24px; height: 24px;
289
+ }
290
+ .plan-details {
291
+ display: flex; flex-direction: column; flex-grow: 1; text-align: left;
292
+ }
293
+ .plan-name {
294
+ font-size: 1.3rem; font-weight: 700; line-height: 1.15; margin-bottom: 5px;
295
+ letter-spacing: 0.5px;
296
+ background: linear-gradient(60deg, var(--text-grad1, #FFFDE7), var(--text-grad2, #FFF59D));
297
+ -webkit-background-clip: text; background-clip: text; color: transparent;
298
+ padding-bottom: 1px;
299
+ }
300
+ .plan-price {
301
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
302
+ font-size: 1.05rem;
303
+ font-weight: 500; /* Medium weight for standard font */
304
+ margin-bottom: 10px;
305
+ opacity: 0.95; /* Slightly more opaque */
306
+ color: var(--card-text);
307
+ letter-spacing: 0.1px; /* More standard letter spacing */
308
+ image-rendering: auto !important;
309
+ -webkit-font-smoothing: auto !important; /* Enable smoothing for standard font */
310
+ font-smooth: auto !important; /* Enable smoothing for standard font */
311
+ }
312
+ .buy-button {
313
+ background-color: rgba(0,0,0,0.4); color: var(--card-text);
314
+ border: 2px solid var(--card-text); opacity: 0.95; padding: 7px 14px;
315
+ border-radius: 2px; box-shadow: 1px 1px 0px rgba(0,0,0,0.6);
316
+ text-transform: uppercase; font-weight: 700; font-size: 0.8rem;
317
+ letter-spacing: 0.5px; cursor: pointer; align-self: flex-start;
318
+ transition: transform 0.08s linear, background-color 0.08s linear;
319
+ }
320
+ .buy-button:hover { background-color: rgba(20,20,20,0.55); opacity: 1; }
321
+ .buy-button:active { transform: translate(1px, 1px); box-shadow: 0px 0px 0px rgba(0,0,0,0.6); }
322
+ @media (max-width: 600px) {
323
+ .greeting { font-size: 1.9rem; }
324
+ .content-box { padding: 1rem; }
325
+ .plans-container { grid-template-columns: 1fr; gap: 1rem; }
326
+ .plan-name { font-size: 1.15rem; }
327
+ .plan-price { font-size: 0.95rem; } /* Adjust if needed */
328
+ .buy-button { font-size: 0.75rem; padding: 6px 10px; }
329
+ }
330
+ `}
331
+ </style>
332
+
333
+ <Show when={status() && !loading()}>
334
+ <div class="status-box">{status()}</div>
335
+ </Show>
336
+
337
+ <div class="content-box">
338
+ <Show when={loading() && !initialLoadComplete()}>
339
+ <p class="loading-text">LOADING USER DATA...</p>
340
+ </Show>
341
+
342
+ <Show when={!loading() && initialLoadComplete() && userData()}>
343
+ <div class="greeting">
344
+ HELLO, {(userData()?.user || userData()?.user?.user || userData()?.data?.user?.user || 'USER').toUpperCase()}!
345
+ </div>
346
+
347
+ <Show when={plans().length > 0}>
348
+ <div class="plans-outer-container">
349
+ <div class="plans-container">
350
+ <For each={plans()}>
351
+ {(planItem) => {
352
+ if (!planItem || typeof planItem.plan !== 'string') {
353
+ return null;
354
+ }
355
+ const style = planStylesConfig[planItem.plan] || defaultPlanStyle;
356
+
357
+ let displayPrice = planItem.price || "$0";
358
+ const originalPriceStr = planItem.price || "$0";
359
+ const numericUsdPrice = parseFloat(originalPriceStr.replace('$', ''));
360
+
361
+ if (!isNaN(numericUsdPrice) && exchangeRate() !== null && exchangeRate() !== undefined) {
362
+ if (numericUsdPrice === 0 && targetCurrency() !== 'USD') {
363
+ displayPrice = `${currencySymbol()}0`;
364
+ } else if (numericUsdPrice === 0 && targetCurrency() === 'USD') {
365
+ displayPrice = `$0`;
366
+ }
367
+ else {
368
+ const convertedPrice = numericUsdPrice * exchangeRate();
369
+ let formattedConvertedPrice;
370
+ if (targetCurrency() === 'JPY' || targetCurrency() === 'KRW') {
371
+ formattedConvertedPrice = Math.round(convertedPrice);
372
+ } else {
373
+ formattedConvertedPrice = convertedPrice.toFixed(2);
374
+ }
375
+ displayPrice = `${currencySymbol()}${formattedConvertedPrice}`;
376
+ }
377
+ }
378
+
379
+ return (
380
+ <div
381
+ class="plan-card"
382
+ style={{
383
+ '--card-grad1': style.cardGrad1, '--card-grad2': style.cardGrad2,
384
+ '--card-border': style.cardBorder, '--card-text': style.textColor,
385
+ '--icon-color': style.iconFill, '--text-grad1': style.textGrad1,
386
+ '--text-grad2': style.textGrad2, '--glow-color': style.glowColor
387
+ }}
388
+ >
389
+ <div class="plan-icon-area">
390
+ <PixelIcon color={style.iconFill} />
391
+ </div>
392
+ <div class="plan-details">
393
+ <div class="plan-name">{(planItem.plan || "PLAN").toUpperCase()}</div>
394
+ <div class="plan-price">{displayPrice}</div>
395
+ <button class="buy-button" onClick={handleBuyClick}>BUY</button>
396
+ </div>
397
+ </div>
398
+ );
399
+ }}
400
+ </For>
401
+ </div>
402
+ </div>
403
+ </Show>
404
+ <Show when={plans().length === 0 && !status().includes('Failed to load subscription plans')}>
405
+ <p style={{color: '#A0A0A0', 'font-weight': '700', 'letter-spacing':'0.5px', 'font-size': '0.9rem'}}>NO PLANS AVAILABLE.</p>
406
+ </Show>
407
+ </Show>
408
+
409
+ <Show when={!loading() && initialLoadComplete() && !userData() && !status().includes('Redirecting')}>
410
+ <p style={{color: '#B0B0B0', 'font-weight': '700', 'letter-spacing':'0.5px', 'font-size': '0.9rem'}}>CANNOT LOAD USER. TRY LOGIN.</p>
411
+ </Show>
412
+ </div>
413
+ </div>
414
+ );
415
+ }
416
+
417
+ render(() => <App />, document.getElementById('app'));
418
+
exocore-web/public/profile.jsx ADDED
@@ -0,0 +1,527 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, Show, For } from 'solid-js';
3
+
4
+ const IconPencil = () => <svg class="icon" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" /></svg>;
5
+ const IconAdd = () => <svg class="icon" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em" style="vertical-align: middle; margin-right: 4px;"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" /></svg>;
6
+ const IconCode = () => <svg class="icon" viewBox="0 0 24 24" fill="currentColor" width="1em" height="1em"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg>;
7
+
8
+ const getBasename = (filePath) => {
9
+ if (!filePath) return '';
10
+ const parts = filePath.split(/[\\/]/);
11
+ return parts[parts.length - 1] || '';
12
+ };
13
+
14
+ const getSkillIcon = (extension, displayName) => {
15
+ const iconPath = `/private/server/exocore/web/public/icons/${extension.toLowerCase()}.svg`;
16
+ return (
17
+ <img
18
+ src={iconPath}
19
+ alt={`${displayName} icon`}
20
+ class="skill-icon"
21
+ onError={(e) => {
22
+ e.currentTarget.style.display = 'none';
23
+ e.currentTarget.parentNode.querySelector('.fallback-icon').style.display = 'block';
24
+ }}
25
+ />
26
+ );
27
+ };
28
+
29
+ const planStylesConfig = {
30
+ "Core Access": {
31
+ textGrad1: '#D0A9F5', textGrad2: '#E8D4F7', cardGrad1: '#6A0DAD', cardGrad2: '#A74AC7',
32
+ cardBorder: 'rgba(75, 0, 130, 0.8)', textColor: '#FFFFFF', iconFill: '#E8D4F7', glowColor: 'rgba(224, 187, 228, 0.3)'
33
+ },
34
+ "Prime Core": {
35
+ textGrad1: '#FFEB3B', textGrad2: '#FFF59D', cardGrad1: '#FBC02D', cardGrad2: '#FFD700',
36
+ cardBorder: 'rgba(185, 139, 0, 0.8)', textColor: '#1A1A1A', iconFill: '#424242', glowColor: 'rgba(255, 250, 205, 0.4)'
37
+ },
38
+ "Alpha Core": {
39
+ textGrad1: '#00BCD4', textGrad2: '#80DEEA', cardGrad1: '#03A9F4', cardGrad2: '#4FC3F7',
40
+ cardBorder: 'rgba(2, 119, 189, 0.8)', textColor: '#FFFFFF', iconFill: '#B2EBF2', glowColor: 'rgba(128, 222, 234, 0.3)'
41
+ },
42
+ "EXO Elite": {
43
+ textGrad1: '#F44336', textGrad2: '#FF8A80', cardGrad1: '#D32F2F', cardGrad2: '#E57373',
44
+ cardBorder: 'rgba(154, 0, 7, 0.8)', textColor: '#FFFFFF', iconFill: '#FFCDD2', glowColor: 'rgba(255, 138, 128, 0.3)'
45
+ },
46
+ "Hacker Core": {
47
+ textGrad1: '#4CAF50', textGrad2: '#A5D6A7', cardGrad1: '#000000', cardGrad2: '#388E3C',
48
+ cardBorder: 'rgba(27, 94, 32, 0.8)', textColor: '#00FF00', iconFill: '#C8E6C9', glowColor: 'rgba(165, 214, 167, 0.3)'
49
+ }
50
+ };
51
+
52
+ const defaultPlanStyle = {
53
+ textGrad1: '#B0BEC5', textGrad2: '#ECEFF1', cardGrad1: '#455A64', cardGrad2: '#607D8B',
54
+ cardBorder: 'rgba(38, 50, 56, 0.8)', textColor: '#FFFFFF', iconFill: '#ECEFF1', glowColor: 'rgba(144, 164, 174, 0.2)'
55
+ };
56
+
57
+ function App() {
58
+ const [loading, setLoading] = createSignal(true);
59
+ const [status, setStatus] = createSignal({ type: '', message: '' });
60
+ const [userData, setUserData] = createSignal(null);
61
+ const [editingBio, setEditingBio] = createSignal(false);
62
+ const [editingNickname, setEditingNickname] = createSignal(false);
63
+ const [nickname, setNickname] = createSignal('');
64
+ const [bio, setBio] = createSignal('');
65
+ const [modalOpen, setModalOpen] = createSignal(false);
66
+ const [modalAction, setModalAction] = createSignal(() => {});
67
+ const [projectSkills, setProjectSkills] = createSignal(null);
68
+
69
+ const avatarDimensions = {
70
+ mobile: { headerH: 170, avatarH: 110, overlap: 55 },
71
+ tablet: { headerH: 240, avatarH: 140, overlap: 70 },
72
+ desktop: { headerH: 280, avatarH: 160, overlap: 80 },
73
+ };
74
+
75
+ const getToken = () => localStorage.getItem('exocore-token') || '';
76
+ const getCookies = () => localStorage.getItem('exocore-cookies') || '';
77
+
78
+ async function fetchUserInfo() {
79
+ // Don't set loading to true here if it's a re-fetch,
80
+ // it will be handled by the calling function.
81
+ // setLoading(true);
82
+ const token = getToken();
83
+ const cookies = getCookies();
84
+
85
+ if (!token || !cookies) {
86
+ window.location.href = '/private/server/exocore/web/public/login';
87
+ return;
88
+ }
89
+
90
+ try {
91
+ const res = await fetch('/private/server/exocore/web/userinfo', {
92
+ method: 'POST',
93
+ headers: { 'Content-Type': 'application/json' },
94
+ body: JSON.stringify({ token, cookies }),
95
+ });
96
+
97
+ if (!res.ok) {
98
+ let errorMsg = `Server error: ${res.status}`;
99
+ try {
100
+ const errorData = await res.json();
101
+ errorMsg = errorData.message || errorMsg;
102
+ } catch (parseError) {}
103
+ throw new Error(errorMsg);
104
+ }
105
+ const data = await res.json();
106
+ if (data.data?.user && data.data.user.verified === 'success') {
107
+ setUserData(data.data.user);
108
+ // fetch skills only if user data is successfully fetched
109
+ fetchSkills();
110
+ } else {
111
+ setUserData(null);
112
+ setStatus({ type: 'error', message: data.message || 'User verification failed. Redirecting...' });
113
+ setTimeout(() => { window.location.href = '/private/server/exocore/web/public/login'; }, 2500);
114
+ }
115
+ } catch (err) {
116
+ setUserData(null);
117
+ setStatus({ type: 'error', message: 'Failed to fetch user info: ' + err.message + '. Redirecting...' });
118
+ setTimeout(() => { window.location.href = '/private/server/exocore/web/public/login'; }, 2500);
119
+ } finally {
120
+ setLoading(false);
121
+ }
122
+ }
123
+
124
+ async function fetchSkills() {
125
+ try {
126
+ const skillsRes = await fetch('/private/server/exocore/web/skills', {
127
+ method: 'POST',
128
+ headers: { 'Content-Type': 'application/json' },
129
+ body: JSON.stringify({})
130
+ });
131
+
132
+ if (skillsRes.ok) {
133
+ const skillsData = await skillsRes.json();
134
+ setProjectSkills(skillsData && skillsData.length > 0 ? skillsData[0] : null);
135
+ } else {
136
+ console.error("Failed to fetch skills:", skillsRes.status);
137
+ setProjectSkills(null);
138
+ }
139
+ } catch (skillsErr) {
140
+ console.error("Error fetching skills:", skillsErr);
141
+ setProjectSkills(null);
142
+ }
143
+ }
144
+
145
+ async function handleUpdate(field, value, endEditStateFn) {
146
+ setLoading(true);
147
+ setModalOpen(false); // Close modal if open
148
+
149
+ const token = getToken();
150
+ const cookies = getCookies();
151
+
152
+ try {
153
+ const res = await fetch('/private/server/exocore/web/userinfoEdit', {
154
+ method: 'POST',
155
+ headers: { 'Content-Type': 'application/json' },
156
+ body: JSON.stringify({ token, cookies, field, edit: value }),
157
+ });
158
+
159
+ const data = await res.json();
160
+
161
+ // Check if the response is NOT OK or if there's an explicit error message
162
+ if (!res.ok || data.success === false) {
163
+ throw new Error(data.message || 'An unknown error occurred.');
164
+ }
165
+
166
+ // SUCCESS!
167
+ setStatus({ type: 'success', message: data.message || 'Update successful!' });
168
+ setTimeout(() => setStatus({ type: '', message: '' }), 3000);
169
+
170
+ // Re-fetch the single source of truth to ensure UI is in sync.
171
+ await fetchUserInfo();
172
+
173
+ if (endEditStateFn) {
174
+ endEditStateFn(false);
175
+ }
176
+
177
+ } catch (err) {
178
+ setStatus({ type: 'error', message: 'Update failed: ' + err.message });
179
+ setTimeout(() => setStatus({ type: '', message: '' }), 3000);
180
+ } finally {
181
+ // Loading is set to false inside fetchUserInfo's finally block
182
+ // setLoading(false);
183
+ }
184
+ }
185
+
186
+ function openImageModal(field) {
187
+ setModalAction(() => () => {
188
+ const input = document.createElement('input');
189
+ input.type = 'file';
190
+ input.accept = 'image/*,.heic,.heif';
191
+ input.onchange = (e) => {
192
+ const file = e.target.files[0];
193
+ if (file) {
194
+ if (file.size > 10 * 1024 * 1024) { // 10MB limit
195
+ setStatus({ type: 'error', message: 'Max file size: 10MB.' });
196
+ setTimeout(() => setStatus({ type: '', message: '' }), 3000);
197
+ return;
198
+ }
199
+ const reader = new FileReader();
200
+ reader.onload = () => handleUpdate(field, reader.result);
201
+ reader.onerror = () => {
202
+ setStatus({ type: 'error', message: 'Error reading file.' });
203
+ setTimeout(() => setStatus({ type: '', message: '' }), 3000);
204
+ }
205
+ reader.readAsDataURL(file);
206
+ }
207
+ };
208
+ input.click();
209
+ });
210
+ setModalOpen(true);
211
+ }
212
+
213
+ onMount(() => {
214
+ setLoading(true);
215
+ fetchUserInfo();
216
+ });
217
+
218
+ const Spinner = () => <div class="spinner"></div>;
219
+
220
+ const activePlanStyles = () => {
221
+ const planName = userData()?.activePlan?.plan;
222
+ return planStylesConfig[planName] || defaultPlanStyle;
223
+ };
224
+
225
+ return (
226
+ <>
227
+ <style>{`
228
+ /* ... (Yung CSS mo dito, walang pagbabago) ... */
229
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
230
+
231
+ :root {
232
+ --bg-primary: #111217; --bg-secondary: #1a1b23; --bg-tertiary: #2a2c3b;
233
+ --text-primary: #e0e0e0; --text-secondary: #8a8f98; --accent-primary: #00aaff;
234
+ --accent-secondary: #0088cc; --success-color: #2ecc71; --error-color: #e74c3c;
235
+ --border-color: rgba(255, 255, 255, 0.1); --shadow-color: rgba(0, 0, 0, 0.5);
236
+ --radius-main: 16px; --radius-inner: 12px;
237
+ --font-body: 'Roboto', sans-serif;
238
+
239
+ --avatar-mobile-top: ${avatarDimensions.mobile.headerH - avatarDimensions.mobile.overlap}px;
240
+ --avatar-tablet-top: ${avatarDimensions.tablet.headerH - avatarDimensions.tablet.overlap}px;
241
+ --avatar-desktop-top: ${avatarDimensions.desktop.headerH - avatarDimensions.desktop.overlap}px;
242
+ }
243
+
244
+ body { background-color: var(--bg-primary); font-family: var(--font-body); color: var(--text-primary); margin: 0; }
245
+ .profile-container { display: flex; justify-content: center; align-items: flex-start; padding: 2rem 1rem; min-height: 100vh; box-sizing: border-box; }
246
+ .profile-card { background: var(--bg-secondary); border-radius: var(--radius-main); box-shadow: 0 15px 40px var(--shadow-color); width: 100%; max-width: 600px; position: relative; border: 1px solid var(--border-color); }
247
+ .profile-header { position: relative; height: ${avatarDimensions.mobile.headerH}px; border-top-left-radius: var(--radius-main); border-top-right-radius: var(--radius-main); overflow: hidden; }
248
+ .cover-photo { width: 100%; height: 100%; object-fit: cover; cursor: pointer; transition: transform 0.4s ease; }
249
+ .cover-photo:hover { transform: scale(1.05); }
250
+ .avatar { width: ${avatarDimensions.mobile.avatarH}px; height: ${avatarDimensions.mobile.avatarH}px; border-radius: 50%; object-fit: cover; background-color: var(--bg-tertiary); border: 5px solid var(--bg-secondary); box-shadow: 0 8px 25px rgba(0,0,0,0.3); position: absolute; top: var(--avatar-mobile-top); left: 50%; transform: translateX(-50%); cursor: pointer; transition: transform 0.3s ease; z-index: 3; }
251
+ .avatar:hover { transform: translateX(-50%) scale(1.1); }
252
+ .profile-body { padding: ${avatarDimensions.mobile.overlap + 15}px 1.5rem 1.5rem; text-align: center; }
253
+
254
+ .nickname-container { display: flex; align-items: center; justify-content: center; gap: .75rem; min-height: 42px; }
255
+ .nickname-text { font-size: 2rem; font-weight: 700; color: var(--text-primary); }
256
+ .user-details { color: var(--text-secondary); margin: 0.25rem 0 1.5rem 0; }
257
+
258
+ .active-plan-container {
259
+ display: inline-flex;
260
+ align-items: center;
261
+ color: #fff;
262
+ padding: 0.3rem 0.8rem;
263
+ border-radius: 15px;
264
+ font-size: 0.85rem;
265
+ font-weight: 500;
266
+ margin-top: -0.5rem;
267
+ margin-bottom: 1.5rem;
268
+ box-shadow: 0 2px 8px rgba(0,0,0,0.2);
269
+ }
270
+ .active-plan-container span {
271
+ margin-left: 0.3rem;
272
+ }
273
+
274
+ .bio-section, .skills-section { margin-top: 1.5rem; padding: 1.5rem; background-color: var(--bg-tertiary); border-radius: var(--radius-inner); text-align: left; }
275
+ .bio-section h3, .skills-section h3 { margin: 0 0 1rem 0; color: var(--text-primary); display: flex; justify-content: space-between; align-items: center; font-size: 1.2rem; }
276
+ .bio-text { color: var(--text-secondary); line-height: 1.6; white-space: pre-wrap; word-wrap: break-word; font-size: 1rem; }
277
+
278
+ .edit-icon-btn { background: none; border: none; padding: .3rem; cursor: pointer; color: var(--text-secondary); display: inline-flex; align-items: center; gap: .4rem; font-size: .9rem; font-family: var(--font-body); }
279
+ .edit-icon-btn:hover { color: var(--accent-primary); }
280
+
281
+ .edit-controls { display: flex; flex-direction: column; gap: .8rem; animation: fadeIn .3s ease; }
282
+ .edit-controls input, .edit-controls textarea { width: 100%; padding: .8rem 1rem; border: 1px solid var(--border-color); border-radius: var(--radius-inner); font-family: var(--font-body); font-size: 1rem; background-color: var(--bg-primary); color: var(--text-primary); box-sizing: border-box; }
283
+ .edit-controls input:focus, .edit-controls textarea:focus { outline:0; border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(0, 170, 255, 0.2); }
284
+ .edit-controls textarea { min-height: 90px; resize: vertical; }
285
+
286
+ .edit-controls-buttons { display: flex; justify-content: flex-end; gap: .6rem; }
287
+ .btn { display: inline-flex; align-items: center; justify-content: center; padding: .6rem 1.2rem; border: none; border-radius: var(--radius-inner); cursor: pointer; font-family: var(--font-body); font-size: 1rem; font-weight: 500; transition: all .2s ease; }
288
+ .btn-primary { background: var(--accent-primary); color: #fff; }
289
+ .btn-primary:hover { background: var(--accent-secondary); }
290
+ .btn-secondary { background: var(--bg-tertiary); color: var(--text-primary); border: 1px solid var(--border-color); }
291
+ .btn-secondary:hover { background: var(--border-color); }
292
+
293
+ .status-message-container { position:fixed; bottom:20px; left:50%; transform:translateX(-50%); z-index:1001; }
294
+ .status-message { padding: .8rem 1.5rem; border-radius: var(--radius-inner); color: #fff; box-shadow: 0 5px 20px rgba(0,0,0,0.3); animation: slideInUp .5s ease, fadeOut .5s ease 2.5s forwards; }
295
+ .status-message.success { background-color: var(--success-color); }
296
+ .status-message.error { background-color: var(--error-color); }
297
+
298
+ .modal-overlay { position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.7); display:flex; justify-content:center; align-items:center; z-index:1000; backdrop-filter:blur(5px); animation:fadeIn .3s ease; }
299
+ .modal-content { background: var(--bg-secondary); padding: 2rem; border-radius: var(--radius-main); text-align:center; max-width: 450px; width: 90%; border: 1px solid var(--border-color); }
300
+ .modal-buttons { display:flex; flex-direction:column; gap: .8rem; margin-top: 1.5rem; }
301
+ .loading-overlay { position:absolute; inset:0; background:rgba(26,27,35,.85); display:flex; justify-content:center; align-items:center; z-index:100; border-radius: var(--radius-main); }
302
+ .spinner { border: 4px solid rgba(255,255,255,.1); width: 36px; height: 36px; border-radius: 50%; border-left-color: var(--accent-primary); animation:spin .8s linear infinite; }
303
+ .initial-load-container { display:flex; flex-direction:column; justify-content:center; align-items:center; min-height:80vh; text-align:center; font-size:1.2rem; color: var(--text-secondary); }
304
+
305
+ .skills-section h3 { margin-bottom: 1.2rem; }
306
+ .skills-section .project-name { font-size: 1.1rem; color: var(--text-primary); margin-bottom: 1rem; text-align: center; font-weight: 500;}
307
+ .skills-grid {
308
+ display: grid;
309
+ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
310
+ gap: 1rem;
311
+ justify-content: center;
312
+ }
313
+ .skill-item {
314
+ background-color: var(--bg-primary);
315
+ padding: 0.8rem;
316
+ padding-bottom: 1.5rem;
317
+ border-radius: var(--radius-inner);
318
+ text-align: center;
319
+ display: flex;
320
+ flex-direction: column;
321
+ align-items: center;
322
+ border: 1px solid var(--border-color);
323
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
324
+ position: relative;
325
+ overflow: hidden;
326
+ }
327
+ .skill-item:hover {
328
+ transform: translateY(-3px);
329
+ box-shadow: 0 5px 15px rgba(0,0,0,0.4);
330
+ }
331
+ .skill-icon-container {
332
+ font-size: 2.5em;
333
+ line-height: 1;
334
+ color: var(--accent-primary);
335
+ margin-bottom: 0.5rem;
336
+ display: flex;
337
+ justify-content: center;
338
+ align-items: center;
339
+ width: 100%;
340
+ height: 50px;
341
+ position: relative;
342
+ }
343
+ .skill-icon {
344
+ max-width: 100%;
345
+ max-height: 100%;
346
+ object-fit: contain;
347
+ }
348
+ .fallback-icon {
349
+ position: absolute;
350
+ top: 50%;
351
+ left: 50%;
352
+ transform: translate(-50%, -50%);
353
+ display: none;
354
+ }
355
+ .skill-name {
356
+ font-size: 0.9rem;
357
+ font-weight: 500;
358
+ color: var(--text-primary);
359
+ margin-bottom: 0.3rem;
360
+ white-space: nowrap;
361
+ overflow: hidden;
362
+ text-overflow: ellipsis;
363
+ width: 100%;
364
+ }
365
+ .skill-percentage {
366
+ font-size: 0.85rem;
367
+ color: var(--text-secondary);
368
+ }
369
+ .skill-percentage-bar {
370
+ position: absolute;
371
+ bottom: 0;
372
+ left: 0;
373
+ height: 8px;
374
+ background-color: var(--accent-primary);
375
+ border-bottom-left-radius: var(--radius-inner);
376
+ border-bottom-right-radius: var(--radius-inner);
377
+ transition: width 0.3s ease-out;
378
+ }
379
+
380
+ @keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
381
+ @keyframes slideInUp{ from { opacity:0; transform:translateY(20px) } to { opacity:1; transform:translateY(0) } }
382
+ @keyframes fadeOut{ from { opacity:1 } to { opacity:0 } }
383
+ @keyframes spin { from { transform:rotate(0deg) } to { transform:rotate(360deg) } }
384
+
385
+ @media (min-width: 768px) {
386
+ .profile-card { max-width: 740px; }
387
+ .profile-header { height: ${avatarDimensions.tablet.headerH}px; }
388
+ .avatar { width: ${avatarDimensions.tablet.avatarH}px; height: ${avatarDimensions.tablet.avatarH}px; top: var(--avatar-tablet-top); border-width: 6px; }
389
+ .profile-body { padding: ${avatarDimensions.tablet.overlap + 20}px 2.5rem 2.5rem; }
390
+ .nickname-text { font-size: 2.2rem; }
391
+ .skills-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
392
+ }
393
+
394
+ @media (min-width: 1024px) {
395
+ .profile-card { max-width: 840px; }
396
+ .profile-header { height: ${avatarDimensions.desktop.headerH}px; }
397
+ .avatar { width: ${avatarDimensions.desktop.avatarH}px; height: ${avatarDimensions.desktop.avatarH}px; top: var(--avatar-desktop-top); border-width: 7px; }
398
+ .profile-body { padding: ${avatarDimensions.desktop.overlap + 25}px 3rem 3rem; }
399
+ .nickname-text { font-size: 2.5rem; }
400
+ .skills-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
401
+ }
402
+ `}</style>
403
+
404
+ <Show when={status().message && !loading()}>
405
+ <div class="status-message-container">
406
+ <div class={`status-message ${status().type}`}>{status().message}</div>
407
+ </div>
408
+ </Show>
409
+
410
+ <div class="profile-container">
411
+ <Show when={!loading() && userData()}
412
+ fallback={
413
+ <div class="initial-load-container">
414
+ <Show when={loading()} fallback={<p>{status().message || 'Could not load profile.'}</p>}>
415
+ <Spinner />
416
+ <p>Loading Profile...</p>
417
+ </Show>
418
+ </div>
419
+ }
420
+ >
421
+ <div class="profile-card">
422
+ <Show when={loading()}><div class="loading-overlay"><Spinner/></div></Show>
423
+
424
+ <div class="profile-header">
425
+ <img class="cover-photo" src={userData()?.cover_photo || `https://source.unsplash.com/random/1600x600/?abstract,dark`} alt="Cover photo" onClick={() => openImageModal('cover_photo')} />
426
+ </div>
427
+
428
+ <img class="avatar" src={userData()?.avatar || `https://api.dicebear.com/8.x/initials/svg?seed=${encodeURIComponent(userData()?.user || 'U')}`} alt="User avatar" onClick={() => openImageModal('avatar')} />
429
+
430
+ <div class="profile-body">
431
+ <div class="nickname-container">
432
+ <Show when={editingNickname()} fallback={
433
+ <>
434
+ <h1 class="nickname-text">{userData()?.nickname || userData()?.user}</h1>
435
+ <button class="edit-icon-btn" title="Edit Nickname" onClick={() => { setNickname(userData()?.nickname || userData()?.user || ''); setEditingNickname(true); }}>
436
+ <IconPencil />
437
+ </button>
438
+ </>
439
+ }>
440
+ <div class="edit-controls">
441
+ <input type="text" value={nickname()} onInput={(e) => setNickname(e.currentTarget.value)} />
442
+ <div class="edit-controls-buttons">
443
+ <button class="btn btn-secondary" onClick={() => setEditingNickname(false)}>Cancel</button>
444
+ <button class="btn btn-primary" onClick={() => handleUpdate('nickname', nickname(), setEditingNickname)}>Save</button>
445
+ </div>
446
+ </div>
447
+ </Show>
448
+ </div>
449
+ <p class="user-details">@{userData()?.user} &bull; ID: {userData()?.id}</p>
450
+
451
+ <Show when={userData()?.activePlan?.plan}>
452
+ <div class="active-plan-container" style={{
453
+ backgroundColor: activePlanStyles().cardGrad1,
454
+ color: activePlanStyles().textColor,
455
+ border: `1px solid ${activePlanStyles().cardBorder}`,
456
+ boxShadow: `0 2px 8px ${activePlanStyles().glowColor}`
457
+ }}>
458
+ {userData()?.activePlan?.plan}
459
+ </div>
460
+ </Show>
461
+
462
+ <div class="bio-section">
463
+ <h3>About Me
464
+ <Show when={!editingBio()}>
465
+ <button class="edit-icon-btn" title="Edit Bio" onClick={() => { setBio(userData()?.bio || ''); setEditingBio(true); }}>
466
+ <IconPencil /> Edit
467
+ </button>
468
+ </Show>
469
+ </h3>
470
+ <Show when={editingBio()} fallback={
471
+ <p class="bio-text">{userData()?.bio || 'No bio yet. Click edit to add one!'}</p>
472
+ }>
473
+ <div class="edit-controls">
474
+ <textarea rows="4" value={bio()} onInput={(e) => setBio(e.currentTarget.value)}></textarea>
475
+ <div class="edit-controls-buttons">
476
+ <button class="btn btn-secondary" onClick={() => setEditingBio(false)}>Cancel</button>
477
+ <button class="btn btn-primary" onClick={() => handleUpdate('bio', bio(), setEditingBio)}>Save Bio</button>
478
+ </div>
479
+ </div>
480
+ </Show>
481
+ </div>
482
+
483
+ <Show when={projectSkills() && projectSkills().skills && projectSkills().skills.length > 0}>
484
+ <div class="skills-section">
485
+ <h3>Project Skills</h3>
486
+ <p class="project-name">Analyzing: {getBasename(projectSkills().project)}</p>
487
+ <div class="skills-grid">
488
+ <For each={projectSkills().skills}>
489
+ {(skill) => (
490
+ <div class="skill-item">
491
+ <div class="skill-icon-container">
492
+ {getSkillIcon(skill.extension, skill.name)}
493
+ <span class="fallback-icon">
494
+ <IconCode />
495
+ </span>
496
+ </div>
497
+ <div class="skill-name" title={skill.name}>{skill.name}</div>
498
+ <div class="skill-percentage">{skill.skill}</div>
499
+ <div class="skill-percentage-bar" style={{ width: skill.skill }}></div>
500
+ </div>
501
+ )}
502
+ </For>
503
+ </div>
504
+ </div>
505
+ </Show>
506
+
507
+ </div>
508
+ </div>
509
+ </Show>
510
+
511
+ <Show when={modalOpen()}>
512
+ <div class="modal-overlay" onClick={() => setModalOpen(false)}>
513
+ <div class="modal-content" onClick={(e) => e.stopPropagation()}>
514
+ <h2 style={{margin: "0 0 1.5rem 0"}}>Update Image</h2>
515
+ <div class="modal-buttons">
516
+ <button class="btn btn-primary" onClick={modalAction()}><IconAdd /> Upload New</button>
517
+ <button class="btn btn-secondary" style={{'margin-top': '1rem'}} onClick={() => setModalOpen(false)}>Cancel</button>
518
+ </div>
519
+ </div>
520
+ </div>
521
+ </Show>
522
+ </div>
523
+ </>
524
+ );
525
+ }
526
+
527
+ render(() => <App />, document.getElementById('app'));
exocore-web/public/project.jsx ADDED
@@ -0,0 +1,483 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, createResource, onMount, Show, For } from 'solid-js';
3
+ import { Alert, Spinner } from 'solid-bootstrap';
4
+
5
+ const BASE_URL = '/private/server/exocore/web';
6
+
7
+ const fetchTemplates = async () => {
8
+ const res = await fetch(`${BASE_URL}/templates`, { method: 'POST' });
9
+ if (!res.ok) throw new Error('Failed to fetch templates');
10
+ return res.json();
11
+ };
12
+
13
+ const checkProjectStatus = async () => {
14
+ try {
15
+ const res = await fetch(`${BASE_URL}/project/status`, { method: 'POST' });
16
+ const json = await res.json();
17
+ if (json.exists) window.location.href = `${BASE_URL}/public/dashboard`;
18
+ } catch (err) {
19
+ console.error('Error checking project status:', err);
20
+ }
21
+ };
22
+
23
+ function App() {
24
+ const [templates] = createResource(fetchTemplates);
25
+ const [step, setStep] = createSignal(1); // 1 for source, 2 for project name
26
+ const [projectName, setProjectName] = createSignal('');
27
+ const [selectedTemplateId, setSelectedTemplateId] = createSignal('');
28
+ const [selectedTemplateGitUrl, setSelectedTemplateGitUrl] = createSignal('');
29
+ const [customGitUrl, setCustomGitUrl] = createSignal('');
30
+ const [projectSourceType, setProjectSourceType] = createSignal('template');
31
+
32
+ const [status, setStatus] = createSignal('');
33
+ const [loading, setLoading] = createSignal(false);
34
+
35
+ onMount(() => {
36
+ checkProjectStatus();
37
+ document.body.style = `
38
+ margin: 0;
39
+ font-family: 'Inter', sans-serif;
40
+ background: #0a0a0a;
41
+ color: #e0e0e0;
42
+ line-height: 1.6;
43
+ overflow-x: hidden;
44
+ `;
45
+ const link = document.createElement('link');
46
+ link.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap';
47
+ link.rel = 'stylesheet';
48
+ document.head.appendChild(link);
49
+ });
50
+
51
+ const inputStyle = {
52
+ background: '#2a2a2a',
53
+ color: '#fff',
54
+ border: '1px solid #444',
55
+ padding: '0.8rem 1rem',
56
+ 'border-radius': '8px',
57
+ width: '100%',
58
+ 'font-family': 'inherit',
59
+ 'font-size': '1rem',
60
+ 'box-shadow': 'inset 0 1px 3px rgba(0,0,0,0.3)',
61
+ 'transition': 'border-color 0.2s ease, box-shadow 0.2s ease',
62
+ };
63
+
64
+ const inputFocusStyle = {
65
+ 'border-color': '#007bff',
66
+ 'box-shadow': '0 0 0 3px rgba(0, 123, 255, 0.25)',
67
+ };
68
+
69
+ const buttonPrimaryColor = '#007bff';
70
+ const buttonHoverColor = '#0056b3';
71
+ const buttonSecondaryColor = '#555';
72
+ const buttonSecondaryHoverColor = '#777';
73
+
74
+ const customRadioContainerStyle = {
75
+ 'display': 'flex',
76
+ 'align-items': 'center',
77
+ 'cursor': 'pointer',
78
+ 'user-select': 'none',
79
+ 'margin-right': '1.5rem',
80
+ };
81
+
82
+ const hiddenRadioInputStyle = {
83
+ 'position': 'absolute',
84
+ 'opacity': '0',
85
+ 'width': '0',
86
+ 'height': '0',
87
+ };
88
+
89
+ const customRadioIndicatorStyle = {
90
+ 'display': 'inline-block',
91
+ 'width': '20px',
92
+ 'height': '20px',
93
+ 'border': '2px solid #666',
94
+ 'border-radius': '50%',
95
+ 'margin-right': '0.8rem',
96
+ 'position': 'relative',
97
+ 'transition': 'all 0.2s ease-in-out',
98
+ 'flex-shrink': 0,
99
+ };
100
+
101
+ const customRadioIndicatorCheckedStyle = {
102
+ 'border-color': buttonPrimaryColor,
103
+ 'background-color': buttonPrimaryColor,
104
+ 'box-shadow': `0 0 0 4px rgba(0, 123, 255, 0.3)`,
105
+ };
106
+
107
+ const customRadioInnerDotStyle = {
108
+ 'position': 'absolute',
109
+ 'top': '50%',
110
+ 'left': '50%',
111
+ 'transform': 'translate(-50%, -50%)',
112
+ 'width': '10px',
113
+ 'height': '10px',
114
+ 'border-radius': '50%',
115
+ 'background': '#fff',
116
+ 'opacity': '0',
117
+ 'transition': 'opacity 0.2s ease-in-out',
118
+ };
119
+
120
+ const customRadioInnerDotCheckedStyle = {
121
+ 'opacity': '1',
122
+ };
123
+
124
+ const templateCardStyle = (isSelected) => ({
125
+ padding: '1.2rem',
126
+ border: `1px solid ${isSelected ? buttonPrimaryColor : '#333'}`,
127
+ 'border-radius': '10px',
128
+ cursor: 'pointer',
129
+ background: isSelected ? '#2a2a3a' : '#1f1f1f',
130
+ 'transition': 'all 0.2s ease-in-out',
131
+ 'display': 'flex',
132
+ 'flex-direction': 'column',
133
+ 'align-items': 'flex-start',
134
+ 'gap': '0.8rem',
135
+ '&:hover': {
136
+ background: '#252525',
137
+ 'border-color': isSelected ? buttonPrimaryColor : '#666'
138
+ },
139
+ 'box-shadow': isSelected ? `0 0 10px rgba(0, 123, 255, 0.4)` : 'none'
140
+ });
141
+
142
+ const templateImageStyle = {
143
+ 'width': '70px',
144
+ 'height': '70px',
145
+ 'object-fit': 'contain',
146
+ 'border-radius': '8px',
147
+ 'background': '#3a3a3a',
148
+ 'padding': '5px',
149
+ };
150
+
151
+ const templateDescriptionStyle = {
152
+ 'font-size': '0.9rem',
153
+ 'color': '#bbb',
154
+ 'line-height': '1.4'
155
+ };
156
+
157
+ const isNextDisabledStep1 = () => {
158
+ if (projectSourceType() === 'template' && !selectedTemplateId()) return true;
159
+ if (projectSourceType() === 'gitUrl' && !customGitUrl().trim()) return true;
160
+ return false;
161
+ };
162
+
163
+ const isCreateDisabledStep2 = () => {
164
+ return loading() || !projectName().trim();
165
+ };
166
+
167
+
168
+ const handleProceedToNameStep = () => {
169
+ if (isNextDisabledStep1()) return;
170
+ setStep(2);
171
+ };
172
+
173
+ const handleBackToSourceStep = () => {
174
+ setStep(1);
175
+ setStatus('');
176
+ };
177
+
178
+ const handleCreateProject = async () => {
179
+ setLoading(true);
180
+ setStatus('');
181
+
182
+ const finalName = projectName().trim();
183
+ if (!finalName) {
184
+ setStatus('Project name cannot be empty');
185
+ setLoading(false);
186
+ return;
187
+ }
188
+
189
+ let gitToUse = '';
190
+ if (projectSourceType() === 'template') {
191
+ const chosenTemplate = templates()?.find(t => t.id === selectedTemplateId());
192
+ if (chosenTemplate) {
193
+ gitToUse = chosenTemplate.git;
194
+ } else {
195
+ setStatus('Error: Selected template not found.');
196
+ setLoading(false);
197
+ return;
198
+ }
199
+ } else { // 'gitUrl'
200
+ gitToUse = customGitUrl().trim();
201
+ if (!gitToUse) {
202
+ setStatus('Git URL cannot be empty.');
203
+ setLoading(false);
204
+ return;
205
+ }
206
+ }
207
+
208
+ try {
209
+ const payload = {
210
+ name: finalName,
211
+ gitUrl: gitToUse,
212
+ };
213
+ const res = await fetch(`${BASE_URL}/project`, {
214
+ method: 'POST',
215
+ headers: { 'Content-Type': 'application/json' },
216
+ body: JSON.stringify(payload),
217
+ });
218
+ const text = await res.text();
219
+ if (res.ok) {
220
+ setStatus(`Success: ${text}`);
221
+ setTimeout(() => window.location.href = `${BASE_URL}/public/dashboard`, 1500);
222
+ } else {
223
+ setStatus(`Failed: ${text || 'Unknown error'}`);
224
+ }
225
+ } catch (err) {
226
+ setStatus(`Error: ${err.message}`);
227
+ } finally {
228
+ setLoading(false);
229
+ }
230
+ };
231
+
232
+
233
+ return (
234
+ <div style={{ display: 'flex', 'justify-content': 'center', 'align-items': 'center', 'min-height': '100vh', padding: '2vh 1vw' }}>
235
+ <div style={{
236
+ width: '100%',
237
+ 'max-width': '600px',
238
+ background: '#1a1a1a',
239
+ padding: '2.5rem',
240
+ 'border-radius': '16px',
241
+ 'box-shadow': '0 10px 30px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.05)',
242
+ 'border': '1px solid rgba(255,255,255,0.08)'
243
+ }}>
244
+ <h2 style={{
245
+ 'text-align': 'center',
246
+ 'margin-bottom': '2.5rem',
247
+ 'font-size': '2rem',
248
+ 'color': '#fff',
249
+ 'text-shadow': '0 0 8px rgba(255,255,255,0.1)'
250
+ }}>✨ Create New Project ✨</h2>
251
+
252
+ <Show when={step() === 1}>
253
+ <h3 style={{ 'margin-bottom': '1.5rem', 'font-size': '1.5rem', 'color': '#fff' }}>Choose Project Source</h3>
254
+
255
+ <div style={{ marginBottom: '2rem' }}>
256
+ <div style={{ 'display': 'flex', 'gap': '1.5rem' }}>
257
+ <label style={customRadioContainerStyle}>
258
+ <input
259
+ type="radio"
260
+ name="projectSource"
261
+ checked={projectSourceType() === 'template'}
262
+ onChange={() => setProjectSourceType('template')}
263
+ style={hiddenRadioInputStyle}
264
+ />
265
+ <span style={{
266
+ ...customRadioIndicatorStyle,
267
+ ...(projectSourceType() === 'template' && customRadioIndicatorCheckedStyle)
268
+ }}>
269
+ <div style={{
270
+ ...customRadioInnerDotStyle,
271
+ ...(projectSourceType() === 'template' && customRadioInnerDotCheckedStyle)
272
+ }}></div>
273
+ </span>
274
+ Template
275
+ </label>
276
+ <label style={customRadioContainerStyle}>
277
+ <input
278
+ type="radio"
279
+ name="projectSource"
280
+ checked={projectSourceType() === 'gitUrl'}
281
+ onChange={() => setProjectSourceType('gitUrl')}
282
+ style={hiddenRadioInputStyle}
283
+ />
284
+ <span style={{
285
+ ...customRadioIndicatorStyle,
286
+ ...(projectSourceType() === 'gitUrl' && customRadioIndicatorCheckedStyle)
287
+ }}>
288
+ <div style={{
289
+ ...customRadioInnerDotStyle,
290
+ ...(projectSourceType() === 'gitUrl' && customRadioInnerDotCheckedStyle)
291
+ }}></div>
292
+ </span>
293
+ Git URL
294
+ </label>
295
+ </div>
296
+ </div>
297
+
298
+ <Show when={projectSourceType() === 'template'}>
299
+ <label style={{ 'display': 'block', 'margin-bottom': '1rem', 'font-weight': '500', 'color': '#ccc' }}>Select a Template</label>
300
+ <div style={{
301
+ 'max-height': '400px',
302
+ 'overflow-y': 'auto',
303
+ 'padding-right': '10px',
304
+ 'margin-bottom': '2rem',
305
+ 'display': 'grid',
306
+ 'grid-template-columns': 'repeat(auto-fill, minmax(200px, 1fr))',
307
+ 'gap': '1rem',
308
+ }}>
309
+ <Show when={templates.loading}>
310
+ <p style={{ 'color': '#aaa', 'text-align': 'center', 'grid-column': '1 / -1' }}>Loading templates...</p>
311
+ </Show>
312
+ <Show when={templates.error}>
313
+ <p style={{ 'color': '#f8d7da', 'text-align': 'center', 'grid-column': '1 / -1' }}>Error loading templates: {templates.error.message}</p>
314
+ </Show>
315
+ <For each={templates()}>{tpl => (
316
+ <div
317
+ style={templateCardStyle(selectedTemplateId() === tpl.id)}
318
+ onClick={() => {
319
+ setSelectedTemplateId(tpl.id);
320
+ setSelectedTemplateGitUrl(tpl.git);
321
+ }}
322
+ >
323
+ <img src={tpl.image} alt={tpl.name} style={templateImageStyle} />
324
+ <h4 style={{ 'margin': '0', 'color': '#fff', 'font-size': '1.1rem' }}>{tpl.name}</h4>
325
+ <p style={templateDescriptionStyle}>{tpl.describe}</p>
326
+ </div>
327
+ )}</For>
328
+ <Show when={!templates.loading && !templates.error && templates()?.length === 0}>
329
+ <p style={{ 'color': '#aaa', 'text-align': 'center', 'grid-column': '1 / -1' }}>No templates available.</p>
330
+ </Show>
331
+ </div>
332
+ </Show>
333
+
334
+ <Show when={projectSourceType() === 'gitUrl'}>
335
+ <div style={{ marginBottom: '2rem' }}>
336
+ <label style={{ 'display': 'block', 'margin-bottom': '0.8rem', 'font-weight': '500', 'color': '#ccc' }}>Git Repository URL</label>
337
+ <input
338
+ type="text"
339
+ placeholder="https://github.com/user/repo.git"
340
+ value={customGitUrl()}
341
+ onInput={e => setCustomGitUrl(e.currentTarget.value)}
342
+ style={{ ...inputStyle, ...(customGitUrl() && inputFocusStyle) }}
343
+ onFocus={e => e.currentTarget.style.borderColor = inputFocusStyle['border-color']}
344
+ onBlur={e => e.currentTarget.style.borderColor = inputStyle.border.split(' ')[2]}
345
+ disabled={loading()}
346
+ />
347
+ </div>
348
+ </Show>
349
+
350
+ <div style={{ 'display': 'flex', 'justify-content': 'flex-end', 'gap': '0.8rem' }}>
351
+ <button
352
+ onClick={() => { /* Implement close/cancel logic, e.g., redirect or reset form */ alert("Close/Cancel action not yet implemented."); }}
353
+ style={{
354
+ padding: '0.7rem 1.4rem',
355
+ background: buttonSecondaryColor,
356
+ color: 'white',
357
+ border: 'none',
358
+ 'border-radius': '8px',
359
+ 'font-size': '1rem',
360
+ cursor: 'pointer',
361
+ 'transition': 'background 0.3s ease'
362
+ }}
363
+ onMouseEnter={(e) => e.currentTarget.style.background = buttonSecondaryHoverColor}
364
+ onMouseLeave={(e) => e.currentTarget.style.background = buttonSecondaryColor}
365
+ >
366
+ Close
367
+ </button>
368
+ <button
369
+ onClick={handleProceedToNameStep}
370
+ disabled={isNextDisabledStep1()}
371
+ style={{
372
+ padding: '0.7rem 1.4rem',
373
+ background: !isNextDisabledStep1() ? buttonPrimaryColor : buttonSecondaryColor,
374
+ color: 'white',
375
+ border: 'none',
376
+ 'border-radius': '8px',
377
+ 'font-size': '1rem',
378
+ cursor: !isNextDisabledStep1() ? 'pointer' : 'not-allowed',
379
+ opacity: !isNextDisabledStep1() ? 1 : 0.6,
380
+ 'transition': 'background 0.3s ease'
381
+ }}
382
+ onMouseEnter={(e) => e.currentTarget.style.background = !isNextDisabledStep1() ? buttonHoverColor : buttonSecondaryColor}
383
+ onMouseLeave={(e) => e.currentTarget.style.background = !isNextDisabledStep1() ? buttonPrimaryColor : buttonSecondaryColor}
384
+ >
385
+ Next &raquo;
386
+ </button>
387
+ </div>
388
+ </Show>
389
+
390
+ <Show when={step() === 2}>
391
+ <h3 style={{ 'margin-bottom': '1.5rem', 'font-size': '1.5rem', 'color': '#fff' }}>Name Your Project</h3>
392
+
393
+ <div style={{ marginBottom: '3rem' }}>
394
+ <label style={{ 'display': 'block', 'margin-bottom': '0.8rem', 'font-weight': '500', 'color': '#ccc' }}>Project Name</label>
395
+ <input
396
+ type="text"
397
+ placeholder="e.g. my-awesome-app"
398
+ value={projectName()}
399
+ onInput={e => setProjectName(e.currentTarget.value)}
400
+ style={{ ...inputStyle, ...(projectName() && inputFocusStyle) }}
401
+ onFocus={e => e.currentTarget.style.borderColor = inputFocusStyle['border-color']}
402
+ onBlur={e => e.currentTarget.style.borderColor = inputStyle.border.split(' ')[2]}
403
+ disabled={loading()}
404
+ />
405
+ </div>
406
+
407
+ <div style={{ 'display': 'flex', 'justify-content': 'space-between', 'align-items': 'center', 'gap': '0.8rem' }}>
408
+ <button
409
+ onClick={handleBackToSourceStep}
410
+ style={{
411
+ padding: '0.7rem 1.4rem',
412
+ background: buttonSecondaryColor,
413
+ color: 'white',
414
+ border: 'none',
415
+ 'border-radius': '8px',
416
+ 'font-size': '1rem',
417
+ cursor: 'pointer',
418
+ 'transition': 'background 0.3s ease'
419
+ }}
420
+ onMouseEnter={(e) => e.currentTarget.style.background = buttonSecondaryHoverColor}
421
+ onMouseLeave={(e) => e.currentTarget.style.background = buttonSecondaryColor}
422
+ >
423
+ &laquo; Back
424
+ </button>
425
+ <button
426
+ onClick={handleCreateProject}
427
+ disabled={isCreateDisabledStep2()}
428
+ style={{
429
+ padding: '1rem',
430
+ background: buttonPrimaryColor,
431
+ color: 'white',
432
+ border: 'none',
433
+ 'border-radius': '10px',
434
+ 'font-size': '1.1rem',
435
+ 'font-weight': '700',
436
+ cursor: isCreateDisabledStep2() ? 'not-allowed' : 'pointer',
437
+ opacity: isCreateDisabledStep2() ? 0.6 : 1,
438
+ 'box-shadow': `0 4px 15px rgba(0, 123, 255, 0.4)`,
439
+ 'transition': 'background 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease',
440
+ '&:hover': {
441
+ background: buttonHoverColor,
442
+ transform: isCreateDisabledStep2() ? 'none' : 'translateY(-2px)',
443
+ 'box-shadow': isCreateDisabledStep2() ? `0 4px 15px rgba(0, 123, 255, 0.4)` : `0 6px 20px rgba(0, 123, 255, 0.6)`
444
+ },
445
+ '&:active': {
446
+ transform: isCreateDisabledStep2() ? 'none' : 'translateY(0)',
447
+ 'box-shadow': isCreateDisabledStep2() ? `0 2px 10px rgba(0, 123, 255, 0.3)` : `0 2px 10px rgba(0, 123, 255, 0.3)`
448
+ }
449
+ }}
450
+ >
451
+ {loading() ? (
452
+ <span style={{ display: 'flex', 'align-items': 'center', 'justify-content': 'center', 'gap': '0.5rem' }}>
453
+ <Spinner animation="border" size="sm" /> Creating...
454
+ </span>
455
+ ) : '🚀 Create Project'}
456
+ </button>
457
+ </div>
458
+ </Show>
459
+
460
+ <Show when={status()}>
461
+ <Alert
462
+ class="mt-4"
463
+ variant={status().startsWith('Success') ? 'success' : 'danger'}
464
+ style={{
465
+ 'text-align': 'center',
466
+ marginTop: '1.5rem',
467
+ 'border-radius': '8px',
468
+ 'padding': '0.8rem 1rem',
469
+ 'font-size': '0.95rem',
470
+ 'background-color': status().startsWith('Success') ? 'rgba(0, 128, 0, 0.3)' : 'rgba(255, 0, 0, 0.3)',
471
+ 'color': status().startsWith('Success') ? '#a0ffa0' : '#ffafaf',
472
+ 'border-color': status().startsWith('Success') ? 'rgba(0, 128, 0, 0.5)' : 'rgba(255, 0, 0, 0.5)'
473
+ }}
474
+ >
475
+ {status()}
476
+ </Alert>
477
+ </Show>
478
+ </div>
479
+ </div>
480
+ );
481
+ }
482
+
483
+ render(() => <App />, document.getElementById('app'));
exocore-web/public/register.jsx ADDED
@@ -0,0 +1,338 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, Show } from 'solid-js';
3
+ import flatpickr from 'flatpickr';
4
+ import 'flatpickr/dist/themes/dark.css';
5
+
6
+ // SVG Icon Components
7
+ const IconEye = () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>;
8
+ const IconEyeOff = () => <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>;
9
+ const IconUpload = () => <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>;
10
+
11
+ function App() {
12
+ // State signals for form data and UI status
13
+ const [loading, setLoading] = createSignal(false);
14
+ const [status, setStatus] = createSignal('');
15
+ const [showPassword, setShowPassword] = createSignal(false);
16
+ const [passwordWarning, setPasswordWarning] = createSignal('');
17
+ const [form, setForm] = createSignal({ user: '', pass: '', email: '', avatar: '', bio: '', nickname: '', dob: '', cover_photo: '', country: '', timezone: '' });
18
+ const [avatarFileName, setAvatarFileName] = createSignal('');
19
+ const [coverPhotoFileName, setCoverPhotoFileName] = createSignal('');
20
+ const [validationErrors, setValidationErrors] = createSignal({});
21
+
22
+ // Refs for file input elements
23
+ let avatarInputRef, coverPhotoInputRef;
24
+
25
+ /**
26
+ * Redirects the user to the dashboard if they are already logged in.
27
+ * Checks for authentication tokens in localStorage.
28
+ */
29
+ function LoggedAlready() {
30
+ if (localStorage.getItem('exocore-token') && localStorage.getItem('exocore-cookies')) {
31
+ window.location.href = '/private/server/exocore/web/public/dashboard';
32
+ }
33
+ }
34
+
35
+ // Lifecycle hook: runs once after the component mounts
36
+ onMount(() => {
37
+ fetchLocation();
38
+ initDatePicker();
39
+ LoggedAlready();
40
+ setInterval(LoggedAlready, 5000); // Periodically check login status
41
+ });
42
+
43
+ /**
44
+ * Initializes the flatpickr date picker on the date of birth input.
45
+ */
46
+ function initDatePicker() {
47
+ setTimeout(() => {
48
+ const dobInput = document.getElementById('dob');
49
+ if (dobInput) {
50
+ flatpickr(dobInput, {
51
+ dateFormat: 'Y-m-d',
52
+ maxDate: 'today',
53
+ altInput: true,
54
+ altFormat: 'F j, Y',
55
+ appendTo: window.document.body,
56
+ onChange: (_, dateStr) => updateField('dob', dateStr),
57
+ });
58
+ }
59
+ }, 100);
60
+ }
61
+
62
+ /**
63
+ * Fetches the user's country and timezone based on their IP address.
64
+ */
65
+ async function fetchLocation() {
66
+ try {
67
+ const res = await fetch('https://ipwho.is/');
68
+ const data = await res.json();
69
+ if (data.success) {
70
+ setForm((prev) => ({ ...prev, country: data.country || '', timezone: data.timezone?.id || '' }));
71
+ }
72
+ } catch (err) {
73
+ console.error('Error fetching location:', err);
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Handles file selection for avatar and cover photo, updating the form state.
79
+ * @param {string} field - The form field to update ('avatar' or 'cover_photo').
80
+ * @param {Event} event - The file input change event.
81
+ */
82
+ function handleFileChange(field, event) {
83
+ const file = event.currentTarget.files[0];
84
+ const targetSignal = field === 'avatar' ? setAvatarFileName : setCoverPhotoFileName;
85
+ if (!file) {
86
+ targetSignal('');
87
+ setForm((prev) => ({ ...prev, [field]: '' }));
88
+ return;
89
+ }
90
+ targetSignal(file.name);
91
+ const reader = new FileReader();
92
+ reader.onload = () => updateField(field, reader.result);
93
+ reader.readAsDataURL(file);
94
+ }
95
+
96
+ /**
97
+ * Validates and submits the registration form data to the server.
98
+ * @param {Event} e - The form submission event.
99
+ */
100
+ async function handleSubmit(e) {
101
+ e.preventDefault();
102
+ setLoading(true);
103
+ setStatus('');
104
+ setValidationErrors({});
105
+
106
+ const currentForm = form();
107
+ // All fields are now required
108
+ const requiredFields = ['user', 'email', 'pass', 'nickname', 'dob', 'country', 'timezone', 'bio', 'avatar', 'cover_photo'];
109
+ const errors = {};
110
+
111
+ // Check for empty required fields
112
+ requiredFields.forEach(field => {
113
+ if (!currentForm[field]) {
114
+ const fieldName = {
115
+ user: 'Username',
116
+ pass: 'Password',
117
+ dob: 'Date of Birth',
118
+ bio: 'Short Bio',
119
+ avatar: 'Avatar',
120
+ cover_photo: 'Cover Photo'
121
+ }[field] || field.charAt(0).toUpperCase() + field.slice(1);
122
+ errors[field] = `${fieldName} is required.`;
123
+ }
124
+ });
125
+
126
+ // If there are validation errors, update state and stop submission
127
+ if (Object.keys(errors).length > 0) {
128
+ setValidationErrors(errors);
129
+ setStatus('Please complete all required fields.');
130
+ setLoading(false);
131
+ return;
132
+ }
133
+
134
+ // Check for password strength issues
135
+ if (passwordWarning()) {
136
+ setStatus('Please correct the password issues before submitting.');
137
+ setLoading(false);
138
+ return;
139
+ }
140
+
141
+ // Attempt to submit the form data
142
+ try {
143
+ const res = await fetch('/private/server/exocore/web/register', {
144
+ method: 'POST',
145
+ headers: { 'Content-Type': 'application/json' },
146
+ body: JSON.stringify(currentForm),
147
+ });
148
+ const responseData = await res.json();
149
+ if (!res.ok) throw new Error(responseData?.message || `Server error: ${res.status}`);
150
+ setStatus('Registration successful! Redirecting to login...');
151
+ setTimeout(() => { window.location.href = '/private/server/exocore/web/public/login'; }, 2000);
152
+ } catch (err) {
153
+ setStatus(err.message);
154
+ }
155
+ setLoading(false);
156
+ }
157
+
158
+ /**
159
+ * Updates a form field's value in the state and performs validation.
160
+ * @param {string} field - The name of the field to update.
161
+ * @param {string} value - The new value for the field.
162
+ */
163
+ function updateField(field, value) {
164
+ let processedValue = (field === 'user' || field === 'email' || field === 'pass')
165
+ ? value.replace(/\s/g, '')
166
+ : value;
167
+
168
+ // Password strength validation
169
+ if (field === 'pass') {
170
+ const warnings = [];
171
+ if (processedValue.length > 0) {
172
+ if (processedValue.length < 8) warnings.push('be at least 8 characters');
173
+ if (!/\d/.test(processedValue)) warnings.push('include a number');
174
+ if (!/[!@#$%^&*(),.?":{}|<>]/.test(processedValue)) warnings.push('include a symbol');
175
+ }
176
+ setPasswordWarning(warnings.length > 0 ? 'Password must ' + warnings.join(', ') + '.' : '');
177
+ }
178
+
179
+ setForm((prev) => ({ ...prev, [field]: processedValue }));
180
+
181
+ // Clear the validation error for the field being edited
182
+ if (validationErrors()[field]) {
183
+ setValidationErrors(prev => {
184
+ const newErrors = { ...prev };
185
+ delete newErrors[field];
186
+ return newErrors;
187
+ });
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Determines if the submit button should be disabled based on form completion and validity.
193
+ * @returns {boolean} True if the button should be disabled.
194
+ */
195
+ const isSubmitDisabled = () => {
196
+ const f = form();
197
+ const requiredFields = ['user', 'email', 'pass', 'nickname', 'dob', 'country', 'timezone', 'bio', 'avatar', 'cover_photo'];
198
+ const hasEmptyFields = requiredFields.some(field => !f[field]);
199
+ return loading() || !!passwordWarning() || hasEmptyFields;
200
+ };
201
+
202
+ return (
203
+ <div class="register-page-wrapper">
204
+ <style>{`
205
+ :root {
206
+ --bg-primary: #111217; --bg-secondary: #1a1b23; --text-primary: #e0e0e0;
207
+ --text-secondary: #8a8f98; --accent-primary: #00aaff; --accent-secondary: #0088cc;
208
+ --border-color: rgba(255, 255, 255, 0.1); --shadow-color: rgba(0, 0, 0, 0.5);
209
+ --radius-main: 16px; --radius-inner: 12px;
210
+ --font-body: 'Roboto', sans-serif;
211
+ --success-color: #2ecc71; --error-color: #e74c3c;
212
+ }
213
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
214
+ body { background-color: var(--bg-primary); font-family: var(--font-body); margin: 0; }
215
+ .register-page-wrapper { display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: 2rem; box-sizing: border-box; }
216
+ .register-card { background: var(--bg-secondary); width: 100%; max-width: 600px; padding: 2.5rem; border-radius: var(--radius-main); border: 1px solid var(--border-color); box-shadow: 0 15px 40px var(--shadow-color); animation: fadeIn 0.5s ease-out; }
217
+ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
218
+ .register-header { text-align: center; margin-bottom: 2.5rem; color: var(--text-primary); font-size: 2rem; font-weight: 700; }
219
+ .form-grid { display: grid; grid-template-columns: 1fr; gap: 1.5rem; }
220
+ @media (min-width: 768px) { .form-grid { grid-template-columns: 1fr 1fr; } .full-width { grid-column: 1 / -1; } }
221
+ .form-group { display: flex; flex-direction: column; }
222
+ .form-label { margin-bottom: 0.5rem; color: var(--text-secondary); font-weight: 500; }
223
+ .input-wrapper { position: relative; }
224
+ .form-input, .form-textarea { width: 100%; padding: 0.9rem 1rem; border: 1px solid var(--border-color); border-radius: var(--radius-inner); font-family: var(--font-body); font-size: 1rem; background-color: var(--bg-primary); color: var(--text-primary); box-sizing: border-box; transition: border-color 0.2s, box-shadow 0.2s; }
225
+ .form-input:focus, .form-textarea:focus { outline:0; border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(0, 170, 255, 0.2); }
226
+ .input-error { border-color: var(--error-color) !important; }
227
+ .input-error:focus { box-shadow: 0 0 0 3px rgba(231, 76, 60, 0.2) !important; }
228
+ .form-textarea { min-height: 80px; resize: vertical; }
229
+ .password-toggle { position: absolute; right: 1rem; top: 50%; transform: translateY(-50%); background: none; border: none; color: var(--text-secondary); cursor: pointer; display: flex; align-items: center; }
230
+ .field-error-message, .password-warning { font-size: 0.875rem; color: var(--error-color); margin-top: 0.5rem; }
231
+ .file-upload-btn { display: flex; align-items: center; gap: 0.75rem; padding: 0.9rem 1rem; background-color: var(--bg-primary); border: 1px solid var(--border-color); border-radius: var(--radius-inner); cursor: pointer; transition: background-color 0.2s, border-color 0.2s; overflow: hidden; }
232
+ .file-upload-btn:hover { background-color: #2a2c3b; }
233
+ .file-name { color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; text-align: left; }
234
+ .register-btn { width: 100%; padding: 1rem 1.5rem; border: none; border-radius: var(--radius-inner); background: linear-gradient(to right, var(--accent-primary), var(--accent-secondary)); color: #fff; font-size: 1.1rem; font-weight: 700; cursor: pointer; transition: all 0.2s ease; margin-top: 1.5rem; }
235
+ .register-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 170, 255, 0.2); }
236
+ .register-btn:disabled { opacity: 0.6; cursor: not-allowed; }
237
+ .status-message { text-align: center; margin-top: 1.5rem; padding: 0.8rem; border-radius: var(--radius-inner); font-weight: 500; }
238
+ .status-success { background-color: rgba(46, 204, 113, 0.15); color: var(--success-color); border: 1px solid var(--success-color); }
239
+ .status-error { background-color: rgba(231, 76, 60, 0.15); color: var(--error-color); border: 1px solid var(--error-color); }
240
+ .login-link-wrapper { text-align: center; margin-top: 2rem; color: var(--text-secondary); }
241
+ .login-link { color: var(--accent-primary); text-decoration: none; font-weight: 500; }
242
+ `}</style>
243
+ <div class="register-card">
244
+ <h1 class="register-header">Create Your Account</h1>
245
+ <form onSubmit={handleSubmit} novalidate>
246
+ <div class="form-grid">
247
+ {/* Username */}
248
+ <div class="form-group">
249
+ <label class="form-label" for="user">Username</label>
250
+ <input id="user" class="form-input" classList={{ 'input-error': !!validationErrors().user }} type="text" value={form().user} onInput={(e) => updateField('user', e.currentTarget.value)} />
251
+ <Show when={validationErrors().user}><div class="field-error-message">{validationErrors().user}</div></Show>
252
+ </div>
253
+ {/* Email */}
254
+ <div class="form-group">
255
+ <label class="form-label" for="email">Email Address</label>
256
+ <input id="email" class="form-input" classList={{ 'input-error': !!validationErrors().email }} type="email" value={form().email} onInput={(e) => updateField('email', e.currentTarget.value)} />
257
+ <Show when={validationErrors().email}><div class="field-error-message">{validationErrors().email}</div></Show>
258
+ </div>
259
+ {/* Nickname */}
260
+ <div class="form-group">
261
+ <label class="form-label" for="nickname">Display Name (Nickname)</label>
262
+ <input id="nickname" class="form-input" classList={{ 'input-error': !!validationErrors().nickname }} type="text" value={form().nickname} onInput={(e) => updateField('nickname', e.currentTarget.value)} />
263
+ <Show when={validationErrors().nickname}><div class="field-error-message">{validationErrors().nickname}</div></Show>
264
+ </div>
265
+ {/* Password */}
266
+ <div class="form-group">
267
+ <label class="form-label" for="password">Password</label>
268
+ <div class="input-wrapper">
269
+ <input id="password" class="form-input" classList={{ 'input-error': !!validationErrors().pass || !!passwordWarning() }} type={showPassword() ? 'text' : 'password'} value={form().pass} onInput={(e) => updateField('pass', e.currentTarget.value)} />
270
+ <button type="button" class="password-toggle" onClick={() => setShowPassword(!showPassword())}>
271
+ <Show when={showPassword()} fallback={<IconEye />}><IconEyeOff /></Show>
272
+ </button>
273
+ </div>
274
+ <Show when={validationErrors().pass}><div class="field-error-message">{validationErrors().pass}</div></Show>
275
+ <Show when={passwordWarning()}><div class="password-warning">{passwordWarning()}</div></Show>
276
+ </div>
277
+ {/* Date of Birth */}
278
+ <div class="form-group">
279
+ <label class="form-label" for="dob">Date of Birth</label>
280
+ <input id="dob" class="form-input" classList={{ 'input-error': !!validationErrors().dob }} type="text" placeholder="Select your birth date..." readOnly />
281
+ <Show when={validationErrors().dob}><div class="field-error-message">{validationErrors().dob}</div></Show>
282
+ </div>
283
+ {/* Country */}
284
+ <div class="form-group">
285
+ <label class="form-label" for="country">Country</label>
286
+ <input id="country" class="form-input" classList={{ 'input-error': !!validationErrors().country }} type="text" value={form().country} onInput={(e) => updateField('country', e.currentTarget.value)} />
287
+ <Show when={validationErrors().country}><div class="field-error-message">{validationErrors().country}</div></Show>
288
+ </div>
289
+ {/* Timezone */}
290
+ <div class="form-group">
291
+ <label class="form-label" for="timezone">Timezone</label>
292
+ <input id="timezone" class="form-input" classList={{ 'input-error': !!validationErrors().timezone }} type="text" value={form().timezone} onInput={(e) => updateField('timezone', e.currentTarget.value)} />
293
+ <Show when={validationErrors().timezone}><div class="field-error-message">{validationErrors().timezone}</div></Show>
294
+ </div>
295
+ {/* Bio */}
296
+ <div class="form-group full-width">
297
+ <label class="form-label" for="bio">Short Bio</label>
298
+ <textarea id="bio" class="form-textarea" classList={{ 'input-error': !!validationErrors().bio }} value={form().bio} onInput={(e) => updateField('bio', e.currentTarget.value)} />
299
+ <Show when={validationErrors().bio}><div class="field-error-message">{validationErrors().bio}</div></Show>
300
+ </div>
301
+ {/* File Uploads */}
302
+ <div class="form-group full-width">
303
+ <label class="form-label">Profile Images</label>
304
+ <div class="form-grid">
305
+ <button type="button" class="file-upload-btn" classList={{ 'input-error': !!validationErrors().avatar }} onClick={() => avatarInputRef?.click()}>
306
+ <IconUpload />
307
+ <span class="file-name" title={avatarFileName()}>{avatarFileName() || 'Choose Avatar'}</span>
308
+ </button>
309
+ <button type="button" class="file-upload-btn" classList={{ 'input-error': !!validationErrors().cover_photo }} onClick={() => coverPhotoInputRef?.click()}>
310
+ <IconUpload />
311
+ <span class="file-name" title={coverPhotoFileName()}>{coverPhotoFileName() || 'Choose Cover Photo'}</span>
312
+ </button>
313
+ </div>
314
+ <Show when={validationErrors().avatar}><div class="field-error-message">{validationErrors().avatar}</div></Show>
315
+ <Show when={validationErrors().cover_photo && !validationErrors().avatar}><div class="field-error-message">{validationErrors().cover_photo}</div></Show>
316
+ <input type="file" accept="image/*" ref={el => avatarInputRef = el} onInput={(e) => handleFileChange('avatar', e)} style={{ display: 'none' }} />
317
+ <input type="file" accept="image/*" ref={el => coverPhotoInputRef = el} onInput={(e) => handleFileChange('cover_photo', e)} style={{ display: 'none' }} />
318
+ </div>
319
+ </div>
320
+ {/* Submit Button */}
321
+ <button type="submit" class="register-btn" disabled={isSubmitDisabled()}>
322
+ {loading() ? 'Creating Account...' : 'Sign Up'}
323
+ </button>
324
+ {/* Status Message */}
325
+ <Show when={status()}>
326
+ <div class={`status-message ${status().includes('success') ? 'status-success' : 'status-error'}`}>{status()}</div>
327
+ </Show>
328
+ {/* Login Link */}
329
+ <div class="login-link-wrapper">
330
+ Already have an account? <a href="/private/server/exocore/web/public/login" class="login-link">Login here</a>
331
+ </div>
332
+ </form>
333
+ </div>
334
+ </div>
335
+ );
336
+ }
337
+
338
+ render(() => <App />, document.getElementById('app'));
exocore-web/public/shell.jsx ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { render } from 'solid-js/web';
2
+ import { createSignal, onMount, Show } from 'solid-js';
3
+
4
+ const FullscreenIcon = () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" /></svg>;
5
+ const ExitFullscreenIcon = () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" /></svg>;
6
+ const KillIcon = () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18.36 6.64a9 9 0 1 1-12.73 0" /><line x1="12" y1="2" x2="12" y2="12" /></svg>
7
+
8
+ function App() {
9
+ const [loading, setLoading] = createSignal(true);
10
+ const [status, setStatus] = createSignal('');
11
+ const [userData, setUserData] = createSignal(null);
12
+ const [wsStatus, setWsStatus] = createSignal('Disconnected');
13
+ const [isFullScreen, setIsFullScreen] = createSignal(false);
14
+ const [promptText, setPromptText] = createSignal('$ ');
15
+
16
+ let consoleRef, logOutputRef, inputLineRef;
17
+ let ansiUpInstance = null;
18
+
19
+ async function fetchUserInfo() {
20
+ setLoading(true);
21
+ // User info logic is assumed to be correct and unchanged
22
+ setLoading(false);
23
+ }
24
+
25
+ function appendToLog(line, isCommand = false) {
26
+ if (!logOutputRef) return;
27
+ const html = ansiUpInstance ? ansiUpInstance.ansi_to_html(line) : line;
28
+ const logEntry = document.createElement('div');
29
+ logEntry.innerHTML = isCommand ? `<span style="color: var(--accent-secondary);">${promptText()}</span>${html}` : html;
30
+ logOutputRef.appendChild(logEntry);
31
+
32
+ while (logOutputRef.children.length > 250) {
33
+ logOutputRef.removeChild(logOutputRef.firstChild);
34
+ }
35
+ if (consoleRef) {
36
+ requestAnimationFrame(() => consoleRef.scrollTop = consoleRef.scrollHeight);
37
+ }
38
+ }
39
+
40
+ async function sendCommand() {
41
+ if (!inputLineRef) return;
42
+ const cmd = inputLineRef.innerText.trim();
43
+ if (!cmd) return;
44
+ appendToLog(cmd, true);
45
+ inputLineRef.innerText = '';
46
+ try {
47
+ await fetch('/private/server/exocore/web/shell/sent', {
48
+ method: 'POST',
49
+ headers: { 'Content-Type': 'application/json' },
50
+ body: JSON.stringify({ command: cmd }),
51
+ });
52
+ } catch (err) {
53
+ appendToLog(`\x1b[31mFailed to send command: ${err.message}\x1b[0m`);
54
+ }
55
+ }
56
+
57
+ async function handleKillShellCommand() {
58
+ appendToLog('\x1b[33mINFO: Sending kill command...\x1b[0m');
59
+ try {
60
+ await fetch('/private/server/exocore/web/shell/kill', { method: 'POST' });
61
+ } catch (err) {
62
+ appendToLog(`\x1b[31mERROR: Could not send kill command: ${err.message}\x1b[0m`);
63
+ }
64
+ }
65
+
66
+ function toggleFullScreen() {
67
+ const el = document.querySelector('.console-wrapper');
68
+ if (!el) return;
69
+ if (!document.fullscreenElement) {
70
+ el.requestFullscreen().catch(err => appendToLog(`\x1b[31mFullscreen Error: ${err.message}\x1b[0m`));
71
+ } else {
72
+ document.exitFullscreen();
73
+ }
74
+ }
75
+
76
+ onMount(() => {
77
+ const fontLink = document.createElement('link');
78
+ fontLink.href = 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&family=Fira+Code:wght@400;500&display=swap';
79
+ fontLink.rel = 'stylesheet';
80
+ document.head.appendChild(fontLink);
81
+
82
+ const ansiScript = document.createElement('script');
83
+ ansiScript.src = 'https://cdn.jsdelivr.net/npm/[email protected]/ansi_up.min.js';
84
+ ansiScript.onload = () => {
85
+ if (typeof AnsiUp !== 'undefined') {
86
+ ansiUpInstance = new AnsiUp();
87
+ ansiUpInstance.use_classes = false;
88
+ }
89
+ };
90
+ document.head.appendChild(ansiScript);
91
+
92
+ fetchUserInfo();
93
+
94
+ const wsUrl = `${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${window.location.host}/private/server/exocore/web/ws/shell`;
95
+ function connectWebSocket() {
96
+ const ws = new WebSocket(wsUrl);
97
+ ws.onopen = () => setWsStatus('Connected');
98
+ ws.onclose = () => {
99
+ setWsStatus('Disconnected');
100
+ setTimeout(connectWebSocket, 2000);
101
+ };
102
+ ws.onerror = () => setWsStatus('Error');
103
+ ws.onmessage = (e) => {
104
+ try {
105
+ const message = JSON.parse(e.data);
106
+ if (message.type === 'prompt') {
107
+ setPromptText(message.data);
108
+ } else {
109
+ appendToLog(message.data);
110
+ }
111
+ } catch (err) {
112
+ appendToLog(e.data);
113
+ }
114
+ };
115
+ }
116
+ connectWebSocket();
117
+ document.addEventListener('fullscreenchange', () => setIsFullScreen(!!document.fullscreenElement));
118
+ consoleRef?.addEventListener('click', (e) => {
119
+ if (inputLineRef && e.target !== inputLineRef) {
120
+ inputLineRef.focus();
121
+ }
122
+ });
123
+ });
124
+
125
+ return (
126
+ <div class="main-wrapper-shell">
127
+ <style>{`
128
+ :root {
129
+ --bg-primary: #111217; --bg-secondary: #1a1b23; --bg-tertiary: #0D0E12;
130
+ --text-primary: #e0e0e0; --text-secondary: #8a8f98; --accent-primary: #00aaff;
131
+ --accent-secondary: #0088cc; --danger-primary: #e74c3c; --danger-secondary: #c0392b;
132
+ --border-color: rgba(255, 255, 255, 0.1); --shadow-color: rgba(0, 0, 0, 0.5);
133
+ --font-body: 'Roboto', sans-serif; --font-console: 'Fira Code', monospace;
134
+ --radius-main: 16px; --radius-inner: 10px;
135
+ }
136
+ body { background-color: var(--bg-primary); color: var(--text-primary); font-family: var(--font-body); margin: 0; }
137
+ .main-wrapper-shell { display: flex; justify-content: center; align-items: center; padding: 4vh 2vw; min-height: 100vh; }
138
+ .app-container-shell { background: var(--bg-secondary); padding: 2rem; width: 100%; max-width: 900px; border-radius: var(--radius-main); border: 1px solid var(--border-color); box-shadow: 0 15px 40px var(--shadow-color); display: flex; flex-direction: column; gap: 1.5rem; }
139
+ .greeting-header-shell { display: flex; justify-content: space-between; align-items: center; }
140
+ .greeting-shell { font-size: 1.75rem; font-weight: 700; color: #fff; }
141
+ .user-welcome-shell { font-size: 0.9rem; color: var(--text-secondary); }
142
+ .console-wrapper { border-radius: var(--radius-inner); background: var(--bg-tertiary); box-shadow: inset 0 4px 15px rgba(0,0,0,0.4); overflow: hidden; display: flex; flex-direction: column; height: 500px; border: 1px solid var(--border-color); }
143
+ .console-wrapper:fullscreen { width: 100vw; height: 100vh; border-radius: 0; border: none; }
144
+ .console-header { background: var(--bg-secondary); padding: 0.6rem 1rem; display: flex; align-items: center; border-bottom: 1px solid var(--border-color); position: relative; }
145
+ .console-header-dots { display: flex; gap: 8px; }
146
+ .console-header-dots span { width: 12px; height: 12px; border-radius: 50%; }
147
+ .console-header-dots .red-dot { background-color: #ff5f57; }
148
+ .console-header-dots .yellow-dot { background-color: #ffbd2e; }
149
+ .console-header-dots .green-dot { background-color: #28c940; }
150
+ .fullscreen-btn { position: absolute; top: 50%; right: 1rem; transform: translateY(-50%); background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 4px; border-radius: 4px; display: flex; align-items: center; justify-content: center; transition: color 0.2s ease, background-color 0.2s ease; }
151
+ .fullscreen-btn:hover { color: var(--text-primary); background-color: rgba(255,255,255,0.1); }
152
+ .console-container { flex-grow: 1; padding: 1rem; font-family: var(--font-console); font-size: 14px; line-height: 1.6; overflow-y: auto; cursor: text; display: flex; flex-direction: column; }
153
+ .log-output { flex-grow: 1; white-space: pre-wrap; word-break: break-word; }
154
+ .input-area { display: flex; margin-top: 4px; }
155
+ .prompt-text-display { color: var(--accent-primary); margin-right: 8px; user-select: none; }
156
+ .input-line { flex-grow: 1; outline: none; color: var(--text-primary); caret-color: var(--text-primary); }
157
+ .bottom-bar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
158
+ .ws-box { padding: 0.4rem 1rem; border-radius: 99px; font-weight: 500; font-size: 0.8rem; transition: all 0.3s ease; font-family: var(--font-console); }
159
+ .ws-box.connected { background-color: rgba(46, 204, 113, 0.15); color: #2ecc71; }
160
+ .ws-box.disconnected, .ws-box.error { background-color: rgba(231, 76, 60, 0.15); color: var(--danger-primary); }
161
+ .controls-area { display: flex; gap: 0.75rem; }
162
+ .btn-shell { display: flex; align-items: center; gap: 0.5rem; padding: 0.6rem 1.2rem; font-size: 0.9rem; font-weight: 500; color: #fff; border: 1px solid var(--border-color); border-radius: var(--radius-inner); background-color: var(--bg-secondary); cursor: pointer; transition: all 0.2s ease; }
163
+ .btn-shell:hover { background-color: var(--border-color); border-color: rgba(255,255,255,0.2); transform: translateY(-2px); }
164
+ .btn-shell.danger { border-color: var(--danger-primary); color: var(--danger-primary); }
165
+ .btn-shell.danger:hover { background-color: var(--danger-primary); color: #fff; }
166
+ `}</style>
167
+
168
+ <Show when={!loading()} fallback={<div>Loading Shell...</div>}>
169
+ <div class="app-container-shell">
170
+ <div class="greeting-header-shell">
171
+ <h2 class="greeting-shell">Interactive Shell</h2>
172
+ </div>
173
+
174
+ <div class="console-wrapper">
175
+ <div class="console-header">
176
+ <div class="console-header-dots">
177
+ <span class="red-dot"></span><span class="yellow-dot"></span><span class="green-dot"></span>
178
+ </div>
179
+ <button class="fullscreen-btn" onClick={toggleFullScreen} title={isFullScreen() ? 'Exit Fullscreen' : 'Enter Fullscreen'}>
180
+ <Show when={isFullScreen()} fallback={<FullscreenIcon />}>
181
+ <ExitFullscreenIcon />
182
+ </Show>
183
+ </button>
184
+ </div>
185
+ <div class="console-container" ref={consoleRef}>
186
+ <div class="log-output" ref={logOutputRef}></div>
187
+ <div class="input-area">
188
+ <span class="prompt-text-display">{promptText()}</span>
189
+ <div class="input-line"
190
+ contenteditable="true"
191
+ ref={inputLineRef}
192
+ onKeyDown={e => e.key === 'Enter' && (e.preventDefault(), sendCommand())}
193
+ spellcheck="false"
194
+ />
195
+ </div>
196
+ </div>
197
+ </div>
198
+
199
+ <div class="bottom-bar">
200
+ <div class="ws-box" classList={{ connected: wsStatus() === 'Connected', disconnected: wsStatus() !== 'Connected' }}>
201
+ {wsStatus()}
202
+ </div>
203
+ <div class="controls-area">
204
+ <button class="btn-shell danger" onClick={handleKillShellCommand}>
205
+ <KillIcon/> Kill Session
206
+ </button>
207
+ </div>
208
+ </div>
209
+
210
+ </div>
211
+ </Show>
212
+ </div>
213
+ );
214
+ }
215
+ render(() => <App />, document.getElementById('app'));