@openshift-migration-advisor/shared-components 0.25.0 → 0.27.0-5b72aa3d4938
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.
- package/README.md +25 -0
- package/dist/report/ChartDownloadButton.d.ts +11 -0
- package/dist/report/ChartDownloadButton.d.ts.map +1 -0
- package/dist/report/ChartDownloadButton.js +24 -0
- package/dist/report/ChartExportProvider.d.ts +23 -0
- package/dist/report/ChartExportProvider.d.ts.map +1 -0
- package/dist/report/ChartExportProvider.js +222 -0
- package/dist/report/ChartExportSurface.d.ts +12 -0
- package/dist/report/ChartExportSurface.d.ts.map +1 -0
- package/dist/report/ChartExportSurface.js +32 -0
- package/dist/report/ClustersOverview.d.ts +24 -0
- package/dist/report/ClustersOverview.d.ts.map +1 -0
- package/dist/report/ClustersOverview.js +228 -0
- package/dist/report/ClustersOverviewStyles.d.ts +12 -0
- package/dist/report/ClustersOverviewStyles.d.ts.map +1 -0
- package/dist/report/ClustersOverviewStyles.js +101 -0
- package/dist/report/CpuAndMemoryOverview.d.ts +19 -0
- package/dist/report/CpuAndMemoryOverview.d.ts.map +1 -0
- package/dist/report/CpuAndMemoryOverview.js +112 -0
- package/dist/report/ErrorTable.d.ts +18 -0
- package/dist/report/ErrorTable.d.ts.map +1 -0
- package/dist/report/ErrorTable.js +20 -0
- package/dist/report/HostPowerStates.d.ts +0 -1
- package/dist/report/HostPowerStates.d.ts.map +1 -1
- package/dist/report/HostPowerStates.js +2 -2
- package/dist/report/HostsOverview.d.ts +13 -0
- package/dist/report/HostsOverview.d.ts.map +1 -0
- package/dist/report/HostsOverview.js +84 -0
- package/dist/report/InfrastructureSummary.d.ts.map +1 -1
- package/dist/report/InfrastructureSummary.js +6 -2
- package/dist/report/NetworkOverview.d.ts +31 -0
- package/dist/report/NetworkOverview.d.ts.map +1 -0
- package/dist/report/NetworkOverview.js +201 -0
- package/dist/report/OSDistribution.d.ts +0 -2
- package/dist/report/OSDistribution.d.ts.map +1 -1
- package/dist/report/OSDistribution.js +8 -5
- package/dist/report/OsUpgradeRecommendationPopover.d.ts +0 -1
- package/dist/report/OsUpgradeRecommendationPopover.d.ts.map +1 -1
- package/dist/report/OsUpgradeRecommendationPopover.js +4 -3
- package/dist/report/PowerStateCard.d.ts +0 -1
- package/dist/report/PowerStateCard.d.ts.map +1 -1
- package/dist/report/PowerStateCard.js +4 -2
- package/dist/report/ReportExportMenu.d.ts +19 -0
- package/dist/report/ReportExportMenu.d.ts.map +1 -0
- package/dist/report/ReportExportMenu.js +31 -0
- package/dist/report/ReportTable.d.ts +14 -0
- package/dist/report/ReportTable.d.ts.map +1 -0
- package/dist/report/ReportTable.js +23 -0
- package/dist/report/SupportTierBadge.d.ts +0 -1
- package/dist/report/SupportTierBadge.d.ts.map +1 -1
- package/dist/report/SupportTierBadge.js +1 -21
- package/dist/report/VCenterClusterDetails.d.ts +0 -1
- package/dist/report/VCenterClusterDetails.d.ts.map +1 -1
- package/dist/report/VCenterClusterDetails.js +9 -4
- package/dist/report/VmPowerStates.d.ts +0 -1
- package/dist/report/VmPowerStates.d.ts.map +1 -1
- package/dist/report/VmPowerStates.js +2 -2
- package/dist/report/WarningsTable.d.ts +9 -0
- package/dist/report/WarningsTable.d.ts.map +1 -0
- package/dist/report/WarningsTable.js +20 -0
- package/dist/report/captureChartElement.d.ts +8 -0
- package/dist/report/captureChartElement.d.ts.map +1 -0
- package/dist/report/captureChartElement.js +304 -0
- package/dist/report/chartExport.d.ts +80 -0
- package/dist/report/chartExport.d.ts.map +1 -0
- package/dist/report/chartExport.js +182 -0
- package/dist/report/chartExportContext.d.ts +32 -0
- package/dist/report/chartExportContext.d.ts.map +1 -0
- package/dist/report/chartExportContext.js +36 -0
- package/dist/report/chartExportFilenames.d.ts +4 -0
- package/dist/report/chartExportFilenames.d.ts.map +1 -0
- package/dist/report/chartExportFilenames.js +16 -0
- package/dist/report/constants.d.ts +2 -0
- package/dist/report/constants.d.ts.map +1 -1
- package/dist/report/constants.js +2 -0
- package/dist/report/dashboardStyles.d.ts +0 -4
- package/dist/report/dashboardStyles.d.ts.map +1 -1
- package/dist/report/dashboardStyles.js +0 -19
- package/dist/report/htmlExport.d.ts +9 -0
- package/dist/report/htmlExport.d.ts.map +1 -0
- package/dist/report/htmlExport.js +65 -0
- package/dist/report/index.d.ts +20 -0
- package/dist/report/index.d.ts.map +1 -1
- package/dist/report/index.js +20 -0
- package/dist/report/pdfExport.d.ts +3 -0
- package/dist/report/pdfExport.d.ts.map +1 -0
- package/dist/report/pdfExport.js +131 -0
- package/dist/report/pdfPage.d.ts +15 -0
- package/dist/report/pdfPage.d.ts.map +1 -0
- package/dist/report/pdfPage.js +44 -0
- package/dist/report/reportExportOptions.d.ts +17 -0
- package/dist/report/reportExportOptions.d.ts.map +1 -0
- package/dist/report/reportExportOptions.js +31 -0
- package/dist/report/zipChartPngs.d.ts +3 -0
- package/dist/report/zipChartPngs.d.ts.map +1 -0
- package/dist/report/zipChartPngs.js +8 -0
- package/package.json +7 -2
- package/src/report/ChartDownloadButton.tsx +59 -0
- package/src/report/ChartExportProvider.tsx +392 -0
- package/src/report/ChartExportSurface.tsx +60 -0
- package/src/report/ClustersOverview.tsx +451 -0
- package/src/report/ClustersOverviewStyles.ts +110 -0
- package/src/report/CpuAndMemoryOverview.tsx +277 -0
- package/src/report/ErrorTable.tsx +85 -0
- package/src/report/HostPowerStates.tsx +0 -3
- package/src/report/HostsOverview.tsx +185 -0
- package/src/report/InfrastructureSummary.tsx +48 -31
- package/src/report/NetworkOverview.tsx +405 -0
- package/src/report/OSDistribution.tsx +46 -42
- package/src/report/OsUpgradeRecommendationPopover.tsx +3 -4
- package/src/report/PowerStateCard.tsx +49 -36
- package/src/report/ReportExportMenu.tsx +119 -0
- package/src/report/ReportTable.tsx +81 -0
- package/src/report/SupportTierBadge.tsx +12 -40
- package/src/report/VCenterClusterDetails.tsx +38 -16
- package/src/report/VmPowerStates.tsx +0 -3
- package/src/report/WarningsTable.tsx +75 -0
- package/src/report/__tests__/ChartExportProvider.test.tsx +582 -0
- package/src/report/__tests__/ClustersOverview.test.tsx +241 -0
- package/src/report/__tests__/CpuAndMemoryOverview.test.tsx +200 -0
- package/src/report/__tests__/HostsOverview.test.tsx +145 -0
- package/src/report/__tests__/InfrastructureSummary.test.tsx +0 -22
- package/src/report/__tests__/NetworkOverview.test.tsx +269 -0
- package/src/report/__tests__/OSDistribution.test.tsx +10 -11
- package/src/report/__tests__/captureChartElement.test.ts +205 -0
- package/src/report/__tests__/chartExportPackagers.test.ts +299 -0
- package/src/report/captureChartElement.ts +398 -0
- package/src/report/chartExport.ts +277 -0
- package/src/report/chartExportContext.tsx +92 -0
- package/src/report/chartExportFilenames.ts +21 -0
- package/src/report/constants.ts +2 -0
- package/src/report/dashboardStyles.ts +0 -23
- package/src/report/htmlExport.ts +83 -0
- package/src/report/index.ts +107 -0
- package/src/report/pdfExport.ts +233 -0
- package/src/report/pdfPage.ts +83 -0
- package/src/report/reportExportOptions.ts +53 -0
- package/src/report/zipChartPngs.ts +10 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { css } from "@emotion/css";
|
|
2
|
+
export const clustersOverviewStyles = {
|
|
3
|
+
titleRow: css `
|
|
4
|
+
width: 100%;
|
|
5
|
+
`,
|
|
6
|
+
cardSubtitle: css `
|
|
7
|
+
color: var(--pf-t--global--text--color--subtle);
|
|
8
|
+
font-size: 0.85rem;
|
|
9
|
+
`,
|
|
10
|
+
menuToggleMinWidth: css `
|
|
11
|
+
min-width: 250px;
|
|
12
|
+
`,
|
|
13
|
+
cpuOvercommitBoxes: css `
|
|
14
|
+
display: flex;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
gap: 12px;
|
|
17
|
+
margin: 124px 0 16px;
|
|
18
|
+
flex-wrap: wrap;
|
|
19
|
+
|
|
20
|
+
@media (max-width: 1200px) {
|
|
21
|
+
margin: 72px 0 12px;
|
|
22
|
+
gap: 20px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@media (max-width: 768px) {
|
|
26
|
+
margin: 40px 0 8px;
|
|
27
|
+
gap: 16px;
|
|
28
|
+
}
|
|
29
|
+
`,
|
|
30
|
+
cpuOvercommitBox: css `
|
|
31
|
+
color: #000;
|
|
32
|
+
min-width: 120px;
|
|
33
|
+
height: 64px;
|
|
34
|
+
border-radius: 12px;
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
font-size: 22px;
|
|
39
|
+
padding: 0 16px;
|
|
40
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
41
|
+
|
|
42
|
+
@media (max-width: 768px) {
|
|
43
|
+
min-width: 96px;
|
|
44
|
+
height: 56px;
|
|
45
|
+
font-size: 18px;
|
|
46
|
+
padding: 0 12px;
|
|
47
|
+
border-radius: 10px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@media (max-width: 480px) {
|
|
51
|
+
min-width: 88px;
|
|
52
|
+
height: 48px;
|
|
53
|
+
font-size: 16px;
|
|
54
|
+
border-radius: 8px;
|
|
55
|
+
}
|
|
56
|
+
`,
|
|
57
|
+
cpuOvercommitLegend: css `
|
|
58
|
+
display: flex;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
gap: 6px 24px;
|
|
61
|
+
flex-wrap: wrap;
|
|
62
|
+
margin-top: 20%;
|
|
63
|
+
|
|
64
|
+
@media (max-width: 1200px) {
|
|
65
|
+
margin-top: 20%;
|
|
66
|
+
gap: 6px 20px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@media (max-width: 768px) {
|
|
70
|
+
margin-top: 20%;
|
|
71
|
+
gap: 6px 16px;
|
|
72
|
+
}
|
|
73
|
+
`,
|
|
74
|
+
cpuOvercommitLegendItem: css `
|
|
75
|
+
display: flex;
|
|
76
|
+
align-items: center;
|
|
77
|
+
gap: 12px;
|
|
78
|
+
`,
|
|
79
|
+
cpuOvercommitLegendSwatch: css `
|
|
80
|
+
display: inline-block;
|
|
81
|
+
width: 12px;
|
|
82
|
+
height: 12px;
|
|
83
|
+
border-radius: 2px;
|
|
84
|
+
|
|
85
|
+
@media (max-width: 768px) {
|
|
86
|
+
width: 10px;
|
|
87
|
+
height: 10px;
|
|
88
|
+
}
|
|
89
|
+
`,
|
|
90
|
+
cpuOvercommitLegendText: css `
|
|
91
|
+
font-size: 16px;
|
|
92
|
+
|
|
93
|
+
@media (max-width: 768px) {
|
|
94
|
+
font-size: 16px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@media (max-width: 480px) {
|
|
98
|
+
font-size: 14px;
|
|
99
|
+
}
|
|
100
|
+
`,
|
|
101
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { FC } from "react";
|
|
2
|
+
import { type MigrationDonutChartLegendVariant } from "../charts/MigrationDonutChart.js";
|
|
3
|
+
export interface CpuAndMemoryOverviewProps {
|
|
4
|
+
cpuTierDistribution?: Record<string, number>;
|
|
5
|
+
memoryTierDistribution?: Record<string, number>;
|
|
6
|
+
memoryTotalGB?: number;
|
|
7
|
+
cpuTotalCores?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Memory-tier slice click. The argument is the distribution key.
|
|
10
|
+
* Agent-ui maps it to a VM memory filter; ui-app omits it.
|
|
11
|
+
*/
|
|
12
|
+
onTierSelect?: (tierLabel: string) => void;
|
|
13
|
+
/** Center-title click. Agent-ui opens the VM list with no extra filters. */
|
|
14
|
+
onTitleClick?: () => void;
|
|
15
|
+
/** `"html"` in agent-ui; ui-app passes `"chart"`. */
|
|
16
|
+
legendVariant?: MigrationDonutChartLegendVariant;
|
|
17
|
+
}
|
|
18
|
+
export declare const CpuAndMemoryOverview: FC<CpuAndMemoryOverviewProps>;
|
|
19
|
+
//# sourceMappingURL=CpuAndMemoryOverview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CpuAndMemoryOverview.d.ts","sourceRoot":"","sources":["../../src/report/CpuAndMemoryOverview.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,EAAE,EAAO,MAAM,OAAO,CAAC;AAErC,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,kCAAkC,CAAC;AAQ1C,MAAM,WAAW,yBAAyB;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,qDAAqD;IACrD,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AAuFD,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CAiJ9D,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { css } from "@emotion/css";
|
|
3
|
+
import { Card, CardBody, CardTitle, Dropdown, DropdownItem, DropdownList, Flex, FlexItem, MenuToggle, } from "@patternfly/react-core";
|
|
4
|
+
import { DataProcessorIcon } from "@patternfly/react-icons";
|
|
5
|
+
import { useMemo, useState } from "react";
|
|
6
|
+
import { MigrationDonutChart, } from "../charts/MigrationDonutChart.js";
|
|
7
|
+
import { CardEmptyState } from "./CardEmptyState.js";
|
|
8
|
+
import { ChartHeaderActions } from "./ChartDownloadButton.js";
|
|
9
|
+
import { ChartExportSurface } from "./ChartExportSurface.js";
|
|
10
|
+
import { chartExportViewsFromLabels } from "./chartExport.js";
|
|
11
|
+
import { REPORT_CARD_EMPTY_STATE_TITLES } from "./constants.js";
|
|
12
|
+
import { dashboardStyles } from "./dashboardStyles.js";
|
|
13
|
+
const VIEW_MODE_LABELS = {
|
|
14
|
+
memoryTiers: "VM distribution by memory size tier",
|
|
15
|
+
vcpuTiers: "VM distribution by vCPU count tier",
|
|
16
|
+
};
|
|
17
|
+
const VIEW_SUBTITLES = {
|
|
18
|
+
memoryTiers: "Memory size tiers",
|
|
19
|
+
vcpuTiers: "vCPU count tiers",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Categorical order shared by the agent-ui and ui-app CPU/memory donuts.
|
|
23
|
+
*/
|
|
24
|
+
const TIER_COLORS = [
|
|
25
|
+
"#0066cc",
|
|
26
|
+
"#5e40be",
|
|
27
|
+
"#b6a6e9",
|
|
28
|
+
"#73c5c5",
|
|
29
|
+
"#b98412",
|
|
30
|
+
"#28a745",
|
|
31
|
+
"#f0ad4e",
|
|
32
|
+
"#d9534f",
|
|
33
|
+
"#009596",
|
|
34
|
+
"#6a6e73",
|
|
35
|
+
];
|
|
36
|
+
const CHART_ID = "cpu-memory-overview";
|
|
37
|
+
const CHART_TITLE = "CPU & memory";
|
|
38
|
+
const cardSubtitle = css `
|
|
39
|
+
color: var(--pf-t--global--text--color--subtle);
|
|
40
|
+
font-size: 0.85rem;
|
|
41
|
+
`;
|
|
42
|
+
const menuToggleMinWidth = css `
|
|
43
|
+
min-width: 290px;
|
|
44
|
+
`;
|
|
45
|
+
const titleRow = css `
|
|
46
|
+
width: 100%;
|
|
47
|
+
`;
|
|
48
|
+
const isViewMode = (value) => value === "memoryTiers" || value === "vcpuTiers";
|
|
49
|
+
const tierSortKey = (label) => {
|
|
50
|
+
const value = Number.parseInt(label.trim(), 10);
|
|
51
|
+
return Number.isFinite(value) ? value : Number.MAX_SAFE_INTEGER;
|
|
52
|
+
};
|
|
53
|
+
const hasUnit = (label, unit) => unit === "GB" ? /gb$/i.test(label) : /cores?$/i.test(label);
|
|
54
|
+
const slicesFromDistribution = (distribution, unit) => Object.entries(distribution ?? {})
|
|
55
|
+
.filter(([, count]) => Number(count) > 0)
|
|
56
|
+
.sort(([left], [right]) => tierSortKey(left) - tierSortKey(right))
|
|
57
|
+
.map(([tier, count]) => {
|
|
58
|
+
const trimmed = tier.trim();
|
|
59
|
+
const name = hasUnit(trimmed, unit) ? trimmed : `${trimmed} ${unit}`;
|
|
60
|
+
const vmCount = Number(count);
|
|
61
|
+
return {
|
|
62
|
+
name,
|
|
63
|
+
count: vmCount,
|
|
64
|
+
countDisplay: `${vmCount} VMs`,
|
|
65
|
+
legendCategory: tier,
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
const legendFor = (categories) => {
|
|
69
|
+
const legend = {};
|
|
70
|
+
categories.forEach((category, index) => {
|
|
71
|
+
const color = TIER_COLORS[index % TIER_COLORS.length];
|
|
72
|
+
if (color) {
|
|
73
|
+
legend[category] = color;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return legend;
|
|
77
|
+
};
|
|
78
|
+
export const CpuAndMemoryOverview = ({ cpuTierDistribution, memoryTierDistribution, memoryTotalGB, cpuTotalCores, onTierSelect, onTitleClick, legendVariant = "html", }) => {
|
|
79
|
+
const [viewMode, setViewMode] = useState("memoryTiers");
|
|
80
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
81
|
+
const memorySlices = useMemo(() => slicesFromDistribution(memoryTierDistribution, "GB"), [memoryTierDistribution]);
|
|
82
|
+
const vcpuSlices = useMemo(() => slicesFromDistribution(cpuTierDistribution, "cores"), [cpuTierDistribution]);
|
|
83
|
+
const activeSlices = viewMode === "memoryTiers" ? memorySlices : vcpuSlices;
|
|
84
|
+
const legend = useMemo(() => legendFor(activeSlices.map((slice) => slice.legendCategory)), [activeSlices]);
|
|
85
|
+
const totalVMs = useMemo(() => activeSlices.reduce((sum, slice) => sum + slice.count, 0), [activeSlices]);
|
|
86
|
+
const chartTitle = `${CHART_TITLE} — ${VIEW_MODE_LABELS[viewMode]}`;
|
|
87
|
+
const subTitle = viewMode === "memoryTiers"
|
|
88
|
+
? typeof memoryTotalGB === "number"
|
|
89
|
+
? `${memoryTotalGB.toLocaleString()} GB`
|
|
90
|
+
: undefined
|
|
91
|
+
: typeof cpuTotalCores === "number"
|
|
92
|
+
? `${cpuTotalCores.toLocaleString()} Cores`
|
|
93
|
+
: undefined;
|
|
94
|
+
const emptyTitle = viewMode === "memoryTiers"
|
|
95
|
+
? REPORT_CARD_EMPTY_STATE_TITLES.memory
|
|
96
|
+
: REPORT_CARD_EMPTY_STATE_TITLES.cpu;
|
|
97
|
+
return (_jsx(ChartExportSurface, { id: CHART_ID, title: chartTitle, exportViews: chartExportViewsFromLabels(CHART_TITLE, VIEW_MODE_LABELS), activeExportViewId: viewMode, onExportViewChange: (viewId) => {
|
|
98
|
+
if (isViewMode(viewId)) {
|
|
99
|
+
setViewMode(viewId);
|
|
100
|
+
}
|
|
101
|
+
}, children: _jsxs(Card, { className: dashboardStyles.card, children: [_jsx(CardTitle, { children: _jsxs(Flex, { className: titleRow, justifyContent: { default: "justifyContentSpaceBetween" }, alignItems: { default: "alignItemsCenter" }, children: [_jsx(FlexItem, { children: _jsxs("div", { children: [_jsxs("div", { children: [_jsx(DataProcessorIcon, {}), " ", CHART_TITLE] }), _jsx("div", { className: cardSubtitle, children: VIEW_SUBTITLES[viewMode] })] }) }), _jsx(ChartHeaderActions, { chartId: CHART_ID, title: chartTitle, children: _jsx(Dropdown, { isOpen: isDropdownOpen, onSelect: (_event, value) => {
|
|
102
|
+
if (isViewMode(value)) {
|
|
103
|
+
setViewMode(value);
|
|
104
|
+
}
|
|
105
|
+
setIsDropdownOpen(false);
|
|
106
|
+
}, onOpenChange: setIsDropdownOpen, toggle: (toggleRef) => (_jsx(MenuToggle, { ref: toggleRef, onClick: () => setIsDropdownOpen((open) => !open), isExpanded: isDropdownOpen, className: menuToggleMinWidth, children: VIEW_MODE_LABELS[viewMode] })), children: _jsxs(DropdownList, { children: [_jsx(DropdownItem, { value: "memoryTiers", children: VIEW_MODE_LABELS.memoryTiers }, "memoryTiers"), _jsx(DropdownItem, { value: "vcpuTiers", children: VIEW_MODE_LABELS.vcpuTiers }, "vcpuTiers")] }) }) })] }) }), _jsx(CardBody, { className: dashboardStyles.cardBodyScrollable, children: activeSlices.length === 0 ? (_jsx(CardEmptyState, { title: emptyTitle })) : (_jsx(MigrationDonutChart, { legendVariant: legendVariant, data: activeSlices, legend: legend, height: 300, width: 420, donutThickness: 18, titleFontSize: 34, title: `${totalVMs} VMs`, subTitle: subTitle, subTitleColor: "var(--pf-t--global--text--color--subtle)", legendLabelFormatter: ({ x, countDisplay }) => `${x} (${countDisplay})`, tooltipLabelFormatter: ({ datum, percent }) => `${datum.countDisplay}\n${percent.toFixed(1)}%`, itemsPerRow: legendVariant === "chart"
|
|
107
|
+
? Math.ceil(activeSlices.length / 2)
|
|
108
|
+
: undefined, labelFontSize: legendVariant === "chart" ? 18 : undefined, marginLeft: legendVariant === "chart" ? "52%" : undefined, onItemClick: viewMode === "memoryTiers" && onTierSelect
|
|
109
|
+
? (item) => onTierSelect(item.legendCategory)
|
|
110
|
+
: undefined, onTitleClick: onTitleClick })) })] }) }));
|
|
111
|
+
};
|
|
112
|
+
CpuAndMemoryOverview.displayName = "CpuAndMemoryOverview";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal shape of a migration issue consumed by {@link ErrorTable}. Declared
|
|
4
|
+
* locally so this package does not depend on a specific SDK (`agent-sdk` or
|
|
5
|
+
* `planner-sdk`); callers pass the subset of `MigrationIssue` fields read here.
|
|
6
|
+
*/
|
|
7
|
+
export interface MigrationIssueLike {
|
|
8
|
+
label: string;
|
|
9
|
+
assessment: string;
|
|
10
|
+
count: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ErrorTableProps {
|
|
13
|
+
errors: MigrationIssueLike[];
|
|
14
|
+
/** Optional drill-down callback invoked with an issue's `label`. */
|
|
15
|
+
onConcernClick?: (concernLabel: string) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare const ErrorTable: React.FC<ErrorTableProps>;
|
|
18
|
+
//# sourceMappingURL=ErrorTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorTable.d.ts","sourceRoot":"","sources":["../../src/report/ErrorTable.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,oEAAoE;IACpE,cAAc,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgDhD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Card, CardBody, CardTitle, Flex, FlexItem, Icon, } from "@patternfly/react-core";
|
|
3
|
+
import { ExclamationCircleIcon } from "@patternfly/react-icons";
|
|
4
|
+
import { CardEmptyState } from "./CardEmptyState.js";
|
|
5
|
+
import { ChartHeaderActions } from "./ChartDownloadButton.js";
|
|
6
|
+
import { ChartExportSurface } from "./ChartExportSurface.js";
|
|
7
|
+
import { REPORT_CARD_EMPTY_STATE_TITLES } from "./constants.js";
|
|
8
|
+
import { dashboardStyles } from "./dashboardStyles.js";
|
|
9
|
+
import { ReportTable } from "./ReportTable.js";
|
|
10
|
+
export const ErrorTable = ({ errors, onConcernClick, }) => {
|
|
11
|
+
const handleRowClick = (issue) => {
|
|
12
|
+
if (issue.label && onConcernClick) {
|
|
13
|
+
onConcernClick(issue.label);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const chartId = "errors-table";
|
|
17
|
+
const chartTitle = "Errors";
|
|
18
|
+
return (_jsx(ChartExportSurface, { id: chartId, title: chartTitle, children: _jsxs(Card, { className: dashboardStyles.card, children: [_jsx(CardTitle, { children: _jsxs(Flex, { justifyContent: { default: "justifyContentSpaceBetween" }, alignItems: { default: "alignItemsCenter" }, children: [_jsxs(FlexItem, { children: [_jsx(Icon, { status: "danger", children: _jsx(ExclamationCircleIcon, {}) }), " ", "Errors"] }), _jsx(ChartHeaderActions, { chartId: chartId, title: chartTitle })] }) }), _jsx(CardBody, { className: dashboardStyles.cardBodyScrollable, children: errors.length === 0 ? (_jsx(CardEmptyState, { title: REPORT_CARD_EMPTY_STATE_TITLES.errors })) : (_jsx("div", { children: _jsx(ReportTable, { data: errors, columns: ["Description", "Total VMs"], fields: ["assessment", "count"], onRowClick: onConcernClick ? handleRowClick : undefined, clickableFields: onConcernClick ? ["assessment"] : [] }) })) })] }) }));
|
|
19
|
+
};
|
|
20
|
+
ErrorTable.displayName = "ErrorTable";
|
|
@@ -2,7 +2,6 @@ import type { FC } from "react";
|
|
|
2
2
|
import type { MigrationDonutChartLegendVariant } from "../charts/MigrationDonutChart.js";
|
|
3
3
|
export interface HostPowerStatesProps {
|
|
4
4
|
hostPowerStates?: Record<string, number>;
|
|
5
|
-
isExportMode?: boolean;
|
|
6
5
|
legendVariant?: MigrationDonutChartLegendVariant;
|
|
7
6
|
}
|
|
8
7
|
export declare const HostPowerStates: FC<HostPowerStatesProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HostPowerStates.d.ts","sourceRoot":"","sources":["../../src/report/HostPowerStates.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,kCAAkC,CAAC;AAKzF,MAAM,WAAW,oBAAoB;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,
|
|
1
|
+
{"version":3,"file":"HostPowerStates.d.ts","sourceRoot":"","sources":["../../src/report/HostPowerStates.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,kCAAkC,CAAC;AAKzF,MAAM,WAAW,oBAAoB;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AAED,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAsBpD,CAAC"}
|
|
@@ -4,8 +4,8 @@ import { useMemo } from "react";
|
|
|
4
4
|
import { REPORT_CARD_EMPTY_STATE_TITLES } from "./constants.js";
|
|
5
5
|
import { PowerStateCard } from "./PowerStateCard.js";
|
|
6
6
|
import { buildHostPowerStateChart } from "./powerStates.js";
|
|
7
|
-
export const HostPowerStates = ({ hostPowerStates,
|
|
7
|
+
export const HostPowerStates = ({ hostPowerStates, legendVariant, }) => {
|
|
8
8
|
const chart = useMemo(() => buildHostPowerStateChart(hostPowerStates), [hostPowerStates]);
|
|
9
|
-
return (_jsx(PowerStateCard, { id: "esxi-host-power-states", title: "ESXi host power states", icon: _jsx(ServerIcon, {}), emptyTitle: REPORT_CARD_EMPTY_STATE_TITLES.hostPowerStates, slices: chart.slices, legend: chart.legend, total: chart.total, subTitle: "Hosts",
|
|
9
|
+
return (_jsx(PowerStateCard, { id: "esxi-host-power-states", title: "ESXi host power states", icon: _jsx(ServerIcon, {}), emptyTitle: REPORT_CARD_EMPTY_STATE_TITLES.hostPowerStates, slices: chart.slices, legend: chart.legend, total: chart.total, subTitle: "Hosts", legendVariant: legendVariant }));
|
|
10
10
|
};
|
|
11
11
|
HostPowerStates.displayName = "HostPowerStates";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FC } from "react";
|
|
2
|
+
import { type MigrationDonutChartLegendVariant } from "../charts/MigrationDonutChart.js";
|
|
3
|
+
/** Smallest host shape this card reads. Apps pass SDK hosts structurally. */
|
|
4
|
+
export interface HostLike {
|
|
5
|
+
model?: string | number;
|
|
6
|
+
}
|
|
7
|
+
export interface HostsOverviewProps {
|
|
8
|
+
hosts?: HostLike[];
|
|
9
|
+
/** `"html"` in agent-ui; ui-app passes `"chart"`. */
|
|
10
|
+
legendVariant?: MigrationDonutChartLegendVariant;
|
|
11
|
+
}
|
|
12
|
+
export declare const HostsOverview: FC<HostsOverviewProps>;
|
|
13
|
+
//# sourceMappingURL=HostsOverview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HostsOverview.d.ts","sourceRoot":"","sources":["../../src/report/HostsOverview.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,kCAAkC,CAAC;AAO1C,6EAA6E;AAC7E,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,qDAAqD;IACrD,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AAuFD,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAwDhD,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { css } from "@emotion/css";
|
|
3
|
+
import { Card, CardBody, CardTitle, Flex, FlexItem, } from "@patternfly/react-core";
|
|
4
|
+
import { ServerIcon } from "@patternfly/react-icons";
|
|
5
|
+
import { chart_color_blue_300, chart_color_green_300, chart_color_purple_100, chart_color_purple_300, chart_color_teal_200, chart_color_yellow_400, } from "@patternfly/react-tokens";
|
|
6
|
+
import { useMemo } from "react";
|
|
7
|
+
import { MigrationDonutChart, } from "../charts/MigrationDonutChart.js";
|
|
8
|
+
import { CardEmptyState } from "./CardEmptyState.js";
|
|
9
|
+
import { ChartHeaderActions } from "./ChartDownloadButton.js";
|
|
10
|
+
import { ChartExportSurface } from "./ChartExportSurface.js";
|
|
11
|
+
import { REPORT_CARD_EMPTY_STATE_TITLES } from "./constants.js";
|
|
12
|
+
import { dashboardStyles } from "./dashboardStyles.js";
|
|
13
|
+
const TOP_HOST_MODELS = 5;
|
|
14
|
+
const OTHER_MODELS_LABEL = "Other models";
|
|
15
|
+
const UNKNOWN_MODEL_LABEL = "Unknown model";
|
|
16
|
+
const CHART_ID = "hosts-overview";
|
|
17
|
+
const CHART_TITLE = "Host distribution by model";
|
|
18
|
+
/**
|
|
19
|
+
* Same categorical order as the ui-app host-model donut, mapped onto
|
|
20
|
+
* PatternFly `chart_color_*` tokens (nearest token where the old hex
|
|
21
|
+
* was not itself a token).
|
|
22
|
+
*/
|
|
23
|
+
const HOST_MODEL_COLORS = [
|
|
24
|
+
chart_color_blue_300.value,
|
|
25
|
+
chart_color_purple_300.value,
|
|
26
|
+
chart_color_purple_100.value,
|
|
27
|
+
chart_color_teal_200.value,
|
|
28
|
+
chart_color_yellow_400.value,
|
|
29
|
+
chart_color_green_300.value,
|
|
30
|
+
];
|
|
31
|
+
const cardSubtitle = css `
|
|
32
|
+
color: var(--pf-t--global--text--color--subtle);
|
|
33
|
+
font-size: 0.85rem;
|
|
34
|
+
`;
|
|
35
|
+
const hostModelLabel = (model) => {
|
|
36
|
+
const raw = typeof model === "string"
|
|
37
|
+
? model
|
|
38
|
+
: typeof model === "number"
|
|
39
|
+
? String(model)
|
|
40
|
+
: "";
|
|
41
|
+
const trimmed = raw.trim();
|
|
42
|
+
return trimmed !== "" ? trimmed : UNKNOWN_MODEL_LABEL;
|
|
43
|
+
};
|
|
44
|
+
const buildHostModelDonut = (hosts) => {
|
|
45
|
+
const counts = new Map();
|
|
46
|
+
for (const host of hosts) {
|
|
47
|
+
const label = hostModelLabel(host?.model);
|
|
48
|
+
counts.set(label, (counts.get(label) ?? 0) + 1);
|
|
49
|
+
}
|
|
50
|
+
const entries = [...counts.entries()]
|
|
51
|
+
.map(([model, count]) => ({ model, count }))
|
|
52
|
+
.sort((a, b) => b.count - a.count);
|
|
53
|
+
const top = entries.slice(0, TOP_HOST_MODELS);
|
|
54
|
+
const restSum = entries
|
|
55
|
+
.slice(TOP_HOST_MODELS)
|
|
56
|
+
.reduce((sum, entry) => sum + entry.count, 0);
|
|
57
|
+
const slices = top.map((entry) => ({
|
|
58
|
+
name: entry.model,
|
|
59
|
+
count: entry.count,
|
|
60
|
+
countDisplay: `${entry.count} hosts`,
|
|
61
|
+
legendCategory: entry.model,
|
|
62
|
+
}));
|
|
63
|
+
if (restSum > 0) {
|
|
64
|
+
slices.push({
|
|
65
|
+
name: OTHER_MODELS_LABEL,
|
|
66
|
+
count: restSum,
|
|
67
|
+
countDisplay: `${restSum} hosts`,
|
|
68
|
+
legendCategory: OTHER_MODELS_LABEL,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const legend = {};
|
|
72
|
+
slices.forEach((slice, index) => {
|
|
73
|
+
const color = HOST_MODEL_COLORS[index % HOST_MODEL_COLORS.length];
|
|
74
|
+
if (color) {
|
|
75
|
+
legend[slice.legendCategory] = color;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return { slices, legend, totalHosts: hosts.length };
|
|
79
|
+
};
|
|
80
|
+
export const HostsOverview = ({ hosts, legendVariant = "html", }) => {
|
|
81
|
+
const { slices, legend, totalHosts } = useMemo(() => buildHostModelDonut(Array.isArray(hosts) ? hosts : []), [hosts]);
|
|
82
|
+
return (_jsx(ChartExportSurface, { id: CHART_ID, title: CHART_TITLE, children: _jsxs(Card, { className: dashboardStyles.card, children: [_jsx(CardTitle, { children: _jsxs(Flex, { justifyContent: { default: "justifyContentSpaceBetween" }, alignItems: { default: "alignItemsCenter" }, children: [_jsx(FlexItem, { children: _jsxs("div", { children: [_jsxs("div", { children: [_jsx(ServerIcon, {}), " ", CHART_TITLE] }), _jsx("div", { className: cardSubtitle, children: "Top 5 models" })] }) }), _jsx(ChartHeaderActions, { chartId: CHART_ID, title: CHART_TITLE })] }) }), _jsx(CardBody, { className: dashboardStyles.cardBodyScrollable, children: slices.length === 0 ? (_jsx(CardEmptyState, { title: REPORT_CARD_EMPTY_STATE_TITLES.hosts })) : (_jsx(MigrationDonutChart, { legendVariant: legendVariant, data: slices, height: 300, width: 420, donutThickness: 18, titleFontSize: 34, legend: legend, legendWidth: 680, title: `${totalHosts}`, subTitle: "Hosts", subTitleColor: "var(--pf-t--global--text--color--subtle)", itemsPerRow: 2, labelFontSize: 16, marginLeft: "0%", tooltipLabelFormatter: ({ datum, percent }) => `${datum.countDisplay}\n${percent.toFixed(1)}%` })) })] }) }));
|
|
83
|
+
};
|
|
84
|
+
HostsOverview.displayName = "HostsOverview";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfrastructureSummary.d.ts","sourceRoot":"","sources":["../../src/report/InfrastructureSummary.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InfrastructureSummary.d.ts","sourceRoot":"","sources":["../../src/report/InfrastructureSummary.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAElF,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,0BAA0B,CAAC;CACrC;AAQD,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CA4ChE,CAAC"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Card, CardBody, CardTitle, DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm, } from "@patternfly/react-core";
|
|
2
|
+
import { Card, CardBody, CardTitle, DescriptionList, DescriptionListDescription, DescriptionListGroup, DescriptionListTerm, Flex, FlexItem, } from "@patternfly/react-core";
|
|
3
|
+
import { ChartHeaderActions } from "./ChartDownloadButton.js";
|
|
4
|
+
import { ChartExportSurface } from "./ChartExportSurface.js";
|
|
3
5
|
const formatCount = (value) => typeof value === "number" ? String(value) : "—";
|
|
4
|
-
|
|
6
|
+
const INFRA_CHART_ID = "infrastructure-summary";
|
|
7
|
+
const INFRA_TITLE = "Infrastructure summary";
|
|
8
|
+
export const InfrastructureSummary = ({ summary, }) => (_jsx(ChartExportSurface, { id: INFRA_CHART_ID, title: INFRA_TITLE, children: _jsxs(Card, { isFullHeight: true, children: [_jsx(CardTitle, { children: _jsxs(Flex, { justifyContent: { default: "justifyContentSpaceBetween" }, alignItems: { default: "alignItemsCenter" }, children: [_jsx(FlexItem, { children: INFRA_TITLE }), _jsx(ChartHeaderActions, { chartId: INFRA_CHART_ID, title: INFRA_TITLE })] }) }), _jsx(CardBody, { children: _jsxs(DescriptionList, { isAutoFit: true, displaySize: "lg", children: [_jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: "VMware version" }), _jsx(DescriptionListDescription, { children: summary.vmwareVersion })] }), _jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: "Datacenters" }), _jsx(DescriptionListDescription, { children: formatCount(summary.datacenters) })] }), _jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: "vCenters" }), _jsx(DescriptionListDescription, { children: formatCount(summary.vCenters) })] }), _jsxs(DescriptionListGroup, { children: [_jsx(DescriptionListTerm, { children: "ESXi hosts" }), _jsx(DescriptionListDescription, { children: formatCount(summary.esxiHosts) })] })] }) })] }) }));
|
|
5
9
|
InfrastructureSummary.displayName = "InfrastructureSummary";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { FC } from "react";
|
|
2
|
+
import { type MigrationDonutChartLegendVariant } from "../charts/MigrationDonutChart.js";
|
|
3
|
+
/** Network fields this card reads. Apps pass SDK networks structurally. */
|
|
4
|
+
export interface NetworkLike {
|
|
5
|
+
vmsCount?: number;
|
|
6
|
+
vlanId?: string | number;
|
|
7
|
+
}
|
|
8
|
+
/** Infra fields this card reads. */
|
|
9
|
+
export interface NetworkInfraLike {
|
|
10
|
+
networks?: NetworkLike[];
|
|
11
|
+
}
|
|
12
|
+
/** Deprecated NIC histogram used when `distributionByNicCount` is absent. */
|
|
13
|
+
export interface NicCountHistogram {
|
|
14
|
+
data?: number[];
|
|
15
|
+
minValue?: number;
|
|
16
|
+
step?: number;
|
|
17
|
+
}
|
|
18
|
+
/** NIC summary fields this card reads from the VM resource breakdown. */
|
|
19
|
+
export interface NicCountSummary {
|
|
20
|
+
total?: number;
|
|
21
|
+
histogram?: NicCountHistogram;
|
|
22
|
+
}
|
|
23
|
+
export interface NetworkOverviewProps {
|
|
24
|
+
infra?: NetworkInfraLike;
|
|
25
|
+
nicCount?: NicCountSummary;
|
|
26
|
+
distributionByNicCount?: Record<string, number>;
|
|
27
|
+
/** `"html"` in agent-ui; ui-app passes `"chart"`. */
|
|
28
|
+
legendVariant?: MigrationDonutChartLegendVariant;
|
|
29
|
+
}
|
|
30
|
+
export declare const NetworkOverview: FC<NetworkOverviewProps>;
|
|
31
|
+
//# sourceMappingURL=NetworkOverview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkOverview.d.ts","sourceRoot":"","sources":["../../src/report/NetworkOverview.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,EAAE,EAAO,MAAM,OAAO,CAAC;AAErC,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,kCAAkC,CAAC;AAQ1C,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED,oCAAoC;AACpC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,qDAAqD;IACrD,aAAa,CAAC,EAAE,gCAAgC,CAAC;CAClD;AAiND,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA2HpD,CAAC"}
|