@adaas/are-html 0.0.20 → 0.0.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 (109) hide show
  1. package/.conf/tsconfig.base.json +1 -0
  2. package/.conf/tsconfig.browser.json +1 -0
  3. package/.conf/tsconfig.node.json +1 -0
  4. package/dist/browser/index.d.mts +206 -7
  5. package/dist/browser/index.mjs +527 -65
  6. package/dist/browser/index.mjs.map +1 -1
  7. package/dist/node/directives/AreDirectiveFor.directive.d.mts +44 -1
  8. package/dist/node/directives/AreDirectiveFor.directive.d.ts +44 -1
  9. package/dist/node/directives/AreDirectiveFor.directive.js +102 -6
  10. package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
  11. package/dist/node/directives/AreDirectiveFor.directive.mjs +102 -6
  12. package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
  13. package/dist/node/directives/AreDirectiveShow.directive.d.mts +32 -0
  14. package/dist/node/directives/AreDirectiveShow.directive.d.ts +32 -0
  15. package/dist/node/directives/AreDirectiveShow.directive.js +81 -0
  16. package/dist/node/directives/AreDirectiveShow.directive.js.map +1 -0
  17. package/dist/node/directives/AreDirectiveShow.directive.mjs +71 -0
  18. package/dist/node/directives/AreDirectiveShow.directive.mjs.map +1 -0
  19. package/dist/node/engine/AreHTML.engine.d.mts +2 -1
  20. package/dist/node/engine/AreHTML.engine.d.ts +2 -1
  21. package/dist/node/engine/AreHTML.engine.js +8 -2
  22. package/dist/node/engine/AreHTML.engine.js.map +1 -1
  23. package/dist/node/engine/AreHTML.engine.mjs +8 -2
  24. package/dist/node/engine/AreHTML.engine.mjs.map +1 -1
  25. package/dist/node/engine/AreHTML.interpreter.d.mts +3 -0
  26. package/dist/node/engine/AreHTML.interpreter.d.ts +3 -0
  27. package/dist/node/engine/AreHTML.interpreter.js +29 -0
  28. package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
  29. package/dist/node/engine/AreHTML.interpreter.mjs +29 -0
  30. package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
  31. package/dist/node/engine/AreHTML.lifecycle.d.mts +8 -1
  32. package/dist/node/engine/AreHTML.lifecycle.d.ts +8 -1
  33. package/dist/node/engine/AreHTML.lifecycle.js +46 -3
  34. package/dist/node/engine/AreHTML.lifecycle.js.map +1 -1
  35. package/dist/node/engine/AreHTML.lifecycle.mjs +46 -3
  36. package/dist/node/engine/AreHTML.lifecycle.mjs.map +1 -1
  37. package/dist/node/helpers/AreScheduler.helper.d.mts +39 -0
  38. package/dist/node/helpers/AreScheduler.helper.d.ts +39 -0
  39. package/dist/node/helpers/AreScheduler.helper.js +40 -0
  40. package/dist/node/helpers/AreScheduler.helper.js.map +1 -0
  41. package/dist/node/helpers/AreScheduler.helper.mjs +40 -0
  42. package/dist/node/helpers/AreScheduler.helper.mjs.map +1 -0
  43. package/dist/node/index.d.mts +4 -1
  44. package/dist/node/index.d.ts +4 -1
  45. package/dist/node/index.js +21 -0
  46. package/dist/node/index.mjs +3 -0
  47. package/dist/node/instructions/AreHTML.instructions.constants.d.mts +1 -0
  48. package/dist/node/instructions/AreHTML.instructions.constants.d.ts +1 -0
  49. package/dist/node/instructions/AreHTML.instructions.constants.js +2 -1
  50. package/dist/node/instructions/AreHTML.instructions.constants.js.map +1 -1
  51. package/dist/node/instructions/AreHTML.instructions.constants.mjs +2 -1
  52. package/dist/node/instructions/AreHTML.instructions.constants.mjs.map +1 -1
  53. package/dist/node/instructions/AreHTML.instructions.types.d.mts +9 -1
  54. package/dist/node/instructions/AreHTML.instructions.types.d.ts +9 -1
  55. package/dist/node/instructions/HideElement.instruction.d.mts +13 -0
  56. package/dist/node/instructions/HideElement.instruction.d.ts +13 -0
  57. package/dist/node/instructions/HideElement.instruction.js +31 -0
  58. package/dist/node/instructions/HideElement.instruction.js.map +1 -0
  59. package/dist/node/instructions/HideElement.instruction.mjs +24 -0
  60. package/dist/node/instructions/HideElement.instruction.mjs.map +1 -0
  61. package/dist/node/lib/AreRoot/AreRoot.component.d.mts +57 -3
  62. package/dist/node/lib/AreRoot/AreRoot.component.d.ts +57 -3
  63. package/dist/node/lib/AreRoot/AreRoot.component.js +138 -49
  64. package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
  65. package/dist/node/lib/AreRoot/AreRoot.component.mjs +140 -51
  66. package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
  67. package/dist/node/lib/AreRoot/AreRootCache.context.d.mts +58 -0
  68. package/dist/node/lib/AreRoot/AreRootCache.context.d.ts +58 -0
  69. package/dist/node/lib/AreRoot/AreRootCache.context.js +106 -0
  70. package/dist/node/lib/AreRoot/AreRootCache.context.js.map +1 -0
  71. package/dist/node/lib/AreRoot/AreRootCache.context.mjs +99 -0
  72. package/dist/node/lib/AreRoot/AreRootCache.context.mjs.map +1 -0
  73. package/examples/dashboard/dist/index.html +1 -1
  74. package/examples/dashboard/dist/{mq19zxz4-mnlgmd.js → mqh9ryml-xat335.js} +1922 -1316
  75. package/examples/dashboard/src/concept.ts +3 -2
  76. package/examples/for-perf/concept.ts +45 -0
  77. package/examples/for-perf/containers/UI.container.ts +161 -0
  78. package/examples/for-perf/dist/index.html +270 -0
  79. package/examples/for-perf/dist/mqh9ryde-m243t8.js +15223 -0
  80. package/examples/for-perf/dist/mqh9ryfo-6a8d0o.js +15223 -0
  81. package/examples/for-perf/dist/mqh9ryfq-4pf5cv.js +15223 -0
  82. package/examples/for-perf/public/index.html +270 -0
  83. package/examples/for-perf/src/components/PerfApp.component.ts +37 -0
  84. package/examples/for-perf/src/components/PerfControls.component.ts +34 -0
  85. package/examples/for-perf/src/components/PerfGrid.component.ts +225 -0
  86. package/examples/for-perf/src/components/PerfHeader.component.ts +34 -0
  87. package/examples/for-perf/src/components/PerfStats.component.ts +43 -0
  88. package/examples/for-perf/src/concept.ts +94 -0
  89. package/examples/jumpstart/dist/index.html +1 -1
  90. package/examples/jumpstart/dist/{mq1a0fv0-ccgtz6.js → mq7mgf58-vbf07e.js} +895 -521
  91. package/examples/signal-routing/dist/index.html +1 -1
  92. package/examples/signal-routing/dist/{mq1bzrik-4lec86.js → mqh9ryc9-dkcbkx.js} +2024 -1300
  93. package/examples/signal-routing/src/components/SettingsPage.component.ts +39 -0
  94. package/examples/signal-routing/src/concept.ts +2 -0
  95. package/jest.config.ts +1 -0
  96. package/package.json +10 -9
  97. package/src/directives/AreDirectiveFor.directive.ts +185 -12
  98. package/src/directives/AreDirectiveShow.directive.ts +127 -0
  99. package/src/engine/AreHTML.engine.ts +11 -1
  100. package/src/engine/AreHTML.interpreter.ts +50 -0
  101. package/src/engine/AreHTML.lifecycle.ts +83 -6
  102. package/src/helpers/AreScheduler.helper.ts +61 -0
  103. package/src/index.ts +3 -0
  104. package/src/instructions/AreHTML.instructions.constants.ts +1 -0
  105. package/src/instructions/AreHTML.instructions.types.ts +9 -0
  106. package/src/instructions/HideElement.instruction.ts +29 -0
  107. package/src/lib/AreRoot/AreRoot.component.ts +205 -72
  108. package/src/lib/AreRoot/AreRootCache.context.ts +133 -0
  109. package/tsconfig.json +1 -0
