cyberia 3.2.9 → 3.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/.github/workflows/engine-cyberia.cd.yml +7 -0
  2. package/.github/workflows/engine-cyberia.ci.yml +14 -2
  3. package/.github/workflows/ghpkg.ci.yml +1 -0
  4. package/.github/workflows/npmpkg.ci.yml +10 -5
  5. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  6. package/.github/workflows/release.cd.yml +1 -0
  7. package/.vscode/extensions.json +9 -9
  8. package/.vscode/settings.json +20 -4
  9. package/CHANGELOG.md +363 -1
  10. package/CLI-HELP.md +975 -1061
  11. package/README.md +190 -348
  12. package/bin/build.js +102 -125
  13. package/bin/build.template.js +33 -0
  14. package/bin/cyberia.js +238 -56
  15. package/bin/deploy.js +16 -3
  16. package/bin/index.js +238 -56
  17. package/bump.config.js +26 -0
  18. package/conf.js +131 -24
  19. package/deployment.yaml +76 -2
  20. package/hardhat/package-lock.json +113 -144
  21. package/hardhat/package.json +4 -3
  22. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
  23. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  24. package/manifests/deployment/dd-cyberia-development/deployment.yaml +76 -2
  25. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  26. package/manifests/kind-config-dev.yaml +8 -0
  27. package/manifests/lxd/lxd-admin-profile.yaml +12 -3
  28. package/manifests/mongodb/pv-pvc.yaml +44 -8
  29. package/manifests/mongodb/statefulset.yaml +55 -68
  30. package/manifests/mongodb-4.4/headless-service.yaml +10 -0
  31. package/manifests/mongodb-4.4/kustomization.yaml +3 -1
  32. package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
  33. package/manifests/mongodb-4.4/pv-pvc.yaml +10 -14
  34. package/manifests/mongodb-4.4/statefulset.yaml +79 -0
  35. package/manifests/mongodb-4.4/storage-class.yaml +9 -0
  36. package/manifests/valkey/statefulset.yaml +1 -1
  37. package/manifests/valkey/valkey-nodeport.yaml +17 -0
  38. package/package.json +31 -19
  39. package/scripts/ipxe-setup.sh +52 -49
  40. package/scripts/k3s-node-setup.sh +81 -46
  41. package/scripts/link-local-underpost-cli.sh +6 -0
  42. package/scripts/lxd-vm-setup.sh +193 -8
  43. package/scripts/maas-nat-firewalld.sh +145 -0
  44. package/scripts/test-monitor.sh +250 -0
  45. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +38 -33
  46. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +16 -16
  47. package/src/api/core/core.router.js +19 -14
  48. package/src/api/core/core.service.js +5 -5
  49. package/src/api/crypto/crypto.router.js +18 -12
  50. package/src/api/crypto/crypto.service.js +3 -3
  51. package/src/api/cyberia-action/cyberia-action.model.js +1 -1
  52. package/src/api/cyberia-action/cyberia-action.router.js +22 -18
  53. package/src/api/cyberia-action/cyberia-action.service.js +5 -5
  54. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +74 -0
  55. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +99 -0
  56. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +98 -0
  57. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
  58. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +25 -20
  59. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +6 -6
  60. package/src/api/cyberia-entity/cyberia-entity.router.js +22 -18
  61. package/src/api/cyberia-entity/cyberia-entity.service.js +5 -5
  62. package/src/api/cyberia-instance/cyberia-fallback-world.js +79 -4
  63. package/src/api/cyberia-instance/cyberia-instance.router.js +57 -52
  64. package/src/api/cyberia-instance/cyberia-instance.service.js +10 -10
  65. package/src/api/cyberia-instance/cyberia-world-generator.js +3 -3
  66. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +14 -48
  67. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +22 -18
  68. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +5 -5
  69. package/src/api/cyberia-map/cyberia-map.router.js +35 -30
  70. package/src/api/cyberia-map/cyberia-map.service.js +7 -7
  71. package/src/api/cyberia-quest/cyberia-quest.model.js +1 -1
  72. package/src/api/cyberia-quest/cyberia-quest.router.js +22 -18
  73. package/src/api/cyberia-quest/cyberia-quest.service.js +5 -5
  74. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +22 -18
  75. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +5 -5
  76. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +458 -0
  77. package/src/api/default/default.router.js +22 -18
  78. package/src/api/default/default.service.js +5 -5
  79. package/src/api/document/document.router.js +28 -23
  80. package/src/api/document/document.service.js +100 -23
  81. package/src/api/file/file.router.js +19 -13
  82. package/src/api/file/file.service.js +9 -7
  83. package/src/api/instance/instance.router.js +29 -24
  84. package/src/api/instance/instance.service.js +6 -6
  85. package/src/api/ipfs/ipfs.router.js +21 -16
  86. package/src/api/ipfs/ipfs.service.js +8 -8
  87. package/src/api/object-layer/object-layer.router.js +512 -507
  88. package/src/api/object-layer/object-layer.service.js +17 -14
  89. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +22 -18
  90. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +5 -5
  91. package/src/api/test/test.router.js +17 -12
  92. package/src/api/types.js +24 -0
  93. package/src/api/user/guest.service.js +5 -4
  94. package/src/api/user/user.router.js +297 -288
  95. package/src/api/user/user.service.js +100 -35
  96. package/src/cli/baremetal.js +132 -101
  97. package/src/cli/cluster.js +700 -232
  98. package/src/cli/db.js +59 -60
  99. package/src/cli/deploy.js +291 -294
  100. package/src/cli/env.js +1 -4
  101. package/src/cli/fs.js +13 -3
  102. package/src/cli/image.js +58 -4
  103. package/src/cli/index.js +127 -15
  104. package/src/cli/ipfs.js +4 -6
  105. package/src/cli/kubectl.js +4 -1
  106. package/src/cli/lxd.js +1099 -223
  107. package/src/cli/monitor.js +396 -9
  108. package/src/cli/release.js +355 -146
  109. package/src/cli/repository.js +169 -30
  110. package/src/cli/run.js +347 -117
  111. package/src/cli/secrets.js +11 -2
  112. package/src/cli/test.js +9 -3
  113. package/src/client/Default.index.js +9 -3
  114. package/src/client/components/core/Auth.js +5 -0
  115. package/src/client/components/core/ClientEvents.js +76 -0
  116. package/src/client/components/core/EventBus.js +4 -0
  117. package/src/client/components/core/Modal.js +82 -41
  118. package/src/client/components/core/PanelForm.js +14 -10
  119. package/src/client/components/core/Worker.js +162 -363
  120. package/src/client/components/cyberia/MapEngineCyberia.js +1 -1
  121. package/src/client/components/cyberia/SharedDefaultsCyberia.js +330 -0
  122. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +55 -1
  123. package/src/client/public/cyberia-docs/ARCHITECTURE.md +223 -361
  124. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +114 -327
  125. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +200 -222
  126. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +212 -185
  127. package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
  128. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +2 -2
  129. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +23 -1
  130. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  131. package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
  132. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  133. package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
  134. package/src/client/ssr/views/CyberiaServerMetrics.js +982 -0
  135. package/src/client/sw/core.sw.js +174 -112
  136. package/src/db/DataBaseProvider.js +115 -15
  137. package/src/db/mariadb/MariaDB.js +2 -1
  138. package/src/db/mongo/MongoBootstrap.js +657 -0
  139. package/src/db/mongo/MongooseDB.js +130 -21
  140. package/src/grpc/cyberia/grpc-server.js +25 -57
  141. package/src/index.js +1 -1
  142. package/src/runtime/cyberia-client/Dockerfile +10 -7
  143. package/src/runtime/cyberia-client/Dockerfile.dev +67 -0
  144. package/src/runtime/cyberia-server/Dockerfile +11 -6
  145. package/src/runtime/cyberia-server/Dockerfile.dev +47 -0
  146. package/src/runtime/express/Express.js +2 -2
  147. package/src/runtime/wp/Dockerfile +3 -3
  148. package/src/runtime/wp/Wp.js +8 -5
  149. package/src/server/auth.js +2 -2
  150. package/src/server/catalog-underpost.js +61 -0
  151. package/src/server/catalog.js +77 -0
  152. package/src/server/client-build-docs.js +1 -1
  153. package/src/server/client-build.js +94 -129
  154. package/src/server/conf.js +496 -135
  155. package/src/server/ipfs-client.js +5 -3
  156. package/src/server/process.js +180 -19
  157. package/src/server/proxy.js +9 -2
  158. package/src/server/runtime-status.js +235 -0
  159. package/src/server/runtime.js +1 -1
  160. package/src/server/start.js +44 -11
  161. package/src/server/valkey.js +2 -0
  162. package/src/ws/IoInterface.js +16 -16
  163. package/src/ws/core/channels/core.ws.chat.js +11 -11
  164. package/src/ws/core/channels/core.ws.mailer.js +29 -29
  165. package/src/ws/core/channels/core.ws.stream.js +19 -19
  166. package/src/ws/core/core.ws.connection.js +8 -8
  167. package/src/ws/core/core.ws.server.js +6 -5
  168. package/src/ws/default/channels/default.ws.main.js +10 -10
  169. package/src/ws/default/default.ws.connection.js +4 -4
  170. package/src/ws/default/default.ws.server.js +4 -3
  171. package/test/deploy-monitor.test.js +251 -0
  172. package/bin/file.js +0 -202
  173. package/bin/vs.js +0 -74
  174. package/bin/zed.js +0 -84
  175. package/manifests/deployment/dd-test-development/deployment.yaml +0 -254
  176. package/manifests/deployment/dd-test-development/proxy.yaml +0 -102
  177. package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +0 -574
  178. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +0 -467
  179. package/src/client/ssr/email/DefaultRecoverEmail.js +0 -21
  180. package/src/client/ssr/email/DefaultVerifyEmail.js +0 -17
  181. package/src/client/ssr/pages/CyberiaServerMetrics.js +0 -461
  182. /package/src/client/ssr/{offline → views}/Maintenance.js +0 -0
  183. /package/src/client/ssr/{offline → views}/NoNetworkConnection.js +0 -0
  184. /package/src/client/ssr/{pages → views}/Test.js +0 -0
