4runr-os 1.0.28 → 1.0.36

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 (211) hide show
  1. package/dist/collectors/collector_assets.d.ts +19 -0
  2. package/dist/collectors/collector_assets.d.ts.map +1 -0
  3. package/dist/collectors/collector_assets.js +72 -0
  4. package/dist/collectors/collector_assets.js.map +1 -0
  5. package/dist/collectors/collector_capabilities.d.ts +19 -0
  6. package/dist/collectors/collector_capabilities.d.ts.map +1 -0
  7. package/dist/collectors/collector_capabilities.js +61 -0
  8. package/dist/collectors/collector_capabilities.js.map +1 -0
  9. package/dist/collectors/collector_feed.d.ts +30 -0
  10. package/dist/collectors/collector_feed.d.ts.map +1 -0
  11. package/dist/collectors/collector_feed.js +78 -0
  12. package/dist/collectors/collector_feed.js.map +1 -0
  13. package/dist/collectors/collector_geo.d.ts +12 -0
  14. package/dist/collectors/collector_geo.d.ts.map +1 -0
  15. package/dist/collectors/collector_geo.js +248 -0
  16. package/dist/collectors/collector_geo.js.map +1 -0
  17. package/dist/collectors/collector_network.d.ts +22 -0
  18. package/dist/collectors/collector_network.d.ts.map +1 -0
  19. package/dist/collectors/collector_network.js +83 -0
  20. package/dist/collectors/collector_network.js.map +1 -0
  21. package/dist/collectors/collector_posture.d.ts +25 -0
  22. package/dist/collectors/collector_posture.d.ts.map +1 -0
  23. package/dist/collectors/collector_posture.js +207 -0
  24. package/dist/collectors/collector_posture.js.map +1 -0
  25. package/dist/collectors/collector_resources.d.ts +21 -0
  26. package/dist/collectors/collector_resources.d.ts.map +1 -0
  27. package/dist/collectors/collector_resources.js +87 -0
  28. package/dist/collectors/collector_resources.js.map +1 -0
  29. package/dist/collectors/helpers.d.ts +21 -0
  30. package/dist/collectors/helpers.d.ts.map +1 -0
  31. package/dist/collectors/helpers.js +49 -0
  32. package/dist/collectors/helpers.js.map +1 -0
  33. package/dist/core/collectorRegistry.d.ts +43 -0
  34. package/dist/core/collectorRegistry.d.ts.map +1 -0
  35. package/dist/core/collectorRegistry.js +76 -0
  36. package/dist/core/collectorRegistry.js.map +1 -0
  37. package/dist/core/constants.d.ts +25 -0
  38. package/dist/core/constants.d.ts.map +1 -0
  39. package/dist/core/constants.js +33 -0
  40. package/dist/core/constants.js.map +1 -0
  41. package/dist/core/eventBus.d.ts +36 -0
  42. package/dist/core/eventBus.d.ts.map +1 -0
  43. package/dist/core/eventBus.js +52 -0
  44. package/dist/core/eventBus.js.map +1 -0
  45. package/dist/core/types.d.ts +128 -0
  46. package/dist/core/types.d.ts.map +1 -0
  47. package/dist/core/types.js +6 -0
  48. package/dist/core/types.js.map +1 -0
  49. package/dist/index.js +135 -5
  50. package/dist/index.js.map +1 -1
  51. package/dist/state/getCollectorResults.d.ts +18 -0
  52. package/dist/state/getCollectorResults.d.ts.map +1 -0
  53. package/dist/state/getCollectorResults.js +25 -0
  54. package/dist/state/getCollectorResults.js.map +1 -0
  55. package/dist/state/historyStore.d.ts +35 -0
  56. package/dist/state/historyStore.d.ts.map +1 -0
  57. package/dist/state/historyStore.js +58 -0
  58. package/dist/state/historyStore.js.map +1 -0
  59. package/dist/state/uiStateBuilder.d.ts +12 -0
  60. package/dist/state/uiStateBuilder.d.ts.map +1 -0
  61. package/dist/state/uiStateBuilder.js +169 -0
  62. package/dist/state/uiStateBuilder.js.map +1 -0
  63. package/dist/state/uiStateScheduler.d.ts +43 -0
  64. package/dist/state/uiStateScheduler.d.ts.map +1 -0
  65. package/dist/state/uiStateScheduler.js +118 -0
  66. package/dist/state/uiStateScheduler.js.map +1 -0
  67. package/dist/ui/boot/sequence.d.ts +10 -0
  68. package/dist/ui/boot/sequence.d.ts.map +1 -0
  69. package/dist/ui/boot/sequence.js +173 -0
  70. package/dist/ui/boot/sequence.js.map +1 -0
  71. package/dist/ui/constraints/layoutSpec.d.ts +47 -0
  72. package/dist/ui/constraints/layoutSpec.d.ts.map +1 -0
  73. package/dist/ui/constraints/layoutSpec.js +60 -0
  74. package/dist/ui/constraints/layoutSpec.js.map +1 -0
  75. package/dist/ui/constraints/unknownHandling.d.ts +29 -0
  76. package/dist/ui/constraints/unknownHandling.d.ts.map +1 -0
  77. package/dist/ui/constraints/unknownHandling.js +60 -0
  78. package/dist/ui/constraints/unknownHandling.js.map +1 -0
  79. package/dist/ui/drilldowns/feed.d.ts +11 -0
  80. package/dist/ui/drilldowns/feed.d.ts.map +1 -0
  81. package/dist/ui/drilldowns/feed.js +68 -0
  82. package/dist/ui/drilldowns/feed.js.map +1 -0
  83. package/dist/ui/drilldowns/index.d.ts +7 -0
  84. package/dist/ui/drilldowns/index.d.ts.map +1 -0
  85. package/dist/ui/drilldowns/index.js +8 -0
  86. package/dist/ui/drilldowns/index.js.map +1 -0
  87. package/dist/ui/drilldowns/posture.d.ts +11 -0
  88. package/dist/ui/drilldowns/posture.d.ts.map +1 -0
  89. package/dist/ui/drilldowns/posture.js +74 -0
  90. package/dist/ui/drilldowns/posture.js.map +1 -0
  91. package/dist/ui/navigation/keymaps.d.ts +26 -0
  92. package/dist/ui/navigation/keymaps.d.ts.map +1 -0
  93. package/dist/ui/navigation/keymaps.js +135 -0
  94. package/dist/ui/navigation/keymaps.js.map +1 -0
  95. package/dist/ui/navigation/palette.d.ts +10 -0
  96. package/dist/ui/navigation/palette.d.ts.map +1 -0
  97. package/dist/ui/navigation/palette.js +133 -0
  98. package/dist/ui/navigation/palette.js.map +1 -0
  99. package/dist/ui/navigation/state.d.ts +47 -0
  100. package/dist/ui/navigation/state.d.ts.map +1 -0
  101. package/dist/ui/navigation/state.js +84 -0
  102. package/dist/ui/navigation/state.js.map +1 -0
  103. package/dist/ui/navigation/types.d.ts +38 -0
  104. package/dist/ui/navigation/types.d.ts.map +1 -0
  105. package/dist/ui/navigation/types.js +36 -0
  106. package/dist/ui/navigation/types.js.map +1 -0
  107. package/dist/ui/panels/active-assets.d.ts +12 -0
  108. package/dist/ui/panels/active-assets.d.ts.map +1 -0
  109. package/dist/ui/panels/active-assets.js +83 -0
  110. package/dist/ui/panels/active-assets.js.map +1 -0
  111. package/dist/ui/panels/capability-flags.d.ts +12 -0
  112. package/dist/ui/panels/capability-flags.d.ts.map +1 -0
  113. package/dist/ui/panels/capability-flags.js +59 -0
  114. package/dist/ui/panels/capability-flags.js.map +1 -0
  115. package/dist/ui/panels/command-surface.d.ts +12 -0
  116. package/dist/ui/panels/command-surface.d.ts.map +1 -0
  117. package/dist/ui/panels/command-surface.js +55 -0
  118. package/dist/ui/panels/command-surface.js.map +1 -0
  119. package/dist/ui/panels/network-origin.d.ts +12 -0
  120. package/dist/ui/panels/network-origin.d.ts.map +1 -0
  121. package/dist/ui/panels/network-origin.js +79 -0
  122. package/dist/ui/panels/network-origin.js.map +1 -0
  123. package/dist/ui/panels/operations-feed.d.ts +12 -0
  124. package/dist/ui/panels/operations-feed.d.ts.map +1 -0
  125. package/dist/ui/panels/operations-feed.js +90 -0
  126. package/dist/ui/panels/operations-feed.js.map +1 -0
  127. package/dist/ui/panels/posture.d.ts +12 -0
  128. package/dist/ui/panels/posture.d.ts.map +1 -0
  129. package/dist/ui/panels/posture.js +84 -0
  130. package/dist/ui/panels/posture.js.map +1 -0
  131. package/dist/ui/panels/resources.d.ts +11 -0
  132. package/dist/ui/panels/resources.d.ts.map +1 -0
  133. package/dist/ui/panels/resources.js +88 -0
  134. package/dist/ui/panels/resources.js.map +1 -0
  135. package/dist/ui/primitives/Panel.d.ts +25 -0
  136. package/dist/ui/primitives/Panel.d.ts.map +1 -0
  137. package/dist/ui/primitives/Panel.js +59 -0
  138. package/dist/ui/primitives/Panel.js.map +1 -0
  139. package/dist/ui/rendering/metricRenderer.d.ts +24 -0
  140. package/dist/ui/rendering/metricRenderer.d.ts.map +1 -0
  141. package/dist/ui/rendering/metricRenderer.js +86 -0
  142. package/dist/ui/rendering/metricRenderer.js.map +1 -0
  143. package/dist/ui/runtime/hub.d.ts +12 -0
  144. package/dist/ui/runtime/hub.d.ts.map +1 -0
  145. package/dist/ui/runtime/hub.js +468 -0
  146. package/dist/ui/runtime/hub.js.map +1 -0
  147. package/dist/ui/runtime/hubValidation.d.ts +23 -0
  148. package/dist/ui/runtime/hubValidation.d.ts.map +1 -0
  149. package/dist/ui/runtime/hubValidation.js +90 -0
  150. package/dist/ui/runtime/hubValidation.js.map +1 -0
  151. package/dist/ui/runtime/index.d.ts +29 -0
  152. package/dist/ui/runtime/index.d.ts.map +1 -0
  153. package/dist/ui/runtime/index.js +299 -0
  154. package/dist/ui/runtime/index.js.map +1 -0
  155. package/dist/ui/runtime/no-tui.d.ts +12 -0
  156. package/dist/ui/runtime/no-tui.d.ts.map +1 -0
  157. package/dist/ui/runtime/no-tui.js +77 -0
  158. package/dist/ui/runtime/no-tui.js.map +1 -0
  159. package/dist/ui/runtime/state-builder.d.ts +13 -0
  160. package/dist/ui/runtime/state-builder.d.ts.map +1 -0
  161. package/dist/ui/runtime/state-builder.js +114 -0
  162. package/dist/ui/runtime/state-builder.js.map +1 -0
  163. package/dist/ui/runtime/terminalSizeCheck.d.ts +10 -0
  164. package/dist/ui/runtime/terminalSizeCheck.d.ts.map +1 -0
  165. package/dist/ui/runtime/terminalSizeCheck.js +51 -0
  166. package/dist/ui/runtime/terminalSizeCheck.js.map +1 -0
  167. package/dist/ui/runtime/tuiLogGate.d.ts +22 -0
  168. package/dist/ui/runtime/tuiLogGate.d.ts.map +1 -0
  169. package/dist/ui/runtime/tuiLogGate.js +68 -0
  170. package/dist/ui/runtime/tuiLogGate.js.map +1 -0
  171. package/dist/ui/state/types.d.ts +72 -0
  172. package/dist/ui/state/types.d.ts.map +1 -0
  173. package/dist/ui/state/types.js +6 -0
  174. package/dist/ui/state/types.js.map +1 -0
  175. package/dist/ui/theme/borders.d.ts +20 -0
  176. package/dist/ui/theme/borders.d.ts.map +1 -0
  177. package/dist/ui/theme/borders.js +55 -0
  178. package/dist/ui/theme/borders.js.map +1 -0
  179. package/dist/ui/theme/tokens.d.ts +28 -0
  180. package/dist/ui/theme/tokens.d.ts.map +1 -0
  181. package/dist/ui/theme/tokens.js +50 -0
  182. package/dist/ui/theme/tokens.js.map +1 -0
  183. package/dist/ui/theme/typography.d.ts +14 -0
  184. package/dist/ui/theme/typography.d.ts.map +1 -0
  185. package/dist/ui/theme/typography.js +30 -0
  186. package/dist/ui/theme/typography.js.map +1 -0
  187. package/dist/ui/widgets/flagRow.d.ts +25 -0
  188. package/dist/ui/widgets/flagRow.d.ts.map +1 -0
  189. package/dist/ui/widgets/flagRow.js +57 -0
  190. package/dist/ui/widgets/flagRow.js.map +1 -0
  191. package/dist/ui/widgets/index.d.ts +9 -0
  192. package/dist/ui/widgets/index.d.ts.map +1 -0
  193. package/dist/ui/widgets/index.js +9 -0
  194. package/dist/ui/widgets/index.js.map +1 -0
  195. package/dist/ui/widgets/meter.d.ts +18 -0
  196. package/dist/ui/widgets/meter.d.ts.map +1 -0
  197. package/dist/ui/widgets/meter.js +38 -0
  198. package/dist/ui/widgets/meter.js.map +1 -0
  199. package/dist/ui/widgets/miniMap.d.ts +26 -0
  200. package/dist/ui/widgets/miniMap.d.ts.map +1 -0
  201. package/dist/ui/widgets/miniMap.js +94 -0
  202. package/dist/ui/widgets/miniMap.js.map +1 -0
  203. package/dist/ui/widgets/sparkline.d.ts +17 -0
  204. package/dist/ui/widgets/sparkline.d.ts.map +1 -0
  205. package/dist/ui/widgets/sparkline.js +63 -0
  206. package/dist/ui/widgets/sparkline.js.map +1 -0
  207. package/package.json +5 -4
  208. package/dist/ui/home-view.d.ts +0 -27
  209. package/dist/ui/home-view.d.ts.map +0 -1
  210. package/dist/ui/home-view.js +0 -127
  211. package/dist/ui/home-view.js.map +0 -1
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Panel 5: NETWORK / ORIGIN
3
+ * Location: Right column (top)
4
+ * Purpose: Situational and geographic awareness
5
+ */
6
+ import { getSystemState } from '../../system-state.js';
7
+ import { createPanel } from '../primitives/Panel.js';
8
+ import { getBlessedColor } from '../theme/tokens.js';
9
+ /**
10
+ * Mask IP address (e.g., 44.222.xxx.xxx)
11
+ */
12
+ function maskIP(ip) {
13
+ const parts = ip.split('.');
14
+ if (parts.length === 4) {
15
+ return `${parts[0]}.${parts[1]}.xxx.xxx`;
16
+ }
17
+ return 'HIDDEN';
18
+ }
19
+ /**
20
+ * Get public IP (simplified - would need actual IP detection)
21
+ */
22
+ function getPublicIP() {
23
+ // For v1, return HIDDEN (would need external API call)
24
+ return 'HIDDEN';
25
+ }
26
+ /**
27
+ * Render NETWORK / ORIGIN panel
28
+ */
29
+ export function renderNetworkOriginPanel(screen, top, left, width, height, appState) {
30
+ let systemState;
31
+ try {
32
+ systemState = getSystemState(appState, false);
33
+ }
34
+ catch {
35
+ systemState = null;
36
+ }
37
+ const content = [];
38
+ if (systemState) {
39
+ const network = systemState.networkContext;
40
+ // ORIGIN
41
+ const origin = `${network.operatorOrigin.region} (${network.operatorOrigin.networkType})`;
42
+ content.push(`ORIGIN: {${getBlessedColor('accentCyan')}-fg}${origin}{/}`);
43
+ // GATEWAY
44
+ const gateway = network.targetInfrastructure.gatewayRegion || 'UNKNOWN';
45
+ content.push(`GATEWAY: {${getBlessedColor('accentCyan')}-fg}${gateway}{/}`);
46
+ // DATABASE
47
+ const database = network.targetInfrastructure.databaseRegion || 'NONE';
48
+ content.push(`DATABASE: {${getBlessedColor('accentCyan')}-fg}${database}{/}`);
49
+ // LATENCY
50
+ const latency = network.targetInfrastructure.latencyClass;
51
+ let latencyColor = getBlessedColor('mutedGrey');
52
+ if (latency === 'LOW')
53
+ latencyColor = getBlessedColor('successGreen');
54
+ else if (latency === 'MEDIUM')
55
+ latencyColor = getBlessedColor('warnAmber');
56
+ else if (latency === 'HIGH')
57
+ latencyColor = getBlessedColor('criticalRed');
58
+ content.push(`LATENCY: {${latencyColor}-fg}${latency}{/}`);
59
+ // PUBLIC IP
60
+ const publicIP = getPublicIP();
61
+ content.push(`PUBLIC IP: {${getBlessedColor('mutedGrey')}-fg}${publicIP}{/}`);
62
+ }
63
+ else {
64
+ content.push('ORIGIN: UNKNOWN');
65
+ content.push('GATEWAY: UNKNOWN');
66
+ content.push('DATABASE: UNKNOWN');
67
+ content.push('LATENCY: UNKNOWN');
68
+ content.push('PUBLIC IP: UNKNOWN');
69
+ }
70
+ return createPanel(screen, {
71
+ title: 'NETWORK / ORIGIN',
72
+ top,
73
+ left,
74
+ width,
75
+ height,
76
+ content,
77
+ });
78
+ }
79
+ //# sourceMappingURL=network-origin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network-origin.js","sourceRoot":"","sources":["../../../src/ui/panels/network-origin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Panel 4: OPERATIONS FEED
3
+ * Location: Center column (main)
4
+ * Purpose: Make the system feel alive and responsive
5
+ */
6
+ import type { Widgets } from 'neo-blessed';
7
+ import type { AppState } from '../../store.js';
8
+ /**
9
+ * Render OPERATIONS FEED panel
10
+ */
11
+ export declare function renderOperationsFeedPanel(screen: Widgets.Screen, top: number, left: number, width: number, height: number, appState: AppState): Widgets.Box;
12
+ //# sourceMappingURL=operations-feed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations-feed.d.ts","sourceRoot":"","sources":["../../../src/ui/panels/operations-feed.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AA4D/C;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,GAAG,CA8Bb"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Panel 4: OPERATIONS FEED
3
+ * Location: Center column (main)
4
+ * Purpose: Make the system feel alive and responsive
5
+ */
6
+ import { getSystemState } from '../../system-state.js';
7
+ import { createPanel } from '../primitives/Panel.js';
8
+ import { getBlessedColor } from '../theme/tokens.js';
9
+ /**
10
+ * Format timestamp as HH:MM:SS
11
+ */
12
+ function formatTime(timestamp) {
13
+ const date = new Date(timestamp);
14
+ const hours = date.getHours().toString().padStart(2, '0');
15
+ const minutes = date.getMinutes().toString().padStart(2, '0');
16
+ const seconds = date.getSeconds().toString().padStart(2, '0');
17
+ return `${hours}:${minutes}:${seconds}`;
18
+ }
19
+ /**
20
+ * Get event tag from event type
21
+ */
22
+ function getEventTag(eventType) {
23
+ if (eventType.includes('RUN'))
24
+ return 'RUN';
25
+ if (eventType.includes('CONNECTION'))
26
+ return 'NET';
27
+ if (eventType.includes('ERROR'))
28
+ return 'SEC';
29
+ if (eventType.includes('DATABASE') || eventType.includes('DB'))
30
+ return 'DB';
31
+ if (eventType.includes('GATEWAY'))
32
+ return 'GATEWAY';
33
+ return 'SYSTEM';
34
+ }
35
+ /**
36
+ * Format event for display
37
+ * Format: [HH:MM:SS] [TAG] message
38
+ */
39
+ function formatEvent(event) {
40
+ const time = formatTime(event.timestamp);
41
+ const tag = getEventTag(event.type);
42
+ // Extract message from description (remove prefix if present)
43
+ let message = event.description;
44
+ if (message.includes(':')) {
45
+ const parts = message.split(':');
46
+ if (parts.length > 1) {
47
+ message = parts.slice(1).join(':').trim();
48
+ }
49
+ }
50
+ const color = event.severity === 'critical'
51
+ ? getBlessedColor('criticalRed')
52
+ : event.severity === 'warning'
53
+ ? getBlessedColor('warnAmber')
54
+ : getBlessedColor('accentCyan');
55
+ // Format: [HH:MM:SS] [TAG] message
56
+ return `{${color}-fg}[${time}] [${tag}] ${message}{/}`;
57
+ }
58
+ /**
59
+ * Render OPERATIONS FEED panel
60
+ */
61
+ export function renderOperationsFeedPanel(screen, top, left, width, height, appState) {
62
+ let systemState;
63
+ try {
64
+ systemState = getSystemState(appState, false);
65
+ }
66
+ catch {
67
+ systemState = null;
68
+ }
69
+ const content = [];
70
+ if (systemState && systemState.operationFeed.length > 0) {
71
+ // Show last 10-12 events (newest first)
72
+ const events = systemState.operationFeed
73
+ .slice(-12)
74
+ .reverse()
75
+ .map(formatEvent);
76
+ content.push(...events);
77
+ }
78
+ else {
79
+ content.push(`{${getBlessedColor('mutedGrey')}-fg}NO RECENT OPERATIONS{/}`);
80
+ }
81
+ return createPanel(screen, {
82
+ title: 'OPERATIONS FEED',
83
+ top,
84
+ left,
85
+ width,
86
+ height,
87
+ content,
88
+ });
89
+ }
90
+ //# sourceMappingURL=operations-feed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations-feed.js","sourceRoot":"","sources":["../../../src/ui/panels/operations-feed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Panel 1: POSTURE
3
+ * Location: Left column (top)
4
+ * Purpose: Answer "Am I safe to operate?"
5
+ */
6
+ import type { Widgets } from 'neo-blessed';
7
+ import type { AppState } from '../../store.js';
8
+ /**
9
+ * Render POSTURE panel
10
+ */
11
+ export declare function renderPosturePanel(screen: Widgets.Screen, top: number, left: number, width: number, height: number, appState: AppState): Widgets.Box;
12
+ //# sourceMappingURL=posture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posture.d.ts","sourceRoot":"","sources":["../../../src/ui/panels/posture.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAM/C;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,GAAG,CAsEb"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Panel 1: POSTURE
3
+ * Location: Left column (top)
4
+ * Purpose: Answer "Am I safe to operate?"
5
+ */
6
+ import { getSystemState } from '../../system-state.js';
7
+ import { createPanel } from '../primitives/Panel.js';
8
+ import { getBlessedColor } from '../theme/tokens.js';
9
+ import { formatRelativeTime } from '../../utils.js';
10
+ /**
11
+ * Render POSTURE panel
12
+ */
13
+ export function renderPosturePanel(screen, top, left, width, height, appState) {
14
+ let systemState;
15
+ try {
16
+ systemState = getSystemState(appState, false);
17
+ }
18
+ catch {
19
+ systemState = null;
20
+ }
21
+ const content = [];
22
+ // POSTURE
23
+ const posture = systemState?.systemPosture.overallPosture || 'UNKNOWN';
24
+ let postureColor = 'white';
25
+ if (posture === 'OPERATIONAL')
26
+ postureColor = getBlessedColor('successGreen');
27
+ else if (posture === 'DEGRADED')
28
+ postureColor = getBlessedColor('warnAmber');
29
+ else if (posture === 'CRITICAL')
30
+ postureColor = getBlessedColor('criticalRed');
31
+ content.push(`POSTURE: {${postureColor}-fg}${posture}{/}`);
32
+ // RISK
33
+ const risk = systemState?.systemPosture.riskLevel || 'UNKNOWN';
34
+ let riskColor = 'white';
35
+ if (risk === 'LOW')
36
+ riskColor = getBlessedColor('successGreen');
37
+ else if (risk === 'ELEVATED')
38
+ riskColor = getBlessedColor('warnAmber');
39
+ else if (risk === 'HIGH')
40
+ riskColor = getBlessedColor('criticalRed');
41
+ content.push(`RISK: {${riskColor}-fg}${risk}{/}`);
42
+ // CONNECTED
43
+ const connected = appState.gatewayConnected ? 'YES' : 'NO';
44
+ const target = appState.gatewayUrl
45
+ ? appState.gatewayUrl.replace(/^https?:\/\//, '').substring(0, 20)
46
+ : '';
47
+ const connectedText = connected === 'YES' && target
48
+ ? `${connected} (${target})`
49
+ : connected;
50
+ const connectedColor = connected === 'YES'
51
+ ? getBlessedColor('successGreen')
52
+ : getBlessedColor('warnAmber');
53
+ content.push(`CONNECTED: {${connectedColor}-fg}${connectedText}{/}`);
54
+ // LAST CHANGE
55
+ const lastChange = systemState?.systemPosture.lastStateChange
56
+ ? formatRelativeTime(systemState.systemPosture.lastStateChange)
57
+ : 'UNKNOWN';
58
+ content.push(`LAST CHANGE: ${lastChange}`);
59
+ // CAUSE (only if not OPERATIONAL)
60
+ if (posture !== 'OPERATIONAL' && posture !== 'UNKNOWN') {
61
+ let cause = '';
62
+ if (posture === 'CRITICAL') {
63
+ cause = 'System initialization failed';
64
+ }
65
+ else if (posture === 'DEGRADED') {
66
+ cause = 'No gateway connection';
67
+ }
68
+ else if (posture === 'OFFLINE') {
69
+ cause = 'Offline mode';
70
+ }
71
+ if (cause) {
72
+ content.push(`CAUSE: {${getBlessedColor('warnAmber')}-fg}${cause}{/}`);
73
+ }
74
+ }
75
+ return createPanel(screen, {
76
+ title: 'POSTURE',
77
+ top,
78
+ left,
79
+ width,
80
+ height,
81
+ content,
82
+ });
83
+ }
84
+ //# sourceMappingURL=posture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posture.js","sourceRoot":"","sources":["../../../src/ui/panels/posture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Panel 2: RESOURCES
3
+ * Location: Left column (middle)
4
+ * Purpose: Give devs confidence the system is under control
5
+ */
6
+ import type { Widgets } from 'neo-blessed';
7
+ /**
8
+ * Render RESOURCES panel
9
+ */
10
+ export declare function renderResourcesPanel(screen: Widgets.Screen, top: number, left: number, width: number, height: number, appState?: any): Widgets.Box;
11
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../../src/ui/panels/resources.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAqD3C;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,GAAG,GACb,OAAO,CAAC,GAAG,CAsCb"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Panel 2: RESOURCES
3
+ * Location: Left column (middle)
4
+ * Purpose: Give devs confidence the system is under control
5
+ */
6
+ import * as os from 'os';
7
+ import { createPanel } from '../primitives/Panel.js';
8
+ // Uptime formatting done inline
9
+ /**
10
+ * Get CPU usage (simplified - would need actual monitoring in production)
11
+ */
12
+ function getCpuUsage() {
13
+ // For v1, return UNKNOWN (would need os-utils or similar)
14
+ // In production, would track CPU over time
15
+ return 'UNKNOWN';
16
+ }
17
+ /**
18
+ * Get load average (1 minute)
19
+ */
20
+ function getLoadAverage() {
21
+ const load = os.loadavg();
22
+ if (load && load.length > 0) {
23
+ return load[0].toFixed(2);
24
+ }
25
+ return 'UNKNOWN';
26
+ }
27
+ /**
28
+ * Get RAM usage
29
+ */
30
+ function getRamUsage() {
31
+ const total = os.totalmem();
32
+ const free = os.freemem();
33
+ const used = total - free;
34
+ const usedGB = (used / 1024 / 1024 / 1024).toFixed(1);
35
+ const totalGB = (total / 1024 / 1024 / 1024).toFixed(1);
36
+ return `${usedGB}G / ${totalGB}G`;
37
+ }
38
+ /**
39
+ * Get disk usage (simplified - would need actual disk monitoring)
40
+ */
41
+ function getDiskUsage() {
42
+ // For v1, return UNKNOWN (would need statvfs or similar)
43
+ return 'UNKNOWN';
44
+ }
45
+ /**
46
+ * Get process count
47
+ */
48
+ function getProcessCount() {
49
+ // Simplified - would count actual processes
50
+ return 'UNKNOWN';
51
+ }
52
+ /**
53
+ * Render RESOURCES panel
54
+ */
55
+ export function renderResourcesPanel(screen, top, left, width, height, appState // Not used but kept for consistency
56
+ ) {
57
+ const content = [];
58
+ // CPU
59
+ const cpu = getCpuUsage();
60
+ content.push(`CPU: ${cpu}`);
61
+ // LOAD
62
+ const load = getLoadAverage();
63
+ content.push(`LOAD: ${load}`);
64
+ // RAM
65
+ const ram = getRamUsage();
66
+ content.push(`RAM: ${ram}`);
67
+ // DISK
68
+ const disk = getDiskUsage();
69
+ content.push(`DISK: ${disk}`);
70
+ // UPTIME
71
+ const uptimeSeconds = os.uptime();
72
+ const hours = Math.floor(uptimeSeconds / 3600);
73
+ const minutes = Math.floor((uptimeSeconds % 3600) / 60);
74
+ const uptime = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
75
+ content.push(`UPTIME: ${uptime}`);
76
+ // PROCS
77
+ const procs = getProcessCount();
78
+ content.push(`PROCS: ${procs}`);
79
+ return createPanel(screen, {
80
+ title: 'RESOURCES',
81
+ top,
82
+ left,
83
+ width,
84
+ height,
85
+ content,
86
+ });
87
+ }
88
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../../src/ui/panels/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Panel Primitive
3
+ * Phase 1: Reusable panel component with consistent styling
4
+ */
5
+ import type { Widgets } from 'neo-blessed';
6
+ import type { PanelId } from '../navigation/types.js';
7
+ /**
8
+ * Panel Options
9
+ */
10
+ export interface PanelOptions {
11
+ title: string;
12
+ top: number;
13
+ left: number;
14
+ width: number;
15
+ height: number;
16
+ content?: string[];
17
+ focused?: boolean;
18
+ panelId?: PanelId;
19
+ severity?: 'OK' | 'WARNING' | 'CRITICAL' | 'NEUTRAL';
20
+ }
21
+ /**
22
+ * Create a consistent panel widget
23
+ */
24
+ export declare function createPanel(screen: Widgets.Screen, options: PanelOptions): Widgets.Box;
25
+ //# sourceMappingURL=Panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../src/ui/primitives/Panel.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAKtD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;CACtD;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,OAAO,CAAC,MAAM,EACtB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,GAAG,CAkEb"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Panel Primitive
3
+ * Phase 1: Reusable panel component with consistent styling
4
+ */
5
+ import blessed from 'neo-blessed';
6
+ import { getBorderStyle } from '../theme/borders.js';
7
+ import { renderPanelTitle } from '../theme/typography.js';
8
+ // Type assertion for blessed (neo-blessed doesn't have full TypeScript support)
9
+ const blessedLib = blessed;
10
+ /**
11
+ * Create a consistent panel widget
12
+ */
13
+ export function createPanel(screen, options) {
14
+ const { title, top, left, width, height, content = [], focused = false, panelId, severity = 'NEUTRAL', } = options;
15
+ // Get border style (Phase 7: glow system)
16
+ const borderStyle = getBorderStyle(panelId || 'POSTURE', focused, severity);
17
+ // Render title with typography standard
18
+ const titleText = renderPanelTitle(title, focused);
19
+ const panel = blessedLib.box({
20
+ top,
21
+ left,
22
+ width,
23
+ height,
24
+ border: {
25
+ type: borderStyle.borderType,
26
+ },
27
+ style: {
28
+ border: {
29
+ fg: borderStyle.borderColor,
30
+ },
31
+ },
32
+ tags: true,
33
+ });
34
+ // Title area (top border label)
35
+ const titleBox = blessedLib.box({
36
+ top: 0,
37
+ left: 1,
38
+ width: title.length + 4, // Account for padding
39
+ height: 1,
40
+ content: titleText,
41
+ tags: true,
42
+ });
43
+ panel.append(titleBox);
44
+ // Content area
45
+ if (content.length > 0) {
46
+ const contentText = content.slice(0, height - 2).join('\n');
47
+ const contentBox = blessedLib.box({
48
+ top: 1,
49
+ left: 1,
50
+ width: width - 2,
51
+ height: height - 2,
52
+ content: contentText,
53
+ tags: true,
54
+ });
55
+ panel.append(contentBox);
56
+ }
57
+ return panel;
58
+ }
59
+ //# sourceMappingURL=Panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Panel.js","sourceRoot":"","sources":["../../../src/ui/primitives/Panel.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,OAAO,MAAM,aAAa,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAoB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,gFAAgF;AAChF,MAAM,UAAU,GAAQ,OAAO,CAAC;AAiBhC;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,MAAsB,EACtB,OAAqB;IAErB,MAAM,EACJ,KAAK,EACL,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,EACN,OAAO,GAAG,EAAE,EACZ,OAAO,GAAG,KAAK,EACf,OAAO,EACP,QAAQ,GAAG,SAAS,GACrB,GAAG,OAAO,CAAC;IAEZ,0CAA0C;IAC1C,MAAM,WAAW,GAAG,cAAc,CAChC,OAAO,IAAI,SAAS,EACpB,OAAO,EACP,QAAQ,CACT,CAAC;IAEF,wCAAwC;IACxC,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAEnD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC;QAC3B,GAAG;QACH,IAAI;QACJ,KAAK;QACL,MAAM;QACN,MAAM,EAAE;YACN,IAAI,EAAE,WAAW,CAAC,UAAU;SAC7B;QACD,KAAK,EAAE;YACL,MAAM,EAAE;gBACN,EAAE,EAAE,WAAW,CAAC,WAAW;aAC5B;SACF;QACD,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;IAEH,gCAAgC;IAChC,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC;QAC9B,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,sBAAsB;QAC/C,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;IAEH,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEvB,eAAe;IACf,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC;YAChC,GAAG,EAAE,CAAC;YACN,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,KAAK,GAAG,CAAC;YAChB,MAAM,EAAE,MAAM,GAAG,CAAC;YAClB,OAAO,EAAE,WAAW;YACpB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Metric Renderer
3
+ * Phase 9: UI rendering guardrail - no raw values
4
+ */
5
+ import type { CollectorResult } from '../../core/types.js';
6
+ /**
7
+ * Render a metric with status awareness
8
+ *
9
+ * Behavior:
10
+ * - LIVE → show value
11
+ * - STALE → show value + STALE (Xm)
12
+ * - UNAVAILABLE → show UNAVAILABLE + message + action
13
+ * - DISABLED → show DISABLED + action
14
+ */
15
+ export declare function renderMetric(label: string, collectorResult: CollectorResult<any>, valuePath: string | ((data: any) => string), options?: {
16
+ labelWidth?: number;
17
+ valueColor?: string;
18
+ formatValue?: (value: any) => string;
19
+ }): string;
20
+ /**
21
+ * Helper to format timestamp as relative time
22
+ */
23
+ export declare function formatRelativeTime(ts: number): string;
24
+ //# sourceMappingURL=metricRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metricRenderer.d.ts","sourceRoot":"","sources":["../../../src/ui/rendering/metricRenderer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,qBAAqB,CAAC;AAI5E;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,eAAe,CAAC,GAAG,CAAC,EACrC,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,MAAM,CAAC,EAC3C,OAAO,GAAE;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAC;CACjC,GACL,MAAM,CAiDR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAerD"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Metric Renderer
3
+ * Phase 9: UI rendering guardrail - no raw values
4
+ */
5
+ import { getBlessedColor } from '../theme/tokens.js';
6
+ import { formatValue } from '../constraints/unknownHandling.js';
7
+ /**
8
+ * Render a metric with status awareness
9
+ *
10
+ * Behavior:
11
+ * - LIVE → show value
12
+ * - STALE → show value + STALE (Xm)
13
+ * - UNAVAILABLE → show UNAVAILABLE + message + action
14
+ * - DISABLED → show DISABLED + action
15
+ */
16
+ export function renderMetric(label, collectorResult, valuePath, options = {}) {
17
+ const { labelWidth = 12, valueColor, formatValue: customFormatter } = options;
18
+ const status = collectorResult.status;
19
+ const data = collectorResult.data;
20
+ // Extract value from data
21
+ let value;
22
+ if (typeof valuePath === 'function') {
23
+ value = data ? valuePath(data) : undefined;
24
+ }
25
+ else {
26
+ // Simple path access (e.g., "cpuPercent")
27
+ value = data ? data[valuePath] : undefined;
28
+ }
29
+ // Format value
30
+ const formatter = customFormatter || ((v) => formatValue(v));
31
+ const formattedValue = value !== undefined ? formatter(value) : undefined;
32
+ // Build output based on status
33
+ let output;
34
+ let statusColor = getBlessedColor('mutedGrey');
35
+ if (status === 'LIVE') {
36
+ // LIVE → show value
37
+ const displayValue = formattedValue || 'UNKNOWN';
38
+ const color = valueColor || getBlessedColor('accentCyan');
39
+ output = `${label.padEnd(labelWidth)}: {${color}-fg}${displayValue}{/}`;
40
+ }
41
+ else if (status === 'STALE') {
42
+ // STALE → show value + STALE (Xm)
43
+ const ageMinutes = Math.floor((Date.now() - collectorResult.asOf) / 60000);
44
+ const displayValue = formattedValue || 'UNKNOWN';
45
+ const color = valueColor || getBlessedColor('warnAmber');
46
+ output = `${label.padEnd(labelWidth)}: {${color}-fg}${displayValue}{/} {${getBlessedColor('warnAmber')}-fg}STALE (${ageMinutes}m){/}`;
47
+ }
48
+ else if (status === 'UNAVAILABLE') {
49
+ // UNAVAILABLE → show UNAVAILABLE + message + action
50
+ const reason = collectorResult.message || collectorResult.reasonCode || 'Unknown reason';
51
+ const action = collectorResult.action ? ` (run: ${collectorResult.action})` : '';
52
+ output = `${label.padEnd(labelWidth)}: {${getBlessedColor('criticalRed')}-fg}UNAVAILABLE{/} — ${reason}${action}`;
53
+ }
54
+ else if (status === 'DISABLED') {
55
+ // DISABLED → show DISABLED + action
56
+ const action = collectorResult.action ? ` (run: ${collectorResult.action})` : '';
57
+ output = `${label.padEnd(labelWidth)}: {${getBlessedColor('mutedGrey')}-fg}DISABLED{/}${action}`;
58
+ }
59
+ else {
60
+ // Fallback
61
+ output = `${label.padEnd(labelWidth)}: {${getBlessedColor('mutedGrey')}-fg}UNKNOWN{/}`;
62
+ }
63
+ return output;
64
+ }
65
+ /**
66
+ * Helper to format timestamp as relative time
67
+ */
68
+ export function formatRelativeTime(ts) {
69
+ const ageMs = Date.now() - ts;
70
+ const ageMinutes = Math.floor(ageMs / 60000);
71
+ const ageHours = Math.floor(ageMinutes / 60);
72
+ const ageDays = Math.floor(ageHours / 24);
73
+ if (ageDays > 0) {
74
+ return `${ageDays}d`;
75
+ }
76
+ else if (ageHours > 0) {
77
+ return `${ageHours}h`;
78
+ }
79
+ else if (ageMinutes > 0) {
80
+ return `${ageMinutes}m`;
81
+ }
82
+ else {
83
+ return '<1m';
84
+ }
85
+ }
86
+ //# sourceMappingURL=metricRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metricRenderer.js","sourceRoot":"","sources":["../../../src/ui/rendering/metricRenderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Hub Grid Layout
3
+ * Phase 3: Render from UiState snapshot (no direct system calls)
4
+ */
5
+ import type { Widgets } from 'neo-blessed';
6
+ import type { UiState } from '../../core/types.js';
7
+ /**
8
+ * Render hub grid layout
9
+ * Phase 9: Validates hub snapshot before rendering
10
+ */
11
+ export declare function renderHub(screen: Widgets.Screen, uiState: UiState, focusedPanelId?: string): void;
12
+ //# sourceMappingURL=hub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../../../src/ui/runtime/hub.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAanD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAuEjG"}