@@ -64,7 +64,7 @@ import { AreDirectiveIf, AreDirectiveFor, AreHTMLEngineContext, AreHTMLEngine, A
64
64
 
65
65
  new A_Config({
66
66
  defaults: {
67
- [A_LOGGER_ENV_KEYS.LOG_LEVEL]: 'info',
67
+ [A_LOGGER_ENV_KEYS.LOG_LEVEL]: 'debug',
68
68
  }
69
69
  }),
70
70
  ]
@@ -73,8 +73,9 @@ import { AreDirectiveIf, AreDirectiveFor, AreHTMLEngineContext, AreHTMLEngine, A
73
73
  const concept = new A_Concept({
74
74
  name: 'adaas-are-example-dashboard',
75
75
  fragments: [new A_Config({
76
- variables: ['CONFIG_VERBOSE', 'DEV_MODE'] as const,
76
+ variables: ['CONFIG_VERBOSE', 'DEV_MODE', A_LOGGER_ENV_KEYS.LOG_LEVEL] as const,
77
77
  defaults: {
78
+ [A_LOGGER_ENV_KEYS.LOG_LEVEL]: 'debug',
78
79
  CONFIG_VERBOSE: true,
79
80
  DEV_MODE: true
80
81
  }
@@ -0,0 +1,45 @@
1
+ import { A_Concept, A_Context } from "@adaas/a-concept"
2
+ import { UIContainer } from "./containers/UI.container"
3
+ import { A_Logger, A_LoggerEnvVariables } from "@adaas/a-utils/a-logger";
4
+ import { A_Polyfill } from "@adaas/a-utils/a-polyfill";
5
+ import { A_Config, ENVConfigReader } from "@adaas/a-utils/a-config";
6
+
7
+
8
+ (async () => {
9
+ try {
10
+ const Application = new UIContainer({
11
+ name: 'ARE For-Perf',
12
+ components: [
13
+ A_Polyfill,
14
+ ENVConfigReader,
15
+ A_Logger
16
+ ],
17
+ fragments: [
18
+ new A_Config({
19
+ defaults: {
20
+ PORT: 8085,
21
+ CONFIG_VERBOSE: true,
22
+ DEV_MODE: true,
23
+ // Logger at debug so $for transform/update traces are visible
24
+ [A_LoggerEnvVariables.A_LOGGER_LEVEL]: 'debug',
25
+ }
26
+ }),
27
+ ]
28
+ });
29
+
30
+
31
+ const concept = new A_Concept({
32
+ name: 'adaas-are-example-for-perf',
33
+ components: [A_Logger, A_Polyfill, ENVConfigReader],
34
+ containers: [Application],
35
+ })
36
+
37
+ await concept.load();
38
+ await concept.start();
39
+
40
+
41
+ } catch (error) {
42
+ const logger = A_Context.root.resolve<A_Logger>(A_Logger)!;
43
+ logger.error(error);
44
+ }
45
+ })();
@@ -0,0 +1,161 @@
1
+ import { A_Concept, A_IdentityHelper, A_Inject } from "@adaas/a-concept"
2
+ import { A_Config } from "@adaas/a-utils/a-config";
3
+ import { A_Logger } from "@adaas/a-utils/a-logger";
4
+ import { A_Service } from "@adaas/a-utils/a-service";
5
+ import { build } from "esbuild";
6
+ import fs from "fs";
7
+ import http from "http";
8
+ import path from "path";
9
+
10
+
11
+
12
+ export class UIContainer extends A_Service {
13
+
14
+ protected server!: any;
15
+
16
+ @A_Concept.Build()
17
+ async build(
18
+ @A_Inject(A_Logger) logger: A_Logger,
19
+ @A_Inject(A_Config) config: A_Config
20
+ ): Promise<void> {
21
+ logger.log('Building UI Container...', process.cwd());
22
+ const entryFile = path.resolve(__dirname, "../src/concept.ts");
23
+ const BundleID = A_IdentityHelper.generateTimeId();
24
+ const outFile = path.resolve(__dirname, `../dist/${BundleID}.js`);
25
+
26
+
27
+ // first to drop folder if exists
28
+ if (fs.existsSync(path.resolve(__dirname, "../dist"))) {
29
+ fs.rmSync(path.resolve(__dirname, "../dist"), { recursive: true, force: true });
30
+ }
31
+
32
+
33
+ // STEP1 generate Bundle
34
+ await build({
35
+ entryPoints: [entryFile],
36
+ outfile: outFile,
37
+ bundle: true,
38
+ minify: false,
39
+ keepNames: true,
40
+ sourcemap: false,
41
+ target: "es2020",
42
+ format: "esm",
43
+ });
44
+
45
+ logger.log('green', 'UI Container built successfully.');
46
+
47
+
48
+ // STEP 2 replace bundle id in index.html with {{BUNDLE_ID}}
49
+ let indexHtml = await fs.promises.readFile(path.resolve(__dirname, "../public/index.html"), 'utf-8');
50
+ indexHtml = indexHtml.replace('{{BUNDLE_ID}}', BundleID);
51
+ await fs.promises.writeFile(path.resolve(__dirname, `../dist/${BundleID}.js`), await fs.promises.readFile(outFile));
52
+ await fs.promises.writeFile(path.resolve(__dirname, "../dist/index.html"), indexHtml);
53
+
54
+ logger.log('green', 'UI Container index.html updated successfully with bundle id.');
55
+
56
+
57
+ // Step3 copy static assets and directories recursively
58
+ const publicDir = path.resolve(__dirname, "../public");
59
+ const distDir = path.resolve(__dirname, "../dist");
60
+
61
+ const copyRecursive = async (src: string, dest: string) => {
62
+ const entries = await fs.promises.readdir(src, { withFileTypes: true });
63
+ await fs.promises.mkdir(dest, { recursive: true });
64
+
65
+ for (const entry of entries) {
66
+ const srcPath = path.join(src, entry.name);
67
+ const destPath = path.join(dest, entry.name);
68
+
69
+ if (entry.isDirectory()) {
70
+ await copyRecursive(srcPath, destPath);
71
+ } else {
72
+ if (entry.name !== 'index.html') {
73
+ await fs.promises.copyFile(srcPath, destPath);
74
+ }
75
+ }
76
+ }
77
+ };
78
+
79
+ await copyRecursive(publicDir, distDir);
80
+
81
+ logger.log('green', 'UI Container static assets copied successfully.');
82
+ }
83
+
84
+
85
+
86
+ @A_Concept.Load()
87
+ async preLoadBuild(
88
+ @A_Inject(A_Logger) logger: A_Logger,
89
+ @A_Inject(A_Config) config: A_Config
90
+ ) {
91
+ await this.build(logger, config);
92
+ }
93
+
94
+
95
+ @A_Concept.Start()
96
+ async startStaticServer(
97
+ @A_Inject(A_Logger) logger: A_Logger,
98
+ @A_Inject(A_Config) config: A_Config
99
+ ) {
100
+ this.server = http.createServer(this.serverStaticFiles.bind(this));
101
+
102
+ const PORT = config.get('PORT') || 8085;
103
+
104
+ this.server.listen(PORT, () => {
105
+ logger.log('green', `UI Container Static Server is running at http://localhost:${PORT}`);
106
+ });
107
+ }
108
+
109
+
110
+ protected async serverStaticFiles(
111
+ req: http.IncomingMessage,
112
+ res: http.ServerResponse,
113
+ ) {
114
+ const url = req.url || '/';
115
+ let filePath = path.join(__dirname, '../dist', url === '/' ? 'index.html' : url);
116
+
117
+ const logger = this.scope.resolve<A_Logger>(A_Logger)!;
118
+ logger.log('blue', `Serving file: ${filePath}`);
119
+
120
+
121
+ const extname = String(path.extname(filePath)).toLowerCase();
122
+ const mimeTypes: { [key: string]: string } = {
123
+ '.html': 'text/html',
124
+ '.js': 'text/javascript',
125
+ '.css': 'text/css',
126
+ '.json': 'application/json',
127
+ '.png': 'image/png',
128
+ '.jpg': 'image/jpg',
129
+ '.gif': 'image/gif',
130
+ '.svg': 'image/svg+xml',
131
+ '.woff': 'application/font-woff',
132
+ '.ttf': 'application/font-ttf',
133
+ '.eot': 'application/vnd.ms-fontobject',
134
+ '.otf': 'application/font-otf',
135
+ '.wasm': 'application/wasm'
136
+ };
137
+
138
+ const contentType = mimeTypes[extname] || 'application/octet-stream';
139
+
140
+ if (!fs.existsSync(filePath)) {
141
+ logger.log('yellow', `File not found: ${filePath}, serving index.html instead.`);
142
+ filePath = path.join(__dirname, '../dist', 'index.html');
143
+ }
144
+
145
+ fs.readFile(filePath, (error, content) => {
146
+ if (error) {
147
+ if (error.code === 'ENOENT') {
148
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
149
+ res.end('404 Not Found', 'utf-8');
150
+ } else {
151
+ res.writeHead(500);
152
+ res.end(`Server Error: ${error.code}`, 'utf-8');
153
+ }
154
+ } else {
155
+ res.writeHead(200, { 'Content-Type': contentType });
156
+ res.end(content, 'utf-8');
157
+ }
158
+ });
159
+ }
160
+
161
+ }
@@ -0,0 +1,270 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>ARE $for Performance Lab</title>
8
+ <style>
9
+ * {
10
+ box-sizing: border-box;
11
+ margin: 0;
12
+ padding: 0;
13
+ }
14
+
15
+ body {
16
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
17
+ background: #0f0f17;
18
+ color: #e5e7eb;
19
+ }
20
+
21
+ are-root {
22
+ display: block;
23
+ min-height: 100vh;
24
+ }
25
+
26
+ .app {
27
+ max-width: 1100px;
28
+ margin: 0 auto;
29
+ padding: 24px 20px 60px;
30
+ }
31
+
32
+ /* ---------- header ---------- */
33
+ .header {
34
+ display: flex;
35
+ align-items: baseline;
36
+ justify-content: space-between;
37
+ gap: 16px;
38
+ padding-bottom: 16px;
39
+ border-bottom: 1px solid #23232f;
40
+ flex-wrap: wrap;
41
+ }
42
+
43
+ .brand {
44
+ display: flex;
45
+ align-items: center;
46
+ gap: 10px;
47
+ }
48
+
49
+ .logo {
50
+ font-size: 22px;
51
+ color: #7c3aed;
52
+ }
53
+
54
+ .title {
55
+ font-size: 20px;
56
+ font-weight: 700;
57
+ }
58
+
59
+ .subtitle {
60
+ font-size: 12px;
61
+ color: #8b8b9b;
62
+ }
63
+
64
+ /* ---------- legend ---------- */
65
+ .legend {
66
+ display: flex;
67
+ gap: 10px;
68
+ flex-wrap: wrap;
69
+ margin: 18px 0 10px;
70
+ }
71
+
72
+ .legend-card {
73
+ display: flex;
74
+ flex-direction: column;
75
+ gap: 2px;
76
+ background: #181824;
77
+ border: 1px solid #23232f;
78
+ border-radius: 8px;
79
+ padding: 8px 12px;
80
+ min-width: 130px;
81
+ }
82
+
83
+ .legend-key {
84
+ font-size: 11px;
85
+ text-transform: uppercase;
86
+ letter-spacing: 0.06em;
87
+ color: #7c3aed;
88
+ font-weight: 700;
89
+ }
90
+
91
+ .legend-label {
92
+ font-size: 12px;
93
+ color: #b6b6c6;
94
+ }
95
+
96
+ /* ---------- hint ---------- */
97
+ .hint {
98
+ display: flex;
99
+ align-items: center;
100
+ gap: 8px;
101
+ font-size: 12px;
102
+ color: #8b8b9b;
103
+ margin-bottom: 18px;
104
+ }
105
+
106
+ .hint-icon {
107
+ color: #7c3aed;
108
+ }
109
+
110
+ /* ---------- toolbar ---------- */
111
+ .toolbar {
112
+ display: flex;
113
+ gap: 8px;
114
+ flex-wrap: wrap;
115
+ align-items: center;
116
+ margin-bottom: 12px;
117
+ }
118
+
119
+ .btn {
120
+ background: #1f1f2e;
121
+ color: #e5e7eb;
122
+ border: 1px solid #2d2d3d;
123
+ border-radius: 6px;
124
+ padding: 8px 14px;
125
+ font-size: 13px;
126
+ cursor: pointer;
127
+ transition: background 0.15s, border-color 0.15s;
128
+ }
129
+
130
+ .btn:hover {
131
+ background: #2a2a3e;
132
+ border-color: #7c3aed;
133
+ }
134
+
135
+ .btn-danger:hover {
136
+ border-color: #ef4444;
137
+ }
138
+
139
+ .sep {
140
+ width: 1px;
141
+ height: 22px;
142
+ background: #2d2d3d;
143
+ margin: 0 4px;
144
+ }
145
+
146
+ /* ---------- meta ---------- */
147
+ .meta {
148
+ display: flex;
149
+ gap: 8px;
150
+ flex-wrap: wrap;
151
+ margin-bottom: 14px;
152
+ }
153
+
154
+ .pill {
155
+ background: #181824;
156
+ border: 1px solid #23232f;
157
+ border-radius: 999px;
158
+ padding: 4px 12px;
159
+ font-size: 12px;
160
+ color: #b6b6c6;
161
+ }
162
+
163
+ .empty {
164
+ padding: 30px;
165
+ text-align: center;
166
+ color: #6b6b7b;
167
+ border: 1px dashed #2d2d3d;
168
+ border-radius: 8px;
169
+ }
170
+
171
+ /* ---------- grid ---------- */
172
+ .grid {
173
+ display: flex;
174
+ flex-direction: column;
175
+ gap: 4px;
176
+ }
177
+
178
+ .row {
179
+ display: flex;
180
+ align-items: center;
181
+ gap: 12px;
182
+ background: #15151f;
183
+ border: 1px solid #1f1f2b;
184
+ border-radius: 6px;
185
+ padding: 6px 12px;
186
+ font-size: 13px;
187
+ }
188
+
189
+ .row-active {
190
+ border-color: #7c3aed;
191
+ background: #1a1626;
192
+ }
193
+
194
+ .row-id {
195
+ width: 64px;
196
+ color: #6b6b7b;
197
+ font-variant-numeric: tabular-nums;
198
+ }
199
+
200
+ .row-label {
201
+ width: 90px;
202
+ font-weight: 600;
203
+ }
204
+
205
+ .badge {
206
+ font-size: 11px;
207
+ font-weight: 600;
208
+ padding: 2px 8px;
209
+ border-radius: 999px;
210
+ text-transform: uppercase;
211
+ letter-spacing: 0.04em;
212
+ }
213
+
214
+ .badge-ok {
215
+ background: #064e3b;
216
+ color: #6ee7b7;
217
+ }
218
+
219
+ .badge-warn {
220
+ background: #4d3c06;
221
+ color: #fcd34d;
222
+ }
223
+
224
+ .badge-error {
225
+ background: #4c0519;
226
+ color: #fda4af;
227
+ }
228
+
229
+ .badge-idle {
230
+ background: #1f2937;
231
+ color: #9ca3af;
232
+ }
233
+
234
+ .star {
235
+ color: #fbbf24;
236
+ }
237
+
238
+ .cells {
239
+ display: flex;
240
+ gap: 4px;
241
+ margin-left: auto;
242
+ }
243
+
244
+ .cell {
245
+ background: #1f1f2e;
246
+ border-radius: 4px;
247
+ padding: 2px 8px;
248
+ font-size: 12px;
249
+ color: #b6b6c6;
250
+ font-variant-numeric: tabular-nums;
251
+ }
252
+
253
+ .row-value {
254
+ width: 70px;
255
+ text-align: right;
256
+ color: #8b8b9b;
257
+ font-variant-numeric: tabular-nums;
258
+ }
259
+ </style>
260
+ </head>
261
+
262
+ <body>
263
+ <are-root id="app">
264
+ <perf-app></perf-app>
265
+ </are-root>
266
+
267
+ <script type="module" src="./mqh9ryfq-4pf5cv.js"></script>
268
+ </body>
269
+
270
+ </html>