@@ -1,461 +0,0 @@
1
- const s = (el) => document.querySelector(el);
2
- const sa = (el) => document.querySelectorAll(el);
3
-
4
- const append = (el, html) => s(el).insertAdjacentHTML('beforeend', html);
5
-
6
- const setHTML = (el, html) => {
7
- const element = s(el);
8
- if (element) element.innerHTML = html;
9
- };
10
-
11
- const getLang = () =>
12
- (localStorage.getItem('lang') || navigator.language || navigator.userLanguage || s('html').lang)
13
- .slice(0, 2)
14
- .toLowerCase();
15
-
16
- const formatUptime = (seconds) => {
17
- const hours = Math.floor(seconds / 3600);
18
- const minutes = Math.floor((seconds % 3600) / 60);
19
- const secs = seconds % 60;
20
- return `${hours}h ${minutes}m ${secs}s`;
21
- };
22
-
23
- const getHealthColor = (health) => {
24
- const colors = {
25
- healthy: '#10b981',
26
- degraded: '#f59e0b',
27
- critical: '#ef4444',
28
- maintenance: '#8b5cf6',
29
- };
30
- return colors[health] || '#6b7280';
31
- };
32
-
33
- const getLoadColor = (load) => {
34
- const colors = {
35
- low: '#10b981',
36
- moderate: '#f59e0b',
37
- high: '#ef4444',
38
- };
39
- return colors[load] || '#6b7280';
40
- };
41
-
42
- const formatPercent = (value) => {
43
- return Math.round(value * 100) / 100;
44
- };
45
-
46
- const createProgressBar = (current, max, label) => {
47
- const percent = (current / max) * 100;
48
- const color = percent > 80 ? '#ef4444' : percent > 50 ? '#f59e0b' : '#10b981';
49
- return html`
50
- <div style="margin-bottom: 12px;">
51
- <div style="display: flex; justify-content: space-between; margin-bottom: 4px; font-size: 13px;">
52
- <span>${label}</span>
53
- <span style="font-weight: bold;">${current} / ${max}</span>
54
- </div>
55
- <div style="width: 100%; height: 8px; background-color: #e5e7eb; border-radius: 4px; overflow: hidden;">
56
- <div style="width: ${percent}%; height: 100%; background-color: ${color}; transition: width 0.3s ease;"></div>
57
- </div>
58
- </div>
59
- `;
60
- };
61
-
62
- const createEntityCard = (entityType) => {
63
- const icons = {
64
- player: '👤',
65
- bot: '🤖',
66
- floor: '🏢',
67
- obstacle: '🚧',
68
- foreground: '🎨',
69
- portal: '🌀',
70
- };
71
- const icon = icons[entityType.type] || '🔷';
72
- return html`
73
- <div
74
- style="background: linear-gradient(135deg, #f3f4f6 0%, #ffffff 100%); padding: 12px; border-radius: 8px; border-left: 4px solid #3b82f6; margin-bottom: 8px;"
75
- >
76
- <div style="display: flex; align-items: center; margin-bottom: 8px;">
77
- <span style="font-size: 20px; margin-right: 8px;">${icon}</span>
78
- <div>
79
- <div style="font-weight: bold; font-size: 14px; text-transform: capitalize;">${entityType.type}</div>
80
- <div style="font-size: 12px; color: #6b7280;">Count: ${entityType.count}</div>
81
- </div>
82
- </div>
83
- ${entityType.total_object_layers > 0
84
- ? `
85
- <div style="font-size: 11px; color: #666; margin-top: 6px; padding-top: 6px; border-top: 1px solid #e5e7eb;">
86
- <div>Layers: ${entityType.active_object_layers}/${entityType.total_object_layers}</div>
87
- </div>
88
- `
89
- : ''}
90
- </div>
91
- `;
92
- };
93
-
94
- const fetchMetrics = async () => {
95
- try {
96
- const response = await fetch('/api/v1/metrics');
97
- if (!response.ok) throw new Error('Failed to fetch metrics');
98
- return await response.json();
99
- } catch (error) {
100
- console.error('Error fetching metrics:', error);
101
- return null;
102
- }
103
- };
104
-
105
- const renderDashboardContent = (metrics) => {
106
- const timestamp = new Date(metrics.timestamp);
107
- const timeString = timestamp.toLocaleTimeString();
108
-
109
- const healthColor = getHealthColor(metrics.health);
110
- const loadColor = getLoadColor(metrics.workload.current_load);
111
-
112
- let entitiesHtml = '';
113
- if (metrics.entities.entities_by_type && Array.isArray(metrics.entities.entities_by_type)) {
114
- entitiesHtml = metrics.entities.entities_by_type.map((et) => createEntityCard(et)).join('');
115
- }
116
-
117
- return html`
118
- <div class="container">
119
- <div class="header">
120
- <h1>🖥️ Cyberia Server Metrics</h1>
121
- <p>Real-time MMO Server Status Dashboard</p>
122
- </div>
123
-
124
- <div class="grid">
125
- <!-- Server Health Card -->
126
- <div class="card">
127
- <div class="card-title">Server Health</div>
128
- <div style="margin-bottom: 12px;">
129
- <span class="health-indicator" style="background-color: ${healthColor};"></span>
130
- <span class="status-badge status-${metrics.health}">${metrics.health}</span>
131
- </div>
132
- <p style="margin: 8px 0 0 0; font-size: 13px; color: #6b7280;">${metrics.health_description}</p>
133
- <div class="timestamp">Updated: ${timeString}</div>
134
- </div>
135
-
136
- <!-- Uptime Card -->
137
- <div class="card">
138
- <div class="card-title">⏱️ Server Uptime</div>
139
- <div style="font-size: 24px; font-weight: 700; color: #667eea; margin: 12px 0;">
140
- ${formatUptime(metrics.server_uptime_sec)}
141
- </div>
142
- <div style="font-size: 12px; color: #6b7280;">WebSocket: ${formatUptime(metrics.websocket.uptime_sec)}</div>
143
- </div>
144
-
145
- <!-- Workload Card -->
146
- <div class="card">
147
- <div class="card-title">📊 Server Load</div>
148
- <div class="load-indicator" style="color: ${loadColor};">
149
- ${formatPercent(metrics.workload.load_percentage)}%
150
- </div>
151
- <div style="font-size: 12px; color: #6b7280; text-align: center;">
152
- Current: <strong>${metrics.workload.current_load}</strong>
153
- </div>
154
- ${createProgressBar(metrics.workload.load_percentage, 100, 'Load Percentage')}
155
- </div>
156
-
157
- <!-- WebSocket Card -->
158
- <div class="card">
159
- <div class="card-title">🔌 WebSocket Status</div>
160
- <div class="metric-item">
161
- <span class="metric-label">Status</span>
162
- <span class="metric-value" style="color: #10b981;">${metrics.websocket.status}</span>
163
- </div>
164
- <div class="metric-item">
165
- <span class="metric-label">Active Connections</span>
166
- <span class="metric-value">${metrics.websocket.active_connections}</span>
167
- </div>
168
- <div class="metric-item">
169
- <span class="metric-label">Uptime</span>
170
- <span class="metric-value">${formatUptime(metrics.websocket.uptime_sec)}</span>
171
- </div>
172
- </div>
173
-
174
- <!-- Entity Summary Card -->
175
- <div class="card">
176
- <div class="card-title">🎮 Entities Summary</div>
177
- <div class="metric-item">
178
- <span class="metric-label">Total Entities</span>
179
- <span class="metric-value">${metrics.entities.total_entities}</span>
180
- </div>
181
- <div class="metric-item">
182
- <span class="metric-label">Active Layers</span>
183
- <span class="metric-value">${metrics.entities.active_object_layers}</span>
184
- </div>
185
- <div class="metric-item">
186
- <span class="metric-label">Avg Layers/Entity</span>
187
- <span class="metric-value">${formatPercent(metrics.entities.avg_object_layers_per_entity)}</span>
188
- </div>
189
- </div>
190
-
191
- <!-- Capacity Card -->
192
- <div class="card">
193
- <div class="card-title">📈 Capacity Usage</div>
194
- ${createProgressBar(metrics.entities.total_entities, metrics.workload.max_entity_capacity, 'Entity Capacity')}
195
- ${createProgressBar(
196
- metrics.entities.total_object_layers,
197
- metrics.workload.max_object_layers,
198
- 'Object Layers',
199
- )}
200
- </div>
201
-
202
- <!-- Entities Breakdown Full Width -->
203
- <div class="card full-width">
204
- <div class="card-title">🎪 Entities Breakdown</div>
205
- <div class="entities-grid">${entitiesHtml}</div>
206
- </div>
207
- </div>
208
-
209
- <div style="text-align: center;">
210
- <a href="${location.origin}" class="back-link">← Back to Homepage</a>
211
- </div>
212
- </div>
213
- `;
214
- };
215
-
216
- const updateDashboard = async () => {
217
- const metrics = await fetchMetrics();
218
- if (!metrics) {
219
- setHTML(
220
- '.dashboard-content',
221
- '<div style="text-align: center; padding: 20px; color: #ef4444;">Unable to load server metrics</div>',
222
- );
223
- return;
224
- }
225
-
226
- const content = renderDashboardContent(metrics);
227
- setHTML('.dashboard-content', content);
228
- };
229
-
230
- const main = () => {
231
- // Initial setup with styles and container
232
- const initialHTML = html`
233
- <style>
234
- * {
235
- box-sizing: border-box;
236
- }
237
-
238
- body {
239
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
240
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
241
- color: #1f2937;
242
- margin: 0;
243
- padding: 0;
244
- min-height: 100vh;
245
- }
246
-
247
- .container {
248
- max-width: 1200px;
249
- margin: 0 auto;
250
- padding: 20px;
251
- }
252
-
253
- .header {
254
- text-align: center;
255
- color: white;
256
- margin-bottom: 30px;
257
- }
258
-
259
- .header h1 {
260
- margin: 0;
261
- font-size: 32px;
262
- font-weight: 700;
263
- margin-bottom: 8px;
264
- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
265
- }
266
-
267
- .header p {
268
- margin: 0;
269
- font-size: 14px;
270
- opacity: 0.9;
271
- }
272
-
273
- .grid {
274
- display: grid;
275
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
276
- gap: 20px;
277
- margin-bottom: 20px;
278
- }
279
-
280
- .card {
281
- background: white;
282
- border-radius: 12px;
283
- padding: 20px;
284
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
285
- transition:
286
- transform 0.3s ease,
287
- box-shadow 0.3s ease;
288
- }
289
-
290
- .card:hover {
291
- transform: translateY(-5px);
292
- box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3);
293
- }
294
-
295
- .card-title {
296
- font-size: 16px;
297
- font-weight: 600;
298
- margin-bottom: 12px;
299
- color: #1f2937;
300
- }
301
-
302
- .status-badge {
303
- display: inline-block;
304
- padding: 6px 12px;
305
- border-radius: 20px;
306
- font-size: 12px;
307
- font-weight: 600;
308
- text-transform: uppercase;
309
- letter-spacing: 0.5px;
310
- }
311
-
312
- .status-healthy {
313
- background-color: #d1fae5;
314
- color: #065f46;
315
- }
316
-
317
- .status-degraded {
318
- background-color: #fef3c7;
319
- color: #92400e;
320
- }
321
-
322
- .status-critical {
323
- background-color: #fee2e2;
324
- color: #991b1b;
325
- }
326
-
327
- .status-maintenance {
328
- background-color: #ede9fe;
329
- color: #5b21b6;
330
- }
331
-
332
- .metric-item {
333
- display: flex;
334
- justify-content: space-between;
335
- padding: 10px 0;
336
- border-bottom: 1px solid #e5e7eb;
337
- }
338
-
339
- .metric-item:last-child {
340
- border-bottom: none;
341
- }
342
-
343
- .metric-label {
344
- color: #6b7280;
345
- font-size: 13px;
346
- }
347
-
348
- .metric-value {
349
- font-weight: 600;
350
- color: #1f2937;
351
- font-size: 14px;
352
- }
353
-
354
- .health-indicator {
355
- display: inline-block;
356
- width: 12px;
357
- height: 12px;
358
- border-radius: 50%;
359
- margin-right: 6px;
360
- animation: pulse 2s infinite;
361
- }
362
-
363
- @keyframes pulse {
364
- 0%,
365
- 100% {
366
- opacity: 1;
367
- }
368
- 50% {
369
- opacity: 0.5;
370
- }
371
- }
372
-
373
- .entities-grid {
374
- display: grid;
375
- grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
376
- gap: 8px;
377
- }
378
-
379
- .back-link {
380
- display: inline-block;
381
- margin-top: 20px;
382
- padding: 10px 20px;
383
- background-color: rgba(255, 255, 255, 0.2);
384
- color: white;
385
- text-decoration: none;
386
- border-radius: 8px;
387
- font-size: 13px;
388
- font-weight: 600;
389
- transition: background-color 0.3s ease;
390
- }
391
-
392
- .back-link:hover {
393
- background-color: rgba(255, 255, 255, 0.3);
394
- }
395
-
396
- .full-width {
397
- grid-column: 1 / -1;
398
- }
399
-
400
- .load-indicator {
401
- font-size: 48px;
402
- text-align: center;
403
- margin: 20px 0;
404
- font-weight: 700;
405
- }
406
-
407
- .timestamp {
408
- font-size: 12px;
409
- color: #9ca3af;
410
- margin-top: 12px;
411
- padding-top: 12px;
412
- border-top: 1px solid #e5e7eb;
413
- }
414
-
415
- .dashboard-content {
416
- animation: fadeIn 0.3s ease-in-out;
417
- }
418
-
419
- @keyframes fadeIn {
420
- from {
421
- opacity: 0;
422
- }
423
- to {
424
- opacity: 1;
425
- }
426
- }
427
- </style>
428
-
429
- <div class="dashboard-content"></div>
430
- `;
431
-
432
- append('body', initialHTML);
433
-
434
- // Initial load
435
- updateDashboard();
436
-
437
- // Auto-refresh every 5 seconds
438
- setInterval(updateDashboard, 5000);
439
- };
440
-
441
- SrrComponent = () =>
442
- html`<script>
443
- {
444
- const s = ${s};
445
- const sa = ${sa};
446
- const append = ${append};
447
- const setHTML = ${setHTML};
448
- const getLang = ${getLang};
449
- const formatUptime = ${formatUptime};
450
- const getHealthColor = ${getHealthColor};
451
- const getLoadColor = ${getLoadColor};
452
- const formatPercent = ${formatPercent};
453
- const createProgressBar = ${createProgressBar};
454
- const createEntityCard = ${createEntityCard};
455
- const fetchMetrics = ${fetchMetrics};
456
- const renderDashboardContent = ${renderDashboardContent};
457
- const updateDashboard = ${updateDashboard};
458
- const main = ${main};
459
- window.onload = main;
460
- }
461
- </script>`;
File without changes