matterbridge 3.3.3-dev-20251012-1af2e85 → 3.3.3-dev-20251014-c1b948a

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.
@@ -24,10 +24,10 @@ export class BroadcastServer extends EventEmitter {
24
24
  return Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;
25
25
  }
26
26
  isWorkerRequest(msg, type) {
27
- return typeof msg === 'object' && msg !== null && 'id' in msg && 'type' in msg && msg.type === type && !('response' in msg) && 'src' in msg && 'dst' in msg;
27
+ return typeof msg === 'object' && msg !== null && 'id' in msg && 'timestamp' in msg && 'type' in msg && msg.type === type && !('response' in msg) && 'src' in msg && 'dst' in msg;
28
28
  }
29
29
  isWorkerResponse(msg, type) {
30
- return typeof msg === 'object' && msg !== null && 'id' in msg && 'type' in msg && msg.type === type && 'response' in msg && 'src' in msg && 'dst' in msg;
30
+ return typeof msg === 'object' && msg !== null && 'id' in msg && 'timestamp' in msg && 'type' in msg && msg.type === type && 'response' in msg && 'src' in msg && 'dst' in msg;
31
31
  }
32
32
  broadcastMessageHandler(event) {
33
33
  const data = event.data;
@@ -38,6 +38,9 @@ export class BroadcastServer extends EventEmitter {
38
38
  if (message.id === undefined) {
39
39
  message.id = this.getUniqueId();
40
40
  }
41
+ if (message.timestamp === undefined) {
42
+ message.timestamp = Date.now();
43
+ }
41
44
  if (!this.isWorkerRequest(message, message.type)) {
42
45
  this.log.error(`Invalid request message format for broadcast: ${debugStringify(message)}`);
43
46
  return;
@@ -46,6 +49,9 @@ export class BroadcastServer extends EventEmitter {
46
49
  this.broadcastChannel.postMessage(message);
47
50
  }
48
51
  respond(message) {
52
+ if (message.timestamp === undefined) {
53
+ message.timestamp = Date.now();
54
+ }
49
55
  if (!this.isWorkerResponse(message, message.type)) {
50
56
  this.log.error(`Invalid response message format for broadcast: ${debugStringify(message)}`);
51
57
  return;
@@ -54,6 +60,12 @@ export class BroadcastServer extends EventEmitter {
54
60
  this.broadcastChannel.postMessage(message);
55
61
  }
56
62
  async fetch(message) {
63
+ if (message.id === undefined) {
64
+ message.id = this.getUniqueId();
65
+ }
66
+ if (message.timestamp === undefined) {
67
+ message.timestamp = Date.now();
68
+ }
57
69
  this.log.debug(`*Fetching message: ${debugStringify(message)}`);
58
70
  return new Promise((resolve, reject) => {
59
71
  const responseHandler = (msg) => {
@@ -2,7 +2,7 @@ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
2
2
  console.log('\u001B[32mCli history loaded.\u001B[40;0m');
3
3
  import { writeFileSync } from 'node:fs';
4
4
  import path from 'node:path';
5
- export const historySize = 4320;
5
+ export const historySize = 2880;
6
6
  export let historyIndex = 0;
7
7
  export function setHistoryIndex(index) {
8
8
  if (!Number.isFinite(index) || !Number.isSafeInteger(index)) {
@@ -70,10 +70,12 @@ export function generateHistoryPage(options = {}) {
70
70
  peakArrayBuffers,
71
71
  };
72
72
  const html = `<!DOCTYPE html>
73
- <html lang="en">
73
+ <html lang="en" translate="no">
74
74
  <head>
75
75
  <meta charset="UTF-8" />
76
76
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
+ <meta name="google" content="notranslate" />
78
+ <meta http-equiv="Content-Language" content="en" />
77
79
  <title>${escapeHtml(pageTitle)}</title>
78
80
  <link rel="preconnect" href="https://fonts.googleapis.com" />
79
81
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
@@ -251,6 +253,11 @@ export function generateHistoryPage(options = {}) {
251
253
  <canvas id="memoryChart"></canvas>
252
254
  </section>
253
255
 
256
+ <section class="card">
257
+ <h2>External and Array Buffers (MB)</h2>
258
+ <canvas id="extArrayChart"></canvas>
259
+ </section>
260
+
254
261
  <section class="card">
255
262
  <h2>Samples</h2>
256
263
  <div class="table-wrapper">
@@ -371,6 +378,31 @@ export function generateHistoryPage(options = {}) {
371
378
  }, 0);
372
379
  const memoryMaxYAxis = Number.isFinite(memoryMaxMb) && memoryMaxMb > 0 ? memoryMaxMb * 1.05 : undefined;
373
380
 
381
+ // Compute External/ArrayBuffers chart dynamic min/max
382
+ const extArrayMinMb = HISTORY_DATA.reduce(function (acc, entry) {
383
+ const values = [entry.external, entry.arrayBuffers].map(bytesToMb);
384
+ const finiteValues = values.filter(function (v) { return Number.isFinite(v); });
385
+ const minEntry = finiteValues.length ? Math.min.apply(Math, finiteValues) : acc;
386
+ return Math.min(acc, minEntry);
387
+ }, Number.POSITIVE_INFINITY);
388
+
389
+ const extArrayMinYAxis = Number.isFinite(extArrayMinMb) && extArrayMinMb > 0
390
+ ? Math.max(0, extArrayMinMb - extArrayMinMb * 0.1)
391
+ : 0;
392
+
393
+ const extArrayMaxMb = HISTORY_DATA.reduce(function (acc, entry) {
394
+ const values = [
395
+ entry.external,
396
+ entry.arrayBuffers,
397
+ entry.peakExternal,
398
+ entry.peakArrayBuffers,
399
+ ].map(bytesToMb);
400
+ const finiteValues = values.filter(function (v) { return Number.isFinite(v); });
401
+ const maxEntry = finiteValues.length ? Math.max.apply(Math, finiteValues) : acc;
402
+ return Math.max(acc, maxEntry);
403
+ }, 0);
404
+ const extArrayMaxYAxis = Number.isFinite(extArrayMaxMb) && extArrayMaxMb > 0 ? extArrayMaxMb * 1.05 : undefined;
405
+
374
406
  renderCharts();
375
407
 
376
408
  function renderCharts() {
@@ -386,7 +418,14 @@ export function generateHistoryPage(options = {}) {
386
418
  return Number.isFinite(entry.cpu) ? Number(entry.cpu.toFixed(2)) : 0;
387
419
  }),
388
420
  color: '#38bdf8',
389
- fill: 'rgba(56, 189, 248, 0.18)'
421
+ fill: 'rgba(56, 189, 248, 0.18)',
422
+ markPeaks: true,
423
+ markerPeakValues: HISTORY_DATA.map(function (entry) {
424
+ if (Number.isFinite(entry.peakCpu)) return entry.peakCpu;
425
+ if (Number.isFinite(entry.cpu)) return entry.cpu;
426
+ return Number.NEGATIVE_INFINITY;
427
+ }),
428
+ markerRadius: 2.5
390
429
  },
391
430
  {
392
431
  label: 'Host Peak CPU %',
@@ -413,7 +452,14 @@ export function generateHistoryPage(options = {}) {
413
452
  return Number.isFinite(entry.processCpu) ? Number(entry.processCpu.toFixed(2)) : 0;
414
453
  }),
415
454
  color: '#a855f7',
416
- fill: 'rgba(168, 85, 247, 0.18)'
455
+ fill: 'rgba(168, 85, 247, 0.18)',
456
+ markPeaks: true,
457
+ markerPeakValues: HISTORY_DATA.map(function (entry) {
458
+ if (Number.isFinite(entry.peakProcessCpu)) return entry.peakProcessCpu;
459
+ if (Number.isFinite(entry.processCpu)) return entry.processCpu;
460
+ return Number.NEGATIVE_INFINITY;
461
+ }),
462
+ markerRadius: 2.5
417
463
  },
418
464
  {
419
465
  label: 'Process Peak CPU %',
@@ -444,17 +490,38 @@ export function generateHistoryPage(options = {}) {
444
490
  label: 'RSS (MB)',
445
491
  values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.rss); }),
446
492
  color: '#34d399',
447
- fill: 'rgba(52, 211, 153, 0.18)'
493
+ fill: 'rgba(52, 211, 153, 0.18)',
494
+ markPeaks: true,
495
+ markerPeakValues: HISTORY_DATA.map(function (entry) {
496
+ if (Number.isFinite(entry.peakRss)) return entry.peakRss;
497
+ if (Number.isFinite(entry.rss)) return entry.rss;
498
+ return Number.NEGATIVE_INFINITY;
499
+ }),
500
+ markerRadius: 2.5
448
501
  },
449
502
  {
450
503
  label: 'Heap Total (MB)',
451
504
  values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.heapTotal); }),
452
- color: '#fb923c'
505
+ color: '#fb923c',
506
+ markPeaks: true,
507
+ markerPeakValues: HISTORY_DATA.map(function (entry) {
508
+ if (Number.isFinite(entry.peakHeapTotal)) return entry.peakHeapTotal;
509
+ if (Number.isFinite(entry.heapTotal)) return entry.heapTotal;
510
+ return Number.NEGATIVE_INFINITY;
511
+ }),
512
+ markerRadius: 2.5
453
513
  },
454
514
  {
455
515
  label: 'Heap Used (MB)',
456
516
  values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.heapUsed); }),
457
- color: '#f472b6'
517
+ color: '#f472b6',
518
+ markPeaks: true,
519
+ markerPeakValues: HISTORY_DATA.map(function (entry) {
520
+ if (Number.isFinite(entry.peakHeapUsed)) return entry.peakHeapUsed;
521
+ if (Number.isFinite(entry.heapUsed)) return entry.heapUsed;
522
+ return Number.NEGATIVE_INFINITY;
523
+ }),
524
+ markerRadius: 2.5
458
525
  }
459
526
  ],
460
527
  minY: memoryMinYAxis,
@@ -463,6 +530,43 @@ export function generateHistoryPage(options = {}) {
463
530
  return value.toFixed(0) + ' MB';
464
531
  }
465
532
  });
533
+
534
+ // External and Array Buffers chart
535
+ renderLineChart('extArrayChart', {
536
+ labels: labels,
537
+ datasets: [
538
+ {
539
+ label: 'External (MB)',
540
+ values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.external); }),
541
+ color: '#60a5fa',
542
+ fill: 'rgba(96, 165, 250, 0.18)',
543
+ markPeaks: true,
544
+ markerPeakValues: HISTORY_DATA.map(function (entry) {
545
+ if (Number.isFinite(entry.peakExternal)) return entry.peakExternal;
546
+ if (Number.isFinite(entry.external)) return entry.external;
547
+ return Number.NEGATIVE_INFINITY;
548
+ }),
549
+ markerRadius: 2.5
550
+ },
551
+ {
552
+ label: 'Array Buffers (MB)',
553
+ values: HISTORY_DATA.map(function (entry) { return bytesToMb(entry.arrayBuffers); }),
554
+ color: '#22d3ee',
555
+ markPeaks: true,
556
+ markerPeakValues: HISTORY_DATA.map(function (entry) {
557
+ if (Number.isFinite(entry.peakArrayBuffers)) return entry.peakArrayBuffers;
558
+ if (Number.isFinite(entry.arrayBuffers)) return entry.arrayBuffers;
559
+ return Number.NEGATIVE_INFINITY;
560
+ }),
561
+ markerRadius: 2.5
562
+ }
563
+ ],
564
+ minY: extArrayMinYAxis,
565
+ maxY: extArrayMaxYAxis,
566
+ yFormatter: function (value) {
567
+ return value.toFixed(0) + ' MB';
568
+ }
569
+ });
466
570
  }
467
571
 
468
572
  draw();
@@ -634,6 +738,29 @@ export function generateHistoryPage(options = {}) {
634
738
  });
635
739
  ctx.stroke();
636
740
  ctx.setLineDash([]);
741
+
742
+ // Draw new-peak markers if enabled
743
+ if (dataset.markPeaks) {
744
+ let runningMax = -Infinity;
745
+ const radius = Number.isFinite(dataset.markerRadius) ? dataset.markerRadius : 2.5;
746
+ ctx.save();
747
+ ctx.fillStyle = dataset.markerColor || dataset.color;
748
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.85)';
749
+ ctx.lineWidth = 1;
750
+ const peakSeries = Array.isArray(dataset.markerPeakValues) ? dataset.markerPeakValues : dataset.values;
751
+ peakSeries.forEach(function (value, idx) {
752
+ if (!Number.isFinite(value)) return;
753
+ if (value > runningMax) {
754
+ runningMax = value;
755
+ const p = points[idx];
756
+ ctx.beginPath();
757
+ ctx.arc(p.x, p.y, radius, 0, Math.PI * 2);
758
+ ctx.fill();
759
+ ctx.stroke();
760
+ }
761
+ });
762
+ ctx.restore();
763
+ }
637
764
  });
638
765
 
639
766
  ctx.setTransform(1, 0, 0, 1, 0, 0);
@@ -16,36 +16,34 @@ export class DeviceManager {
16
16
  this.server.close();
17
17
  }
18
18
  async msgHandler(msg) {
19
- if (!this.server.isWorkerRequest(msg, msg.type))
20
- return;
21
- if (!msg.id || (msg.dst !== 'all' && msg.dst !== 'devices'))
22
- return;
23
- this.log.debug(`**Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
24
- switch (msg.type) {
25
- case 'devices_length':
26
- this.server.respond({ ...msg, id: msg.id, response: { length: this.length } });
27
- break;
28
- case 'devices_size':
29
- this.server.respond({ ...msg, id: msg.id, response: { size: this.size } });
30
- break;
31
- case 'devices_has':
32
- this.server.respond({ ...msg, id: msg.id, response: { has: this.has(msg.params.uniqueId) } });
33
- break;
34
- case 'devices_get':
35
- this.server.respond({ ...msg, id: msg.id, response: { device: this.get(msg.params.uniqueId) } });
36
- break;
37
- case 'devices_set':
38
- this.server.respond({ ...msg, id: msg.id, response: { device: this.set(msg.params.device) } });
39
- break;
40
- case 'devices_remove':
41
- this.server.respond({ ...msg, id: msg.id, response: { success: this.remove(msg.params.device) } });
42
- break;
43
- case 'devices_clear':
44
- this.clear();
45
- this.server.respond({ ...msg, id: msg.id, response: { success: true } });
46
- break;
47
- default:
48
- this.log.warn(`Unknown broadcast message ${CYAN}${msg.type}${wr} from ${CYAN}${msg.src}${wr}`);
19
+ if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'devices')) {
20
+ this.log.debug(`**Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
21
+ switch (msg.type) {
22
+ case 'devices_length':
23
+ this.server.respond({ ...msg, response: { length: this.length } });
24
+ break;
25
+ case 'devices_size':
26
+ this.server.respond({ ...msg, response: { size: this.size } });
27
+ break;
28
+ case 'devices_has':
29
+ this.server.respond({ ...msg, response: { has: this.has(msg.params.uniqueId) } });
30
+ break;
31
+ case 'devices_get':
32
+ this.server.respond({ ...msg, response: { device: this.get(msg.params.uniqueId) } });
33
+ break;
34
+ case 'devices_set':
35
+ this.server.respond({ ...msg, response: { device: this.set(msg.params.device) } });
36
+ break;
37
+ case 'devices_remove':
38
+ this.server.respond({ ...msg, response: { success: this.remove(msg.params.device) } });
39
+ break;
40
+ case 'devices_clear':
41
+ this.clear();
42
+ this.server.respond({ ...msg, response: { success: true } });
43
+ break;
44
+ default:
45
+ this.log.warn(`Unknown broadcast message ${CYAN}${msg.type}${wr} from ${CYAN}${msg.src}${wr}`);
46
+ }
49
47
  }
50
48
  }
51
49
  get length() {
package/dist/frontend.js CHANGED
@@ -42,18 +42,16 @@ export class Frontend extends EventEmitter {
42
42
  this.server.close();
43
43
  }
44
44
  async msgHandler(msg) {
45
- if (this.server.isWorkerRequest(msg, msg.type)) {
46
- if (!msg.id || (msg.dst !== 'all' && msg.dst !== 'frontend'))
47
- return;
45
+ if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'frontend')) {
48
46
  this.log.debug(`**Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
49
47
  switch (msg.type) {
50
48
  case 'frontend_start':
51
49
  await this.start(msg.params.port);
52
- this.server.respond({ ...msg, id: msg.id, response: { success: true } });
50
+ this.server.respond({ ...msg, response: { success: true } });
53
51
  break;
54
52
  case 'frontend_stop':
55
53
  await this.stop();
56
- this.server.respond({ ...msg, id: msg.id, response: { success: true } });
54
+ this.server.respond({ ...msg, response: { success: true } });
57
55
  break;
58
56
  default:
59
57
  this.log.warn(`Unknown broadcast request ${CYAN}${msg.type}${wr} from ${CYAN}${msg.src}${wr}`);
@@ -21,38 +21,36 @@ export class PluginManager extends EventEmitter {
21
21
  this.server.close();
22
22
  }
23
23
  async msgHandler(msg) {
24
- if (!this.server.isWorkerRequest(msg, msg.type))
25
- return;
26
- if (!msg.id || (msg.dst !== 'all' && msg.dst !== 'plugins'))
27
- return;
28
- this.log.debug(`**Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
29
- switch (msg.type) {
30
- case 'plugins_length':
31
- this.server.respond({ ...msg, id: msg.id, response: { length: this.length } });
32
- break;
33
- case 'plugins_size':
34
- this.server.respond({ ...msg, id: msg.id, response: { size: this.size } });
35
- break;
36
- case 'plugins_has':
37
- this.server.respond({ ...msg, id: msg.id, response: { has: this.has(msg.params.name) } });
38
- break;
39
- case 'plugins_get':
40
- this.server.respond({ ...msg, id: msg.id, response: { plugin: this.get(msg.params.name) } });
41
- break;
42
- case 'plugins_set':
43
- this.server.respond({ ...msg, id: msg.id, response: { plugin: this.set(msg.params.plugin) } });
44
- break;
45
- case 'plugins_baseArray':
46
- this.server.respond({ ...msg, id: msg.id, response: { plugins: this.baseArray() } });
47
- break;
48
- case 'plugins_install':
49
- this.server.respond({ ...msg, id: msg.id, response: { packageName: msg.params.packageName, success: await this.install(msg.params.packageName) } });
50
- break;
51
- case 'plugins_uninstall':
52
- this.server.respond({ ...msg, id: msg.id, response: { packageName: msg.params.packageName, success: await this.uninstall(msg.params.packageName) } });
53
- break;
54
- default:
55
- this.log.warn(`Unknown broadcast message ${CYAN}${msg.type}${wr} from ${CYAN}${msg.src}${wr}`);
24
+ if (this.server.isWorkerRequest(msg, msg.type) && (msg.dst === 'all' || msg.dst === 'plugins')) {
25
+ this.log.debug(`**Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
26
+ switch (msg.type) {
27
+ case 'plugins_length':
28
+ this.server.respond({ ...msg, response: { length: this.length } });
29
+ break;
30
+ case 'plugins_size':
31
+ this.server.respond({ ...msg, response: { size: this.size } });
32
+ break;
33
+ case 'plugins_has':
34
+ this.server.respond({ ...msg, response: { has: this.has(msg.params.name) } });
35
+ break;
36
+ case 'plugins_get':
37
+ this.server.respond({ ...msg, response: { plugin: this.get(msg.params.name) } });
38
+ break;
39
+ case 'plugins_set':
40
+ this.server.respond({ ...msg, response: { plugin: this.set(msg.params.plugin) } });
41
+ break;
42
+ case 'plugins_baseArray':
43
+ this.server.respond({ ...msg, response: { plugins: this.baseArray() } });
44
+ break;
45
+ case 'plugins_install':
46
+ this.server.respond({ ...msg, response: { packageName: msg.params.packageName, success: await this.install(msg.params.packageName) } });
47
+ break;
48
+ case 'plugins_uninstall':
49
+ this.server.respond({ ...msg, response: { packageName: msg.params.packageName, success: await this.uninstall(msg.params.packageName) } });
50
+ break;
51
+ default:
52
+ this.log.warn(`Unknown broadcast message ${CYAN}${msg.type}${wr} from ${CYAN}${msg.src}${wr}`);
53
+ }
56
54
  }
57
55
  }
58
56
  get length() {
@@ -1 +1 @@
1
- body{font-family:Roboto,sans-serif}[frontend-theme=classic]{--main-bg-color: #c4c2c2;--main-text-color: black;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: #4d4d4d;--main-log-color: var(--main-text-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: #26292d;--main-menu-bg-color: #e2e2e2;--main-menu-hover-color: #959595;--main-label-color: var(--main-grey-color);--primary-color: #009a00;--secondary-color: #92771f;--header-bg-color: var(--primary-color);--header-text-color: white;--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: #ddd;--table-text-color: black;--table-even-bg-color: #bdbdbd;--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #5f8c9e;--table-selected-bg-color: #5f8c9e;--div-bg-color: #adadad;--div-text-color: black;--div-shadow-color: #888;--div-border-color: rgb(139, 139, 139);--div-border-radius: 0px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: black;background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=dark]{--main-bg-color: #26292d;--main-text-color: #ffffff;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: var(--main-light-color);--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-light-color);--main-menu-bg-color: var(--main-bg-color);--main-menu-hover-color: var(--div-bg-color);--main-label-color: var(--main-grey-color);--primary-color: #1976d2;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--primary-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: var(--main-bg-color);--table-selected-bg-color: var(--main-bg-color);--div-bg-color: #1b1d21;--div-text-color: var(--main-light-color);--div-shadow-color: #34373d;--div-border-color: #1b1d21;--div-border-radius: 5px;--div-title-bg-color: #1b1d21;--div-title-text-color: var(--primary-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=light]{--main-bg-color: #f0f0f0;--main-text-color: #212121;--main-grey-color: #616161;--main-light-color: #363636;--main-icon-color: #7a7a7a;--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-text-color);--main-menu-bg-color: var(--div-bg-color);--main-menu-hover-color: #85c0d8;--main-label-color: var(--main-grey-color);--primary-color: #2196f3;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--div-text-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #85c0d8;--table-selected-bg-color: #85c0d8;--div-bg-color: #ffffff;--div-text-color: #212121;--div-shadow-color: #bfbfbf;--div-border-color: var(--div-bg-color);--div-border-radius: 5px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: var(--div-text-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-thumb:hover{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-track{background:"inherit"}html,.thin-scroll{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--div-bg-color)}.thin-scroll::-webkit-scrollbar{width:5px;height:5px}.thin-scroll::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}.tooltip-container{position:relative;display:inline-block;z-index:10}.tooltip-text{visibility:hidden;background-color:var(--ttip-bg-color);color:var(--ttip-text-color);text-align:center;padding:5px;border-radius:6px;position:absolute;z-index:10;bottom:calc(100% + 10px);left:50%;margin-left:-60px;opacity:0;transition:opacity .3s;font-size:12px}.tooltip-container:hover{cursor:pointer;z-index:10}.tooltip-container:hover .tooltip-text{visibility:visible;opacity:1;z-index:10}.status-enabled{background-color:green;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-disabled{background-color:red;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-information{background-color:#9e9e9e;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-warning{background-color:#e9db18;color:#000;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-sponsor{background-color:#b6409c;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-blue{background-color:#5f8c9e;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:20px;margin:0;padding:0;height:40px}.sub-header{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;gap:20px;margin:0;padding:0;height:40px}nav{display:flex;align-items:center}.nav-link{margin:0 10px;font-size:20px;text-decoration:none;color:var(--main-icon-color);transition:color .3s ease}.nav-link:hover{color:var(--primary-color)}table{border-collapse:collapse;width:100%;table-layout:auto}thead{position:sticky;top:0;border:1px solid var(--table-border-color);z-index:10}thead th{border:1px solid var(--table-border-color);padding:5px 10px;color:var(--header-text-color);background:var(--header-bg-color);text-align:left;z-index:10}tbody td{border:1px solid var(--table-border-color);margin:0;padding:5px 10px;text-align:left;font-size:14px}tbody tr:hover{color:var(--table-text-color);background-color:var(--table-hover-bg-color)}.table-content-even{color:var(--table-text-color);background-color:var(--table-even-bg-color)}.table-content-odd{color:var(--table-text-color);background-color:var(--table-odd-bg-color)}.table-content-selected{color:var(--table-text-color);background-color:var(--table-selected-bg-color)}h3{margin:0}.MbfScreen{display:flex;flex-direction:column;width:calc(100vw - 40px);height:calc(100vh - 40px);gap:20px;margin:0;padding:20px;background-color:var(--main-bg-color)}.MbfPageDiv{display:flex;flex-direction:column;height:100%;width:100%;margin:0;padding:0;gap:20px}.MbfWindowDiv{display:flex;flex-direction:column;box-shadow:5px 5px 10px var(--div-shadow-color);border:1px solid var(--table-border-color);border-radius:var(--div-border-radius);box-sizing:border-box;background-color:var(--div-bg-color)}.MbfWindowDivTable{display:flex;flex-direction:column;flex:1 1 auto;margin:-1px;padding:0;gap:0;overflow:auto;display:block}.MbfWindowHeaderFooterIcons{display:flex;flex-direction:row;margin:0;padding:0 10px;gap:10px}.MbfWindowHeader{display:flex;flex-direction:row;align-items:center;width:100%;border-bottom:1px solid var(--table-border-color);color:var(--header-text-color);background-color:var(--header-bg-color);margin:0;padding:0;box-sizing:border-box}.MbfWindowHeaderText{color:var(--header-text-color);font-weight:700;margin:0;padding:5px 10px}.MbfWindowFooter{display:flex;flex-direction:row;align-items:center;justify-content:center;color:var(--footer-text-color);background-color:var(--footer-bg-color);margin:0;padding:0}.MbfWindowFooterText{color:var(--footer-text-color);background-color:var(--footer-bg-color);font-weight:700;text-align:center;margin:0;padding:5px 10px}.MbfWindowBody{display:flex;flex:1 1 auto;margin:0;padding:10px;gap:10px}.MbfWindowBodyColumn{display:flex;flex-direction:column;flex:1 1 auto;width:100%;margin:0;padding:10px 0;gap:0px;overflow:auto}.MbfWindowBodyRow{display:flex;flex-direction:row;flex:1 1 auto;height:100%;margin:0;padding:0 10px;gap:0px;overflow:auto}.configSubmitButton{display:flex;flex-direction:row;justify-content:center;width:auto;margin:20px}.configSubmitButton button{width:auto}@media (max-width: 1300px){.MbfScreen{width:1300px;height:1024px}.xxxheader{flex-direction:column;align-items:start;justify-content:start}.xxxsub-header{align-items:start;justify-content:start}}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}
1
+ body{font-family:Roboto,sans-serif}[frontend-theme=classic]{--main-bg-color: #c4c2c2;--main-text-color: black;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: #4d4d4d;--main-log-color: var(--main-text-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: #26292d;--main-menu-bg-color: #e2e2e2;--main-menu-hover-color: #959595;--main-label-color: var(--main-grey-color);--primary-color: #009a00;--secondary-color: #92771f;--header-bg-color: var(--primary-color);--header-text-color: white;--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: #ddd;--table-text-color: black;--table-even-bg-color: #bdbdbd;--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #5f8c9e;--table-selected-bg-color: #5f8c9e;--div-bg-color: #adadad;--div-text-color: black;--div-shadow-color: #888;--div-border-color: rgb(139, 139, 139);--div-border-radius: 0px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: black;background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=dark]{--main-bg-color: #26292d;--main-text-color: #ffffff;--main-grey-color: #616161;--main-light-color: #959595;--main-icon-color: var(--main-light-color);--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-light-color);--main-menu-bg-color: var(--main-bg-color);--main-menu-hover-color: var(--div-bg-color);--main-label-color: var(--main-grey-color);--primary-color: #1976d2;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--primary-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: var(--main-bg-color);--table-selected-bg-color: var(--main-bg-color);--div-bg-color: #1b1d21;--div-text-color: var(--main-light-color);--div-shadow-color: #34373d;--div-border-color: #1b1d21;--div-border-radius: 5px;--div-title-bg-color: #1b1d21;--div-title-text-color: var(--primary-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}[frontend-theme=light]{--main-bg-color: #f0f0f0;--main-text-color: #212121;--main-grey-color: #616161;--main-light-color: #363636;--main-icon-color: #7a7a7a;--main-log-color: var(--main-light-color);--main-button-color: #ffffff;--main-button-bg-color: var(--primary-color);--main-menu-color: var(--main-text-color);--main-menu-bg-color: var(--div-bg-color);--main-menu-hover-color: #85c0d8;--main-label-color: var(--main-grey-color);--primary-color: #2196f3;--secondary-color: #a58827;--header-bg-color: var(--div-bg-color);--header-text-color: var(--div-text-color);--footer-bg-color: var(--div-bg-color);--footer-text-color: var(--div-text-color);--ttip-bg-color: #555;--ttip-text-color: #fff;--table-border-color: var(--div-bg-color);--table-text-color: var(--main-light-color);--table-even-bg-color: var(--div-bg-color);--table-odd-bg-color: var(--div-bg-color);--table-hover-bg-color: #85c0d8;--table-selected-bg-color: #85c0d8;--div-bg-color: #ffffff;--div-text-color: #212121;--div-shadow-color: #bfbfbf;--div-border-color: var(--div-bg-color);--div-border-radius: 5px;--div-title-bg-color: var(--div-bg-color);--div-title-text-color: var(--div-text-color);background-color:var(--main-bg-color);color:var(--main-text-color);font-family:Roboto,Helvetica,Arial,sans-serif}::-webkit-scrollbar{width:10px}::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-thumb:hover{background:var(--primary-color);border-radius:5px}::-webkit-scrollbar-track{background:"inherit"}html,.thin-scroll{scrollbar-width:thin;scrollbar-color:var(--primary-color) var(--div-bg-color)}.thin-scroll::-webkit-scrollbar{width:5px;height:5px}.thin-scroll::-webkit-scrollbar-thumb{background:var(--primary-color);border-radius:5px}.tooltip-container{position:relative;display:inline-block;z-index:10}.tooltip-text{visibility:hidden;background-color:var(--ttip-bg-color);color:var(--ttip-text-color);text-align:center;padding:5px;border-radius:6px;position:absolute;z-index:10;bottom:calc(100% + 10px);left:50%;margin-left:-60px;opacity:0;transition:opacity .3s;font-size:12px}.tooltip-container:hover{cursor:pointer;z-index:10}.tooltip-container:hover .tooltip-text{visibility:visible;opacity:1;z-index:10}.status-enabled{background-color:green;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-disabled{background-color:red;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-information{background-color:#9e9e9e;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-warning{background-color:#e9db18;color:#000;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-sponsor{background-color:#b6409c;color:#fff;padding:2px 10px;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.status-blue{background-color:#5f8c9e;color:#fff;padding:.2rem;border-radius:.25rem;text-align:center;font-size:12px;cursor:pointer;box-shadow:2px 2px 2px #0003}.header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:20px;margin:0;padding:0;height:40px}.sub-header{flex:0 0 auto;display:flex;flex-direction:row;align-items:center;gap:20px;margin:0;padding:0;height:40px}nav{display:flex;align-items:center;gap:10px}.nav-link{margin:0;font-size:20px;text-decoration:none;color:var(--main-icon-color);transition:color .3s ease}.nav-link:hover{color:var(--primary-color)}table{border-collapse:collapse;width:100%;table-layout:auto}thead{position:sticky;top:0;border:1px solid var(--table-border-color);z-index:10}thead th{border:1px solid var(--table-border-color);padding:5px 10px;color:var(--header-text-color);background:var(--header-bg-color);text-align:left;z-index:10}tbody td{border:1px solid var(--table-border-color);margin:0;padding:5px 10px;text-align:left;font-size:14px}tbody tr:hover{color:var(--table-text-color);background-color:var(--table-hover-bg-color)}.table-content-even{color:var(--table-text-color);background-color:var(--table-even-bg-color)}.table-content-odd{color:var(--table-text-color);background-color:var(--table-odd-bg-color)}.table-content-selected{color:var(--table-text-color);background-color:var(--table-selected-bg-color)}h3{margin:0}.MbfScreen{display:flex;flex-direction:column;width:calc(100vw - 40px);height:calc(100vh - 40px);gap:20px;margin:0;padding:20px;background-color:var(--main-bg-color)}.MbfPageDiv{display:flex;flex-direction:column;height:100%;width:100%;margin:0;padding:0;gap:20px}.MbfWindowDiv{display:flex;flex-direction:column;box-shadow:5px 5px 10px var(--div-shadow-color);border:1px solid var(--table-border-color);border-radius:var(--div-border-radius);box-sizing:border-box;background-color:var(--div-bg-color)}.MbfWindowDivTable{display:flex;flex-direction:column;flex:1 1 auto;margin:-1px;padding:0;gap:0;overflow:auto;display:block}.MbfWindowHeaderFooterIcons{display:flex;flex-direction:row;margin:0;padding:0 10px;gap:10px}.MbfWindowHeader{display:flex;flex-direction:row;align-items:center;width:100%;border-bottom:1px solid var(--table-border-color);color:var(--header-text-color);background-color:var(--header-bg-color);margin:0;padding:0;box-sizing:border-box}.MbfWindowHeaderText{color:var(--header-text-color);font-weight:700;margin:0;padding:5px 10px}.MbfWindowFooter{display:flex;flex-direction:row;align-items:center;justify-content:center;color:var(--footer-text-color);background-color:var(--footer-bg-color);margin:0;padding:0}.MbfWindowFooterText{color:var(--footer-text-color);background-color:var(--footer-bg-color);font-weight:700;text-align:center;margin:0;padding:5px 10px}.MbfWindowBody{display:flex;flex:1 1 auto;margin:0;padding:10px;gap:10px}.MbfWindowBodyColumn{display:flex;flex-direction:column;flex:1 1 auto;width:100%;margin:0;padding:10px 0;gap:0px;overflow:auto}.MbfWindowBodyRow{display:flex;flex-direction:row;flex:1 1 auto;height:100%;margin:0;padding:0 10px;gap:0px;overflow:auto}.configSubmitButton{display:flex;flex-direction:row;justify-content:center;width:auto;margin:20px}.configSubmitButton button{width:auto}@media (max-width: 1300px){.MbfScreen{width:1300px;height:1024px}.xxxheader{flex-direction:column;align-items:start;justify-content:start}.xxxsub-header{align-items:start;justify-content:start}}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}