@elementor/editor-audits 4.4.0-1101 → 4.4.0-1103

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/dist/index.mjs CHANGED
@@ -6,18 +6,18 @@ import { __registerSlice as registerSlice } from "@elementor/store";
6
6
  import { utilitiesMenu } from "@elementor/editor-app-bar";
7
7
 
8
8
  // src/hooks/use-audit-toggle-props.ts
9
- import { ShieldCheckIcon as ShieldCheckIcon2 } from "@elementor/icons";
10
- import { __ as __22 } from "@wordpress/i18n";
9
+ import { ShieldCheckIcon as ShieldCheckIcon3 } from "@elementor/icons";
10
+ import { __ as __24 } from "@wordpress/i18n";
11
11
 
12
12
  // src/editor-panel.tsx
13
13
  import { createFloatingPanel } from "@elementor/editor-floating-panels";
14
14
 
15
15
  // src/components/audit-panel.tsx
16
- import * as React23 from "react";
16
+ import * as React25 from "react";
17
17
  import { getCurrentDocumentId as getCurrentDocumentId2 } from "@elementor/editor-elements";
18
18
  import { FloatingPanelBody, FloatingPanelFooter, FloatingPanelHeader } from "@elementor/editor-floating-panels";
19
- import { Box as Box19, Button as Button5, Typography as Typography15 } from "@elementor/ui";
20
- import { __ as __21 } from "@wordpress/i18n";
19
+ import { Box as Box21, Button as Button5, Typography as Typography16 } from "@elementor/ui";
20
+ import { __ as __23 } from "@wordpress/i18n";
21
21
 
22
22
  // src/hooks/use-audit-report.ts
23
23
  import { useEffect } from "react";
@@ -134,7 +134,7 @@ var CATEGORY_LABELS = {
134
134
  seo: __("SEO", "elementor"),
135
135
  accessibility: __("Accessibility", "elementor"),
136
136
  performance: __("Performance", "elementor"),
137
- compliance: __("Compliance", "elementor")
137
+ compliance: __("Site compliance", "elementor")
138
138
  };
139
139
 
140
140
  // src/utils/audit-status-summary.ts
@@ -733,10 +733,10 @@ function WelcomePage() {
733
733
  }
734
734
 
735
735
  // src/components/report-shell.tsx
736
- import * as React22 from "react";
737
- import { useState as useState4 } from "react";
738
- import { Box as Box18, Divider as Divider2, Tab, Tabs } from "@elementor/ui";
739
- import { __ as __20 } from "@wordpress/i18n";
736
+ import * as React24 from "react";
737
+ import { useState as useState5 } from "react";
738
+ import { Box as Box20, Divider as Divider3, Tab, Tabs } from "@elementor/ui";
739
+ import { __ as __22 } from "@wordpress/i18n";
740
740
 
741
741
  // src/components/pages/all-audits-page.tsx
742
742
  import * as React12 from "react";
@@ -795,7 +795,7 @@ function SubpageHeader({ title, onBack, backLabel, icon }) {
795
795
  import * as React11 from "react";
796
796
  import { useState as useState3 } from "react";
797
797
  import { getElementIcon, getElementTitle } from "@elementor/editor-elements";
798
- import { AlertCircleIcon as AlertCircleIcon2, BulbIcon, CheckIcon, ChevronDownIcon as ChevronDownIcon2, EyeIcon, HelpIcon } from "@elementor/icons";
798
+ import { AlertCircleIcon as AlertCircleIcon2, BulbIcon as BulbIcon2, CheckIcon, ChevronDownIcon as ChevronDownIcon2, EyeIcon, HelpIcon } from "@elementor/icons";
799
799
  import { Alert, AlertTitle, Box as Box7, Collapse as Collapse2, IconButton as IconButton5, Tooltip as Tooltip3, Typography as Typography6 } from "@elementor/ui";
800
800
  import { __ as __11 } from "@wordpress/i18n";
801
801
 
@@ -898,11 +898,11 @@ function FixViolationWithAngie({ prompt }) {
898
898
 
899
899
  // src/components/severity-icons.tsx
900
900
  import * as React8 from "react";
901
- import { AlertCircleIcon, AlertTriangleFilledIcon, InfoCircleIcon } from "@elementor/icons";
901
+ import { AlertCircleIcon, AlertTriangleFilledIcon, BulbIcon } from "@elementor/icons";
902
902
  var SEVERITY_CONFIG = {
903
903
  error: { Icon: AlertTriangleFilledIcon, color: "error" },
904
904
  warning: { Icon: AlertCircleIcon, color: "warning" },
905
- info: { Icon: InfoCircleIcon, color: "info" }
905
+ info: { Icon: BulbIcon, color: "info" }
906
906
  };
907
907
  function SeverityIcon({ severity }) {
908
908
  const { Icon, color } = SEVERITY_CONFIG[severity];
@@ -1005,7 +1005,7 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
1005
1005
  {
1006
1006
  severity: "info",
1007
1007
  sx: { p: 1 },
1008
- icon: /* @__PURE__ */ React11.createElement(BulbIcon, { fontSize: "small", color: "info", "aria-hidden": true })
1008
+ icon: /* @__PURE__ */ React11.createElement(BulbIcon2, { fontSize: "small", color: "info", "aria-hidden": true })
1009
1009
  },
1010
1010
  /* @__PURE__ */ React11.createElement(AlertTitle, null, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, __11("How to resolve", "elementor"))),
1011
1011
  /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit23.fixHint)
@@ -1038,7 +1038,12 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
1038
1038
  },
1039
1039
  /* @__PURE__ */ React11.createElement(ViolationIcon, { violation, widgetIcon }),
1040
1040
  /* @__PURE__ */ React11.createElement(Box7, { sx: { flex: 1 } }, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption" }, rowLabel), violation.detail && /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary" }, violation.detail)),
1041
- violation.angieFix && /* @__PURE__ */ React11.createElement(FixViolationWithAngie, { prompt: buildAngiePrompt(rowLabel) }),
1041
+ violation.angieFix && /* @__PURE__ */ React11.createElement(
1042
+ FixViolationWithAngie,
1043
+ {
1044
+ prompt: violation.angiePrompt ?? buildAngiePrompt(rowLabel)
1045
+ }
1046
+ ),
1042
1047
  violation.ctaLabel && violation.externalUrl ? /* @__PURE__ */ React11.createElement(
1043
1048
  ViolationCtaButton,
1044
1049
  {
@@ -1099,19 +1104,13 @@ import { Box as Box9 } from "@elementor/ui";
1099
1104
  import { __ as __13 } from "@wordpress/i18n";
1100
1105
 
1101
1106
  // src/components/category-icons.ts
1102
- import {
1103
- ElementorAccessibilityIcon,
1104
- FilterIcon,
1105
- HeartHandShakeIcon,
1106
- Settings2Icon,
1107
- ShieldHalfFilledIcon
1108
- } from "@elementor/icons";
1107
+ import { BoltIcon, ElementorAccessibilityIcon, FileSearchIcon, Settings2Icon, ShieldCheckIcon as ShieldCheckIcon2 } from "@elementor/icons";
1109
1108
  var CATEGORY_ICONS = {
1110
1109
  "best-practices": Settings2Icon,
1111
- seo: FilterIcon,
1110
+ seo: FileSearchIcon,
1112
1111
  accessibility: ElementorAccessibilityIcon,
1113
- performance: ShieldHalfFilledIcon,
1114
- compliance: HeartHandShakeIcon
1112
+ performance: BoltIcon,
1113
+ compliance: ShieldCheckIcon2
1115
1114
  };
1116
1115
 
1117
1116
  // src/components/pages/category-page.tsx
@@ -1139,12 +1138,13 @@ function CategoryPage({ category, report, onBack }) {
1139
1138
  }
1140
1139
 
1141
1140
  // src/components/pages/issues-page.tsx
1142
- import * as React17 from "react";
1143
- import { Box as Box13, Link, Typography as Typography10 } from "@elementor/ui";
1141
+ import * as React18 from "react";
1142
+ import { useState as useState4 } from "react";
1143
+ import { Box as Box14, Link, Typography as Typography10 } from "@elementor/ui";
1144
1144
  import { __ as __17 } from "@wordpress/i18n";
1145
1145
 
1146
1146
  // src/utils/severity-counts.ts
1147
- import { __ as __14, sprintf as sprintf2 } from "@wordpress/i18n";
1147
+ import { __ as __14 } from "@wordpress/i18n";
1148
1148
  var ALL_SEVERITIES = ["error", "warning", "info"];
1149
1149
  function countSeverities(report, category) {
1150
1150
  const counts = { error: 0, warning: 0, info: 0 };
@@ -1169,41 +1169,115 @@ function severityPluralLabel(severity) {
1169
1169
  case "warning":
1170
1170
  return __14("Warnings", "elementor");
1171
1171
  case "info":
1172
- return __14("Info", "elementor");
1172
+ return __14("Suggestions", "elementor");
1173
1173
  }
1174
1174
  }
1175
- function severityRemainingCountLabel(severity, count) {
1176
- switch (severity) {
1177
- case "error":
1178
- return sprintf2(
1179
- /* translators: %d: number of remaining error violations. */
1180
- __14("%d errors", "elementor"),
1181
- count
1182
- );
1183
- case "warning":
1184
- return sprintf2(
1185
- /* translators: %d: number of remaining warning violations. */
1186
- __14("%d warnings", "elementor"),
1187
- count
1188
- );
1189
- case "info":
1190
- return sprintf2(
1191
- /* translators: %d: number of remaining info violations. */
1192
- __14("%d info", "elementor"),
1193
- count
1194
- );
1175
+
1176
+ // src/components/audit-statuses-section.tsx
1177
+ import * as React15 from "react";
1178
+ import { Box as Box11, Divider, Typography as Typography8 } from "@elementor/ui";
1179
+ import { __ as __15, sprintf as sprintf2 } from "@wordpress/i18n";
1180
+
1181
+ // src/components/count-summary-circle.tsx
1182
+ import * as React14 from "react";
1183
+ import { Box as Box10, Chip as Chip2, Typography as Typography7 } from "@elementor/ui";
1184
+ var COUNT_SUMMARY_CIRCLE_SIZE = 64;
1185
+ var COUNT_SUMMARY_BORDER_WIDTH = 4;
1186
+ function chipBorderColor(theme, color) {
1187
+ if (color === "default" || !color) {
1188
+ return theme.palette.text.secondary;
1195
1189
  }
1190
+ return theme.palette[color].main;
1191
+ }
1192
+ function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
1193
+ return /* @__PURE__ */ React14.createElement(
1194
+ Box10,
1195
+ {
1196
+ "aria-label": ariaLabel,
1197
+ component: "button",
1198
+ onClick,
1199
+ type: "button",
1200
+ sx: {
1201
+ alignItems: "center",
1202
+ background: "none",
1203
+ border: "none",
1204
+ cursor: "pointer",
1205
+ display: "flex",
1206
+ flex: 1,
1207
+ flexDirection: "column",
1208
+ gap: 0.5,
1209
+ padding: 0
1210
+ }
1211
+ },
1212
+ /* @__PURE__ */ React14.createElement(
1213
+ Chip2,
1214
+ {
1215
+ color,
1216
+ label: count,
1217
+ size: "small",
1218
+ variant: "standard",
1219
+ sx: (theme) => ({
1220
+ border: `${COUNT_SUMMARY_BORDER_WIDTH}px solid ${chipBorderColor(theme, color)}`,
1221
+ borderRadius: "50%",
1222
+ height: COUNT_SUMMARY_CIRCLE_SIZE,
1223
+ maxWidth: COUNT_SUMMARY_CIRCLE_SIZE,
1224
+ width: COUNT_SUMMARY_CIRCLE_SIZE,
1225
+ "& .MuiChip-label": {
1226
+ fontSize: theme.typography.body2.fontSize,
1227
+ fontWeight: 700,
1228
+ lineHeight: 1,
1229
+ padding: 0
1230
+ }
1231
+ })
1232
+ }
1233
+ ),
1234
+ /* @__PURE__ */ React14.createElement(Typography7, { color: "text.secondary", sx: { textAlign: "center" }, variant: "caption" }, label)
1235
+ );
1236
+ }
1237
+
1238
+ // src/components/audit-statuses-section.tsx
1239
+ var STATUS_ARIA_LABELS = {
1240
+ pass: (count) => sprintf2(
1241
+ /* translators: %d: number of passed audits. */
1242
+ __15("%d passed audits, view all", "elementor"),
1243
+ count
1244
+ ),
1245
+ fail: (count) => sprintf2(
1246
+ /* translators: %d: number of failed audit violations. */
1247
+ __15("%d failed audits, view all", "elementor"),
1248
+ count
1249
+ ),
1250
+ skipped: (count) => sprintf2(
1251
+ /* translators: %d: number of skipped audits. */
1252
+ __15("%d skipped audits, view all", "elementor"),
1253
+ count
1254
+ )
1255
+ };
1256
+ var STATUS_GROUPS = ["fail", "pass", "skipped"];
1257
+ function AuditStatusesSection({ report, onStatusClick }) {
1258
+ const statusCounts = auditStatusDisplayCounts(report);
1259
+ return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Typography8, { variant: "subtitle1", fontWeight: "bold" }, __15("Audit statuses", "elementor")), /* @__PURE__ */ React15.createElement(Box11, { sx: { display: "flex", justifyContent: "space-around", gap: 2 } }, STATUS_GROUPS.map((status) => /* @__PURE__ */ React15.createElement(
1260
+ CountSummaryCircle,
1261
+ {
1262
+ key: status,
1263
+ ariaLabel: STATUS_ARIA_LABELS[status](statusCounts[status]),
1264
+ color: auditStatusColor(status),
1265
+ count: statusCounts[status],
1266
+ label: auditStatusLabel(status),
1267
+ onClick: () => onStatusClick(status)
1268
+ }
1269
+ ))), /* @__PURE__ */ React15.createElement(Divider, null));
1196
1270
  }
1197
1271
 
1198
1272
  // src/components/issues-category-row.tsx
1199
- import * as React14 from "react";
1273
+ import * as React16 from "react";
1200
1274
  import { ChevronRightIcon } from "@elementor/icons";
1201
- import { Box as Box10, Rotate as Rotate2, Typography as Typography7, useTheme as useTheme2 } from "@elementor/ui";
1275
+ import { Box as Box12, Rotate as Rotate2, Typography as Typography9, useTheme as useTheme2 } from "@elementor/ui";
1202
1276
  function IssuesCategoryRow({ category, label, counts, onClick }) {
1203
1277
  const isRtl = "rtl" === useTheme2().direction;
1204
1278
  const Icon = CATEGORY_ICONS[category];
1205
- return /* @__PURE__ */ React14.createElement(
1206
- Box10,
1279
+ return /* @__PURE__ */ React16.createElement(
1280
+ Box12,
1207
1281
  {
1208
1282
  role: "button",
1209
1283
  tabIndex: 0,
@@ -1224,21 +1298,112 @@ function IssuesCategoryRow({ category, label, counts, onClick }) {
1224
1298
  "&:focus-visible": { outline: "2px solid", outlineColor: "primary.main" }
1225
1299
  }
1226
1300
  },
1227
- /* @__PURE__ */ React14.createElement(Icon, { fontSize: "small", color: "action" }),
1228
- /* @__PURE__ */ React14.createElement(Typography7, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
1229
- /* @__PURE__ */ React14.createElement(Box10, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React14.createElement(Box10, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React14.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React14.createElement(Typography7, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
1230
- /* @__PURE__ */ React14.createElement(Rotate2, { in: isRtl }, /* @__PURE__ */ React14.createElement(ChevronRightIcon, { fontSize: "small", color: "action" }))
1301
+ /* @__PURE__ */ React16.createElement(Icon, { fontSize: "small", color: "action" }),
1302
+ /* @__PURE__ */ React16.createElement(Typography9, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
1303
+ /* @__PURE__ */ React16.createElement(Box12, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React16.createElement(Box12, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React16.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React16.createElement(Typography9, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
1304
+ /* @__PURE__ */ React16.createElement(Rotate2, { in: isRtl }, /* @__PURE__ */ React16.createElement(ChevronRightIcon, { fontSize: "small", color: "action" }))
1231
1305
  );
1232
1306
  }
1233
1307
 
1234
- // src/components/promotions.tsx
1235
- import * as React16 from "react";
1236
- import { Box as Box12, Typography as Typography9 } from "@elementor/ui";
1308
+ // src/components/severity-filter-chips.tsx
1309
+ import * as React17 from "react";
1310
+ import { Box as Box13, Chip as Chip3 } from "@elementor/ui";
1237
1311
  import { __ as __16 } from "@wordpress/i18n";
1312
+ function SeverityFilterChips({ selected, onChange }) {
1313
+ return /* @__PURE__ */ React17.createElement(Box13, { sx: { display: "flex", alignItems: "center", gap: 1 } }, /* @__PURE__ */ React17.createElement(
1314
+ FilterChip,
1315
+ {
1316
+ label: __16("All", "elementor"),
1317
+ isSelected: selected === "all",
1318
+ onClick: () => onChange("all")
1319
+ }
1320
+ ), ALL_SEVERITIES.map((severity) => /* @__PURE__ */ React17.createElement(
1321
+ FilterChip,
1322
+ {
1323
+ key: severity,
1324
+ label: severityPluralLabel(severity),
1325
+ icon: /* @__PURE__ */ React17.createElement(SeverityIcon, { severity }),
1326
+ isSelected: selected === severity,
1327
+ onClick: () => onChange(severity)
1328
+ }
1329
+ )));
1330
+ }
1331
+ function FilterChip({ label, icon, isSelected, onClick }) {
1332
+ return /* @__PURE__ */ React17.createElement(
1333
+ Chip3,
1334
+ {
1335
+ label,
1336
+ icon,
1337
+ size: "small",
1338
+ variant: "filled",
1339
+ color: "default",
1340
+ onClick,
1341
+ "aria-pressed": isSelected,
1342
+ sx: { bgcolor: isSelected ? "action.selected" : "transparent" }
1343
+ }
1344
+ );
1345
+ }
1346
+
1347
+ // src/components/pages/issues-page.tsx
1348
+ function filterCounts(counts, filter) {
1349
+ if (filter === "all") {
1350
+ return counts;
1351
+ }
1352
+ return { error: 0, warning: 0, info: 0, [filter]: counts[filter] };
1353
+ }
1354
+ function IssuesPage({ report, onCategoryClick, onAllAuditsClick, onStatusClick }) {
1355
+ const [filter, setFilter] = useState4("all");
1356
+ const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1357
+ const categoryRows = populatedCategories.map((category) => ({ category, counts: filterCounts(countSeverities(report, category), filter) })).filter(({ counts }) => Object.values(counts).some((count) => count > 0));
1358
+ return /* @__PURE__ */ React18.createElement(Box14, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React18.createElement(AuditStatusesSection, { report, onStatusClick }), /* @__PURE__ */ React18.createElement(
1359
+ Link,
1360
+ {
1361
+ component: "button",
1362
+ underline: "none",
1363
+ color: "inherit",
1364
+ onClick: onAllAuditsClick,
1365
+ sx: { textAlign: "start" }
1366
+ },
1367
+ /* @__PURE__ */ React18.createElement(Typography10, { variant: "subtitle1", component: "h2" }, __17("All issues", "elementor"))
1368
+ ), /* @__PURE__ */ React18.createElement(SeverityFilterChips, { selected: filter, onChange: setFilter }), /* @__PURE__ */ React18.createElement(Box14, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, categoryRows.map(({ category, counts }) => /* @__PURE__ */ React18.createElement(
1369
+ IssuesCategoryRow,
1370
+ {
1371
+ key: category,
1372
+ category,
1373
+ label: CATEGORY_LABELS[category],
1374
+ counts,
1375
+ onClick: () => onCategoryClick(category)
1376
+ }
1377
+ ))));
1378
+ }
1379
+
1380
+ // src/components/pages/overview-page.tsx
1381
+ import * as React23 from "react";
1382
+ import { Box as Box19, Chip as Chip4, Typography as Typography15 } from "@elementor/ui";
1383
+ import { __ as __21 } from "@wordpress/i18n";
1384
+
1385
+ // src/utils/score-thresholds.ts
1386
+ import { __ as __18 } from "@wordpress/i18n";
1387
+ var GOOD_THRESHOLD = 90;
1388
+ var OK_THRESHOLD = 50;
1389
+ function getScoreTier(score) {
1390
+ if (score >= GOOD_THRESHOLD) {
1391
+ return { color: "success", label: __18("Good", "elementor") };
1392
+ }
1393
+ if (score >= OK_THRESHOLD) {
1394
+ return { color: "warning", label: __18("Needs work", "elementor") };
1395
+ }
1396
+ return { color: "error", label: __18("At risk", "elementor") };
1397
+ }
1398
+
1399
+ // src/components/promotions.tsx
1400
+ import * as React20 from "react";
1401
+ import { Box as Box16, Divider as Divider2, Typography as Typography12 } from "@elementor/ui";
1402
+ import { __ as __20 } from "@wordpress/i18n";
1238
1403
 
1239
1404
  // src/register-promotions.ts
1240
- import { ElementorCookieIcon, PhotoIcon, ShieldHalfFilledIcon as ShieldHalfFilledIcon2 } from "@elementor/icons";
1241
- import { __ as __15, _n, sprintf as sprintf3 } from "@wordpress/i18n";
1405
+ import { ElementorCookieIcon, PhotoIcon, ShieldHalfFilledIcon } from "@elementor/icons";
1406
+ import { __ as __19, _n, sprintf as sprintf3 } from "@wordpress/i18n";
1242
1407
  function firstFailExternalUrl(run) {
1243
1408
  return run.result.status === "fail" ? run.result.violations[0]?.externalUrl : void 0;
1244
1409
  }
@@ -1246,7 +1411,7 @@ var PROMOTIONS = [
1246
1411
  {
1247
1412
  auditId: "audits/images-alt-text",
1248
1413
  icon: PhotoIcon,
1249
- ctaLabel: __15("Fix with Ally", "elementor"),
1414
+ ctaLabel: __19("Fix with Ally", "elementor"),
1250
1415
  formatSubtitle: (run) => {
1251
1416
  if (run.result.status !== "fail") {
1252
1417
  return null;
@@ -1266,21 +1431,21 @@ var PROMOTIONS = [
1266
1431
  {
1267
1432
  auditId: "audits/cookie-policy",
1268
1433
  icon: ElementorCookieIcon,
1269
- ctaLabel: __15("Fix with Cookiez", "elementor"),
1270
- formatSubtitle: (run) => run.result.status === "fail" ? __15("Generate cookie policy", "elementor") : null,
1434
+ ctaLabel: __19("Fix with Cookiez", "elementor"),
1435
+ formatSubtitle: (run) => run.result.status === "fail" ? __19("Generate cookie policy", "elementor") : null,
1271
1436
  getCtaUrl: firstFailExternalUrl
1272
1437
  },
1273
1438
  {
1274
1439
  auditId: "audits/scan-for-cookies",
1275
1440
  icon: ElementorCookieIcon,
1276
- ctaLabel: __15("Scan", "elementor"),
1277
- formatSubtitle: (run) => run.result.status === "fail" ? __15("Scan this page for cookies", "elementor") : null,
1441
+ ctaLabel: __19("Scan", "elementor"),
1442
+ formatSubtitle: (run) => run.result.status === "fail" ? __19("Scan this page for cookies", "elementor") : null,
1278
1443
  getCtaUrl: firstFailExternalUrl
1279
1444
  },
1280
1445
  {
1281
1446
  auditId: "audits/images-too-large",
1282
- icon: ShieldHalfFilledIcon2,
1283
- ctaLabel: __15("Optimize all", "elementor"),
1447
+ icon: ShieldHalfFilledIcon,
1448
+ ctaLabel: __19("Optimize all", "elementor"),
1284
1449
  formatSubtitle: (run) => {
1285
1450
  if (run.result.status !== "fail") {
1286
1451
  return null;
@@ -1305,11 +1470,11 @@ function findAuditRun(report, auditId) {
1305
1470
  }
1306
1471
 
1307
1472
  // src/components/promotion-card.tsx
1308
- import * as React15 from "react";
1309
- import { Box as Box11, Button as Button4, Typography as Typography8 } from "@elementor/ui";
1473
+ import * as React19 from "react";
1474
+ import { Box as Box15, Button as Button4, Typography as Typography11 } from "@elementor/ui";
1310
1475
  function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle, title }) {
1311
- return /* @__PURE__ */ React15.createElement(
1312
- Box11,
1476
+ return /* @__PURE__ */ React19.createElement(
1477
+ Box15,
1313
1478
  {
1314
1479
  sx: {
1315
1480
  alignItems: "center",
@@ -1322,9 +1487,9 @@ function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle
1322
1487
  py: 1.5
1323
1488
  }
1324
1489
  },
1325
- /* @__PURE__ */ React15.createElement(Icon, { fontSize: "small", color: "action" }),
1326
- /* @__PURE__ */ React15.createElement(Box11, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React15.createElement(Typography8, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React15.createElement(Typography8, { variant: "caption", color: "text.secondary" }, subtitle)),
1327
- /* @__PURE__ */ React15.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
1490
+ /* @__PURE__ */ React19.createElement(Icon, { fontSize: "small", color: "action" }),
1491
+ /* @__PURE__ */ React19.createElement(Box15, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React19.createElement(Typography11, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React19.createElement(Typography11, { variant: "caption", color: "text.secondary" }, subtitle)),
1492
+ /* @__PURE__ */ React19.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
1328
1493
  );
1329
1494
  }
1330
1495
 
@@ -1353,7 +1518,7 @@ function Promotions({ report }) {
1353
1518
  if (cards.length === 0) {
1354
1519
  return null;
1355
1520
  }
1356
- return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Typography9, { variant: "subtitle1", fontWeight: "bold" }, __16("Quick wins", "elementor")), /* @__PURE__ */ React16.createElement(Box12, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React16.createElement(
1521
+ return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(Divider2, null), /* @__PURE__ */ React20.createElement(Typography12, { variant: "subtitle1", fontWeight: "bold" }, __20("Quick actions", "elementor")), /* @__PURE__ */ React20.createElement(Box16, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React20.createElement(
1357
1522
  PromotionCard,
1358
1523
  {
1359
1524
  key,
@@ -1371,115 +1536,14 @@ function Promotions({ report }) {
1371
1536
  ))));
1372
1537
  }
1373
1538
 
1374
- // src/components/pages/issues-page.tsx
1375
- function IssuesPage({ report, onCategoryClick, onAllAuditsClick }) {
1376
- const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1377
- return /* @__PURE__ */ React17.createElement(Box13, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React17.createElement(
1378
- Link,
1379
- {
1380
- component: "button",
1381
- underline: "none",
1382
- color: "inherit",
1383
- onClick: onAllAuditsClick,
1384
- sx: { textAlign: "start" }
1385
- },
1386
- /* @__PURE__ */ React17.createElement(Typography10, { variant: "subtitle1", component: "h2" }, __17("All issues", "elementor"))
1387
- ), /* @__PURE__ */ React17.createElement(Box13, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, populatedCategories.map((category) => /* @__PURE__ */ React17.createElement(
1388
- IssuesCategoryRow,
1389
- {
1390
- key: category,
1391
- category,
1392
- label: CATEGORY_LABELS[category],
1393
- counts: countSeverities(report, category),
1394
- onClick: () => onCategoryClick(category)
1395
- }
1396
- ))), /* @__PURE__ */ React17.createElement(Promotions, { report }));
1397
- }
1398
-
1399
- // src/components/pages/overview-page.tsx
1400
- import * as React21 from "react";
1401
- import { Box as Box17, Chip as Chip3, Divider, Typography as Typography14 } from "@elementor/ui";
1402
- import { __ as __19, sprintf as sprintf4 } from "@wordpress/i18n";
1403
-
1404
- // src/utils/score-thresholds.ts
1405
- import { __ as __18 } from "@wordpress/i18n";
1406
- var GOOD_THRESHOLD = 90;
1407
- var OK_THRESHOLD = 50;
1408
- function getScoreTier(score) {
1409
- if (score >= GOOD_THRESHOLD) {
1410
- return { color: "success", label: __18("Good", "elementor") };
1411
- }
1412
- if (score >= OK_THRESHOLD) {
1413
- return { color: "warning", label: __18("Needs work", "elementor") };
1414
- }
1415
- return { color: "error", label: __18("At risk", "elementor") };
1416
- }
1417
-
1418
- // src/components/count-summary-circle.tsx
1419
- import * as React18 from "react";
1420
- import { Box as Box14, Chip as Chip2, Typography as Typography11 } from "@elementor/ui";
1421
- var COUNT_SUMMARY_CIRCLE_SIZE = 64;
1422
- var COUNT_SUMMARY_BORDER_WIDTH = 4;
1423
- function chipBorderColor(theme, color) {
1424
- if (color === "default" || !color) {
1425
- return theme.palette.text.secondary;
1426
- }
1427
- return theme.palette[color].main;
1428
- }
1429
- function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
1430
- return /* @__PURE__ */ React18.createElement(
1431
- Box14,
1432
- {
1433
- "aria-label": ariaLabel,
1434
- component: "button",
1435
- onClick,
1436
- type: "button",
1437
- sx: {
1438
- alignItems: "center",
1439
- background: "none",
1440
- border: "none",
1441
- cursor: "pointer",
1442
- display: "flex",
1443
- flex: 1,
1444
- flexDirection: "column",
1445
- gap: 0.5,
1446
- padding: 0
1447
- }
1448
- },
1449
- /* @__PURE__ */ React18.createElement(
1450
- Chip2,
1451
- {
1452
- color,
1453
- label: count,
1454
- size: "small",
1455
- variant: "standard",
1456
- sx: (theme) => ({
1457
- border: `${COUNT_SUMMARY_BORDER_WIDTH}px solid ${chipBorderColor(theme, color)}`,
1458
- borderRadius: "50%",
1459
- height: COUNT_SUMMARY_CIRCLE_SIZE,
1460
- maxWidth: COUNT_SUMMARY_CIRCLE_SIZE,
1461
- width: COUNT_SUMMARY_CIRCLE_SIZE,
1462
- "& .MuiChip-label": {
1463
- fontSize: theme.typography.body2.fontSize,
1464
- fontWeight: 700,
1465
- lineHeight: 1,
1466
- padding: 0
1467
- }
1468
- })
1469
- }
1470
- ),
1471
- /* @__PURE__ */ React18.createElement(Typography11, { color: "text.secondary", sx: { textAlign: "center" }, variant: "caption" }, label)
1472
- );
1473
- }
1474
-
1475
1539
  // src/components/score-bar.tsx
1476
- import * as React19 from "react";
1540
+ import * as React21 from "react";
1477
1541
  import { ChevronRightIcon as ChevronRightIcon2 } from "@elementor/icons";
1478
- import { Box as Box15, LinearProgress, Rotate as Rotate3, Typography as Typography12, useTheme as useTheme3 } from "@elementor/ui";
1542
+ import { Box as Box17, LinearProgress, Rotate as Rotate3, Typography as Typography13, useTheme as useTheme3 } from "@elementor/ui";
1479
1543
  function ScoreBar({ label, score, onClick }) {
1480
1544
  const isRtl = "rtl" === useTheme3().direction;
1481
- return /* @__PURE__ */ React19.createElement(
1482
- Box15,
1545
+ return /* @__PURE__ */ React21.createElement(
1546
+ Box17,
1483
1547
  {
1484
1548
  role: onClick ? "button" : void 0,
1485
1549
  tabIndex: onClick ? 0 : void 0,
@@ -1495,8 +1559,8 @@ function ScoreBar({ label, score, onClick }) {
1495
1559
  py: 0.5
1496
1560
  }
1497
1561
  },
1498
- /* @__PURE__ */ React19.createElement(Typography12, { variant: "body2", sx: { minWidth: 96 } }, label),
1499
- /* @__PURE__ */ React19.createElement(
1562
+ /* @__PURE__ */ React21.createElement(Typography13, { variant: "body2", sx: { minWidth: 96 } }, label),
1563
+ /* @__PURE__ */ React21.createElement(
1500
1564
  LinearProgress,
1501
1565
  {
1502
1566
  variant: "determinate",
@@ -1505,8 +1569,8 @@ function ScoreBar({ label, score, onClick }) {
1505
1569
  sx: { flex: 1, height: 6, borderRadius: 4, bgcolor: "action.disabledBackground" }
1506
1570
  }
1507
1571
  ),
1508
- /* @__PURE__ */ React19.createElement(
1509
- Typography12,
1572
+ /* @__PURE__ */ React21.createElement(
1573
+ Typography13,
1510
1574
  {
1511
1575
  variant: "body2",
1512
1576
  color: "text.primary",
@@ -1514,19 +1578,19 @@ function ScoreBar({ label, score, onClick }) {
1514
1578
  },
1515
1579
  score
1516
1580
  ),
1517
- onClick && /* @__PURE__ */ React19.createElement(Rotate3, { in: isRtl }, /* @__PURE__ */ React19.createElement(ChevronRightIcon2, { fontSize: "small", color: "action" }))
1581
+ onClick && /* @__PURE__ */ React21.createElement(Rotate3, { in: isRtl }, /* @__PURE__ */ React21.createElement(ChevronRightIcon2, { fontSize: "small", color: "action" }))
1518
1582
  );
1519
1583
  }
1520
1584
 
1521
1585
  // src/components/score-circle.tsx
1522
- import * as React20 from "react";
1523
- import { Box as Box16, CircularProgress as CircularProgress2, Typography as Typography13 } from "@elementor/ui";
1586
+ import * as React22 from "react";
1587
+ import { Box as Box18, CircularProgress as CircularProgress2, Typography as Typography14 } from "@elementor/ui";
1524
1588
  var SCORE_CIRCLE_SIZE = 88;
1525
1589
  var SCORE_CIRCLE_THICKNESS = 3;
1526
1590
  function ScoreCircle({ color, score }) {
1527
1591
  const progressColor = color ?? getScoreTier(score).color;
1528
- return /* @__PURE__ */ React20.createElement(
1529
- Box16,
1592
+ return /* @__PURE__ */ React22.createElement(
1593
+ Box18,
1530
1594
  {
1531
1595
  role: "progressbar",
1532
1596
  "aria-valuenow": score,
@@ -1534,7 +1598,7 @@ function ScoreCircle({ color, score }) {
1534
1598
  "aria-valuemax": 100,
1535
1599
  sx: { position: "relative", display: "inline-flex" }
1536
1600
  },
1537
- /* @__PURE__ */ React20.createElement(
1601
+ /* @__PURE__ */ React22.createElement(
1538
1602
  CircularProgress2,
1539
1603
  {
1540
1604
  variant: "determinate",
@@ -1544,7 +1608,7 @@ function ScoreCircle({ color, score }) {
1544
1608
  sx: { color: "action.disabledBackground" }
1545
1609
  }
1546
1610
  ),
1547
- /* @__PURE__ */ React20.createElement(
1611
+ /* @__PURE__ */ React22.createElement(
1548
1612
  CircularProgress2,
1549
1613
  {
1550
1614
  variant: "determinate",
@@ -1555,8 +1619,8 @@ function ScoreCircle({ color, score }) {
1555
1619
  sx: { position: "absolute", left: 0 }
1556
1620
  }
1557
1621
  ),
1558
- /* @__PURE__ */ React20.createElement(
1559
- Box16,
1622
+ /* @__PURE__ */ React22.createElement(
1623
+ Box18,
1560
1624
  {
1561
1625
  sx: {
1562
1626
  position: "absolute",
@@ -1566,8 +1630,8 @@ function ScoreCircle({ color, score }) {
1566
1630
  justifyContent: "center"
1567
1631
  }
1568
1632
  },
1569
- /* @__PURE__ */ React20.createElement(
1570
- Typography13,
1633
+ /* @__PURE__ */ React22.createElement(
1634
+ Typography14,
1571
1635
  {
1572
1636
  variant: "h4",
1573
1637
  component: "span",
@@ -1581,31 +1645,11 @@ function ScoreCircle({ color, score }) {
1581
1645
  }
1582
1646
 
1583
1647
  // src/components/pages/overview-page.tsx
1584
- var STATUS_ARIA_LABELS = {
1585
- pass: (count) => sprintf4(
1586
- /* translators: %d: number of passed audits. */
1587
- __19("%d passed audits, view all", "elementor"),
1588
- count
1589
- ),
1590
- fail: (count) => sprintf4(
1591
- /* translators: %d: number of failed audit violations. */
1592
- __19("%d failed audits, view all", "elementor"),
1593
- count
1594
- ),
1595
- skipped: (count) => sprintf4(
1596
- /* translators: %d: number of skipped audits. */
1597
- __19("%d skipped audits, view all", "elementor"),
1598
- count
1599
- )
1600
- };
1601
- var STATUS_GROUPS = ["fail", "pass", "skipped"];
1602
- function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1648
+ function OverviewPage({ onCategoryClick, report }) {
1603
1649
  const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
1604
- const severityCounts = countSeverities(report);
1605
- const statusCounts = auditStatusDisplayCounts(report);
1606
1650
  const overallScore = getScoreTier(report.overall);
1607
- return /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", alignItems: "center", gap: 2 } }, /* @__PURE__ */ React21.createElement(ScoreCircle, { color: overallScore.color, score: report.overall }), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React21.createElement(
1608
- Chip3,
1651
+ return /* @__PURE__ */ React23.createElement(Box19, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React23.createElement(Box19, { sx: { display: "flex", alignItems: "center", gap: 2 } }, /* @__PURE__ */ React23.createElement(ScoreCircle, { color: overallScore.color, score: report.overall }), /* @__PURE__ */ React23.createElement(Box19, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React23.createElement(
1652
+ Chip4,
1609
1653
  {
1610
1654
  label: overallScore.label,
1611
1655
  color: overallScore.color,
@@ -1613,7 +1657,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1613
1657
  size: "small",
1614
1658
  sx: { fontWeight: 600, alignSelf: "flex-start" }
1615
1659
  }
1616
- ), /* @__PURE__ */ React21.createElement(Typography14, { variant: "body2", color: "text.secondary" }, __19("Overall score", "elementor")))), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 2 } }, populatedCategories.map((category) => /* @__PURE__ */ React21.createElement(
1660
+ ), /* @__PURE__ */ React23.createElement(Typography15, { variant: "body2", color: "text.secondary" }, __21("Overall score", "elementor")))), /* @__PURE__ */ React23.createElement(Box19, { sx: { display: "flex", flexDirection: "column", gap: 2 } }, populatedCategories.map((category) => /* @__PURE__ */ React23.createElement(
1617
1661
  ScoreBar,
1618
1662
  {
1619
1663
  key: category,
@@ -1621,45 +1665,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
1621
1665
  score: report.categories[category].score,
1622
1666
  onClick: () => onCategoryClick(category)
1623
1667
  }
1624
- ))), /* @__PURE__ */ React21.createElement(Divider, null), /* @__PURE__ */ React21.createElement(Typography14, { variant: "subtitle1", fontWeight: "bold" }, __19("Audit statuses", "elementor")), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", justifyContent: "space-around", gap: 2 } }, STATUS_GROUPS.map((status) => /* @__PURE__ */ React21.createElement(
1625
- CountSummaryCircle,
1626
- {
1627
- key: status,
1628
- ariaLabel: STATUS_ARIA_LABELS[status](statusCounts[status]),
1629
- color: auditStatusColor(status),
1630
- count: statusCounts[status],
1631
- label: auditStatusLabel(status),
1632
- onClick: () => onStatusClick(status)
1633
- }
1634
- ))), /* @__PURE__ */ React21.createElement(Divider, null), /* @__PURE__ */ React21.createElement(Typography14, { variant: "subtitle1", fontWeight: "bold" }, __19("Remaining issues", "elementor")), /* @__PURE__ */ React21.createElement(
1635
- Box17,
1636
- {
1637
- component: "ul",
1638
- sx: {
1639
- display: "flex",
1640
- flexDirection: "column",
1641
- gap: 1,
1642
- listStyle: "none",
1643
- m: 0,
1644
- p: 0
1645
- }
1646
- },
1647
- ALL_SEVERITIES.map((severity) => {
1648
- const count = severityCounts[severity];
1649
- return /* @__PURE__ */ React21.createElement(
1650
- Box17,
1651
- {
1652
- "aria-label": severityRemainingCountLabel(severity, count),
1653
- component: "li",
1654
- key: severity,
1655
- sx: { alignItems: "center", display: "flex", gap: 0.5 }
1656
- },
1657
- /* @__PURE__ */ React21.createElement(SeverityIcon, { severity }),
1658
- /* @__PURE__ */ React21.createElement(Typography14, { variant: "body2", fontWeight: "bold" }, count),
1659
- /* @__PURE__ */ React21.createElement(Typography14, { variant: "body2" }, severityPluralLabel(severity))
1660
- );
1661
- })
1662
- ));
1668
+ ))), /* @__PURE__ */ React23.createElement(Promotions, { report }));
1663
1669
  }
1664
1670
 
1665
1671
  // src/components/report-shell.tsx
@@ -1679,7 +1685,7 @@ function isCategoryPage(page) {
1679
1685
  return typeof page === "object" && "category" in page;
1680
1686
  }
1681
1687
  function ReportShell({ report }) {
1682
- const [activePage, setActivePage] = useState4("overview");
1688
+ const [activePage, setActivePage] = useState5("overview");
1683
1689
  const currentTab = activeTab(activePage);
1684
1690
  const handleTabChange = (_, value) => {
1685
1691
  setActivePage(value);
@@ -1695,10 +1701,10 @@ function ReportShell({ report }) {
1695
1701
  setActivePage(activePage.backTo);
1696
1702
  }
1697
1703
  };
1698
- return /* @__PURE__ */ React22.createElement(Box18, null, /* @__PURE__ */ React22.createElement(
1704
+ return /* @__PURE__ */ React24.createElement(Box20, { sx: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 } }, /* @__PURE__ */ React24.createElement(Box20, { sx: { flexShrink: 0 } }, /* @__PURE__ */ React24.createElement(
1699
1705
  Tabs,
1700
1706
  {
1701
- "aria-label": __20("Audit navigation", "elementor"),
1707
+ "aria-label": __22("Audit navigation", "elementor"),
1702
1708
  value: currentTab,
1703
1709
  onChange: handleTabChange,
1704
1710
  textColor: "secondary",
@@ -1707,30 +1713,30 @@ function ReportShell({ report }) {
1707
1713
  centered: true,
1708
1714
  variant: "fullWidth"
1709
1715
  },
1710
- /* @__PURE__ */ React22.createElement(Tab, { value: "overview", label: __20("Overview", "elementor") }),
1711
- /* @__PURE__ */ React22.createElement(Tab, { value: "issues", label: __20("Issues", "elementor") })
1712
- ), /* @__PURE__ */ React22.createElement(Divider2, null), activePage === "overview" && /* @__PURE__ */ React22.createElement(
1716
+ /* @__PURE__ */ React24.createElement(Tab, { value: "overview", label: __22("Overview", "elementor") }),
1717
+ /* @__PURE__ */ React24.createElement(Tab, { value: "issues", label: __22("Issues", "elementor") })
1718
+ ), /* @__PURE__ */ React24.createElement(Divider3, null)), /* @__PURE__ */ React24.createElement(Box20, { sx: { flex: 1, minHeight: 0, overflowY: "auto" } }, activePage === "overview" && /* @__PURE__ */ React24.createElement(
1713
1719
  OverviewPage,
1714
1720
  {
1715
1721
  report,
1716
- onCategoryClick: (category) => openCategory(category, "overview"),
1717
- onStatusClick: (status) => openAllAudits(status, "overview")
1722
+ onCategoryClick: (category) => openCategory(category, "overview")
1718
1723
  }
1719
- ), activePage === "issues" && /* @__PURE__ */ React22.createElement(
1724
+ ), activePage === "issues" && /* @__PURE__ */ React24.createElement(
1720
1725
  IssuesPage,
1721
1726
  {
1722
1727
  report,
1723
1728
  onCategoryClick: (category) => openCategory(category, "issues"),
1724
- onAllAuditsClick: () => openAllAudits()
1729
+ onAllAuditsClick: () => openAllAudits(),
1730
+ onStatusClick: (status) => openAllAudits(status)
1725
1731
  }
1726
- ), isAllAuditsPage(activePage) && /* @__PURE__ */ React22.createElement(
1732
+ ), isAllAuditsPage(activePage) && /* @__PURE__ */ React24.createElement(
1727
1733
  AllAuditsPage,
1728
1734
  {
1729
1735
  report,
1730
1736
  initialExpandedStatus: activePage.expand,
1731
1737
  onBack: backFromSubPage
1732
1738
  }
1733
- ), isCategoryPage(activePage) && /* @__PURE__ */ React22.createElement(CategoryPage, { category: activePage.category, report, onBack: backFromSubPage }));
1739
+ ), isCategoryPage(activePage) && /* @__PURE__ */ React24.createElement(CategoryPage, { category: activePage.category, report, onBack: backFromSubPage })));
1734
1740
  }
1735
1741
 
1736
1742
  // src/components/audit-panel.tsx
@@ -1739,15 +1745,24 @@ function AuditPanel() {
1739
1745
  const currentDocumentId = getCurrentDocumentId2() ?? 0;
1740
1746
  const onRun = () => run(currentDocumentId);
1741
1747
  const lastScanLabel = report ? new Date(report.runAt).toLocaleTimeString() : null;
1742
- return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(
1748
+ return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(
1743
1749
  FloatingPanelHeader,
1744
1750
  {
1745
1751
  panelId: "audit-panel",
1746
- title: __21("Page Audit", "elementor"),
1747
- badge: __21("Beta", "elementor"),
1752
+ title: __23("Page Audit", "elementor"),
1753
+ badge: __23("Beta", "elementor"),
1748
1754
  titleVariant: "subtitle2"
1749
1755
  }
1750
- ), /* @__PURE__ */ React23.createElement(FloatingPanelBody, null, status === "idle" && /* @__PURE__ */ React23.createElement(WelcomePage, null), status === "loading" && /* @__PURE__ */ React23.createElement(LoadingPage, null), status === "error" && /* @__PURE__ */ React23.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }), status === "ready" && report && /* @__PURE__ */ React23.createElement(ReportShell, { report })), /* @__PURE__ */ React23.createElement(FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React23.createElement(Typography15, { variant: "caption", sx: { flex: 1 } }, __21("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React23.createElement(Box19, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React23.createElement(AuditFeedback, null), /* @__PURE__ */ React23.createElement(
1756
+ ), /* @__PURE__ */ React25.createElement(
1757
+ FloatingPanelBody,
1758
+ {
1759
+ sx: status === "ready" ? { display: "flex", flexDirection: "column", overflow: "hidden", minHeight: 0 } : void 0
1760
+ },
1761
+ status === "idle" && /* @__PURE__ */ React25.createElement(WelcomePage, null),
1762
+ status === "loading" && /* @__PURE__ */ React25.createElement(LoadingPage, null),
1763
+ status === "error" && /* @__PURE__ */ React25.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }),
1764
+ status === "ready" && report && /* @__PURE__ */ React25.createElement(ReportShell, { report })
1765
+ ), /* @__PURE__ */ React25.createElement(FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React25.createElement(Typography16, { variant: "caption", sx: { flex: 1 } }, __23("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React25.createElement(Box21, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React25.createElement(AuditFeedback, null), /* @__PURE__ */ React25.createElement(
1751
1766
  Button5,
1752
1767
  {
1753
1768
  variant: "contained",
@@ -1755,7 +1770,7 @@ function AuditPanel() {
1755
1770
  onClick: onRun,
1756
1771
  disabled: status === "loading" || currentDocumentId === 0
1757
1772
  },
1758
- lastScanLabel ? __21("Re-scan", "elementor") : __21("Run page audit", "elementor")
1773
+ lastScanLabel ? __23("Re-scan", "elementor") : __23("Run page audit", "elementor")
1759
1774
  )));
1760
1775
  }
1761
1776
 
@@ -1780,8 +1795,8 @@ function useAuditToggleProps() {
1780
1795
  const { isOpen } = auditPanel.useFloatingPanelStatus();
1781
1796
  const { toggle } = auditPanel.useFloatingPanelActions();
1782
1797
  return {
1783
- title: __22("Audit Page", "elementor"),
1784
- icon: ShieldCheckIcon2,
1798
+ title: __24("Audit Page", "elementor"),
1799
+ icon: ShieldCheckIcon3,
1785
1800
  selected: isOpen,
1786
1801
  onClick: () => toggle()
1787
1802
  };
@@ -1798,15 +1813,15 @@ function registerAppBarAuditsToggle() {
1798
1813
  }
1799
1814
 
1800
1815
  // src/audits/accessibility-policy.ts
1801
- import { __ as __23 } from "@wordpress/i18n";
1816
+ import { __ as __25 } from "@wordpress/i18n";
1802
1817
  var audit = {
1803
1818
  id: "audits/accessibility-policy",
1804
- title: __23("Accessibility policy", "elementor"),
1805
- description: __23(
1819
+ title: __25("Accessibility policy", "elementor"),
1820
+ description: __25(
1806
1821
  "An accessibility policy demonstrates your commitment to digital inclusion and may be legally required in some regions.",
1807
1822
  "elementor"
1808
1823
  ),
1809
- fixHint: __23("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
1824
+ fixHint: __25("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
1810
1825
  categories: ["compliance"],
1811
1826
  severity: "info",
1812
1827
  weight: 1,
@@ -1819,7 +1834,7 @@ var audit = {
1819
1834
  violations: [
1820
1835
  {
1821
1836
  auditId: audit.id,
1822
- label: __23("Ally plugin is not installed or active.", "elementor"),
1837
+ label: __25("Ally plugin is not installed or active.", "elementor"),
1823
1838
  externalUrl: ctx.pageContext.ally_plugin_url
1824
1839
  }
1825
1840
  ]
@@ -1828,15 +1843,15 @@ var audit = {
1828
1843
  };
1829
1844
 
1830
1845
  // src/audits/cookie-policy.ts
1831
- import { __ as __24 } from "@wordpress/i18n";
1846
+ import { __ as __26 } from "@wordpress/i18n";
1832
1847
  var audit2 = {
1833
1848
  id: "audits/cookie-policy",
1834
- title: __24("Cookie policy", "elementor"),
1835
- description: __24(
1849
+ title: __26("Cookie policy", "elementor"),
1850
+ description: __26(
1836
1851
  "A cookie policy is required by privacy regulations such as GDPR (EU) or CCPA (US) to inform visitors about tracking and data collection.",
1837
1852
  "elementor"
1838
1853
  ),
1839
- fixHint: __24("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
1854
+ fixHint: __26("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
1840
1855
  categories: ["compliance"],
1841
1856
  severity: "info",
1842
1857
  weight: 1,
@@ -1849,7 +1864,7 @@ var audit2 = {
1849
1864
  violations: [
1850
1865
  {
1851
1866
  auditId: audit2.id,
1852
- label: __24("Cookiez plugin is not installed or active.", "elementor"),
1867
+ label: __26("Cookiez plugin is not installed or active.", "elementor"),
1853
1868
  externalUrl: ctx.pageContext.cookiez_plugin_url
1854
1869
  }
1855
1870
  ]
@@ -1859,7 +1874,7 @@ var audit2 = {
1859
1874
 
1860
1875
  // src/audits/deep-nesting.ts
1861
1876
  import { getWidgetsCache } from "@elementor/editor-elements";
1862
- import { __ as __25 } from "@wordpress/i18n";
1877
+ import { __ as __27 } from "@wordpress/i18n";
1863
1878
  var MAX_NESTING_DEPTH = 6;
1864
1879
  function isNestingElement(node, widgetsCache) {
1865
1880
  if (node.elType === "container") {
@@ -1869,18 +1884,18 @@ function isNestingElement(node, widgetsCache) {
1869
1884
  }
1870
1885
  var audit3 = {
1871
1886
  id: "audits/deep-nesting",
1872
- title: __25("Deep container nesting", "elementor"),
1873
- description: __25(
1887
+ title: __27("Deep container nesting", "elementor"),
1888
+ description: __27(
1874
1889
  "Container nesting exceeds the recommended depth. Deep DOM trees hurt rendering performance and readability.",
1875
1890
  "elementor"
1876
1891
  ),
1877
- fixHint: __25("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
1892
+ fixHint: __27("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
1878
1893
  categories: ["performance", "best-practices"],
1879
1894
  severity: "warning",
1880
1895
  weight: 5,
1881
1896
  evaluate: (ctx) => {
1882
1897
  if (ctx.elements.tree.length === 0) {
1883
- return { status: "skipped", reason: __25("No elements", "elementor") };
1898
+ return { status: "skipped", reason: __27("No elements", "elementor") };
1884
1899
  }
1885
1900
  const widgetsCache = getWidgetsCache();
1886
1901
  const violations = [];
@@ -1894,7 +1909,7 @@ var audit3 = {
1894
1909
  auditId: audit3.id,
1895
1910
  elementId: node.id,
1896
1911
  targetHint: "element-settings",
1897
- label: __25("Container nesting is too deep.", "elementor")
1912
+ label: __27("Container nesting is too deep.", "elementor")
1898
1913
  });
1899
1914
  }
1900
1915
  });
@@ -1903,15 +1918,15 @@ var audit3 = {
1903
1918
  };
1904
1919
 
1905
1920
  // src/audits/default-design-system.ts
1906
- import { __ as __26 } from "@wordpress/i18n";
1921
+ import { __ as __28 } from "@wordpress/i18n";
1907
1922
  var audit4 = {
1908
1923
  id: "audits/default-design-system",
1909
- title: __26("Default website kit", "elementor"),
1910
- description: __26(
1924
+ title: __28("Default website kit", "elementor"),
1925
+ description: __28(
1911
1926
  "Your website is using the default design system colors and fonts. Custom branding makes the website feel uniquely yours.",
1912
1927
  "elementor"
1913
1928
  ),
1914
- fixHint: __26("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
1929
+ fixHint: __28("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
1915
1930
  categories: ["best-practices"],
1916
1931
  severity: "info",
1917
1932
  weight: 1,
@@ -1924,7 +1939,7 @@ var audit4 = {
1924
1939
  violations: [
1925
1940
  {
1926
1941
  auditId: audit4.id,
1927
- label: __26("Kit appears unchanged from default.", "elementor"),
1942
+ label: __28("Kit appears unchanged from default.", "elementor"),
1928
1943
  targetHint: "site-settings"
1929
1944
  }
1930
1945
  ]
@@ -1934,16 +1949,16 @@ var audit4 = {
1934
1949
 
1935
1950
  // src/audits/deprecated-widgets.ts
1936
1951
  import { getWidgetsCache as getWidgetsCache2 } from "@elementor/editor-elements";
1937
- import { __ as __27 } from "@wordpress/i18n";
1952
+ import { __ as __29 } from "@wordpress/i18n";
1938
1953
  var DEPRECATION_CONTROL_NAME = "deprecation_message";
1939
1954
  var audit5 = {
1940
1955
  id: "audits/deprecated-widgets",
1941
- title: __27("Deprecated widgets", "elementor"),
1942
- description: __27(
1956
+ title: __29("Deprecated widgets", "elementor"),
1957
+ description: __29(
1943
1958
  "Deprecated widgets should not be used. For better capabilities use the recommended replacement.",
1944
1959
  "elementor"
1945
1960
  ),
1946
- fixHint: __27("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
1961
+ fixHint: __29("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
1947
1962
  categories: ["best-practices", "performance"],
1948
1963
  severity: "warning",
1949
1964
  weight: 7,
@@ -1970,7 +1985,7 @@ var audit5 = {
1970
1985
  auditId: audit5.id,
1971
1986
  elementId: node.id,
1972
1987
  targetHint: "element-settings",
1973
- label: __27("Using deprecated widget.", "elementor")
1988
+ label: __29("Using deprecated widget.", "elementor")
1974
1989
  });
1975
1990
  });
1976
1991
  return violations.length === 0 ? { status: "pass" } : { status: "fail", violations };
@@ -1978,7 +1993,7 @@ var audit5 = {
1978
1993
  };
1979
1994
 
1980
1995
  // src/audits/google-consent-mode.ts
1981
- import { __ as __28 } from "@wordpress/i18n";
1996
+ import { __ as __30 } from "@wordpress/i18n";
1982
1997
 
1983
1998
  // src/utils/fetch-rendered-html.ts
1984
1999
  var FETCH_TIMEOUT_MS = 1e4;
@@ -2022,12 +2037,12 @@ function hasConsentDefaultCall(html) {
2022
2037
  // src/audits/google-consent-mode.ts
2023
2038
  var audit6 = {
2024
2039
  id: "audits/google-consent-mode",
2025
- title: __28("Google Consent Mode", "elementor"),
2026
- description: __28(
2040
+ title: __30("Google Consent Mode", "elementor"),
2041
+ description: __30(
2027
2042
  "Google Analytics, Ads, or Tag Manager are running on this site and may not receive a consent signal, which risks losing conversion/analytics data and compliance exposure.",
2028
2043
  "elementor"
2029
2044
  ),
2030
- fixHint: __28(
2045
+ fixHint: __30(
2031
2046
  "Turn on Google Consent Mode in your cookie consent plugin so Google tags respect visitor consent choices.",
2032
2047
  "elementor"
2033
2048
  ),
@@ -2036,19 +2051,19 @@ var audit6 = {
2036
2051
  weight: 1,
2037
2052
  evaluate: async (ctx) => {
2038
2053
  if (!ctx.pageContext.frontend_url) {
2039
- return { status: "skipped", reason: __28("Page is not published.", "elementor") };
2054
+ return { status: "skipped", reason: __30("Page is not published.", "elementor") };
2040
2055
  }
2041
2056
  const html = await fetchRenderedHtml(ctx.pageContext.frontend_url);
2042
2057
  if (!html) {
2043
- return { status: "skipped", reason: __28("Could not fetch the published page.", "elementor") };
2058
+ return { status: "skipped", reason: __30("Could not fetch the published page.", "elementor") };
2044
2059
  }
2045
2060
  if (!hasGoogleTracking(html)) {
2046
- return { status: "skipped", reason: __28("No Google tracking product detected.", "elementor") };
2061
+ return { status: "skipped", reason: __30("No Google tracking product detected.", "elementor") };
2047
2062
  }
2048
2063
  if (hasConsentDefaultCall(html)) {
2049
2064
  return { status: "pass" };
2050
2065
  }
2051
- const label = __28("No Google Consent Mode signal was found on the page.", "elementor");
2066
+ const label = __30("No Google Consent Mode signal was found on the page.", "elementor");
2052
2067
  const isCookiezReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
2053
2068
  if (isCookiezReady) {
2054
2069
  return {
@@ -2057,7 +2072,7 @@ var audit6 = {
2057
2072
  {
2058
2073
  auditId: audit6.id,
2059
2074
  label,
2060
- ctaLabel: __28("Enable", "elementor"),
2075
+ ctaLabel: __30("Enable", "elementor"),
2061
2076
  externalUrl: ctx.pageContext.cookiez_consent_mode_settings_url
2062
2077
  }
2063
2078
  ]
@@ -2077,7 +2092,7 @@ var audit6 = {
2077
2092
  };
2078
2093
 
2079
2094
  // src/audits/heading-structure.ts
2080
- import { __ as __29 } from "@wordpress/i18n";
2095
+ import { __ as __31 } from "@wordpress/i18n";
2081
2096
  var HEADING_LEVELS = ["h1", "h2", "h3", "h4", "h5", "h6"];
2082
2097
  var HEADING_CONTROLS_REGISTRY = {
2083
2098
  // Core
@@ -2255,27 +2270,27 @@ function extractPageHeadings(tree) {
2255
2270
  }
2256
2271
  var audit7 = {
2257
2272
  id: "audits/heading-structure",
2258
- title: __29("Heading structure", "elementor"),
2259
- description: __29("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
2260
- fixHint: __29("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
2273
+ title: __31("Heading structure", "elementor"),
2274
+ description: __31("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
2275
+ fixHint: __31("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
2261
2276
  categories: ["seo", "accessibility"],
2262
2277
  severity: "error",
2263
2278
  weight: 10,
2264
2279
  evaluate: (ctx) => {
2265
2280
  if (ctx.elements.tree.length === 0) {
2266
- return { status: "skipped", reason: __29("No elements", "elementor") };
2281
+ return { status: "skipped", reason: __31("No elements", "elementor") };
2267
2282
  }
2268
2283
  const headings = extractPageHeadings(ctx.elements.tree);
2269
2284
  const violations = [];
2270
2285
  if (headings.length === 0) {
2271
2286
  violations.push({
2272
2287
  auditId: audit7.id,
2273
- label: __29("No headings found on the page.", "elementor")
2288
+ label: __31("No headings found on the page.", "elementor")
2274
2289
  });
2275
2290
  } else {
2276
2291
  const h1Count = headings.filter((h) => h.level === 1).length;
2277
2292
  if (h1Count === 0) {
2278
- violations.push({ auditId: audit7.id, label: __29("No H1 on the page.", "elementor") });
2293
+ violations.push({ auditId: audit7.id, label: __31("No H1 on the page.", "elementor") });
2279
2294
  }
2280
2295
  if (h1Count > 1) {
2281
2296
  headings.filter((h) => h.level === 1).slice(1).forEach(
@@ -2283,7 +2298,7 @@ var audit7 = {
2283
2298
  auditId: audit7.id,
2284
2299
  elementId: h.elementId,
2285
2300
  targetHint: "element-settings",
2286
- label: __29("More than one H1 on the page.", "elementor")
2301
+ label: __31("More than one H1 on the page.", "elementor")
2287
2302
  })
2288
2303
  );
2289
2304
  }
@@ -2293,7 +2308,7 @@ var audit7 = {
2293
2308
  auditId: audit7.id,
2294
2309
  elementId: headings[i].elementId,
2295
2310
  targetHint: "element-settings",
2296
- label: __29("Heading level skipped.", "elementor")
2311
+ label: __31("Heading level skipped.", "elementor")
2297
2312
  });
2298
2313
  }
2299
2314
  }
@@ -2303,24 +2318,24 @@ var audit7 = {
2303
2318
  };
2304
2319
 
2305
2320
  // src/audits/hidden-elements.ts
2306
- import { __ as __30 } from "@wordpress/i18n";
2321
+ import { __ as __32 } from "@wordpress/i18n";
2307
2322
  function isHiddenOnAllDevices(settings) {
2308
2323
  return Boolean(settings.hide_desktop) && Boolean(settings.hide_tablet) && Boolean(settings.hide_mobile);
2309
2324
  }
2310
2325
  var audit8 = {
2311
2326
  id: "audits/hidden-elements",
2312
- title: __30("Hidden elements", "elementor"),
2313
- description: __30(
2327
+ title: __32("Hidden elements", "elementor"),
2328
+ description: __32(
2314
2329
  "Elements hidden on all devices simultaneously are effectively dead code in the page tree.",
2315
2330
  "elementor"
2316
2331
  ),
2317
- fixHint: __30("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
2332
+ fixHint: __32("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
2318
2333
  categories: ["best-practices", "performance"],
2319
2334
  severity: "info",
2320
2335
  weight: 3,
2321
2336
  evaluate: (ctx) => {
2322
2337
  if (ctx.elements.tree.length === 0) {
2323
- return { status: "skipped", reason: __30("No elements", "elementor") };
2338
+ return { status: "skipped", reason: __32("No elements", "elementor") };
2324
2339
  }
2325
2340
  const violations = [];
2326
2341
  walkElements(ctx.elements.tree, (node) => {
@@ -2329,7 +2344,7 @@ var audit8 = {
2329
2344
  auditId: audit8.id,
2330
2345
  elementId: node.id,
2331
2346
  targetHint: "element-settings",
2332
- label: __30("Element is hidden on all devices.", "elementor")
2347
+ label: __32("Element is hidden on all devices.", "elementor")
2333
2348
  });
2334
2349
  }
2335
2350
  });
@@ -2338,7 +2353,7 @@ var audit8 = {
2338
2353
  };
2339
2354
 
2340
2355
  // src/audits/images-alt-text.ts
2341
- import { __ as __31 } from "@wordpress/i18n";
2356
+ import { __ as __33 } from "@wordpress/i18n";
2342
2357
 
2343
2358
  // src/utils/image-alt.ts
2344
2359
  function hasMeaningfulAlt(media, pageContext) {
@@ -2358,15 +2373,15 @@ function isImageSourcePresent(media) {
2358
2373
  // src/audits/images-alt-text.ts
2359
2374
  var audit9 = {
2360
2375
  id: "audits/images-alt-text",
2361
- title: __31("Images alt text", "elementor"),
2362
- description: __31("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
2363
- fixHint: __31("Open the image's settings and add an Alt Text describing the image.", "elementor"),
2376
+ title: __33("Images alt text", "elementor"),
2377
+ description: __33("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
2378
+ fixHint: __33("Open the image's settings and add an Alt Text describing the image.", "elementor"),
2364
2379
  categories: ["seo", "accessibility"],
2365
2380
  severity: "error",
2366
2381
  weight: 10,
2367
2382
  evaluate: (ctx) => {
2368
2383
  if (!hasPageImages(ctx.elements.tree)) {
2369
- return { status: "skipped", reason: __31("No images", "elementor") };
2384
+ return { status: "skipped", reason: __33("No images", "elementor") };
2370
2385
  }
2371
2386
  const violations = [];
2372
2387
  const failedWidgetIds = /* @__PURE__ */ new Set();
@@ -2382,7 +2397,7 @@ var audit9 = {
2382
2397
  auditId: audit9.id,
2383
2398
  elementId: node.id,
2384
2399
  targetHint: "element-settings",
2385
- label: __31("Image is missing alt text.", "elementor"),
2400
+ label: __33("Image is missing alt text.", "elementor"),
2386
2401
  externalUrl: ctx.pageContext.ally_plugin_url
2387
2402
  });
2388
2403
  }
@@ -2392,20 +2407,20 @@ var audit9 = {
2392
2407
  };
2393
2408
 
2394
2409
  // src/audits/images-too-large.ts
2395
- import { __ as __32, sprintf as sprintf5 } from "@wordpress/i18n";
2410
+ import { __ as __34, sprintf as sprintf4 } from "@wordpress/i18n";
2396
2411
  var SIZE_THRESHOLD_BYTES = 500 * 1024;
2397
2412
  var BYTES_PER_KB = 1024;
2398
2413
  var audit10 = {
2399
2414
  id: "audits/images-too-large",
2400
- title: __32("Oversized images", "elementor"),
2401
- description: __32("Large image files slow down the page.", "elementor"),
2402
- fixHint: __32("Replace the image with a smaller version or enable image optimization.", "elementor"),
2415
+ title: __34("Oversized images", "elementor"),
2416
+ description: __34("Large image files slow down the page.", "elementor"),
2417
+ fixHint: __34("Replace the image with a smaller version or enable image optimization.", "elementor"),
2403
2418
  categories: ["performance"],
2404
2419
  severity: "warning",
2405
2420
  weight: 7,
2406
2421
  evaluate: (ctx) => {
2407
2422
  if (!hasPageImages(ctx.elements.tree)) {
2408
- return { status: "skipped", reason: __32("No images", "elementor") };
2423
+ return { status: "skipped", reason: __34("No images", "elementor") };
2409
2424
  }
2410
2425
  const widgetMaxKb = /* @__PURE__ */ new Map();
2411
2426
  let oversizedImageCount = 0;
@@ -2427,9 +2442,9 @@ var audit10 = {
2427
2442
  auditId: audit10.id,
2428
2443
  elementId,
2429
2444
  targetHint: "element-settings",
2430
- label: sprintf5(
2445
+ label: sprintf4(
2431
2446
  /* translators: %d is the image file size in kilobytes. */
2432
- __32("Image is %d KB (over 500 KB).", "elementor"),
2447
+ __34("Image is %d KB (over 500 KB).", "elementor"),
2433
2448
  kb
2434
2449
  ),
2435
2450
  externalUrl: ctx.pageContext.image_optimization_plugin_url
@@ -2439,21 +2454,21 @@ var audit10 = {
2439
2454
  };
2440
2455
 
2441
2456
  // src/audits/nested-boxed-containers.ts
2442
- import { __ as __33 } from "@wordpress/i18n";
2457
+ import { __ as __35 } from "@wordpress/i18n";
2443
2458
  function isBoxed(settings) {
2444
2459
  return settings.content_width === "boxed";
2445
2460
  }
2446
2461
  var audit11 = {
2447
2462
  id: "audits/nested-boxed-containers",
2448
- title: __33("Boxed container nested inside a boxed parent", "elementor"),
2449
- description: __33("An inner container does not need to be boxed when its parent already is.", "elementor"),
2450
- fixHint: __33("Change the inner container's content width to Full Width.", "elementor"),
2463
+ title: __35("Boxed container nested inside a boxed parent", "elementor"),
2464
+ description: __35("An inner container does not need to be boxed when its parent already is.", "elementor"),
2465
+ fixHint: __35("Change the inner container's content width to Full Width.", "elementor"),
2451
2466
  categories: ["best-practices", "performance"],
2452
2467
  severity: "info",
2453
2468
  weight: 5,
2454
2469
  evaluate: (ctx) => {
2455
2470
  if (ctx.elements.tree.length === 0) {
2456
- return { status: "skipped", reason: __33("No elements", "elementor") };
2471
+ return { status: "skipped", reason: __35("No elements", "elementor") };
2457
2472
  }
2458
2473
  const violations = [];
2459
2474
  walkElements(ctx.elements.tree, (node, parents) => {
@@ -2466,7 +2481,7 @@ var audit11 = {
2466
2481
  auditId: audit11.id,
2467
2482
  elementId: node.id,
2468
2483
  targetHint: "element-settings",
2469
- label: __33("Nested boxed container.", "elementor")
2484
+ label: __35("Nested boxed container.", "elementor")
2470
2485
  });
2471
2486
  }
2472
2487
  });
@@ -2475,12 +2490,12 @@ var audit11 = {
2475
2490
  };
2476
2491
 
2477
2492
  // src/audits/page-excerpt.ts
2478
- import { __ as __34 } from "@wordpress/i18n";
2493
+ import { __ as __36 } from "@wordpress/i18n";
2479
2494
  var audit12 = {
2480
2495
  id: "audits/page-excerpt",
2481
- title: __34("Page excerpt", "elementor"),
2482
- description: __34("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2483
- fixHint: __34("Open Page Settings and write a short excerpt.", "elementor"),
2496
+ title: __36("Page excerpt", "elementor"),
2497
+ description: __36("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2498
+ fixHint: __36("Open Page Settings and write a short excerpt.", "elementor"),
2484
2499
  categories: ["seo"],
2485
2500
  severity: "warning",
2486
2501
  weight: 5,
@@ -2493,7 +2508,7 @@ var audit12 = {
2493
2508
  violations: [
2494
2509
  {
2495
2510
  auditId: audit12.id,
2496
- label: __34("Page has no excerpt.", "elementor"),
2511
+ label: __36("Page has no excerpt.", "elementor"),
2497
2512
  targetHint: "page-settings",
2498
2513
  angieFix: true
2499
2514
  }
@@ -2503,12 +2518,12 @@ var audit12 = {
2503
2518
  };
2504
2519
 
2505
2520
  // src/audits/page-featured-image.ts
2506
- import { __ as __35 } from "@wordpress/i18n";
2521
+ import { __ as __37 } from "@wordpress/i18n";
2507
2522
  var audit13 = {
2508
2523
  id: "audits/page-featured-image",
2509
- title: __35("Page featured image", "elementor"),
2510
- description: __35("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2511
- fixHint: __35("Open Page Settings and set a featured image.", "elementor"),
2524
+ title: __37("Page featured image", "elementor"),
2525
+ description: __37("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2526
+ fixHint: __37("Open Page Settings and set a featured image.", "elementor"),
2512
2527
  categories: ["seo"],
2513
2528
  severity: "info",
2514
2529
  weight: 5,
@@ -2521,7 +2536,7 @@ var audit13 = {
2521
2536
  violations: [
2522
2537
  {
2523
2538
  auditId: audit13.id,
2524
- label: __35("No featured image set.", "elementor"),
2539
+ label: __37("No featured image set.", "elementor"),
2525
2540
  targetHint: "page-settings"
2526
2541
  }
2527
2542
  ]
@@ -2530,13 +2545,13 @@ var audit13 = {
2530
2545
  };
2531
2546
 
2532
2547
  // src/audits/page-title.ts
2533
- import { __ as __36 } from "@wordpress/i18n";
2548
+ import { __ as __38 } from "@wordpress/i18n";
2534
2549
  var MAX_TITLE_LENGTH = 60;
2535
2550
  var audit14 = {
2536
2551
  id: "audits/page-title",
2537
- title: __36("Page title", "elementor"),
2538
- description: __36("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2539
- fixHint: __36("Open Page Settings and add a title.", "elementor"),
2552
+ title: __38("Page title", "elementor"),
2553
+ description: __38("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2554
+ fixHint: __38("Open Page Settings and add a title.", "elementor"),
2540
2555
  categories: ["seo"],
2541
2556
  severity: "error",
2542
2557
  weight: 10,
@@ -2548,9 +2563,13 @@ var audit14 = {
2548
2563
  violations: [
2549
2564
  {
2550
2565
  auditId: audit14.id,
2551
- label: __36("Page has no title.", "elementor"),
2566
+ label: __38("Page has no title.", "elementor"),
2552
2567
  targetHint: "page-settings",
2553
- angieFix: true
2568
+ angieFix: true,
2569
+ angiePrompt: __38(
2570
+ "Based on this page's contents, generate a title for this page.",
2571
+ "elementor"
2572
+ )
2554
2573
  }
2555
2574
  ]
2556
2575
  };
@@ -2561,7 +2580,7 @@ var audit14 = {
2561
2580
  violations: [
2562
2581
  {
2563
2582
  auditId: audit14.id,
2564
- label: __36("Page title is too long.", "elementor"),
2583
+ label: __38("Page title is too long.", "elementor"),
2565
2584
  targetHint: "page-settings",
2566
2585
  angieFix: true
2567
2586
  }
@@ -2573,7 +2592,7 @@ var audit14 = {
2573
2592
  };
2574
2593
 
2575
2594
  // src/audits/prefer-global-colors.ts
2576
- import { __ as __37, sprintf as sprintf6 } from "@wordpress/i18n";
2595
+ import { __ as __39, sprintf as sprintf5 } from "@wordpress/i18n";
2577
2596
 
2578
2597
  // src/utils/collect-hardcoded-colors.ts
2579
2598
  var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2641,18 +2660,18 @@ function findMatchingGlobalByValue(value, globals) {
2641
2660
  // src/audits/prefer-global-colors.ts
2642
2661
  var audit15 = {
2643
2662
  id: "audits/prefer-global-colors",
2644
- title: __37("Prefer global colors", "elementor"),
2645
- description: __37("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2646
- fixHint: __37("Replace the hard-coded value with the matching global color.", "elementor"),
2663
+ title: __39("Prefer global colors", "elementor"),
2664
+ description: __39("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2665
+ fixHint: __39("Replace the hard-coded value with the matching global color.", "elementor"),
2647
2666
  categories: ["best-practices"],
2648
2667
  severity: "info",
2649
2668
  weight: 3,
2650
2669
  evaluate: (ctx) => {
2651
2670
  if (ctx.elements.tree.length === 0) {
2652
- return { status: "skipped", reason: __37("No elements", "elementor") };
2671
+ return { status: "skipped", reason: __39("No elements", "elementor") };
2653
2672
  }
2654
2673
  if (ctx.kit.globals.colors.length === 0) {
2655
- return { status: "skipped", reason: __37("No global colors", "elementor") };
2674
+ return { status: "skipped", reason: __39("No global colors", "elementor") };
2656
2675
  }
2657
2676
  const violations = [];
2658
2677
  walkElements(ctx.elements.tree, (node) => {
@@ -2666,9 +2685,9 @@ var audit15 = {
2666
2685
  elementId: node.id,
2667
2686
  targetHint: "element-settings",
2668
2687
  angieFix: true,
2669
- label: sprintf6(
2688
+ label: sprintf5(
2670
2689
  /* translators: 1: hard-coded color value, 2: global color title. */
2671
- __37('replace "%1$s" with "%2$s" global color', "elementor"),
2690
+ __39('replace "%1$s" with "%2$s" global color', "elementor"),
2672
2691
  value,
2673
2692
  global.title
2674
2693
  )
@@ -2680,7 +2699,7 @@ var audit15 = {
2680
2699
  };
2681
2700
 
2682
2701
  // src/audits/prefer-global-fonts.ts
2683
- import { __ as __38, sprintf as sprintf7 } from "@wordpress/i18n";
2702
+ import { __ as __40, sprintf as sprintf6 } from "@wordpress/i18n";
2684
2703
 
2685
2704
  // src/utils/collect-hardcoded-fonts.ts
2686
2705
  var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2740,18 +2759,18 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
2740
2759
  // src/audits/prefer-global-fonts.ts
2741
2760
  var audit16 = {
2742
2761
  id: "audits/prefer-global-fonts",
2743
- title: __38("Prefer global fonts", "elementor"),
2744
- description: __38("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2745
- fixHint: __38("Replace the hard-coded value with the matching global font.", "elementor"),
2762
+ title: __40("Prefer global fonts", "elementor"),
2763
+ description: __40("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2764
+ fixHint: __40("Replace the hard-coded value with the matching global font.", "elementor"),
2746
2765
  categories: ["best-practices", "performance"],
2747
2766
  severity: "info",
2748
2767
  weight: 3,
2749
2768
  evaluate: (ctx) => {
2750
2769
  if (ctx.elements.tree.length === 0) {
2751
- return { status: "skipped", reason: __38("No elements", "elementor") };
2770
+ return { status: "skipped", reason: __40("No elements", "elementor") };
2752
2771
  }
2753
2772
  if (ctx.kit.globals.fonts.length === 0) {
2754
- return { status: "skipped", reason: __38("No global fonts", "elementor") };
2773
+ return { status: "skipped", reason: __40("No global fonts", "elementor") };
2755
2774
  }
2756
2775
  const violations = [];
2757
2776
  walkElements(ctx.elements.tree, (node) => {
@@ -2764,9 +2783,9 @@ var audit16 = {
2764
2783
  auditId: audit16.id,
2765
2784
  elementId: node.id,
2766
2785
  targetHint: "element-settings",
2767
- label: sprintf7(
2786
+ label: sprintf6(
2768
2787
  /* translators: %s: global font title. */
2769
- __38('replace hardcoded typography with "%s" global font', "elementor"),
2788
+ __40('replace hardcoded typography with "%s" global font', "elementor"),
2770
2789
  global.title
2771
2790
  )
2772
2791
  });
@@ -2777,15 +2796,15 @@ var audit16 = {
2777
2796
  };
2778
2797
 
2779
2798
  // src/audits/privacy-policy.ts
2780
- import { __ as __39 } from "@wordpress/i18n";
2799
+ import { __ as __41 } from "@wordpress/i18n";
2781
2800
  var audit17 = {
2782
2801
  id: "audits/privacy-policy",
2783
- title: __39("Privacy policy", "elementor"),
2784
- description: __39(
2802
+ title: __41("Privacy policy", "elementor"),
2803
+ description: __41(
2785
2804
  "A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
2786
2805
  "elementor"
2787
2806
  ),
2788
- fixHint: __39(
2807
+ fixHint: __41(
2789
2808
  "Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
2790
2809
  "elementor"
2791
2810
  ),
@@ -2801,9 +2820,9 @@ var audit17 = {
2801
2820
  violations: [
2802
2821
  {
2803
2822
  auditId: audit17.id,
2804
- label: __39("No privacy policy page is set.", "elementor"),
2823
+ label: __41("No privacy policy page is set.", "elementor"),
2805
2824
  externalUrl: ctx.pageContext.privacy_settings_url,
2806
- ctaLabel: __39("Create", "elementor")
2825
+ ctaLabel: __41("Create", "elementor")
2807
2826
  }
2808
2827
  ]
2809
2828
  };
@@ -2811,15 +2830,15 @@ var audit17 = {
2811
2830
  };
2812
2831
 
2813
2832
  // src/audits/robots-noindex.ts
2814
- import { __ as __40 } from "@wordpress/i18n";
2833
+ import { __ as __42 } from "@wordpress/i18n";
2815
2834
  var audit18 = {
2816
2835
  id: "audits/robots-noindex",
2817
- title: __40("Search engine visibility", "elementor"),
2818
- description: __40(
2836
+ title: __42("Search engine visibility", "elementor"),
2837
+ description: __42(
2819
2838
  "When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
2820
2839
  "elementor"
2821
2840
  ),
2822
- fixHint: __40(
2841
+ fixHint: __42(
2823
2842
  'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
2824
2843
  "elementor"
2825
2844
  ),
@@ -2835,7 +2854,7 @@ var audit18 = {
2835
2854
  violations: [
2836
2855
  {
2837
2856
  auditId: audit18.id,
2838
- label: __40("Search engines are discouraged from indexing this website.", "elementor"),
2857
+ label: __42("Search engines are discouraged from indexing this website.", "elementor"),
2839
2858
  externalUrl: ctx.pageContext.reading_settings_url
2840
2859
  }
2841
2860
  ]
@@ -2844,15 +2863,15 @@ var audit18 = {
2844
2863
  };
2845
2864
 
2846
2865
  // src/audits/scan-for-cookies.ts
2847
- import { __ as __41 } from "@wordpress/i18n";
2866
+ import { __ as __43 } from "@wordpress/i18n";
2848
2867
  var audit19 = {
2849
2868
  id: "audits/scan-for-cookies",
2850
- title: __41("Scan for cookies", "elementor"),
2851
- description: __41(
2869
+ title: __43("Scan for cookies", "elementor"),
2870
+ description: __43(
2852
2871
  "Your site may be setting cookies you haven't disclosed. Some countries require a banner even without a full consent policy. Scan to see what needs disclosure.",
2853
2872
  "elementor"
2854
2873
  ),
2855
- fixHint: __41("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2874
+ fixHint: __43("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2856
2875
  categories: ["compliance"],
2857
2876
  severity: "info",
2858
2877
  weight: 0,
@@ -2863,7 +2882,7 @@ var audit19 = {
2863
2882
  violations: [
2864
2883
  {
2865
2884
  auditId: audit19.id,
2866
- label: __41("This page has not been scanned for cookies yet.", "elementor"),
2885
+ label: __43("This page has not been scanned for cookies yet.", "elementor"),
2867
2886
  externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
2868
2887
  }
2869
2888
  ]
@@ -2872,21 +2891,21 @@ var audit19 = {
2872
2891
  };
2873
2892
 
2874
2893
  // src/audits/sections-and-columns.ts
2875
- import { __ as __42 } from "@wordpress/i18n";
2894
+ import { __ as __44 } from "@wordpress/i18n";
2876
2895
  var audit20 = {
2877
2896
  id: "audits/sections-and-columns",
2878
- title: __42("Sections and columns", "elementor"),
2879
- description: __42(
2897
+ title: __44("Sections and columns", "elementor"),
2898
+ description: __44(
2880
2899
  "Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
2881
2900
  "elementor"
2882
2901
  ),
2883
- fixHint: __42("Use the Container Converter to replace each section/column with a container.", "elementor"),
2902
+ fixHint: __44("Use the Container Converter to replace each section/column with a container.", "elementor"),
2884
2903
  categories: ["best-practices", "performance"],
2885
2904
  severity: "warning",
2886
2905
  weight: 7,
2887
2906
  evaluate: (ctx) => {
2888
2907
  if (ctx.elements.tree.length === 0) {
2889
- return { status: "skipped", reason: __42("No elements", "elementor") };
2908
+ return { status: "skipped", reason: __44("No elements", "elementor") };
2890
2909
  }
2891
2910
  const violations = [];
2892
2911
  walkElements(ctx.elements.tree, (node) => {
@@ -2894,7 +2913,7 @@ var audit20 = {
2894
2913
  violations.push({
2895
2914
  auditId: audit20.id,
2896
2915
  elementId: node.id,
2897
- label: node.elType === "section" ? __42("Section element", "elementor") : __42("Column element", "elementor")
2916
+ label: node.elType === "section" ? __44("Section element", "elementor") : __44("Column element", "elementor")
2898
2917
  });
2899
2918
  }
2900
2919
  });
@@ -2903,15 +2922,15 @@ var audit20 = {
2903
2922
  };
2904
2923
 
2905
2924
  // src/audits/site-identity.ts
2906
- import { __ as __43 } from "@wordpress/i18n";
2925
+ import { __ as __45 } from "@wordpress/i18n";
2907
2926
  var audit21 = {
2908
2927
  id: "audits/site-identity",
2909
- title: __43("Site identity", "elementor"),
2910
- description: __43(
2928
+ title: __45("Site identity", "elementor"),
2929
+ description: __45(
2911
2930
  "Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
2912
2931
  "elementor"
2913
2932
  ),
2914
- fixHint: __43("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2933
+ fixHint: __45("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2915
2934
  categories: ["best-practices", "seo"],
2916
2935
  severity: "info",
2917
2936
  weight: 7,
@@ -2921,14 +2940,14 @@ var audit21 = {
2921
2940
  if (!identity.site_name_set) {
2922
2941
  violations.push({
2923
2942
  auditId: audit21.id,
2924
- label: __43("Site name is missing or still uses the default.", "elementor"),
2943
+ label: __45("Site name is missing or still uses the default.", "elementor"),
2925
2944
  targetHint: "site-identity-settings"
2926
2945
  });
2927
2946
  }
2928
2947
  if (!identity.site_description_set) {
2929
2948
  violations.push({
2930
2949
  auditId: audit21.id,
2931
- label: __43("Site description is missing or still uses the default.", "elementor"),
2950
+ label: __45("Site description is missing or still uses the default.", "elementor"),
2932
2951
  targetHint: "site-identity-settings",
2933
2952
  angieFix: true
2934
2953
  });
@@ -2936,14 +2955,14 @@ var audit21 = {
2936
2955
  if (!identity.site_logo_set) {
2937
2956
  violations.push({
2938
2957
  auditId: audit21.id,
2939
- label: __43("Site logo is not set.", "elementor"),
2958
+ label: __45("Site logo is not set.", "elementor"),
2940
2959
  targetHint: "site-identity-settings"
2941
2960
  });
2942
2961
  }
2943
2962
  if (!identity.site_favicon_set) {
2944
2963
  violations.push({
2945
2964
  auditId: audit21.id,
2946
- label: __43("Site favicon is not set.", "elementor"),
2965
+ label: __45("Site favicon is not set.", "elementor"),
2947
2966
  targetHint: "site-identity-settings"
2948
2967
  });
2949
2968
  }
@@ -2959,7 +2978,7 @@ var audit21 = {
2959
2978
 
2960
2979
  // src/audits/too-many-widgets.ts
2961
2980
  import { getWidgetsCache as getWidgetsCache3 } from "@elementor/editor-elements";
2962
- import { __ as __44 } from "@wordpress/i18n";
2981
+ import { __ as __46 } from "@wordpress/i18n";
2963
2982
  var WIDGET_COUNT_THRESHOLD = 100;
2964
2983
  function isCountableWidget(node, widgetsCache) {
2965
2984
  if (node.elType === "widget") {
@@ -2969,15 +2988,15 @@ function isCountableWidget(node, widgetsCache) {
2969
2988
  }
2970
2989
  var audit22 = {
2971
2990
  id: "audits/too-many-widgets",
2972
- title: __44("Too many widgets", "elementor"),
2973
- description: __44("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2974
- fixHint: __44("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2991
+ title: __46("Too many widgets", "elementor"),
2992
+ description: __46("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2993
+ fixHint: __46("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2975
2994
  categories: ["best-practices", "performance"],
2976
2995
  severity: "warning",
2977
2996
  weight: 5,
2978
2997
  evaluate: (ctx) => {
2979
2998
  if (ctx.elements.tree.length === 0) {
2980
- return { status: "skipped", reason: __44("No elements", "elementor") };
2999
+ return { status: "skipped", reason: __46("No elements", "elementor") };
2981
3000
  }
2982
3001
  const widgetsCache = getWidgetsCache3();
2983
3002
  let widgetCount = 0;
@@ -2994,7 +3013,7 @@ var audit22 = {
2994
3013
  violations: [
2995
3014
  {
2996
3015
  auditId: audit22.id,
2997
- label: __44("Page has too many widgets.", "elementor")
3016
+ label: __46("Page has too many widgets.", "elementor")
2998
3017
  }
2999
3018
  ]
3000
3019
  };