lighthouse 9.5.0-dev.20220607 → 9.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/dist/report/bundle.esm.js +467 -520
  2. package/dist/report/flow.js +22 -22
  3. package/dist/report/standalone.js +19 -19
  4. package/flow-report/src/summary/category.tsx +1 -1
  5. package/flow-report/src/topbar.tsx +2 -10
  6. package/flow-report/src/util.ts +1 -1
  7. package/flow-report/test/topbar-test.tsx +8 -7
  8. package/jest.config.js +1 -1
  9. package/lighthouse-cli/.eslintrc.cjs +4 -3
  10. package/lighthouse-cli/bin.js +1 -0
  11. package/lighthouse-cli/cli-flags.js +4 -3
  12. package/lighthouse-cli/commands/commands.js +1 -0
  13. package/lighthouse-cli/commands/list-audits.js +1 -0
  14. package/lighthouse-cli/commands/list-locales.js +1 -0
  15. package/lighthouse-cli/commands/list-trace-categories.js +1 -0
  16. package/lighthouse-cli/index.js +1 -0
  17. package/lighthouse-cli/printer.js +1 -0
  18. package/lighthouse-cli/run.js +24 -9
  19. package/lighthouse-cli/sentry-prompt.js +1 -0
  20. package/lighthouse-cli/test/smokehouse/core-tests.js +1 -0
  21. package/lighthouse-cli/test/smokehouse/frontends/back-compat-util.js +1 -0
  22. package/lighthouse-cli/test/smokehouse/frontends/lib.js +1 -0
  23. package/lighthouse-cli/test/smokehouse/frontends/node.js +1 -0
  24. package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +1 -0
  25. package/lighthouse-cli/test/smokehouse/lib/child-process-error.js +1 -0
  26. package/lighthouse-cli/test/smokehouse/lib/concurrent-mapper.js +1 -0
  27. package/lighthouse-cli/test/smokehouse/lib/local-console.js +1 -0
  28. package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +23 -109
  29. package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +3 -2
  30. package/lighthouse-cli/test/smokehouse/lighthouse-runners/devtools.js +19 -28
  31. package/lighthouse-cli/test/smokehouse/report-assert.js +4 -3
  32. package/lighthouse-cli/test/smokehouse/smokehouse.js +1 -1
  33. package/lighthouse-cli/test/smokehouse/version-check-test.js +3 -0
  34. package/lighthouse-cli/test/smokehouse/version-check.js +1 -0
  35. package/lighthouse-core/audits/accessibility/accesskeys.js +1 -1
  36. package/lighthouse-core/audits/accessibility/aria-allowed-attr.js +1 -1
  37. package/lighthouse-core/audits/accessibility/aria-command-name.js +1 -1
  38. package/lighthouse-core/audits/accessibility/aria-hidden-body.js +1 -1
  39. package/lighthouse-core/audits/accessibility/aria-hidden-focus.js +1 -1
  40. package/lighthouse-core/audits/accessibility/aria-input-field-name.js +1 -1
  41. package/lighthouse-core/audits/accessibility/aria-meter-name.js +1 -1
  42. package/lighthouse-core/audits/accessibility/aria-progressbar-name.js +1 -1
  43. package/lighthouse-core/audits/accessibility/aria-required-attr.js +1 -1
  44. package/lighthouse-core/audits/accessibility/aria-required-children.js +1 -1
  45. package/lighthouse-core/audits/accessibility/aria-required-parent.js +1 -1
  46. package/lighthouse-core/audits/accessibility/aria-roles.js +1 -1
  47. package/lighthouse-core/audits/accessibility/aria-toggle-field-name.js +1 -1
  48. package/lighthouse-core/audits/accessibility/aria-tooltip-name.js +1 -1
  49. package/lighthouse-core/audits/accessibility/aria-treeitem-name.js +1 -1
  50. package/lighthouse-core/audits/accessibility/aria-valid-attr-value.js +1 -1
  51. package/lighthouse-core/audits/accessibility/aria-valid-attr.js +1 -1
  52. package/lighthouse-core/audits/accessibility/button-name.js +1 -1
  53. package/lighthouse-core/audits/accessibility/bypass.js +1 -1
  54. package/lighthouse-core/audits/accessibility/color-contrast.js +1 -1
  55. package/lighthouse-core/audits/accessibility/definition-list.js +1 -1
  56. package/lighthouse-core/audits/accessibility/dlitem.js +1 -1
  57. package/lighthouse-core/audits/accessibility/document-title.js +1 -1
  58. package/lighthouse-core/audits/accessibility/duplicate-id-active.js +1 -1
  59. package/lighthouse-core/audits/accessibility/duplicate-id-aria.js +1 -1
  60. package/lighthouse-core/audits/accessibility/form-field-multiple-labels.js +1 -1
  61. package/lighthouse-core/audits/accessibility/frame-title.js +1 -1
  62. package/lighthouse-core/audits/accessibility/heading-order.js +1 -1
  63. package/lighthouse-core/audits/accessibility/html-has-lang.js +1 -1
  64. package/lighthouse-core/audits/accessibility/html-lang-valid.js +1 -1
  65. package/lighthouse-core/audits/accessibility/image-alt.js +1 -1
  66. package/lighthouse-core/audits/accessibility/input-image-alt.js +1 -1
  67. package/lighthouse-core/audits/accessibility/label.js +1 -1
  68. package/lighthouse-core/audits/accessibility/link-name.js +1 -1
  69. package/lighthouse-core/audits/accessibility/list.js +1 -1
  70. package/lighthouse-core/audits/accessibility/listitem.js +5 -5
  71. package/lighthouse-core/audits/accessibility/meta-refresh.js +1 -1
  72. package/lighthouse-core/audits/accessibility/meta-viewport.js +1 -1
  73. package/lighthouse-core/audits/accessibility/object-alt.js +1 -1
  74. package/lighthouse-core/audits/accessibility/tabindex.js +1 -1
  75. package/lighthouse-core/audits/accessibility/td-headers-attr.js +1 -1
  76. package/lighthouse-core/audits/accessibility/th-has-data-cells.js +1 -1
  77. package/lighthouse-core/audits/accessibility/valid-lang.js +1 -1
  78. package/lighthouse-core/audits/accessibility/video-caption.js +1 -1
  79. package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +1 -2
  80. package/lighthouse-core/audits/byte-efficiency/duplicated-javascript.js +12 -11
  81. package/lighthouse-core/audits/byte-efficiency/efficient-animated-content.js +1 -1
  82. package/lighthouse-core/audits/byte-efficiency/legacy-javascript.js +24 -22
  83. package/lighthouse-core/audits/byte-efficiency/offscreen-images.js +2 -3
  84. package/lighthouse-core/audits/byte-efficiency/render-blocking-resources.js +3 -2
  85. package/lighthouse-core/audits/byte-efficiency/unminified-css.js +5 -3
  86. package/lighthouse-core/audits/byte-efficiency/unminified-javascript.js +11 -10
  87. package/lighthouse-core/audits/byte-efficiency/unused-css-rules.js +1 -0
  88. package/lighthouse-core/audits/byte-efficiency/unused-javascript.js +8 -11
  89. package/lighthouse-core/audits/byte-efficiency/uses-responsive-images.js +1 -1
  90. package/lighthouse-core/audits/byte-efficiency/uses-text-compression.js +1 -1
  91. package/lighthouse-core/audits/deprecations.js +598 -8
  92. package/lighthouse-core/audits/diagnostics.js +3 -4
  93. package/lighthouse-core/audits/dobetterweb/doctype.js +9 -20
  94. package/lighthouse-core/audits/dobetterweb/geolocation-on-start.js +1 -1
  95. package/lighthouse-core/audits/dobetterweb/no-document-write.js +1 -1
  96. package/lighthouse-core/audits/dobetterweb/notification-on-start.js +1 -1
  97. package/lighthouse-core/audits/dobetterweb/uses-http2.js +1 -2
  98. package/lighthouse-core/audits/dobetterweb/uses-passive-event-listeners.js +1 -1
  99. package/lighthouse-core/audits/errors-in-console.js +2 -2
  100. package/lighthouse-core/audits/long-tasks.js +2 -3
  101. package/lighthouse-core/audits/metrics/first-contentful-paint-3g.js +2 -2
  102. package/lighthouse-core/audits/metrics/first-contentful-paint.js +2 -3
  103. package/lighthouse-core/audits/metrics/first-meaningful-paint.js +2 -3
  104. package/lighthouse-core/audits/metrics/interactive.js +2 -3
  105. package/lighthouse-core/audits/metrics/largest-contentful-paint.js +2 -3
  106. package/lighthouse-core/audits/metrics/max-potential-fid.js +2 -3
  107. package/lighthouse-core/audits/metrics/speed-index.js +2 -3
  108. package/lighthouse-core/audits/metrics/total-blocking-time.js +2 -3
  109. package/lighthouse-core/audits/metrics.js +2 -3
  110. package/lighthouse-core/audits/no-unload-listeners.js +15 -7
  111. package/lighthouse-core/audits/predictive-perf.js +1 -2
  112. package/lighthouse-core/audits/preload-lcp-image.js +3 -3
  113. package/lighthouse-core/audits/redirects.js +1 -1
  114. package/lighthouse-core/audits/script-treemap-data.js +45 -45
  115. package/lighthouse-core/audits/seo/http-status-code.js +4 -2
  116. package/lighthouse-core/audits/seo/link-text.js +0 -2
  117. package/lighthouse-core/audits/server-response-time.js +17 -2
  118. package/lighthouse-core/audits/service-worker.js +2 -7
  119. package/lighthouse-core/audits/timing-budget.js +2 -3
  120. package/lighthouse-core/audits/uses-rel-preconnect.js +1 -1
  121. package/lighthouse-core/audits/uses-rel-preload.js +1 -1
  122. package/lighthouse-core/audits/valid-source-maps.js +14 -12
  123. package/lighthouse-core/audits/violation-audit.js +1 -1
  124. package/lighthouse-core/audits/work-during-interaction.js +2 -2
  125. package/lighthouse-core/computed/critical-request-chains.js +9 -5
  126. package/lighthouse-core/computed/js-bundles.js +11 -11
  127. package/lighthouse-core/computed/main-resource.js +2 -3
  128. package/lighthouse-core/computed/metrics/first-contentful-paint-all-frames.js +1 -1
  129. package/lighthouse-core/computed/metrics/first-contentful-paint.js +1 -1
  130. package/lighthouse-core/computed/metrics/first-meaningful-paint.js +1 -1
  131. package/lighthouse-core/computed/metrics/interactive.js +1 -1
  132. package/lighthouse-core/computed/metrics/lantern-first-contentful-paint.js +1 -1
  133. package/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js +1 -1
  134. package/lighthouse-core/computed/metrics/lantern-interactive.js +1 -1
  135. package/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js +1 -1
  136. package/lighthouse-core/computed/metrics/lantern-max-potential-fid.js +1 -1
  137. package/lighthouse-core/computed/metrics/lantern-metric.js +5 -3
  138. package/lighthouse-core/computed/metrics/lantern-speed-index.js +1 -1
  139. package/lighthouse-core/computed/metrics/lantern-total-blocking-time.js +1 -1
  140. package/lighthouse-core/computed/metrics/largest-contentful-paint-all-frames.js +1 -1
  141. package/lighthouse-core/computed/metrics/largest-contentful-paint.js +1 -1
  142. package/lighthouse-core/computed/metrics/max-potential-fid.js +1 -1
  143. package/lighthouse-core/computed/metrics/metric.js +0 -1
  144. package/lighthouse-core/computed/metrics/speed-index.js +1 -1
  145. package/lighthouse-core/computed/metrics/timing-summary.js +6 -13
  146. package/lighthouse-core/computed/metrics/total-blocking-time.js +1 -1
  147. package/lighthouse-core/computed/module-duplication.js +5 -6
  148. package/lighthouse-core/computed/page-dependency-graph.js +28 -55
  149. package/lighthouse-core/computed/resource-summary.js +5 -5
  150. package/lighthouse-core/computed/unused-css.js +7 -6
  151. package/lighthouse-core/computed/unused-javascript-summary.js +36 -16
  152. package/lighthouse-core/config/budget.js +2 -2
  153. package/lighthouse-core/config/default-config.js +1 -2
  154. package/lighthouse-core/fraggle-rock/api.js +1 -1
  155. package/lighthouse-core/fraggle-rock/config/default-config.js +0 -3
  156. package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +3 -6
  157. package/lighthouse-core/fraggle-rock/gather/driver.js +2 -2
  158. package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +26 -51
  159. package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +3 -0
  160. package/lighthouse-core/fraggle-rock/gather/session.js +22 -23
  161. package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +4 -5
  162. package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +6 -6
  163. package/lighthouse-core/gather/connections/cri.js +1 -5
  164. package/lighthouse-core/gather/driver/execution-context.js +2 -5
  165. package/lighthouse-core/gather/driver/navigation.js +10 -13
  166. package/lighthouse-core/gather/driver/network-monitor.js +3 -16
  167. package/lighthouse-core/gather/driver.js +1 -6
  168. package/lighthouse-core/gather/fetcher.js +210 -34
  169. package/lighthouse-core/gather/gather-runner.js +17 -13
  170. package/lighthouse-core/gather/gatherers/accessibility.js +4 -16
  171. package/lighthouse-core/gather/gatherers/console-messages.js +2 -4
  172. package/lighthouse-core/gather/gatherers/dobetterweb/doctype.js +2 -4
  173. package/lighthouse-core/gather/gatherers/full-page-screenshot.js +2 -3
  174. package/lighthouse-core/gather/gatherers/iframe-elements.js +1 -4
  175. package/lighthouse-core/gather/gatherers/image-elements.js +0 -2
  176. package/lighthouse-core/gather/gatherers/js-usage.js +87 -12
  177. package/lighthouse-core/gather/gatherers/link-elements.js +14 -12
  178. package/lighthouse-core/gather/gatherers/main-document-content.js +8 -8
  179. package/lighthouse-core/gather/gatherers/script-elements.js +56 -7
  180. package/lighthouse-core/gather/gatherers/seo/robots-txt.js +30 -2
  181. package/lighthouse-core/gather/gatherers/source-maps.js +1 -8
  182. package/lighthouse-core/gather/gatherers/web-app-manifest.js +2 -2
  183. package/lighthouse-core/index.js +2 -26
  184. package/lighthouse-core/lib/cdt/generated/SourceMap.js +1 -1
  185. package/lighthouse-core/lib/dependency-graph/simulator/network-analyzer.js +29 -8
  186. package/lighthouse-core/lib/navigation-error.js +4 -13
  187. package/lighthouse-core/lib/page-functions.js +1 -3
  188. package/lighthouse-core/lib/script-helpers.js +6 -11
  189. package/lighthouse-core/lib/url-shim.js +2 -2
  190. package/lighthouse-core/runner.js +5 -0
  191. package/lighthouse-core/scripts/manual-chrome-launcher.js +1 -0
  192. package/lighthouse-core/util-commonjs.js +6 -8
  193. package/package.json +13 -13
  194. package/readme.md +1 -1
  195. package/report/.eslintrc.cjs +1 -3
  196. package/report/assets/styles.css +5 -10
  197. package/report/assets/templates.html +9 -10
  198. package/report/clients/bundle.js +1 -0
  199. package/report/clients/standalone.js +1 -0
  200. package/report/generator/report-generator.js +21 -46
  201. package/report/renderer/api.js +2 -0
  202. package/report/renderer/category-renderer.js +24 -20
  203. package/report/renderer/components.js +304 -303
  204. package/report/renderer/crc-details-renderer.js +24 -21
  205. package/report/renderer/details-renderer.js +12 -12
  206. package/report/renderer/dom.js +7 -6
  207. package/report/renderer/drop-down-menu.js +1 -0
  208. package/report/renderer/element-screenshot-renderer.js +5 -1
  209. package/report/renderer/features-util.js +1 -0
  210. package/report/renderer/i18n.js +62 -118
  211. package/report/renderer/logger.js +1 -0
  212. package/report/renderer/open-tab.js +3 -1
  213. package/report/renderer/performance-category-renderer.js +11 -10
  214. package/report/renderer/pwa-category-renderer.js +4 -3
  215. package/report/renderer/report-renderer.js +17 -17
  216. package/report/renderer/report-ui-features.js +1 -0
  217. package/report/renderer/snippet-renderer.js +3 -2
  218. package/report/renderer/swap-locale-feature.js +1 -0
  219. package/report/renderer/text-encoding.js +1 -0
  220. package/report/renderer/topbar-features.js +1 -0
  221. package/report/renderer/util.js +6 -7
  222. package/report/test/clients/bundle-test.js +5 -0
  223. package/report/test/generator/file-namer-test.js +1 -0
  224. package/report/test/generator/report-generator-test.js +20 -25
  225. package/report/test/renderer/category-renderer-test.js +4 -3
  226. package/report/test/renderer/components-test.js +3 -0
  227. package/report/test/renderer/crc-details-renderer-test.js +3 -0
  228. package/report/test/renderer/details-renderer-test.js +3 -49
  229. package/report/test/renderer/dom-test.js +3 -0
  230. package/report/test/renderer/element-screenshot-renderer-test.js +6 -3
  231. package/report/test/renderer/i18n-test.js +25 -70
  232. package/report/test/renderer/performance-category-renderer-test.js +5 -14
  233. package/report/test/renderer/pwa-category-renderer-test.js +4 -3
  234. package/report/test/renderer/report-renderer-axe-test.js +4 -3
  235. package/report/test/renderer/report-renderer-test.js +4 -3
  236. package/report/test/renderer/report-ui-features-test.js +4 -3
  237. package/report/test/renderer/snippet-renderer-test.js +3 -0
  238. package/report/test/renderer/text-encoding-test.js +3 -0
  239. package/report/test/renderer/util-test.js +5 -4
  240. package/report/test-assets/faux-psi.js +1 -2
  241. package/shared/localization/format.js +3 -7
  242. package/shared/localization/locales/en-US.json +238 -55
  243. package/shared/localization/locales/en-XL.json +238 -55
  244. package/shared/test/localization/format-test.js +2 -8
  245. package/shared/test/localization/locales-test.js +2 -0
  246. package/shared/test/localization/swap-locale-test.js +2 -0
  247. package/third-party/chromium-synchronization/inspector-issueAdded-types-test.js +2 -0
  248. package/third-party/chromium-synchronization/installability-errors-test.js +2 -0
  249. package/tsconfig.json +0 -1
  250. package/types/artifacts.d.ts +8 -47
  251. package/types/config.d.ts +0 -2
  252. package/types/externs.d.ts +2 -3
  253. package/types/gatherer.d.ts +2 -1
  254. package/types/global-lh.d.ts +0 -3
  255. package/types/lhr/lhr.d.ts +2 -2
  256. package/types/lhr/treemap.d.ts +1 -0
  257. package/changelog.md +0 -5902
  258. package/lighthouse-core/audits/script-elements-test-audit.js +0 -30
  259. package/lighthouse-core/gather/gatherers/scripts.js +0 -154
  260. package/lighthouse-core/scripts/package.json +0 -4
  261. package/report/test/.eslintrc.cjs +0 -11
  262. package/shared/test/localization/.eslintrc.cjs +0 -11
@@ -429,11 +429,10 @@ class Util {
429
429
  break;
430
430
  case 'devtools': {
431
431
  const {cpuSlowdownMultiplier, requestLatencyMs} = throttling;
432
- // eslint-disable-next-line max-len
433
432
  cpuThrottling = `${Util.i18n.formatNumber(cpuSlowdownMultiplier)}x slowdown (DevTools)`;
434
- networkThrottling = `${Util.i18n.formatMilliseconds(requestLatencyMs)} HTTP RTT, ` +
435
- `${Util.i18n.formatKbps(throttling.downloadThroughputKbps)} down, ` +
436
- `${Util.i18n.formatKbps(throttling.uploadThroughputKbps)} up (DevTools)`;
433
+ networkThrottling = `${Util.i18n.formatNumber(requestLatencyMs)}${NBSP}ms HTTP RTT, ` +
434
+ `${Util.i18n.formatNumber(throttling.downloadThroughputKbps)}${NBSP}Kbps down, ` +
435
+ `${Util.i18n.formatNumber(throttling.uploadThroughputKbps)}${NBSP}Kbps up (DevTools)`;
437
436
 
438
437
  const isSlow4G = () => {
439
438
  return requestLatencyMs === 150 * 3.75 &&
@@ -445,10 +444,9 @@ class Util {
445
444
  }
446
445
  case 'simulate': {
447
446
  const {cpuSlowdownMultiplier, rttMs, throughputKbps} = throttling;
448
- // eslint-disable-next-line max-len
449
447
  cpuThrottling = `${Util.i18n.formatNumber(cpuSlowdownMultiplier)}x slowdown (Simulated)`;
450
- networkThrottling = `${Util.i18n.formatMilliseconds(rttMs)} TCP RTT, ` +
451
- `${Util.i18n.formatKbps(throughputKbps)} throughput (Simulated)`;
448
+ networkThrottling = `${Util.i18n.formatNumber(rttMs)}${NBSP}ms TCP RTT, ` +
449
+ `${Util.i18n.formatNumber(throughputKbps)}${NBSP}Kbps throughput (Simulated)`;
452
450
 
453
451
  const isSlow4G = () => {
454
452
  return rttMs === 150 && throughputKbps === 1.6 * 1024;
@@ -704,7 +702,7 @@ Util.UIStrings = UIStrings;
704
702
 
705
703
  /** @typedef {import('./dom.js').DOM} DOM */
706
704
 
707
- /* eslint-disable max-len, quotes, comma-spacing */
705
+ /* eslint-disable max-len */
708
706
 
709
707
 
710
708
  /**
@@ -712,19 +710,19 @@ Util.UIStrings = UIStrings;
712
710
  */
713
711
  function create3pFilterComponent(dom) {
714
712
  const el0 = dom.createFragment();
715
- const el1 = dom.createElement("style");
716
- el1.append("\n .lh-3p-filter {\n color: var(--color-gray-600);\n float: right;\n padding: 6px var(--stackpack-padding-horizontal);\n }\n .lh-3p-filter-label, .lh-3p-filter-input {\n vertical-align: middle;\n user-select: none;\n }\n .lh-3p-filter-input:disabled + .lh-3p-ui-string {\n text-decoration: line-through;\n }\n ");
713
+ const el1 = dom.createElement('style');
714
+ el1.append('\n .lh-3p-filter {\n color: var(--color-gray-600);\n float: right;\n padding: 6px var(--stackpack-padding-horizontal);\n }\n .lh-3p-filter-label, .lh-3p-filter-input {\n vertical-align: middle;\n user-select: none;\n }\n .lh-3p-filter-input:disabled + .lh-3p-ui-string {\n text-decoration: line-through;\n }\n ');
717
715
  el0.append(el1);
718
- const el2 = dom.createElement("div", "lh-3p-filter");
719
- const el3 = dom.createElement("label", "lh-3p-filter-label");
720
- const el4 = dom.createElement("input", "lh-3p-filter-input");
716
+ const el2 = dom.createElement('div', 'lh-3p-filter');
717
+ const el3 = dom.createElement('label', 'lh-3p-filter-label');
718
+ const el4 = dom.createElement('input', 'lh-3p-filter-input');
721
719
  el4.setAttribute('type', 'checkbox');
722
720
  el4.setAttribute('checked', '');
723
- const el5 = dom.createElement("span", "lh-3p-ui-string");
724
- el5.append("Show 3rd party resources");
725
- const el6 = dom.createElement("span", "lh-3p-filter-count");
726
- el3.append(" ",el4," ",el5," (",el6,") ");
727
- el2.append(" ",el3," ");
721
+ const el5 = dom.createElement('span', 'lh-3p-ui-string');
722
+ el5.append('Show 3rd party resources');
723
+ const el6 = dom.createElement('span', 'lh-3p-filter-count');
724
+ el3.append(' ', el4, ' ', el5, ' (', el6, ') ');
725
+ el2.append(' ', el3, ' ');
728
726
  el0.append(el2);
729
727
  return el0;
730
728
  }
@@ -734,22 +732,22 @@ function create3pFilterComponent(dom) {
734
732
  */
735
733
  function createAuditComponent(dom) {
736
734
  const el0 = dom.createFragment();
737
- const el1 = dom.createElement("div", "lh-audit");
738
- const el2 = dom.createElement("details", "lh-expandable-details");
739
- const el3 = dom.createElement("summary");
740
- const el4 = dom.createElement("div", "lh-audit__header lh-expandable-details__summary");
741
- const el5 = dom.createElement("span", "lh-audit__score-icon");
742
- const el6 = dom.createElement("span", "lh-audit__title-and-text");
743
- const el7 = dom.createElement("span", "lh-audit__title");
744
- const el8 = dom.createElement("span", "lh-audit__display-text");
745
- el6.append(" ",el7," ",el8," ");
746
- const el9 = dom.createElement("div", "lh-chevron-container");
747
- el4.append(" ",el5," ",el6," ",el9," ");
748
- el3.append(" ",el4," ");
749
- const el10 = dom.createElement("div", "lh-audit__description");
750
- const el11 = dom.createElement("div", "lh-audit__stackpacks");
751
- el2.append(" ",el3," ",el10," ",el11," ");
752
- el1.append(" ",el2," ");
735
+ const el1 = dom.createElement('div', 'lh-audit');
736
+ const el2 = dom.createElement('details', 'lh-expandable-details');
737
+ const el3 = dom.createElement('summary');
738
+ const el4 = dom.createElement('div', 'lh-audit__header lh-expandable-details__summary');
739
+ const el5 = dom.createElement('span', 'lh-audit__score-icon');
740
+ const el6 = dom.createElement('span', 'lh-audit__title-and-text');
741
+ const el7 = dom.createElement('span', 'lh-audit__title');
742
+ const el8 = dom.createElement('span', 'lh-audit__display-text');
743
+ el6.append(' ', el7, ' ', el8, ' ');
744
+ const el9 = dom.createElement('div', 'lh-chevron-container');
745
+ el4.append(' ', el5, ' ', el6, ' ', el9, ' ');
746
+ el3.append(' ', el4, ' ');
747
+ const el10 = dom.createElement('div', 'lh-audit__description');
748
+ const el11 = dom.createElement('div', 'lh-audit__stackpacks');
749
+ el2.append(' ', el3, ' ', el10, ' ', el11, ' ');
750
+ el1.append(' ', el2, ' ');
753
751
  el0.append(el1);
754
752
  return el0;
755
753
  }
@@ -759,12 +757,12 @@ function createAuditComponent(dom) {
759
757
  */
760
758
  function createCategoryHeaderComponent(dom) {
761
759
  const el0 = dom.createFragment();
762
- const el1 = dom.createElement("div", "lh-category-header");
763
- const el2 = dom.createElement("div", "lh-score__gauge");
760
+ const el1 = dom.createElement('div', 'lh-category-header');
761
+ const el2 = dom.createElement('div', 'lh-score__gauge');
764
762
  el2.setAttribute('role', 'heading');
765
763
  el2.setAttribute('aria-level', '2');
766
- const el3 = dom.createElement("div", "lh-category-header__description");
767
- el1.append(" ",el2," ",el3," ");
764
+ const el3 = dom.createElement('div', 'lh-category-header__description');
765
+ el1.append(' ', el2, ' ', el3, ' ');
768
766
  el0.append(el1);
769
767
  return el0;
770
768
  }
@@ -774,15 +772,15 @@ function createCategoryHeaderComponent(dom) {
774
772
  */
775
773
  function createChevronComponent(dom) {
776
774
  const el0 = dom.createFragment();
777
- const el1 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-chevron");
775
+ const el1 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg', 'lh-chevron');
778
776
  el1.setAttribute('viewBox', '0 0 100 100');
779
- const el2 = dom.createElementNS("http://www.w3.org/2000/svg", "g", "lh-chevron__lines");
780
- const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-chevron__line lh-chevron__line-left");
777
+ const el2 = dom.createElementNS('http://www.w3.org/2000/svg', 'g', 'lh-chevron__lines');
778
+ const el3 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-chevron__line lh-chevron__line-left');
781
779
  el3.setAttribute('d', 'M10 50h40');
782
- const el4 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-chevron__line lh-chevron__line-right");
780
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-chevron__line lh-chevron__line-right');
783
781
  el4.setAttribute('d', 'M90 50H50');
784
- el2.append(" ",el3," ",el4," ");
785
- el1.append(" ",el2," ");
782
+ el2.append(' ', el3, ' ', el4, ' ');
783
+ el1.append(' ', el2, ' ');
786
784
  el0.append(el1);
787
785
  return el0;
788
786
  }
@@ -792,22 +790,22 @@ function createChevronComponent(dom) {
792
790
  */
793
791
  function createClumpComponent(dom) {
794
792
  const el0 = dom.createFragment();
795
- const el1 = dom.createElement("div", "lh-audit-group");
796
- const el2 = dom.createElement("details", "lh-clump");
797
- const el3 = dom.createElement("summary");
798
- const el4 = dom.createElement("div", "lh-audit-group__summary");
799
- const el5 = dom.createElement("div", "lh-audit-group__header");
800
- const el6 = dom.createElement("span", "lh-audit-group__title");
801
- const el7 = dom.createElement("span", "lh-audit-group__itemcount");
802
- el5.append(" ",el6," ",el7," "," "," ");
803
- const el8 = dom.createElement("div", "lh-clump-toggle");
804
- const el9 = dom.createElement("span", "lh-clump-toggletext--show");
805
- const el10 = dom.createElement("span", "lh-clump-toggletext--hide");
806
- el8.append(" ",el9," ",el10," ");
807
- el4.append(" ",el5," ",el8," ");
808
- el3.append(" ",el4," ");
809
- el2.append(" ",el3," ");
810
- el1.append(" "," ",el2," ");
793
+ const el1 = dom.createElement('div', 'lh-audit-group');
794
+ const el2 = dom.createElement('details', 'lh-clump');
795
+ const el3 = dom.createElement('summary');
796
+ const el4 = dom.createElement('div', 'lh-audit-group__summary');
797
+ const el5 = dom.createElement('div', 'lh-audit-group__header');
798
+ const el6 = dom.createElement('span', 'lh-audit-group__title');
799
+ const el7 = dom.createElement('span', 'lh-audit-group__itemcount');
800
+ el5.append(' ', el6, ' ', el7, ' ', ' ', ' ');
801
+ const el8 = dom.createElement('div', 'lh-clump-toggle');
802
+ const el9 = dom.createElement('span', 'lh-clump-toggletext--show');
803
+ const el10 = dom.createElement('span', 'lh-clump-toggletext--hide');
804
+ el8.append(' ', el9, ' ', el10, ' ');
805
+ el4.append(' ', el5, ' ', el8, ' ');
806
+ el3.append(' ', el4, ' ');
807
+ el2.append(' ', el3, ' ');
808
+ el1.append(' ', ' ', el2, ' ');
811
809
  el0.append(el1);
812
810
  return el0;
813
811
  }
@@ -817,19 +815,19 @@ function createClumpComponent(dom) {
817
815
  */
818
816
  function createCrcComponent(dom) {
819
817
  const el0 = dom.createFragment();
820
- const el1 = dom.createElement("div", "lh-crc-container");
821
- const el2 = dom.createElement("style");
822
- el2.append("\n .lh-crc .lh-tree-marker {\n width: 12px;\n height: 26px;\n display: block;\n float: left;\n background-position: top left;\n }\n .lh-crc .lh-horiz-down {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"%23D8D8D8\" fill-rule=\"evenodd\"><path d=\"M16 12v2H-2v-2z\"/><path d=\"M9 12v14H7V12z\"/></g></svg>');\n }\n .lh-crc .lh-right {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16 12v2H0v-2z\" fill=\"%23D8D8D8\" fill-rule=\"evenodd\"/></svg>');\n }\n .lh-crc .lh-up-right {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 0h2v14H7zm2 12h7v2H9z\" fill=\"%23D8D8D8\" fill-rule=\"evenodd\"/></svg>');\n }\n .lh-crc .lh-vert-right {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 0h2v27H7zm2 12h7v2H9z\" fill=\"%23D8D8D8\" fill-rule=\"evenodd\"/></svg>');\n }\n .lh-crc .lh-vert {\n background: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"26\" viewBox=\"0 0 16 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 0h2v26H7z\" fill=\"%23D8D8D8\" fill-rule=\"evenodd\"/></svg>');\n }\n .lh-crc .lh-crc-tree {\n font-size: 14px;\n width: 100%;\n overflow-x: auto;\n }\n .lh-crc .lh-crc-node {\n height: 26px;\n line-height: 26px;\n white-space: nowrap;\n }\n .lh-crc .lh-crc-node__tree-value {\n margin-left: 10px;\n }\n .lh-crc .lh-crc-node__tree-value div {\n display: inline;\n }\n .lh-crc .lh-crc-node__chain-duration {\n font-weight: 700;\n }\n .lh-crc .lh-crc-initial-nav {\n color: #595959;\n font-style: italic;\n }\n .lh-crc__summary-value {\n margin-bottom: 10px;\n }\n ");
823
- const el3 = dom.createElement("div");
824
- const el4 = dom.createElement("div", "lh-crc__summary-value");
825
- const el5 = dom.createElement("span", "lh-crc__longest_duration_label");
826
- const el6 = dom.createElement("b", "lh-crc__longest_duration");
827
- el4.append(" ",el5," ",el6," ");
828
- el3.append(" ",el4," ");
829
- const el7 = dom.createElement("div", "lh-crc");
830
- const el8 = dom.createElement("div", "lh-crc-initial-nav");
831
- el7.append(" ",el8," "," ");
832
- el1.append(" ",el2," ",el3," ",el7," ");
818
+ const el1 = dom.createElement('div', 'lh-crc-container');
819
+ const el2 = dom.createElement('style');
820
+ el2.append('\n .lh-crc .lh-tree-marker {\n width: 12px;\n height: 26px;\n display: block;\n float: left;\n background-position: top left;\n }\n .lh-crc .lh-horiz-down {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><g fill="%23D8D8D8" fill-rule="evenodd"><path d="M16 12v2H-2v-2z"/><path d="M9 12v14H7V12z"/></g></svg>\');\n }\n .lh-crc .lh-right {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M16 12v2H0v-2z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>\');\n }\n .lh-crc .lh-up-right {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v14H7zm2 12h7v2H9z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>\');\n }\n .lh-crc .lh-vert-right {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v27H7zm2 12h7v2H9z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>\');\n }\n .lh-crc .lh-vert {\n background: url(\'data:image/svg+xml;utf8,<svg width="16" height="26" viewBox="0 0 16 26" xmlns="http://www.w3.org/2000/svg"><path d="M7 0h2v26H7z" fill="%23D8D8D8" fill-rule="evenodd"/></svg>\');\n }\n .lh-crc .lh-crc-tree {\n font-size: 14px;\n width: 100%;\n overflow-x: auto;\n }\n .lh-crc .lh-crc-node {\n height: 26px;\n line-height: 26px;\n white-space: nowrap;\n }\n .lh-crc .lh-crc-node__tree-value {\n margin-left: 10px;\n }\n .lh-crc .lh-crc-node__tree-value div {\n display: inline;\n }\n .lh-crc .lh-crc-node__chain-duration {\n font-weight: 700;\n }\n .lh-crc .lh-crc-initial-nav {\n color: #595959;\n font-style: italic;\n }\n .lh-crc__summary-value {\n margin-bottom: 10px;\n }\n ');
821
+ const el3 = dom.createElement('div');
822
+ const el4 = dom.createElement('div', 'lh-crc__summary-value');
823
+ const el5 = dom.createElement('span', 'lh-crc__longest_duration_label');
824
+ const el6 = dom.createElement('b', 'lh-crc__longest_duration');
825
+ el4.append(' ', el5, ' ', el6, ' ');
826
+ el3.append(' ', el4, ' ');
827
+ const el7 = dom.createElement('div', 'lh-crc');
828
+ const el8 = dom.createElement('div', 'lh-crc-initial-nav');
829
+ el7.append(' ', el8, ' ', ' ');
830
+ el1.append(' ', el2, ' ', el3, ' ', el7, ' ');
833
831
  el0.append(el1);
834
832
  return el0;
835
833
  }
@@ -839,10 +837,10 @@ function createCrcComponent(dom) {
839
837
  */
840
838
  function createCrcChainComponent(dom) {
841
839
  const el0 = dom.createFragment();
842
- const el1 = dom.createElement("div", "lh-crc-node");
843
- const el2 = dom.createElement("span", "lh-crc-node__tree-marker");
844
- const el3 = dom.createElement("span", "lh-crc-node__tree-value");
845
- el1.append(" ",el2," ",el3," ");
840
+ const el1 = dom.createElement('div', 'lh-crc-node');
841
+ const el2 = dom.createElement('span', 'lh-crc-node__tree-marker');
842
+ const el3 = dom.createElement('span', 'lh-crc-node__tree-value');
843
+ el1.append(' ', el2, ' ', el3, ' ');
846
844
  el0.append(el1);
847
845
  return el0;
848
846
  }
@@ -852,23 +850,22 @@ function createCrcChainComponent(dom) {
852
850
  */
853
851
  function createElementScreenshotComponent(dom) {
854
852
  const el0 = dom.createFragment();
855
- const el1 = dom.createElement("div", "lh-element-screenshot");
856
- const el2 = dom.createElement("div", "lh-element-screenshot__content");
857
- const el3 = dom.createElement("div", "lh-element-screenshot__image");
858
- const el4 = dom.createElement("div", "lh-element-screenshot__mask");
859
- const el5 = dom.createElementNS("http://www.w3.org/2000/svg", "svg");
860
- el5.setAttribute('height', '0');
861
- el5.setAttribute('width', '0');
862
- const el6 = dom.createElementNS("http://www.w3.org/2000/svg", "defs");
863
- const el7 = dom.createElementNS("http://www.w3.org/2000/svg", "clipPath");
864
- el7.setAttribute('clipPathUnits', 'objectBoundingBox');
865
- el6.append(" ",el7," "," ");
866
- el5.append(" ",el6," ");
867
- el4.append(" ",el5," ");
868
- const el8 = dom.createElement("div", "lh-element-screenshot__element-marker");
869
- el3.append(" ",el4," ",el8," ");
870
- el2.append(" ",el3," ");
871
- el1.append(" ",el2," ");
853
+ const el1 = dom.createElement('div', 'lh-element-screenshot');
854
+ const el2 = dom.createElement('div', 'lh-element-screenshot__content');
855
+ const el3 = dom.createElement('div', 'lh-element-screenshot__mask');
856
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg');
857
+ el4.setAttribute('height', '0');
858
+ el4.setAttribute('width', '0');
859
+ const el5 = dom.createElementNS('http://www.w3.org/2000/svg', 'defs');
860
+ const el6 = dom.createElementNS('http://www.w3.org/2000/svg', 'clipPath');
861
+ el6.setAttribute('clipPathUnits', 'objectBoundingBox');
862
+ el5.append(' ', el6, ' ', ' ');
863
+ el4.append(' ', el5, ' ');
864
+ el3.append(' ', el4, ' ');
865
+ const el7 = dom.createElement('div', 'lh-element-screenshot__image');
866
+ const el8 = dom.createElement('div', 'lh-element-screenshot__element-marker');
867
+ el2.append(' ', el3, ' ', el7, ' ', el8, ' ');
868
+ el1.append(' ', el2, ' ');
872
869
  el0.append(el1);
873
870
  return el0;
874
871
  }
@@ -878,23 +875,23 @@ function createElementScreenshotComponent(dom) {
878
875
  */
879
876
  function createFooterComponent(dom) {
880
877
  const el0 = dom.createFragment();
881
- const el1 = dom.createElement("style");
882
- el1.append("\n .lh-footer {\n padding: var(--footer-padding-vertical) calc(var(--default-padding) * 2);\n max-width: var(--report-content-max-width);\n margin: 0 auto;\n }\n .lh-footer .lh-generated {\n text-align: center;\n }\n ");
878
+ const el1 = dom.createElement('style');
879
+ el1.append('\n .lh-footer {\n padding: var(--footer-padding-vertical) calc(var(--default-padding) * 2);\n max-width: var(--report-content-max-width);\n margin: 0 auto;\n }\n .lh-footer .lh-generated {\n text-align: center;\n }\n ');
883
880
  el0.append(el1);
884
- const el2 = dom.createElement("footer", "lh-footer");
885
- const el3 = dom.createElement("ul", "lh-meta__items");
886
- el3.append(" ");
887
- const el4 = dom.createElement("div", "lh-generated");
888
- const el5 = dom.createElement("b");
889
- el5.append("Lighthouse");
890
- const el6 = dom.createElement("span", "lh-footer__version");
891
- const el7 = dom.createElement("a", "lh-footer__version_issue");
881
+ const el2 = dom.createElement('footer', 'lh-footer');
882
+ const el3 = dom.createElement('ul', 'lh-meta__items');
883
+ el3.append(' ');
884
+ const el4 = dom.createElement('div', 'lh-generated');
885
+ const el5 = dom.createElement('b');
886
+ el5.append('Lighthouse');
887
+ const el6 = dom.createElement('span', 'lh-footer__version');
888
+ const el7 = dom.createElement('a', 'lh-footer__version_issue');
892
889
  el7.setAttribute('href', 'https://github.com/GoogleChrome/Lighthouse/issues');
893
890
  el7.setAttribute('target', '_blank');
894
891
  el7.setAttribute('rel', 'noopener');
895
- el7.append("File an issue");
896
- el4.append(" "," Generated by ",el5," ",el6," | ",el7," ");
897
- el2.append(" ",el3," ",el4," ");
892
+ el7.append('File an issue');
893
+ el4.append(' ', ' Generated by ', el5, ' ', el6, ' | ', el7, ' ');
894
+ el2.append(' ', el3, ' ', el4, ' ');
898
895
  el0.append(el2);
899
896
  return el0;
900
897
  }
@@ -904,14 +901,14 @@ function createFooterComponent(dom) {
904
901
  */
905
902
  function createFractionComponent(dom) {
906
903
  const el0 = dom.createFragment();
907
- const el1 = dom.createElement("a", "lh-fraction__wrapper");
908
- const el2 = dom.createElement("div", "lh-fraction__content-wrapper");
909
- const el3 = dom.createElement("div", "lh-fraction__content");
910
- const el4 = dom.createElement("div", "lh-fraction__background");
911
- el3.append(" ",el4," ");
912
- el2.append(" ",el3," ");
913
- const el5 = dom.createElement("div", "lh-fraction__label");
914
- el1.append(" ",el2," ",el5," ");
904
+ const el1 = dom.createElement('a', 'lh-fraction__wrapper');
905
+ const el2 = dom.createElement('div', 'lh-fraction__content-wrapper');
906
+ const el3 = dom.createElement('div', 'lh-fraction__content');
907
+ const el4 = dom.createElement('div', 'lh-fraction__background');
908
+ el3.append(' ', el4, ' ');
909
+ el2.append(' ', el3, ' ');
910
+ const el5 = dom.createElement('div', 'lh-fraction__label');
911
+ el1.append(' ', el2, ' ', el5, ' ');
915
912
  el0.append(el1);
916
913
  return el0;
917
914
  }
@@ -921,25 +918,25 @@ function createFractionComponent(dom) {
921
918
  */
922
919
  function createGaugeComponent(dom) {
923
920
  const el0 = dom.createFragment();
924
- const el1 = dom.createElement("a", "lh-gauge__wrapper");
925
- const el2 = dom.createElement("div", "lh-gauge__svg-wrapper");
926
- const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-gauge");
921
+ const el1 = dom.createElement('a', 'lh-gauge__wrapper');
922
+ const el2 = dom.createElement('div', 'lh-gauge__svg-wrapper');
923
+ const el3 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg', 'lh-gauge');
927
924
  el3.setAttribute('viewBox', '0 0 120 120');
928
- const el4 = dom.createElementNS("http://www.w3.org/2000/svg", "circle", "lh-gauge-base");
925
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle', 'lh-gauge-base');
929
926
  el4.setAttribute('r', '56');
930
927
  el4.setAttribute('cx', '60');
931
928
  el4.setAttribute('cy', '60');
932
929
  el4.setAttribute('stroke-width', '8');
933
- const el5 = dom.createElementNS("http://www.w3.org/2000/svg", "circle", "lh-gauge-arc");
930
+ const el5 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle', 'lh-gauge-arc');
934
931
  el5.setAttribute('r', '56');
935
932
  el5.setAttribute('cx', '60');
936
933
  el5.setAttribute('cy', '60');
937
934
  el5.setAttribute('stroke-width', '8');
938
- el3.append(" ",el4," ",el5," ");
939
- el2.append(" ",el3," ");
940
- const el6 = dom.createElement("div", "lh-gauge__percentage");
941
- const el7 = dom.createElement("div", "lh-gauge__label");
942
- el1.append(" "," ",el2," ",el6," "," ",el7," ");
935
+ el3.append(' ', el4, ' ', el5, ' ');
936
+ el2.append(' ', el3, ' ');
937
+ const el6 = dom.createElement('div', 'lh-gauge__percentage');
938
+ const el7 = dom.createElement('div', 'lh-gauge__label');
939
+ el1.append(' ', ' ', el2, ' ', el6, ' ', ' ', el7, ' ');
943
940
  el0.append(el1);
944
941
  return el0;
945
942
  }
@@ -949,97 +946,97 @@ function createGaugeComponent(dom) {
949
946
  */
950
947
  function createGaugePwaComponent(dom) {
951
948
  const el0 = dom.createFragment();
952
- const el1 = dom.createElement("style");
953
- el1.append("\n .lh-gauge--pwa .lh-gauge--pwa__component {\n display: none;\n }\n .lh-gauge--pwa__wrapper:not(.lh-badged--all) .lh-gauge--pwa__logo > path {\n /* Gray logo unless everything is passing. */\n fill: #B0B0B0;\n }\n\n .lh-gauge--pwa__disc {\n fill: var(--color-gray-200);\n }\n\n .lh-gauge--pwa__logo--primary-color {\n fill: #304FFE;\n }\n\n .lh-gauge--pwa__logo--secondary-color {\n fill: #3D3D3D;\n }\n .lh-dark .lh-gauge--pwa__logo--secondary-color {\n fill: #D8B6B6;\n }\n\n /* No passing groups. */\n .lh-gauge--pwa__wrapper:not([class*='lh-badged--']) .lh-gauge--pwa__na-line {\n display: inline;\n }\n /* Just optimized. Same n/a line as no passing groups. */\n .lh-gauge--pwa__wrapper.lh-badged--pwa-optimized:not(.lh-badged--pwa-installable) .lh-gauge--pwa__na-line {\n display: inline;\n }\n\n /* Just installable. */\n .lh-gauge--pwa__wrapper.lh-badged--pwa-installable .lh-gauge--pwa__installable-badge {\n display: inline;\n }\n\n /* All passing groups. */\n .lh-gauge--pwa__wrapper.lh-badged--all .lh-gauge--pwa__check-circle {\n display: inline;\n }\n ");
949
+ const el1 = dom.createElement('style');
950
+ el1.append('\n .lh-gauge--pwa .lh-gauge--pwa__component {\n display: none;\n }\n .lh-gauge--pwa__wrapper:not(.lh-badged--all) .lh-gauge--pwa__logo > path {\n /* Gray logo unless everything is passing. */\n fill: #B0B0B0;\n }\n\n .lh-gauge--pwa__disc {\n fill: var(--color-gray-200);\n }\n\n .lh-gauge--pwa__logo--primary-color {\n fill: #304FFE;\n }\n\n .lh-gauge--pwa__logo--secondary-color {\n fill: #3D3D3D;\n }\n .lh-dark .lh-gauge--pwa__logo--secondary-color {\n fill: #D8B6B6;\n }\n\n /* No passing groups. */\n .lh-gauge--pwa__wrapper:not([class*=\'lh-badged--\']) .lh-gauge--pwa__na-line {\n display: inline;\n }\n /* Just optimized. Same n/a line as no passing groups. */\n .lh-gauge--pwa__wrapper.lh-badged--pwa-optimized:not(.lh-badged--pwa-installable) .lh-gauge--pwa__na-line {\n display: inline;\n }\n\n /* Just installable. */\n .lh-gauge--pwa__wrapper.lh-badged--pwa-installable .lh-gauge--pwa__installable-badge {\n display: inline;\n }\n\n /* All passing groups. */\n .lh-gauge--pwa__wrapper.lh-badged--all .lh-gauge--pwa__check-circle {\n display: inline;\n }\n ');
954
951
  el0.append(el1);
955
- const el2 = dom.createElement("a", "lh-gauge__wrapper lh-gauge--pwa__wrapper");
956
- const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-gauge lh-gauge--pwa");
952
+ const el2 = dom.createElement('a', 'lh-gauge__wrapper lh-gauge--pwa__wrapper');
953
+ const el3 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg', 'lh-gauge lh-gauge--pwa');
957
954
  el3.setAttribute('viewBox', '0 0 60 60');
958
- const el4 = dom.createElementNS("http://www.w3.org/2000/svg", "defs");
959
- const el5 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
955
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'defs');
956
+ const el5 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
960
957
  el5.setAttribute('id', 'lh-gauge--pwa__check-circle__gradient');
961
958
  el5.setAttribute('x1', '50%');
962
959
  el5.setAttribute('y1', '0%');
963
960
  el5.setAttribute('x2', '50%');
964
961
  el5.setAttribute('y2', '100%');
965
- const el6 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
962
+ const el6 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
966
963
  el6.setAttribute('stop-color', '#00C852');
967
964
  el6.setAttribute('offset', '0%');
968
- const el7 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
965
+ const el7 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
969
966
  el7.setAttribute('stop-color', '#009688');
970
967
  el7.setAttribute('offset', '100%');
971
- el5.append(" ",el6," ",el7," ");
972
- const el8 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
968
+ el5.append(' ', el6, ' ', el7, ' ');
969
+ const el8 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
973
970
  el8.setAttribute('id', 'lh-gauge--pwa__installable__shadow-gradient');
974
971
  el8.setAttribute('x1', '76.056%');
975
972
  el8.setAttribute('x2', '24.111%');
976
973
  el8.setAttribute('y1', '82.995%');
977
974
  el8.setAttribute('y2', '24.735%');
978
- const el9 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
975
+ const el9 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
979
976
  el9.setAttribute('stop-color', '#A5D6A7');
980
977
  el9.setAttribute('offset', '0%');
981
- const el10 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
978
+ const el10 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
982
979
  el10.setAttribute('stop-color', '#80CBC4');
983
980
  el10.setAttribute('offset', '100%');
984
- el8.append(" ",el9," ",el10," ");
985
- const el11 = dom.createElementNS("http://www.w3.org/2000/svg", "g");
981
+ el8.append(' ', el9, ' ', el10, ' ');
982
+ const el11 = dom.createElementNS('http://www.w3.org/2000/svg', 'g');
986
983
  el11.setAttribute('id', 'lh-gauge--pwa__installable-badge');
987
- const el12 = dom.createElementNS("http://www.w3.org/2000/svg", "circle");
984
+ const el12 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle');
988
985
  el12.setAttribute('fill', '#FFFFFF');
989
986
  el12.setAttribute('cx', '10');
990
987
  el12.setAttribute('cy', '10');
991
988
  el12.setAttribute('r', '10');
992
- const el13 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
989
+ const el13 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
993
990
  el13.setAttribute('fill', '#009688');
994
991
  el13.setAttribute('d', 'M10 4.167A5.835 5.835 0 0 0 4.167 10 5.835 5.835 0 0 0 10 15.833 5.835 5.835 0 0 0 15.833 10 5.835 5.835 0 0 0 10 4.167zm2.917 6.416h-2.334v2.334H9.417v-2.334H7.083V9.417h2.334V7.083h1.166v2.334h2.334v1.166z');
995
- el11.append(" ",el12," ",el13," ");
996
- el4.append(" ",el5," ",el8," ",el11," ");
997
- const el14 = dom.createElementNS("http://www.w3.org/2000/svg", "g");
992
+ el11.append(' ', el12, ' ', el13, ' ');
993
+ el4.append(' ', el5, ' ', el8, ' ', el11, ' ');
994
+ const el14 = dom.createElementNS('http://www.w3.org/2000/svg', 'g');
998
995
  el14.setAttribute('stroke', 'none');
999
996
  el14.setAttribute('fill-rule', 'nonzero');
1000
- const el15 = dom.createElementNS("http://www.w3.org/2000/svg", "circle", "lh-gauge--pwa__disc");
997
+ const el15 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle', 'lh-gauge--pwa__disc');
1001
998
  el15.setAttribute('cx', '30');
1002
999
  el15.setAttribute('cy', '30');
1003
1000
  el15.setAttribute('r', '30');
1004
- const el16 = dom.createElementNS("http://www.w3.org/2000/svg", "g", "lh-gauge--pwa__logo");
1005
- const el17 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-gauge--pwa__logo--secondary-color");
1001
+ const el16 = dom.createElementNS('http://www.w3.org/2000/svg', 'g', 'lh-gauge--pwa__logo');
1002
+ const el17 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-gauge--pwa__logo--secondary-color');
1006
1003
  el17.setAttribute('d', 'M35.66 19.39l.7-1.75h2L37.4 15 38.6 12l3.4 9h-2.51l-.58-1.61z');
1007
- const el18 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-gauge--pwa__logo--primary-color");
1004
+ const el18 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-gauge--pwa__logo--primary-color');
1008
1005
  el18.setAttribute('d', 'M33.52 21l3.65-9h-2.42l-2.5 5.82L30.5 12h-1.86l-1.9 5.82-1.35-2.65-1.21 3.72L25.4 21h2.38l1.72-5.2 1.64 5.2z');
1009
- const el19 = dom.createElementNS("http://www.w3.org/2000/svg", "path", "lh-gauge--pwa__logo--secondary-color");
1006
+ const el19 = dom.createElementNS('http://www.w3.org/2000/svg', 'path', 'lh-gauge--pwa__logo--secondary-color');
1010
1007
  el19.setAttribute('fill-rule', 'nonzero');
1011
1008
  el19.setAttribute('d', 'M20.3 17.91h1.48c.45 0 .85-.05 1.2-.15l.39-1.18 1.07-3.3a2.64 2.64 0 0 0-.28-.37c-.55-.6-1.36-.91-2.42-.91H18v9h2.3V17.9zm1.96-3.84c.22.22.33.5.33.87 0 .36-.1.65-.29.87-.2.23-.59.35-1.15.35h-.86v-2.41h.87c.52 0 .89.1 1.1.32z');
1012
- el16.append(" ",el17," ",el18," ",el19," ");
1013
- const el20 = dom.createElementNS("http://www.w3.org/2000/svg", "rect", "lh-gauge--pwa__component lh-gauge--pwa__na-line");
1009
+ el16.append(' ', el17, ' ', el18, ' ', el19, ' ');
1010
+ const el20 = dom.createElementNS('http://www.w3.org/2000/svg', 'rect', 'lh-gauge--pwa__component lh-gauge--pwa__na-line');
1014
1011
  el20.setAttribute('fill', '#FFFFFF');
1015
1012
  el20.setAttribute('x', '20');
1016
1013
  el20.setAttribute('y', '32');
1017
1014
  el20.setAttribute('width', '20');
1018
1015
  el20.setAttribute('height', '4');
1019
1016
  el20.setAttribute('rx', '2');
1020
- const el21 = dom.createElementNS("http://www.w3.org/2000/svg", "g", "lh-gauge--pwa__component lh-gauge--pwa__installable-badge");
1017
+ const el21 = dom.createElementNS('http://www.w3.org/2000/svg', 'g', 'lh-gauge--pwa__component lh-gauge--pwa__installable-badge');
1021
1018
  el21.setAttribute('transform', 'translate(20, 29)');
1022
- const el22 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1019
+ const el22 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1023
1020
  el22.setAttribute('fill', 'url(#lh-gauge--pwa__installable__shadow-gradient)');
1024
1021
  el22.setAttribute('d', 'M33.629 19.487c-4.272 5.453-10.391 9.39-17.415 10.869L3 17.142 17.142 3 33.63 19.487z');
1025
- const el23 = dom.createElementNS("http://www.w3.org/2000/svg", "use");
1022
+ const el23 = dom.createElementNS('http://www.w3.org/2000/svg', 'use');
1026
1023
  el23.setAttribute('href', '#lh-gauge--pwa__installable-badge');
1027
- el21.append(" ",el22," ",el23," ");
1028
- const el24 = dom.createElementNS("http://www.w3.org/2000/svg", "g", "lh-gauge--pwa__component lh-gauge--pwa__check-circle");
1024
+ el21.append(' ', el22, ' ', el23, ' ');
1025
+ const el24 = dom.createElementNS('http://www.w3.org/2000/svg', 'g', 'lh-gauge--pwa__component lh-gauge--pwa__check-circle');
1029
1026
  el24.setAttribute('transform', 'translate(18, 28)');
1030
- const el25 = dom.createElementNS("http://www.w3.org/2000/svg", "circle");
1027
+ const el25 = dom.createElementNS('http://www.w3.org/2000/svg', 'circle');
1031
1028
  el25.setAttribute('fill', '#FFFFFF');
1032
1029
  el25.setAttribute('cx', '12');
1033
1030
  el25.setAttribute('cy', '12');
1034
1031
  el25.setAttribute('r', '12');
1035
- const el26 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1032
+ const el26 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1036
1033
  el26.setAttribute('fill', 'url(#lh-gauge--pwa__check-circle__gradient)');
1037
1034
  el26.setAttribute('d', 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z');
1038
- el24.append(" ",el25," ",el26," ");
1039
- el14.append(" "," ",el15," ",el16," "," ",el20," "," ",el21," "," ",el24," ");
1040
- el3.append(" ",el4," ",el14," ");
1041
- const el27 = dom.createElement("div", "lh-gauge__label");
1042
- el2.append(" ",el3," ",el27," ");
1035
+ el24.append(' ', el25, ' ', el26, ' ');
1036
+ el14.append(' ', ' ', el15, ' ', el16, ' ', ' ', el20, ' ', ' ', el21, ' ', ' ', el24, ' ');
1037
+ el3.append(' ', el4, ' ', el14, ' ');
1038
+ const el27 = dom.createElement('div', 'lh-gauge__label');
1039
+ el2.append(' ', el3, ' ', el27, ' ');
1043
1040
  el0.append(el2);
1044
1041
  return el0;
1045
1042
  }
@@ -1049,12 +1046,12 @@ function createGaugePwaComponent(dom) {
1049
1046
  */
1050
1047
  function createHeadingComponent(dom) {
1051
1048
  const el0 = dom.createFragment();
1052
- const el1 = dom.createElement("style");
1053
- el1.append("\n /* CSS Fireworks. Originally by Eddie Lin\n https://codepen.io/paulirish/pen/yEVMbP\n */\n .lh-pyro {\n display: none;\n z-index: 1;\n pointer-events: none;\n }\n .lh-score100 .lh-pyro {\n display: block;\n }\n .lh-score100 .lh-lighthouse stop:first-child {\n stop-color: hsla(200, 12%, 95%, 0);\n }\n .lh-score100 .lh-lighthouse stop:last-child {\n stop-color: hsla(65, 81%, 76%, 1);\n }\n\n .lh-pyro > .lh-pyro-before, .lh-pyro > .lh-pyro-after {\n position: absolute;\n width: 5px;\n height: 5px;\n border-radius: 2.5px;\n box-shadow: 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff;\n animation: 1s bang ease-out infinite backwards, 1s gravity ease-in infinite backwards, 5s position linear infinite backwards;\n animation-delay: 1s, 1s, 1s;\n }\n\n .lh-pyro > .lh-pyro-after {\n animation-delay: 2.25s, 2.25s, 2.25s;\n animation-duration: 1.25s, 1.25s, 6.25s;\n }\n\n @keyframes bang {\n to {\n box-shadow: -70px -115.67px #47ebbc, -28px -99.67px #eb47a4, 58px -31.67px #7eeb47, 13px -141.67px #eb47c5, -19px 6.33px #7347eb, -2px -74.67px #ebd247, 24px -151.67px #eb47e0, 57px -138.67px #b4eb47, -51px -104.67px #479eeb, 62px 8.33px #ebcf47, -93px 0.33px #d547eb, -16px -118.67px #47bfeb, 53px -84.67px #47eb83, 66px -57.67px #eb47bf, -93px -65.67px #91eb47, 30px -13.67px #86eb47, -2px -59.67px #83eb47, -44px 1.33px #eb47eb, 61px -58.67px #47eb73, 5px -22.67px #47e8eb, -66px -28.67px #ebe247, 42px -123.67px #eb5547, -75px 26.33px #7beb47, 15px -52.67px #a147eb, 36px -51.67px #eb8347, -38px -12.67px #eb5547, -46px -59.67px #47eb81, 78px -114.67px #eb47ba, 15px -156.67px #eb47bf, -36px 1.33px #eb4783, -72px -86.67px #eba147, 31px -46.67px #ebe247, -68px 29.33px #47e2eb, -55px 19.33px #ebe047, -56px 27.33px #4776eb, -13px -91.67px #eb5547, -47px -138.67px #47ebc7, -18px -96.67px #eb47ac, 11px -88.67px #4783eb, -67px -28.67px #47baeb, 53px 10.33px #ba47eb, 11px 19.33px #5247eb, -5px -11.67px #eb4791, -68px -4.67px #47eba7, 95px -37.67px #eb478b, -67px -162.67px #eb5d47, -54px -120.67px #eb6847, 49px -12.67px #ebe047, 88px 8.33px #47ebda, 97px 33.33px #eb8147, 6px -71.67px #ebbc47;\n }\n }\n @keyframes gravity {\n to {\n transform: translateY(80px);\n opacity: 0;\n }\n }\n @keyframes position {\n 0%, 19.9% {\n margin-top: 4%;\n margin-left: 47%;\n }\n 20%, 39.9% {\n margin-top: 7%;\n margin-left: 30%;\n }\n 40%, 59.9% {\n margin-top: 6%;\n margin-left: 70%;\n }\n 60%, 79.9% {\n margin-top: 3%;\n margin-left: 20%;\n }\n 80%, 99.9% {\n margin-top: 3%;\n margin-left: 80%;\n }\n }\n ");
1049
+ const el1 = dom.createElement('style');
1050
+ el1.append('\n /* CSS Fireworks. Originally by Eddie Lin\n https://codepen.io/paulirish/pen/yEVMbP\n */\n .lh-pyro {\n display: none;\n z-index: 1;\n pointer-events: none;\n }\n .lh-score100 .lh-pyro {\n display: block;\n }\n .lh-score100 .lh-lighthouse stop:first-child {\n stop-color: hsla(200, 12%, 95%, 0);\n }\n .lh-score100 .lh-lighthouse stop:last-child {\n stop-color: hsla(65, 81%, 76%, 1);\n }\n\n .lh-pyro > .lh-pyro-before, .lh-pyro > .lh-pyro-after {\n position: absolute;\n width: 5px;\n height: 5px;\n border-radius: 2.5px;\n box-shadow: 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff, 0 0 #fff;\n animation: 1s bang ease-out infinite backwards, 1s gravity ease-in infinite backwards, 5s position linear infinite backwards;\n animation-delay: 1s, 1s, 1s;\n }\n\n .lh-pyro > .lh-pyro-after {\n animation-delay: 2.25s, 2.25s, 2.25s;\n animation-duration: 1.25s, 1.25s, 6.25s;\n }\n\n @keyframes bang {\n to {\n box-shadow: -70px -115.67px #47ebbc, -28px -99.67px #eb47a4, 58px -31.67px #7eeb47, 13px -141.67px #eb47c5, -19px 6.33px #7347eb, -2px -74.67px #ebd247, 24px -151.67px #eb47e0, 57px -138.67px #b4eb47, -51px -104.67px #479eeb, 62px 8.33px #ebcf47, -93px 0.33px #d547eb, -16px -118.67px #47bfeb, 53px -84.67px #47eb83, 66px -57.67px #eb47bf, -93px -65.67px #91eb47, 30px -13.67px #86eb47, -2px -59.67px #83eb47, -44px 1.33px #eb47eb, 61px -58.67px #47eb73, 5px -22.67px #47e8eb, -66px -28.67px #ebe247, 42px -123.67px #eb5547, -75px 26.33px #7beb47, 15px -52.67px #a147eb, 36px -51.67px #eb8347, -38px -12.67px #eb5547, -46px -59.67px #47eb81, 78px -114.67px #eb47ba, 15px -156.67px #eb47bf, -36px 1.33px #eb4783, -72px -86.67px #eba147, 31px -46.67px #ebe247, -68px 29.33px #47e2eb, -55px 19.33px #ebe047, -56px 27.33px #4776eb, -13px -91.67px #eb5547, -47px -138.67px #47ebc7, -18px -96.67px #eb47ac, 11px -88.67px #4783eb, -67px -28.67px #47baeb, 53px 10.33px #ba47eb, 11px 19.33px #5247eb, -5px -11.67px #eb4791, -68px -4.67px #47eba7, 95px -37.67px #eb478b, -67px -162.67px #eb5d47, -54px -120.67px #eb6847, 49px -12.67px #ebe047, 88px 8.33px #47ebda, 97px 33.33px #eb8147, 6px -71.67px #ebbc47;\n }\n }\n @keyframes gravity {\n to {\n transform: translateY(80px);\n opacity: 0;\n }\n }\n @keyframes position {\n 0%, 19.9% {\n margin-top: 4%;\n margin-left: 47%;\n }\n 20%, 39.9% {\n margin-top: 7%;\n margin-left: 30%;\n }\n 40%, 59.9% {\n margin-top: 6%;\n margin-left: 70%;\n }\n 60%, 79.9% {\n margin-top: 3%;\n margin-left: 20%;\n }\n 80%, 99.9% {\n margin-top: 3%;\n margin-left: 80%;\n }\n }\n ');
1054
1051
  el0.append(el1);
1055
- const el2 = dom.createElement("div", "lh-header-container");
1056
- const el3 = dom.createElement("div", "lh-scores-wrapper-placeholder");
1057
- el2.append(" ",el3," ");
1052
+ const el2 = dom.createElement('div', 'lh-header-container');
1053
+ const el3 = dom.createElement('div', 'lh-scores-wrapper-placeholder');
1054
+ el2.append(' ', el3, ' ');
1058
1055
  el0.append(el2);
1059
1056
  return el0;
1060
1057
  }
@@ -1064,14 +1061,14 @@ function createHeadingComponent(dom) {
1064
1061
  */
1065
1062
  function createMetricComponent(dom) {
1066
1063
  const el0 = dom.createFragment();
1067
- const el1 = dom.createElement("div", "lh-metric");
1068
- const el2 = dom.createElement("div", "lh-metric__innerwrap");
1069
- const el3 = dom.createElement("div", "lh-metric__icon");
1070
- const el4 = dom.createElement("span", "lh-metric__title");
1071
- const el5 = dom.createElement("div", "lh-metric__value");
1072
- const el6 = dom.createElement("div", "lh-metric__description");
1073
- el2.append(" ",el3," ",el4," ",el5," ",el6," ");
1074
- el1.append(" ",el2," ");
1064
+ const el1 = dom.createElement('div', 'lh-metric');
1065
+ const el2 = dom.createElement('div', 'lh-metric__innerwrap');
1066
+ const el3 = dom.createElement('div', 'lh-metric__icon');
1067
+ const el4 = dom.createElement('span', 'lh-metric__title');
1068
+ const el5 = dom.createElement('div', 'lh-metric__value');
1069
+ const el6 = dom.createElement('div', 'lh-metric__description');
1070
+ el2.append(' ', el3, ' ', el4, ' ', el5, ' ', el6, ' ');
1071
+ el1.append(' ', el2, ' ');
1075
1072
  el0.append(el1);
1076
1073
  return el0;
1077
1074
  }
@@ -1081,31 +1078,31 @@ function createMetricComponent(dom) {
1081
1078
  */
1082
1079
  function createOpportunityComponent(dom) {
1083
1080
  const el0 = dom.createFragment();
1084
- const el1 = dom.createElement("div", "lh-audit lh-audit--load-opportunity");
1085
- const el2 = dom.createElement("details", "lh-expandable-details");
1086
- const el3 = dom.createElement("summary");
1087
- const el4 = dom.createElement("div", "lh-audit__header");
1088
- const el5 = dom.createElement("div", "lh-load-opportunity__cols");
1089
- const el6 = dom.createElement("div", "lh-load-opportunity__col lh-load-opportunity__col--one");
1090
- const el7 = dom.createElement("span", "lh-audit__score-icon");
1091
- const el8 = dom.createElement("div", "lh-audit__title");
1092
- el6.append(" ",el7," ",el8," ");
1093
- const el9 = dom.createElement("div", "lh-load-opportunity__col lh-load-opportunity__col--two");
1094
- const el10 = dom.createElement("div", "lh-load-opportunity__sparkline");
1095
- const el11 = dom.createElement("div", "lh-sparkline");
1096
- const el12 = dom.createElement("div", "lh-sparkline__bar");
1081
+ const el1 = dom.createElement('div', 'lh-audit lh-audit--load-opportunity');
1082
+ const el2 = dom.createElement('details', 'lh-expandable-details');
1083
+ const el3 = dom.createElement('summary');
1084
+ const el4 = dom.createElement('div', 'lh-audit__header');
1085
+ const el5 = dom.createElement('div', 'lh-load-opportunity__cols');
1086
+ const el6 = dom.createElement('div', 'lh-load-opportunity__col lh-load-opportunity__col--one');
1087
+ const el7 = dom.createElement('span', 'lh-audit__score-icon');
1088
+ const el8 = dom.createElement('div', 'lh-audit__title');
1089
+ el6.append(' ', el7, ' ', el8, ' ');
1090
+ const el9 = dom.createElement('div', 'lh-load-opportunity__col lh-load-opportunity__col--two');
1091
+ const el10 = dom.createElement('div', 'lh-load-opportunity__sparkline');
1092
+ const el11 = dom.createElement('div', 'lh-sparkline');
1093
+ const el12 = dom.createElement('div', 'lh-sparkline__bar');
1097
1094
  el11.append(el12);
1098
- el10.append(" ",el11," ");
1099
- const el13 = dom.createElement("div", "lh-audit__display-text");
1100
- const el14 = dom.createElement("div", "lh-chevron-container");
1101
- el9.append(" ",el10," ",el13," ",el14," ");
1102
- el5.append(" ",el6," ",el9," ");
1103
- el4.append(" ",el5," ");
1104
- el3.append(" ",el4," ");
1105
- const el15 = dom.createElement("div", "lh-audit__description");
1106
- const el16 = dom.createElement("div", "lh-audit__stackpacks");
1107
- el2.append(" ",el3," ",el15," ",el16," ");
1108
- el1.append(" ",el2," ");
1095
+ el10.append(' ', el11, ' ');
1096
+ const el13 = dom.createElement('div', 'lh-audit__display-text');
1097
+ const el14 = dom.createElement('div', 'lh-chevron-container');
1098
+ el9.append(' ', el10, ' ', el13, ' ', el14, ' ');
1099
+ el5.append(' ', el6, ' ', el9, ' ');
1100
+ el4.append(' ', el5, ' ');
1101
+ el3.append(' ', el4, ' ');
1102
+ const el15 = dom.createElement('div', 'lh-audit__description');
1103
+ const el16 = dom.createElement('div', 'lh-audit__stackpacks');
1104
+ el2.append(' ', el3, ' ', el15, ' ', el16, ' ');
1105
+ el1.append(' ', el2, ' ');
1109
1106
  el0.append(el1);
1110
1107
  return el0;
1111
1108
  }
@@ -1115,10 +1112,10 @@ function createOpportunityComponent(dom) {
1115
1112
  */
1116
1113
  function createOpportunityHeaderComponent(dom) {
1117
1114
  const el0 = dom.createFragment();
1118
- const el1 = dom.createElement("div", "lh-load-opportunity__header lh-load-opportunity__cols");
1119
- const el2 = dom.createElement("div", "lh-load-opportunity__col lh-load-opportunity__col--one");
1120
- const el3 = dom.createElement("div", "lh-load-opportunity__col lh-load-opportunity__col--two");
1121
- el1.append(" ",el2," ",el3," ");
1115
+ const el1 = dom.createElement('div', 'lh-load-opportunity__header lh-load-opportunity__cols');
1116
+ const el2 = dom.createElement('div', 'lh-load-opportunity__col lh-load-opportunity__col--one');
1117
+ const el3 = dom.createElement('div', 'lh-load-opportunity__col lh-load-opportunity__col--two');
1118
+ el1.append(' ', el2, ' ', el3, ' ');
1122
1119
  el0.append(el1);
1123
1120
  return el0;
1124
1121
  }
@@ -1128,14 +1125,14 @@ function createOpportunityHeaderComponent(dom) {
1128
1125
  */
1129
1126
  function createScorescaleComponent(dom) {
1130
1127
  const el0 = dom.createFragment();
1131
- const el1 = dom.createElement("div", "lh-scorescale");
1132
- const el2 = dom.createElement("span", "lh-scorescale-range lh-scorescale-range--fail");
1133
- el2.append("0–49");
1134
- const el3 = dom.createElement("span", "lh-scorescale-range lh-scorescale-range--average");
1135
- el3.append("50–89");
1136
- const el4 = dom.createElement("span", "lh-scorescale-range lh-scorescale-range--pass");
1137
- el4.append("90–100");
1138
- el1.append(" ",el2," ",el3," ",el4," ");
1128
+ const el1 = dom.createElement('div', 'lh-scorescale');
1129
+ const el2 = dom.createElement('span', 'lh-scorescale-range lh-scorescale-range--fail');
1130
+ el2.append('0–49');
1131
+ const el3 = dom.createElement('span', 'lh-scorescale-range lh-scorescale-range--average');
1132
+ el3.append('50–89');
1133
+ const el4 = dom.createElement('span', 'lh-scorescale-range lh-scorescale-range--pass');
1134
+ el4.append('90–100');
1135
+ el1.append(' ', el2, ' ', el3, ' ', el4, ' ');
1139
1136
  el0.append(el1);
1140
1137
  return el0;
1141
1138
  }
@@ -1145,17 +1142,17 @@ function createScorescaleComponent(dom) {
1145
1142
  */
1146
1143
  function createScoresWrapperComponent(dom) {
1147
1144
  const el0 = dom.createFragment();
1148
- const el1 = dom.createElement("style");
1149
- el1.append("\n .lh-scores-container {\n display: flex;\n flex-direction: column;\n padding: var(--default-padding) 0;\n position: relative;\n width: 100%;\n }\n\n .lh-sticky-header {\n --gauge-circle-size: var(--gauge-circle-size-sm);\n --plugin-badge-size: 16px;\n --plugin-icon-size: 75%;\n --gauge-wrapper-width: 60px;\n --gauge-percentage-font-size: 13px;\n position: fixed;\n left: 0;\n right: 0;\n top: var(--topbar-height);\n font-weight: 500;\n display: none;\n justify-content: center;\n background-color: var(--sticky-header-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n padding-top: var(--score-container-padding);\n padding-bottom: 4px;\n z-index: 1;\n pointer-events: none;\n }\n\n .lh-devtools .lh-sticky-header {\n /* The report within DevTools is placed in a container with overflow, which changes the placement of this header unless we change `position` to `sticky.` */\n position: sticky;\n }\n\n .lh-sticky-header--visible {\n display: grid;\n grid-auto-flow: column;\n pointer-events: auto;\n }\n\n /* Disable the gauge arc animation for the sticky header, so toggling display: none\n does not play the animation. */\n .lh-sticky-header .lh-gauge-arc {\n animation: none;\n }\n\n .lh-sticky-header .lh-gauge__label,\n .lh-sticky-header .lh-fraction__label {\n display: none;\n }\n\n .lh-highlighter {\n width: var(--gauge-wrapper-width);\n height: 1px;\n background-color: var(--highlighter-background-color);\n /* Position at bottom of first gauge in sticky header. */\n position: absolute;\n grid-column: 1;\n bottom: -1px;\n }\n\n .lh-gauge__wrapper:first-of-type {\n contain: none;\n }\n ");
1145
+ const el1 = dom.createElement('style');
1146
+ el1.append('\n .lh-scores-container {\n display: flex;\n flex-direction: column;\n padding: var(--default-padding) 0;\n position: relative;\n width: 100%;\n }\n\n .lh-sticky-header {\n --gauge-circle-size: var(--gauge-circle-size-sm);\n --plugin-badge-size: 16px;\n --plugin-icon-size: 75%;\n --gauge-wrapper-width: 60px;\n --gauge-percentage-font-size: 13px;\n position: fixed;\n left: 0;\n right: 0;\n top: var(--topbar-height);\n font-weight: 500;\n display: none;\n justify-content: center;\n background-color: var(--sticky-header-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n padding-top: var(--score-container-padding);\n padding-bottom: 4px;\n z-index: 1;\n pointer-events: none;\n }\n\n .lh-devtools .lh-sticky-header {\n /* The report within DevTools is placed in a container with overflow, which changes the placement of this header unless we change `position` to `sticky.` */\n position: sticky;\n }\n\n .lh-sticky-header--visible {\n display: grid;\n grid-auto-flow: column;\n pointer-events: auto;\n }\n\n /* Disable the gauge arc animation for the sticky header, so toggling display: none\n does not play the animation. */\n .lh-sticky-header .lh-gauge-arc {\n animation: none;\n }\n\n .lh-sticky-header .lh-gauge__label,\n .lh-sticky-header .lh-fraction__label {\n display: none;\n }\n\n .lh-highlighter {\n width: var(--gauge-wrapper-width);\n height: 1px;\n background-color: var(--highlighter-background-color);\n /* Position at bottom of first gauge in sticky header. */\n position: absolute;\n grid-column: 1;\n bottom: -1px;\n }\n\n .lh-gauge__wrapper:first-of-type {\n contain: none;\n }\n ');
1150
1147
  el0.append(el1);
1151
- const el2 = dom.createElement("div", "lh-scores-wrapper");
1152
- const el3 = dom.createElement("div", "lh-scores-container");
1153
- const el4 = dom.createElement("div", "lh-pyro");
1154
- const el5 = dom.createElement("div", "lh-pyro-before");
1155
- const el6 = dom.createElement("div", "lh-pyro-after");
1156
- el4.append(" ",el5," ",el6," ");
1157
- el3.append(" ",el4," ");
1158
- el2.append(" ",el3," ");
1148
+ const el2 = dom.createElement('div', 'lh-scores-wrapper');
1149
+ const el3 = dom.createElement('div', 'lh-scores-container');
1150
+ const el4 = dom.createElement('div', 'lh-pyro');
1151
+ const el5 = dom.createElement('div', 'lh-pyro-before');
1152
+ const el6 = dom.createElement('div', 'lh-pyro-after');
1153
+ el4.append(' ', el5, ' ', el6, ' ');
1154
+ el3.append(' ', el4, ' ');
1155
+ el2.append(' ', el3, ' ');
1159
1156
  el0.append(el2);
1160
1157
  return el0;
1161
1158
  }
@@ -1165,10 +1162,10 @@ function createScoresWrapperComponent(dom) {
1165
1162
  */
1166
1163
  function createSnippetComponent(dom) {
1167
1164
  const el0 = dom.createFragment();
1168
- const el1 = dom.createElement("div", "lh-snippet");
1169
- const el2 = dom.createElement("style");
1170
- el2.append("\n :root {\n --snippet-highlight-light: #fbf1f2;\n --snippet-highlight-dark: #ffd6d8;\n }\n\n .lh-snippet__header {\n position: relative;\n overflow: hidden;\n padding: 10px;\n border-bottom: none;\n color: var(--snippet-color);\n background-color: var(--snippet-background-color);\n border: 1px solid var(--report-border-color-secondary);\n }\n .lh-snippet__title {\n font-weight: bold;\n float: left;\n }\n .lh-snippet__node {\n float: left;\n margin-left: 4px;\n }\n .lh-snippet__toggle-expand {\n padding: 1px 7px;\n margin-top: -1px;\n margin-right: -7px;\n float: right;\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n color: #0c50c7;\n }\n\n .lh-snippet__snippet {\n overflow: auto;\n border: 1px solid var(--report-border-color-secondary);\n }\n /* Container needed so that all children grow to the width of the scroll container */\n .lh-snippet__snippet-inner {\n display: inline-block;\n min-width: 100%;\n }\n\n .lh-snippet:not(.lh-snippet--expanded) .lh-snippet__show-if-expanded {\n display: none;\n }\n .lh-snippet.lh-snippet--expanded .lh-snippet__show-if-collapsed {\n display: none;\n }\n\n .lh-snippet__line {\n background: white;\n white-space: pre;\n display: flex;\n }\n .lh-snippet__line:not(.lh-snippet__line--message):first-child {\n padding-top: 4px;\n }\n .lh-snippet__line:not(.lh-snippet__line--message):last-child {\n padding-bottom: 4px;\n }\n .lh-snippet__line--content-highlighted {\n background: var(--snippet-highlight-dark);\n }\n .lh-snippet__line--message {\n background: var(--snippet-highlight-light);\n }\n .lh-snippet__line--message .lh-snippet__line-number {\n padding-top: 10px;\n padding-bottom: 10px;\n }\n .lh-snippet__line--message code {\n padding: 10px;\n padding-left: 5px;\n color: var(--color-fail);\n font-family: var(--report-font-family);\n }\n .lh-snippet__line--message code {\n white-space: normal;\n }\n .lh-snippet__line-icon {\n padding-top: 10px;\n display: none;\n }\n .lh-snippet__line--message .lh-snippet__line-icon {\n display: block;\n }\n .lh-snippet__line-icon:before {\n content: \"\";\n display: inline-block;\n vertical-align: middle;\n margin-right: 4px;\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n background-image: var(--fail-icon-url);\n }\n .lh-snippet__line-number {\n flex-shrink: 0;\n width: 40px;\n text-align: right;\n font-family: monospace;\n padding-right: 5px;\n margin-right: 5px;\n color: var(--color-gray-600);\n user-select: none;\n }\n ");
1171
- el1.append(" ",el2," ");
1165
+ const el1 = dom.createElement('div', 'lh-snippet');
1166
+ const el2 = dom.createElement('style');
1167
+ el2.append('\n :root {\n --snippet-highlight-light: #fbf1f2;\n --snippet-highlight-dark: #ffd6d8;\n }\n\n .lh-snippet__header {\n position: relative;\n overflow: hidden;\n padding: 10px;\n border-bottom: none;\n color: var(--snippet-color);\n background-color: var(--snippet-background-color);\n border: 1px solid var(--report-border-color-secondary);\n }\n .lh-snippet__title {\n font-weight: bold;\n float: left;\n }\n .lh-snippet__node {\n float: left;\n margin-left: 4px;\n }\n .lh-snippet__toggle-expand {\n padding: 1px 7px;\n margin-top: -1px;\n margin-right: -7px;\n float: right;\n background: transparent;\n border: none;\n cursor: pointer;\n font-size: 14px;\n color: #0c50c7;\n }\n\n .lh-snippet__snippet {\n overflow: auto;\n border: 1px solid var(--report-border-color-secondary);\n }\n /* Container needed so that all children grow to the width of the scroll container */\n .lh-snippet__snippet-inner {\n display: inline-block;\n min-width: 100%;\n }\n\n .lh-snippet:not(.lh-snippet--expanded) .lh-snippet__show-if-expanded {\n display: none;\n }\n .lh-snippet.lh-snippet--expanded .lh-snippet__show-if-collapsed {\n display: none;\n }\n\n .lh-snippet__line {\n background: white;\n white-space: pre;\n display: flex;\n }\n .lh-snippet__line:not(.lh-snippet__line--message):first-child {\n padding-top: 4px;\n }\n .lh-snippet__line:not(.lh-snippet__line--message):last-child {\n padding-bottom: 4px;\n }\n .lh-snippet__line--content-highlighted {\n background: var(--snippet-highlight-dark);\n }\n .lh-snippet__line--message {\n background: var(--snippet-highlight-light);\n }\n .lh-snippet__line--message .lh-snippet__line-number {\n padding-top: 10px;\n padding-bottom: 10px;\n }\n .lh-snippet__line--message code {\n padding: 10px;\n padding-left: 5px;\n color: var(--color-fail);\n font-family: var(--report-font-family);\n }\n .lh-snippet__line--message code {\n white-space: normal;\n }\n .lh-snippet__line-icon {\n padding-top: 10px;\n display: none;\n }\n .lh-snippet__line--message .lh-snippet__line-icon {\n display: block;\n }\n .lh-snippet__line-icon:before {\n content: "";\n display: inline-block;\n vertical-align: middle;\n margin-right: 4px;\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n background-image: var(--fail-icon-url);\n }\n .lh-snippet__line-number {\n flex-shrink: 0;\n width: 40px;\n text-align: right;\n font-family: monospace;\n padding-right: 5px;\n margin-right: 5px;\n color: var(--color-gray-600);\n user-select: none;\n }\n ');
1168
+ el1.append(' ', el2, ' ');
1172
1169
  el0.append(el1);
1173
1170
  return el0;
1174
1171
  }
@@ -1178,9 +1175,9 @@ function createSnippetComponent(dom) {
1178
1175
  */
1179
1176
  function createSnippetContentComponent(dom) {
1180
1177
  const el0 = dom.createFragment();
1181
- const el1 = dom.createElement("div", "lh-snippet__snippet");
1182
- const el2 = dom.createElement("div", "lh-snippet__snippet-inner");
1183
- el1.append(" ",el2," ");
1178
+ const el1 = dom.createElement('div', 'lh-snippet__snippet');
1179
+ const el2 = dom.createElement('div', 'lh-snippet__snippet-inner');
1180
+ el1.append(' ', el2, ' ');
1184
1181
  el0.append(el1);
1185
1182
  return el0;
1186
1183
  }
@@ -1190,14 +1187,14 @@ function createSnippetContentComponent(dom) {
1190
1187
  */
1191
1188
  function createSnippetHeaderComponent(dom) {
1192
1189
  const el0 = dom.createFragment();
1193
- const el1 = dom.createElement("div", "lh-snippet__header");
1194
- const el2 = dom.createElement("div", "lh-snippet__title");
1195
- const el3 = dom.createElement("div", "lh-snippet__node");
1196
- const el4 = dom.createElement("button", "lh-snippet__toggle-expand");
1197
- const el5 = dom.createElement("span", "lh-snippet__btn-label-collapse lh-snippet__show-if-expanded");
1198
- const el6 = dom.createElement("span", "lh-snippet__btn-label-expand lh-snippet__show-if-collapsed");
1199
- el4.append(" ",el5," ",el6," ");
1200
- el1.append(" ",el2," ",el3," ",el4," ");
1190
+ const el1 = dom.createElement('div', 'lh-snippet__header');
1191
+ const el2 = dom.createElement('div', 'lh-snippet__title');
1192
+ const el3 = dom.createElement('div', 'lh-snippet__node');
1193
+ const el4 = dom.createElement('button', 'lh-snippet__toggle-expand');
1194
+ const el5 = dom.createElement('span', 'lh-snippet__btn-label-collapse lh-snippet__show-if-expanded');
1195
+ const el6 = dom.createElement('span', 'lh-snippet__btn-label-expand lh-snippet__show-if-collapsed');
1196
+ el4.append(' ', el5, ' ', el6, ' ');
1197
+ el1.append(' ', el2, ' ', el3, ' ', el4, ' ');
1201
1198
  el0.append(el1);
1202
1199
  return el0;
1203
1200
  }
@@ -1207,11 +1204,11 @@ function createSnippetHeaderComponent(dom) {
1207
1204
  */
1208
1205
  function createSnippetLineComponent(dom) {
1209
1206
  const el0 = dom.createFragment();
1210
- const el1 = dom.createElement("div", "lh-snippet__line");
1211
- const el2 = dom.createElement("div", "lh-snippet__line-number");
1212
- const el3 = dom.createElement("div", "lh-snippet__line-icon");
1213
- const el4 = dom.createElement("code");
1214
- el1.append(" ",el2," ",el3," ",el4," ");
1207
+ const el1 = dom.createElement('div', 'lh-snippet__line');
1208
+ const el2 = dom.createElement('div', 'lh-snippet__line-number');
1209
+ const el3 = dom.createElement('div', 'lh-snippet__line-icon');
1210
+ const el4 = dom.createElement('code');
1211
+ el1.append(' ', el2, ' ', el3, ' ', el4, ' ');
1215
1212
  el0.append(el1);
1216
1213
  return el0;
1217
1214
  }
@@ -1221,8 +1218,8 @@ function createSnippetLineComponent(dom) {
1221
1218
  */
1222
1219
  function createStylesComponent(dom) {
1223
1220
  const el0 = dom.createFragment();
1224
- const el1 = dom.createElement("style");
1225
- el1.append("/**\n * @license\n * Copyright 2017 The Lighthouse Authors. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS-IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n Naming convention:\n\n If a variable is used for a specific component: --{component}-{property name}-{modifier}\n\n Both {component} and {property name} should be kebab-case. If the target is the entire page,\n use 'report' for the component. The property name should not be abbreviated. Use the\n property name the variable is intended for - if it's used for multiple, a common descriptor\n is fine (ex: 'size' for a variable applied to 'width' and 'height'). If a variable is shared\n across multiple components, either create more variables or just drop the \"{component}-\"\n part of the name. Append any modifiers at the end (ex: 'big', 'dark').\n\n For colors: --color-{hue}-{intensity}\n\n {intensity} is the Material Design tag - 700, A700, etc.\n*/\n.lh-vars {\n /* Palette using Material Design Colors\n * https://www.materialui.co/colors */\n --color-amber-50: #FFF8E1;\n --color-blue-200: #90CAF9;\n --color-blue-900: #0D47A1;\n --color-blue-A700: #2962FF;\n --color-blue-primary: #06f;\n --color-cyan-500: #00BCD4;\n --color-gray-100: #F5F5F5;\n --color-gray-300: #CFCFCF;\n --color-gray-200: #E0E0E0;\n --color-gray-400: #BDBDBD;\n --color-gray-50: #FAFAFA;\n --color-gray-500: #9E9E9E;\n --color-gray-600: #757575;\n --color-gray-700: #616161;\n --color-gray-800: #424242;\n --color-gray-900: #212121;\n --color-gray: #000000;\n --color-green-700: #080;\n --color-green: #0c6;\n --color-lime-400: #D3E156;\n --color-orange-50: #FFF3E0;\n --color-orange-700: #C33300;\n --color-orange: #fa3;\n --color-red-700: #c00;\n --color-red: #f33;\n --color-teal-600: #00897B;\n --color-white: #FFFFFF;\n\n /* Context-specific colors */\n --color-average-secondary: var(--color-orange-700);\n --color-average: var(--color-orange);\n --color-fail-secondary: var(--color-red-700);\n --color-fail: var(--color-red);\n --color-hover: var(--color-gray-50);\n --color-informative: var(--color-blue-900);\n --color-pass-secondary: var(--color-green-700);\n --color-pass: var(--color-green);\n --color-not-applicable: var(--color-gray-600);\n\n /* Component variables */\n --audit-description-padding-left: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right));\n --audit-explanation-line-height: 16px;\n --audit-group-margin-bottom: calc(var(--default-padding) * 6);\n --audit-group-padding-vertical: 8px;\n --audit-margin-horizontal: 5px;\n --audit-padding-vertical: 8px;\n --category-padding: calc(var(--default-padding) * 6) var(--edge-gap-padding) calc(var(--default-padding) * 4);\n --chevron-line-stroke: var(--color-gray-600);\n --chevron-size: 12px;\n --default-padding: 8px;\n --edge-gap-padding: calc(var(--default-padding) * 4);\n --env-item-background-color: var(--color-gray-100);\n --env-item-font-size: 28px;\n --env-item-line-height: 36px;\n --env-item-padding: 10px 0px;\n --env-name-min-width: 220px;\n --footer-padding-vertical: 16px;\n --gauge-circle-size-big: 96px;\n --gauge-circle-size: 48px;\n --gauge-circle-size-sm: 32px;\n --gauge-label-font-size-big: 18px;\n --gauge-label-font-size: var(--report-font-size-secondary);\n --gauge-label-line-height-big: 24px;\n --gauge-label-line-height: var(--report-line-height-secondary);\n --gauge-percentage-font-size-big: 38px;\n --gauge-percentage-font-size: var(--report-font-size-secondary);\n --gauge-wrapper-width: 120px;\n --header-line-height: 24px;\n --highlighter-background-color: var(--report-text-color);\n --icon-square-size: calc(var(--score-icon-size) * 0.88);\n --image-preview-size: 48px;\n --link-color: var(--color-blue-primary);\n --locale-selector-background-color: var(--color-white);\n --metric-toggle-lines-fill: #7F7F7F;\n --metric-value-font-size: calc(var(--report-font-size) * 1.8);\n --metrics-toggle-background-color: var(--color-gray-200);\n --plugin-badge-background-color: var(--color-white);\n --plugin-badge-size-big: calc(var(--gauge-circle-size-big) / 2.7);\n --plugin-badge-size: calc(var(--gauge-circle-size) / 2.7);\n --plugin-icon-size: 65%;\n --pwa-icon-margin: 0 var(--default-padding);\n --pwa-icon-size: var(--topbar-logo-size);\n --report-background-color: #fff;\n --report-border-color-secondary: #ebebeb;\n --report-font-family-monospace: 'Roboto Mono', 'Menlo', 'dejavu sans mono', 'Consolas', 'Lucida Console', monospace;\n --report-font-family: Roboto, Helvetica, Arial, sans-serif;\n --report-font-size: 14px;\n --report-font-size-secondary: 12px;\n --report-icon-size: var(--score-icon-background-size);\n --report-line-height: 24px;\n --report-line-height-secondary: 20px;\n --report-monospace-font-size: calc(var(--report-font-size) * 0.85);\n --report-text-color-secondary: var(--color-gray-800);\n --report-text-color: var(--color-gray-900);\n --report-content-max-width: calc(60 * var(--report-font-size)); /* defaults to 840px */\n --report-content-min-width: 360px;\n --report-content-max-width-minus-edge-gap: calc(var(--report-content-max-width) - var(--edge-gap-padding) * 2);\n --score-container-padding: 8px;\n --score-icon-background-size: 24px;\n --score-icon-margin-left: 6px;\n --score-icon-margin-right: 14px;\n --score-icon-margin: 0 var(--score-icon-margin-right) 0 var(--score-icon-margin-left);\n --score-icon-size: 12px;\n --score-icon-size-big: 16px;\n --screenshot-overlay-background: rgba(0, 0, 0, 0.3);\n --section-padding-vertical: calc(var(--default-padding) * 6);\n --snippet-background-color: var(--color-gray-50);\n --snippet-color: #0938C2;\n --sparkline-height: 5px;\n --stackpack-padding-horizontal: 10px;\n --sticky-header-background-color: var(--report-background-color);\n --table-higlight-background-color: hsla(210, 17%, 77%, 0.1);\n --tools-icon-color: var(--color-gray-600);\n --topbar-background-color: var(--color-white);\n --topbar-height: 32px;\n --topbar-logo-size: 24px;\n --topbar-padding: 0 8px;\n --toplevel-warning-background-color: hsla(30, 100%, 75%, 10%);\n --toplevel-warning-message-text-color: var(--color-average-secondary);\n --toplevel-warning-padding: 18px;\n --toplevel-warning-text-color: var(--report-text-color);\n\n /* SVGs */\n --plugin-icon-url-dark: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24px\" height=\"24px\" viewBox=\"0 0 24 24\" fill=\"%23FFFFFF\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z\"/></svg>');\n --plugin-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24px\" height=\"24px\" viewBox=\"0 0 24 24\" fill=\"%23757575\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z\"/></svg>');\n\n --pass-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 48 48\"><title>check</title><path fill=\"%23178239\" d=\"M24 4C12.95 4 4 12.95 4 24c0 11.04 8.95 20 20 20 11.04 0 20-8.96 20-20 0-11.05-8.96-20-20-20zm-4 30L10 24l2.83-2.83L20 28.34l15.17-15.17L38 16 20 34z\"/></svg>');\n --average-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 48 48\"><title>info</title><path fill=\"%23E67700\" d=\"M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm2 30h-4V22h4v12zm0-16h-4v-4h4v4z\"/></svg>');\n --fail-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 48 48\"><title>warn</title><path fill=\"%23C7221F\" d=\"M2 42h44L24 4 2 42zm24-6h-4v-4h4v4zm0-8h-4v-8h4v8z\"/></svg>');\n\n --pwa-installable-gray-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"nonzero\"><circle fill=\"%23DAE0E3\" cx=\"12\" cy=\"12\" r=\"12\"/><path d=\"M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z\" fill=\"%23FFF\"/></g></svg>');\n --pwa-optimized-gray-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"%23DAE0E3\" width=\"24\" height=\"24\" rx=\"12\"/><path fill=\"%23FFF\" d=\"M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z\"/><path d=\"M5 5h14v14H5z\"/></g></svg>');\n\n --pwa-installable-gray-url-dark: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"nonzero\"><circle fill=\"%23424242\" cx=\"12\" cy=\"12\" r=\"12\"/><path d=\"M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z\" fill=\"%23FFF\"/></g></svg>');\n --pwa-optimized-gray-url-dark: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"%23424242\" width=\"24\" height=\"24\" rx=\"12\"/><path fill=\"%23FFF\" d=\"M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z\"/><path d=\"M5 5h14v14H5z\"/></g></svg>');\n\n --pwa-installable-color-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"nonzero\" fill=\"none\"><circle fill=\"%230CCE6B\" cx=\"12\" cy=\"12\" r=\"12\"/><path d=\"M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z\" fill=\"%23FFF\"/></g></svg>');\n --pwa-optimized-color-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\"><g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"%230CCE6B\" width=\"24\" height=\"24\" rx=\"12\"/><path d=\"M5 5h14v14H5z\"/><path fill=\"%23FFF\" d=\"M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z\"/></g></svg>');\n\n --swap-locale-icon-url: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#000000\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><path d=\"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z\"/></svg>');\n}\n\n@media not print {\n .lh-dark {\n /* Pallete */\n --color-gray-200: var(--color-gray-800);\n --color-gray-300: #616161;\n --color-gray-400: var(--color-gray-600);\n --color-gray-700: var(--color-gray-400);\n --color-gray-50: #757575;\n --color-gray-600: var(--color-gray-500);\n --color-green-700: var(--color-green);\n --color-orange-700: var(--color-orange);\n --color-red-700: var(--color-red);\n --color-teal-600: var(--color-cyan-500);\n\n /* Context-specific colors */\n --color-hover: rgba(0, 0, 0, 0.2);\n --color-informative: var(--color-blue-200);\n\n /* Component variables */\n --env-item-background-color: #393535;\n --link-color: var(--color-blue-200);\n --locale-selector-background-color: var(--color-gray-200);\n --plugin-badge-background-color: var(--color-gray-800);\n --report-background-color: var(--color-gray-900);\n --report-border-color-secondary: var(--color-gray-200);\n --report-text-color-secondary: var(--color-gray-400);\n --report-text-color: var(--color-gray-100);\n --snippet-color: var(--color-cyan-500);\n --topbar-background-color: var(--color-gray);\n --toplevel-warning-background-color: hsl(33deg 14% 18%);\n --toplevel-warning-message-text-color: var(--color-orange-700);\n --toplevel-warning-text-color: var(--color-gray-100);\n\n /* SVGs */\n --plugin-icon-url: var(--plugin-icon-url-dark);\n --pwa-installable-gray-url: var(--pwa-installable-gray-url-dark);\n --pwa-optimized-gray-url: var(--pwa-optimized-gray-url-dark);\n }\n}\n\n@media only screen and (max-width: 480px) {\n .lh-vars {\n --audit-group-margin-bottom: 20px;\n --edge-gap-padding: var(--default-padding);\n --env-name-min-width: 120px;\n --gauge-circle-size-big: 96px;\n --gauge-circle-size: 72px;\n --gauge-label-font-size-big: 22px;\n --gauge-label-font-size: 14px;\n --gauge-label-line-height-big: 26px;\n --gauge-label-line-height: 20px;\n --gauge-percentage-font-size-big: 34px;\n --gauge-percentage-font-size: 26px;\n --gauge-wrapper-width: 112px;\n --header-padding: 16px 0 16px 0;\n --image-preview-size: 24px;\n --plugin-icon-size: 75%;\n --pwa-icon-margin: 0 7px 0 -3px;\n --report-font-size: 14px;\n --report-line-height: 20px;\n --score-icon-margin-left: 2px;\n --score-icon-size: 10px;\n --topbar-height: 28px;\n --topbar-logo-size: 20px;\n }\n\n /* Not enough space to adequately show the relative savings bars. */\n .lh-sparkline {\n display: none;\n }\n}\n\n.lh-vars.lh-devtools {\n --audit-explanation-line-height: 14px;\n --audit-group-margin-bottom: 20px;\n --audit-group-padding-vertical: 12px;\n --audit-padding-vertical: 4px;\n --category-padding: 12px;\n --default-padding: 12px;\n --env-name-min-width: 120px;\n --footer-padding-vertical: 8px;\n --gauge-circle-size-big: 72px;\n --gauge-circle-size: 64px;\n --gauge-label-font-size-big: 22px;\n --gauge-label-font-size: 14px;\n --gauge-label-line-height-big: 26px;\n --gauge-label-line-height: 20px;\n --gauge-percentage-font-size-big: 34px;\n --gauge-percentage-font-size: 26px;\n --gauge-wrapper-width: 97px;\n --header-line-height: 20px;\n --header-padding: 16px 0 16px 0;\n --screenshot-overlay-background: transparent;\n --plugin-icon-size: 75%;\n --pwa-icon-margin: 0 7px 0 -3px;\n --report-font-family-monospace: 'Menlo', 'dejavu sans mono', 'Consolas', 'Lucida Console', monospace;\n --report-font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif;\n --report-font-size: 12px;\n --report-line-height: 20px;\n --score-icon-margin-left: 2px;\n --score-icon-size: 10px;\n --section-padding-vertical: 8px;\n}\n\n.lh-devtools.lh-root {\n height: 100%;\n}\n.lh-devtools.lh-root img {\n /* Override devtools default 'min-width: 0' so svg without size in a flexbox isn't collapsed. */\n min-width: auto;\n}\n.lh-devtools .lh-container {\n overflow-y: scroll;\n height: calc(100% - var(--topbar-height));\n}\n@media print {\n .lh-devtools .lh-container {\n overflow: unset;\n }\n}\n.lh-devtools .lh-sticky-header {\n /* This is normally the height of the topbar, but we want it to stick to the top of our scroll container .lh-container` */\n top: 0;\n}\n.lh-devtools .lh-element-screenshot__overlay {\n position: absolute;\n}\n\n@keyframes fadeIn {\n 0% { opacity: 0;}\n 100% { opacity: 0.6;}\n}\n\n.lh-root *, .lh-root *::before, .lh-root *::after {\n box-sizing: border-box;\n}\n\n.lh-root {\n font-family: var(--report-font-family);\n font-size: var(--report-font-size);\n margin: 0;\n line-height: var(--report-line-height);\n background: var(--report-background-color);\n color: var(--report-text-color);\n}\n\n.lh-root :focus {\n outline: -webkit-focus-ring-color auto 3px;\n}\n.lh-root summary:focus {\n outline: none;\n box-shadow: 0 0 0 1px hsl(217, 89%, 61%);\n}\n\n.lh-root [hidden] {\n display: none !important;\n}\n\n.lh-root pre {\n margin: 0;\n}\n\n.lh-root details > summary {\n cursor: pointer;\n}\n\n.lh-hidden {\n display: none !important;\n}\n\n.lh-container {\n /*\n Text wrapping in the report is so much FUN!\n We have a `word-break: break-word;` globally here to prevent a few common scenarios, namely\n long non-breakable text (usually URLs) found in:\n 1. The footer\n 2. .lh-node (outerHTML)\n 3. .lh-code\n\n With that sorted, the next challenge is appropriate column sizing and text wrapping inside our\n .lh-details tables. Even more fun.\n * We don't want table headers (\"Potential Savings (ms)\") to wrap or their column values, but\n we'd be happy for the URL column to wrap if the URLs are particularly long.\n * We want the narrow columns to remain narrow, providing the most column width for URL\n * We don't want the table to extend past 100% width.\n * Long URLs in the URL column can wrap. Util.getURLDisplayName maxes them out at 64 characters,\n but they do not get any overflow:ellipsis treatment.\n */\n word-break: break-word;\n}\n\n.lh-audit-group a,\n.lh-category-header__description a,\n.lh-audit__description a,\n.lh-warnings a,\n.lh-footer a,\n.lh-table-column--link a {\n color: var(--link-color);\n}\n\n.lh-audit__description, .lh-audit__stackpack {\n --inner-audit-padding-right: var(--stackpack-padding-horizontal);\n padding-left: var(--audit-description-padding-left);\n padding-right: var(--inner-audit-padding-right);\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n.lh-details {\n margin-top: var(--default-padding);\n margin-bottom: var(--default-padding);\n margin-left: var(--audit-description-padding-left);\n /* whatever the .lh-details side margins are */\n width: 100%;\n}\n\n.lh-audit__stackpack {\n display: flex;\n align-items: center;\n}\n\n.lh-audit__stackpack__img {\n max-width: 30px;\n margin-right: var(--default-padding)\n}\n\n/* Report header */\n\n.lh-report-icon {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n cursor: pointer;\n}\n.lh-report-icon[disabled] {\n opacity: 0.3;\n pointer-events: none;\n}\n\n.lh-report-icon::before {\n content: \"\";\n margin: 4px;\n background-repeat: no-repeat;\n width: var(--report-icon-size);\n height: var(--report-icon-size);\n opacity: 0.7;\n display: inline-block;\n vertical-align: middle;\n}\n.lh-report-icon:hover::before {\n opacity: 1;\n}\n.lh-dark .lh-report-icon::before {\n filter: invert(1);\n}\n.lh-report-icon--print::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\"/><path fill=\"none\" d=\"M0 0h24v24H0z\"/></svg>');\n}\n.lh-report-icon--copy::before {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"/></svg>');\n}\n.lh-report-icon--open::before {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z\"/></svg>');\n}\n.lh-report-icon--download::before {\n background-image: url('data:image/svg+xml;utf8,<svg height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"/><path d=\"M0 0h24v24H0z\" fill=\"none\"/></svg>');\n}\n.lh-report-icon--dark::before {\n background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 100 125\"><path d=\"M50 23.587c-16.27 0-22.799 12.574-22.799 21.417 0 12.917 10.117 22.451 12.436 32.471h20.726c2.32-10.02 12.436-19.554 12.436-32.471 0-8.843-6.528-21.417-22.799-21.417zM39.637 87.161c0 3.001 1.18 4.181 4.181 4.181h.426l.41 1.231C45.278 94.449 46.042 95 48.019 95h3.963c1.978 0 2.74-.551 3.365-2.427l.409-1.231h.427c3.002 0 4.18-1.18 4.18-4.181V80.91H39.637v6.251zM50 18.265c1.26 0 2.072-.814 2.072-2.073v-9.12C52.072 5.813 51.26 5 50 5c-1.259 0-2.072.813-2.072 2.073v9.12c0 1.259.813 2.072 2.072 2.072zM68.313 23.727c.994.774 2.135.634 2.91-.357l5.614-7.187c.776-.992.636-2.135-.356-2.909-.992-.776-2.135-.636-2.91.357l-5.613 7.186c-.778.993-.636 2.135.355 2.91zM91.157 36.373c-.306-1.222-1.291-1.815-2.513-1.51l-8.85 2.207c-1.222.305-1.814 1.29-1.51 2.512.305 1.223 1.291 1.814 2.513 1.51l8.849-2.206c1.223-.305 1.816-1.291 1.511-2.513zM86.757 60.48l-8.331-3.709c-1.15-.512-2.225-.099-2.736 1.052-.512 1.151-.1 2.224 1.051 2.737l8.33 3.707c1.15.514 2.225.101 2.736-1.05.513-1.149.1-2.223-1.05-2.737zM28.779 23.37c.775.992 1.917 1.131 2.909.357.992-.776 1.132-1.917.357-2.91l-5.615-7.186c-.775-.992-1.917-1.132-2.909-.357s-1.131 1.917-.356 2.909l5.614 7.187zM21.715 39.583c.305-1.223-.288-2.208-1.51-2.513l-8.849-2.207c-1.222-.303-2.208.289-2.513 1.511-.303 1.222.288 2.207 1.511 2.512l8.848 2.206c1.222.304 2.208-.287 2.513-1.509zM21.575 56.771l-8.331 3.711c-1.151.511-1.563 1.586-1.05 2.735.511 1.151 1.586 1.563 2.736 1.052l8.331-3.711c1.151-.511 1.563-1.586 1.05-2.735-.512-1.15-1.585-1.562-2.736-1.052z\"/></svg>');\n}\n.lh-report-icon--treemap::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"black\"><path d=\"M3 5v14h19V5H3zm2 2h15v4H5V7zm0 10v-4h4v4H5zm6 0v-4h9v4h-9z\"/></svg>');\n}\n.lh-report-icon--date::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M7 11h2v2H7v-2zm14-5v14a2 2 0 01-2 2H5a2 2 0 01-2-2V6c0-1.1.9-2 2-2h1V2h2v2h8V2h2v2h1a2 2 0 012 2zM5 8h14V6H5v2zm14 12V10H5v10h14zm-4-7h2v-2h-2v2zm-4 0h2v-2h-2v2z\"/></svg>');\n}\n.lh-report-icon--devices::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 6h18V4H4a2 2 0 00-2 2v11H0v3h14v-3H4V6zm19 2h-6a1 1 0 00-1 1v10c0 .6.5 1 1 1h6c.6 0 1-.5 1-1V9c0-.6-.5-1-1-1zm-1 9h-4v-7h4v7z\"/></svg>');\n}\n.lh-report-icon--world::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm7 6h-3c-.3-1.3-.8-2.5-1.4-3.6A8 8 0 0 1 18.9 8zm-7-4a14 14 0 0 1 2 4h-4a14 14 0 0 1 2-4zM4.3 14a8.2 8.2 0 0 1 0-4h3.3a16.5 16.5 0 0 0 0 4H4.3zm.8 2h3a14 14 0 0 0 1.3 3.6A8 8 0 0 1 5.1 16zm3-8H5a8 8 0 0 1 4.3-3.6L8 8zM12 20a14 14 0 0 1-2-4h4a14 14 0 0 1-2 4zm2.3-6H9.7a14.7 14.7 0 0 1 0-4h4.6a14.6 14.6 0 0 1 0 4zm.3 5.6c.6-1.2 1-2.4 1.4-3.6h3a8 8 0 0 1-4.4 3.6zm1.8-5.6a16.5 16.5 0 0 0 0-4h3.3a8.2 8.2 0 0 1 0 4h-3.3z\"/></svg>');\n}\n.lh-report-icon--stopwatch::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.1-6.6L20.5 6l-1.4-1.4L17.7 6A9 9 0 0 0 3 13a9 9 0 1 0 16-5.6zm-7 12.6a7 7 0 1 1 0-14 7 7 0 0 1 0 14z\"/></svg>');\n}\n.lh-report-icon--networkspeed::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.9 5c-.2 0-.3 0-.4.2v.2L10.1 17a2 2 0 0 0-.2 1 2 2 0 0 0 4 .4l2.4-12.9c0-.3-.2-.5-.5-.5zM1 9l2 2c2.9-2.9 6.8-4 10.5-3.6l1.2-2.7C10 3.8 4.7 5.3 1 9zm20 2 2-2a15.4 15.4 0 0 0-5.6-3.6L17 8.2c1.5.7 2.9 1.6 4.1 2.8zm-4 4 2-2a9.9 9.9 0 0 0-2.7-1.9l-.5 3 1.2.9zM5 13l2 2a7.1 7.1 0 0 1 4-2l1.3-2.9C9.7 10.1 7 11 5 13z\"/></svg>');\n}\n.lh-report-icon--samples-one::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><circle cx=\"7\" cy=\"14\" r=\"3\"/><path d=\"M7 18a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5.6 17.6a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/></svg>');\n}\n.lh-report-icon--samples-many::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M7 18a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5.6 17.6a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/><circle cx=\"7\" cy=\"14\" r=\"3\"/><circle cx=\"11\" cy=\"6\" r=\"3\"/></svg>');\n}\n.lh-report-icon--chrome::before {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-50 -50 562 562\"><path d=\"M256 25.6v25.6a204 204 0 0 1 144.8 60 204 204 0 0 1 60 144.8 204 204 0 0 1-60 144.8 204 204 0 0 1-144.8 60 204 204 0 0 1-144.8-60 204 204 0 0 1-60-144.8 204 204 0 0 1 60-144.8 204 204 0 0 1 144.8-60V0a256 256 0 1 0 0 512 256 256 0 0 0 0-512v25.6z\"/><path d=\"M256 179.2v25.6a51.3 51.3 0 0 1 0 102.4 51.3 51.3 0 0 1 0-102.4v-51.2a102.3 102.3 0 1 0-.1 204.7 102.3 102.3 0 0 0 .1-204.7v25.6z\"/><path d=\"M256 204.8h217.6a25.6 25.6 0 0 0 0-51.2H256a25.6 25.6 0 0 0 0 51.2m44.3 76.8L191.5 470.1a25.6 25.6 0 1 0 44.4 25.6l108.8-188.5a25.6 25.6 0 1 0-44.4-25.6m-88.6 0L102.9 93.2a25.7 25.7 0 0 0-35-9.4 25.7 25.7 0 0 0-9.4 35l108.8 188.5a25.7 25.7 0 0 0 35 9.4 25.9 25.9 0 0 0 9.4-35.1\"/></svg>');\n}\n\n\n\n.lh-buttons {\n display: flex;\n flex-wrap: wrap;\n margin: var(--default-padding) 0;\n}\n.lh-button {\n height: 32px;\n border: 1px solid var(--report-border-color-secondary);\n border-radius: 3px;\n color: var(--link-color);\n background-color: var(--report-background-color);\n margin: 5px;\n}\n\n.lh-button:first-of-type {\n margin-left: 0;\n}\n\n/* Node */\n.lh-node__snippet {\n font-family: var(--report-font-family-monospace);\n color: var(--snippet-color);\n font-size: var(--report-monospace-font-size);\n line-height: 20px;\n}\n\n/* Score */\n\n.lh-audit__score-icon {\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n margin: var(--score-icon-margin);\n}\n\n.lh-audit--pass .lh-audit__display-text {\n color: var(--color-pass-secondary);\n}\n.lh-audit--pass .lh-audit__score-icon,\n.lh-scorescale-range--pass::before {\n border-radius: 100%;\n background: var(--color-pass);\n}\n\n.lh-audit--average .lh-audit__display-text {\n color: var(--color-average-secondary);\n}\n.lh-audit--average .lh-audit__score-icon,\n.lh-scorescale-range--average::before {\n background: var(--color-average);\n width: var(--icon-square-size);\n height: var(--icon-square-size);\n}\n\n.lh-audit--fail .lh-audit__display-text {\n color: var(--color-fail-secondary);\n}\n.lh-audit--fail .lh-audit__score-icon,\n.lh-audit--error .lh-audit__score-icon,\n.lh-scorescale-range--fail::before {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n\n.lh-audit--manual .lh-audit__display-text,\n.lh-audit--notapplicable .lh-audit__display-text {\n color: var(--color-gray-600);\n}\n.lh-audit--manual .lh-audit__score-icon,\n.lh-audit--notapplicable .lh-audit__score-icon {\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-400);\n border-radius: 100%;\n background: none;\n}\n\n.lh-audit--informative .lh-audit__display-text {\n color: var(--color-gray-600);\n}\n\n.lh-audit--informative .lh-audit__score-icon {\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-400);\n border-radius: 100%;\n}\n\n.lh-audit__description,\n.lh-audit__stackpack {\n color: var(--report-text-color-secondary);\n}\n.lh-audit__adorn {\n border: 1px solid slategray;\n border-radius: 3px;\n margin: 0 3px;\n padding: 0 2px;\n line-height: 1.1;\n display: inline-block;\n font-size: 90%;\n}\n\n.lh-category-header__description {\n text-align: center;\n color: var(--color-gray-700);\n margin: 0px auto;\n max-width: 400px;\n}\n\n\n.lh-audit__display-text,\n.lh-load-opportunity__sparkline,\n.lh-chevron-container {\n margin: 0 var(--audit-margin-horizontal);\n}\n.lh-chevron-container {\n margin-right: 0;\n}\n\n.lh-audit__title-and-text {\n flex: 1;\n}\n\n.lh-audit__title-and-text code {\n color: var(--snippet-color);\n font-size: var(--report-monospace-font-size);\n}\n\n/* Prepend display text with em dash separator. But not in Opportunities. */\n.lh-audit__display-text:not(:empty):before {\n content: '—';\n margin-right: var(--audit-margin-horizontal);\n}\n.lh-audit-group.lh-audit-group--load-opportunities .lh-audit__display-text:not(:empty):before {\n display: none;\n}\n\n/* Expandable Details (Audit Groups, Audits) */\n.lh-audit__header {\n display: flex;\n align-items: center;\n padding: var(--default-padding);\n}\n\n.lh-audit--load-opportunity .lh-audit__header {\n display: block;\n}\n\n\n.lh-metricfilter {\n display: grid;\n justify-content: end;\n align-items: center;\n grid-auto-flow: column;\n gap: 4px;\n color: var(--color-gray-700);\n}\n\n.lh-metricfilter__radio {\n position: absolute;\n left: -9999px;\n}\n.lh-metricfilter input[type='radio']:focus-visible + label {\n outline: -webkit-focus-ring-color auto 1px;\n}\n\n.lh-metricfilter__label {\n display: inline-flex;\n padding: 0 4px;\n height: 16px;\n text-decoration: underline;\n align-items: center;\n cursor: pointer;\n font-size: 90%;\n}\n\n.lh-metricfilter__label--active {\n background: var(--color-blue-primary);\n color: var(--color-white);\n border-radius: 3px;\n text-decoration: none;\n}\n/* Give the 'All' choice a more muted display */\n.lh-metricfilter__label--active[for=\"metric-All\"] {\n background-color: var(--color-blue-200) !important;\n color: black !important;\n}\n\n.lh-metricfilter__text {\n margin-right: 8px;\n}\n\n/* If audits are filtered, hide the itemcount for Passed Audits… */\n.lh-category--filtered .lh-audit-group .lh-audit-group__itemcount {\n display: none;\n}\n\n\n.lh-audit__header:hover {\n background-color: var(--color-hover);\n}\n\n/* We want to hide the browser's default arrow marker on summary elements. Admittedly, it's complicated. */\n.lh-root details > summary {\n /* Blink 89+ and Firefox will hide the arrow when display is changed from (new) default of `list-item` to block. https://chromestatus.com/feature/6730096436051968*/\n display: block;\n}\n/* Safari and Blink <=88 require using the -webkit-details-marker selector */\n.lh-root details > summary::-webkit-details-marker {\n display: none;\n}\n\n/* Perf Metric */\n\n.lh-metrics-container {\n display: grid;\n grid-auto-rows: 1fr;\n grid-template-columns: 1fr 1fr;\n grid-column-gap: var(--report-line-height);\n margin-bottom: var(--default-padding);\n}\n\n.lh-metric {\n border-top: 1px solid var(--report-border-color-secondary);\n}\n\n.lh-category:not(.lh--hoisted-meta) .lh-metric:nth-last-child(-n+2) {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\n\n.lh-metric__innerwrap {\n display: grid;\n /**\n * Icon -- Metric Name\n * -- Metric Value\n */\n grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 1fr;\n align-items: center;\n padding: var(--default-padding);\n}\n\n.lh-metric__details {\n order: -1;\n}\n\n.lh-metric__title {\n flex: 1;\n}\n\n.lh-calclink {\n padding-left: calc(1ex / 3);\n}\n\n.lh-metric__description {\n display: none;\n grid-column-start: 2;\n grid-column-end: 4;\n color: var(--report-text-color-secondary);\n}\n\n.lh-metric__value {\n font-size: var(--metric-value-font-size);\n margin: calc(var(--default-padding) / 2) 0;\n white-space: nowrap; /* No wrapping between metric value and the icon */\n grid-column-start: 2;\n}\n\n\n@media screen and (max-width: 535px) {\n .lh-metrics-container {\n display: block;\n }\n\n .lh-metric {\n border-bottom: none !important;\n }\n .lh-category:not(.lh--hoisted-meta) .lh-metric:nth-last-child(1) {\n border-bottom: 1px solid var(--report-border-color-secondary) !important;\n }\n\n /* Change the grid to 3 columns for narrow viewport. */\n .lh-metric__innerwrap {\n /**\n * Icon -- Metric Name -- Metric Value\n */\n grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 2fr 1fr;\n }\n .lh-metric__value {\n justify-self: end;\n grid-column-start: unset;\n }\n}\n\n/* No-JS toggle switch */\n/* Keep this selector sync'd w/ `magicSelector` in report-ui-features-test.js */\n .lh-metrics-toggle__input:checked ~ .lh-metrics-container .lh-metric__description {\n display: block;\n}\n\n/* TODO get rid of the SVGS and clean up these some more */\n.lh-metrics-toggle__input {\n opacity: 0;\n position: absolute;\n right: 0;\n top: 0px;\n}\n\n.lh-metrics-toggle__input + div > label > .lh-metrics-toggle__labeltext--hide,\n.lh-metrics-toggle__input:checked + div > label > .lh-metrics-toggle__labeltext--show {\n display: none;\n}\n.lh-metrics-toggle__input:checked + div > label > .lh-metrics-toggle__labeltext--hide {\n display: inline;\n}\n.lh-metrics-toggle__input:focus + div > label {\n outline: -webkit-focus-ring-color auto 3px;\n}\n\n.lh-metrics-toggle__label {\n cursor: pointer;\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n color: var(--color-gray-700);\n}\n\n/* Pushes the metric description toggle button to the right. */\n.lh-audit-group--metrics .lh-audit-group__header {\n display: flex;\n justify-content: space-between;\n}\n\n.lh-metric__icon,\n.lh-scorescale-range::before {\n content: '';\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n display: inline-block;\n margin: var(--score-icon-margin);\n}\n\n.lh-metric--pass .lh-metric__value {\n color: var(--color-pass-secondary);\n}\n.lh-metric--pass .lh-metric__icon {\n border-radius: 100%;\n background: var(--color-pass);\n}\n\n.lh-metric--average .lh-metric__value {\n color: var(--color-average-secondary);\n}\n.lh-metric--average .lh-metric__icon {\n background: var(--color-average);\n width: var(--icon-square-size);\n height: var(--icon-square-size);\n}\n\n.lh-metric--fail .lh-metric__value {\n color: var(--color-fail-secondary);\n}\n.lh-metric--fail .lh-metric__icon,\n.lh-metric--error .lh-metric__icon {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n\n.lh-metric--error .lh-metric__value,\n.lh-metric--error .lh-metric__description {\n color: var(--color-fail-secondary);\n}\n\n/* Perf load opportunity */\n\n.lh-load-opportunity__cols {\n display: flex;\n align-items: flex-start;\n}\n\n.lh-load-opportunity__header .lh-load-opportunity__col {\n color: var(--color-gray-600);\n display: unset;\n line-height: calc(2.3 * var(--report-font-size));\n}\n\n.lh-load-opportunity__col {\n display: flex;\n}\n\n.lh-load-opportunity__col--one {\n flex: 5;\n align-items: center;\n margin-right: 2px;\n}\n.lh-load-opportunity__col--two {\n flex: 4;\n text-align: right;\n}\n\n.lh-audit--load-opportunity .lh-audit__display-text {\n text-align: right;\n flex: 0 0 calc(3 * var(--report-font-size));\n}\n\n\n/* Sparkline */\n\n.lh-load-opportunity__sparkline {\n flex: 1;\n margin-top: calc((var(--report-line-height) - var(--sparkline-height)) / 2);\n}\n\n.lh-sparkline {\n height: var(--sparkline-height);\n width: 100%;\n}\n\n.lh-sparkline__bar {\n height: 100%;\n float: right;\n}\n\n.lh-audit--pass .lh-sparkline__bar {\n background: var(--color-pass);\n}\n\n.lh-audit--average .lh-sparkline__bar {\n background: var(--color-average);\n}\n\n.lh-audit--fail .lh-sparkline__bar {\n background: var(--color-fail);\n}\n\n/* Filmstrip */\n\n.lh-filmstrip-container {\n /* smaller gap between metrics and filmstrip */\n margin: -8px auto 0 auto;\n}\n\n.lh-filmstrip {\n display: grid;\n justify-content: space-between;\n padding-bottom: var(--default-padding);\n width: 100%;\n grid-template-columns: repeat(auto-fit, 60px);\n}\n\n.lh-filmstrip__frame {\n text-align: right;\n position: relative;\n}\n\n.lh-filmstrip__thumbnail {\n border: 1px solid var(--report-border-color-secondary);\n max-height: 100px;\n max-width: 60px;\n}\n\n/* Audit */\n\n.lh-audit {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\n\n/* Apply border-top to just the first audit. */\n.lh-audit {\n border-top: 1px solid var(--report-border-color-secondary);\n}\n.lh-audit ~ .lh-audit {\n border-top: none;\n}\n\n\n.lh-audit--error .lh-audit__display-text {\n color: var(--color-fail-secondary);\n}\n\n/* Audit Group */\n\n.lh-audit-group {\n margin-bottom: var(--audit-group-margin-bottom);\n position: relative;\n}\n.lh-audit-group--metrics {\n margin-bottom: calc(var(--audit-group-margin-bottom) / 2);\n}\n\n.lh-audit-group__header::before {\n /* By default, groups don't get an icon */\n content: none;\n width: var(--pwa-icon-size);\n height: var(--pwa-icon-size);\n margin: var(--pwa-icon-margin);\n display: inline-block;\n vertical-align: middle;\n}\n\n/* Style the \"over budget\" columns red. */\n.lh-audit-group--budgets #performance-budget tbody tr td:nth-child(4),\n.lh-audit-group--budgets #performance-budget tbody tr td:nth-child(5),\n.lh-audit-group--budgets #timing-budget tbody tr td:nth-child(3) {\n color: var(--color-red-700);\n}\n\n/* Align the \"over budget request count\" text to be close to the \"over budget bytes\" column. */\n.lh-audit-group--budgets .lh-table tbody tr td:nth-child(4){\n text-align: right;\n}\n\n.lh-audit-group--budgets .lh-details--budget {\n width: 100%;\n margin: 0 0 var(--default-padding);\n}\n\n.lh-audit-group--pwa-installable .lh-audit-group__header::before {\n content: '';\n background-image: var(--pwa-installable-gray-url);\n}\n.lh-audit-group--pwa-optimized .lh-audit-group__header::before {\n content: '';\n background-image: var(--pwa-optimized-gray-url);\n}\n.lh-audit-group--pwa-installable.lh-badged .lh-audit-group__header::before {\n background-image: var(--pwa-installable-color-url);\n}\n.lh-audit-group--pwa-optimized.lh-badged .lh-audit-group__header::before {\n background-image: var(--pwa-optimized-color-url);\n}\n\n.lh-audit-group--metrics .lh-audit-group__summary {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.lh-audit-group__summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.lh-audit-group__header .lh-chevron {\n margin-top: calc((var(--report-line-height) - 5px) / 2);\n}\n\n.lh-audit-group__header {\n letter-spacing: 0.8px;\n padding: var(--default-padding);\n padding-left: 0;\n}\n\n.lh-audit-group__header, .lh-audit-group__summary {\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n color: var(--color-gray-700);\n}\n\n.lh-audit-group__title {\n text-transform: uppercase;\n font-weight: 500;\n}\n\n.lh-audit-group__itemcount {\n color: var(--color-gray-600);\n}\n\n.lh-audit-group__footer {\n color: var(--color-gray-600);\n display: block;\n margin-top: var(--default-padding);\n}\n\n.lh-details,\n.lh-category-header__description,\n.lh-load-opportunity__header,\n.lh-audit-group__footer {\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n}\n\n.lh-audit-explanation {\n margin: var(--audit-padding-vertical) 0 calc(var(--audit-padding-vertical) / 2) var(--audit-margin-horizontal);\n line-height: var(--audit-explanation-line-height);\n display: inline-block;\n}\n\n.lh-audit--fail .lh-audit-explanation {\n color: var(--color-fail-secondary);\n}\n\n/* Report */\n.lh-list > :not(:last-child) {\n margin-bottom: calc(var(--default-padding) * 2);\n}\n\n.lh-header-container {\n display: block;\n margin: 0 auto;\n position: relative;\n word-wrap: break-word;\n}\n\n.lh-header-container .lh-scores-wrapper {\n border-bottom: 1px solid var(--color-gray-200);\n}\n\n\n.lh-report {\n min-width: var(--report-content-min-width);\n}\n\n.lh-exception {\n font-size: large;\n}\n\n.lh-code {\n white-space: normal;\n margin-top: 0;\n font-size: var(--report-monospace-font-size);\n}\n\n.lh-warnings {\n --item-margin: calc(var(--report-line-height) / 6);\n color: var(--color-average-secondary);\n margin: var(--audit-padding-vertical) 0;\n padding: var(--default-padding)\n var(--default-padding)\n var(--default-padding)\n calc(var(--audit-description-padding-left));\n background-color: var(--toplevel-warning-background-color);\n}\n.lh-warnings span {\n font-weight: bold;\n}\n\n.lh-warnings--toplevel {\n --item-margin: calc(var(--header-line-height) / 4);\n color: var(--toplevel-warning-text-color);\n margin-left: auto;\n margin-right: auto;\n max-width: var(--report-content-max-width-minus-edge-gap);\n padding: var(--toplevel-warning-padding);\n border-radius: 8px;\n}\n\n.lh-warnings__msg {\n color: var(--toplevel-warning-message-text-color);\n margin: 0;\n}\n\n.lh-warnings ul {\n margin: 0;\n}\n.lh-warnings li {\n margin: var(--item-margin) 0;\n}\n.lh-warnings li:last-of-type {\n margin-bottom: 0;\n}\n\n.lh-scores-header {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n}\n.lh-scores-header__solo {\n padding: 0;\n border: 0;\n}\n\n/* Gauge */\n\n.lh-gauge__wrapper--pass {\n color: var(--color-pass-secondary);\n fill: var(--color-pass);\n stroke: var(--color-pass);\n}\n\n.lh-gauge__wrapper--average {\n color: var(--color-average-secondary);\n fill: var(--color-average);\n stroke: var(--color-average);\n}\n\n.lh-gauge__wrapper--fail {\n color: var(--color-fail-secondary);\n fill: var(--color-fail);\n stroke: var(--color-fail);\n}\n\n.lh-gauge__wrapper--not-applicable {\n color: var(--color-not-applicable);\n fill: var(--color-not-applicable);\n stroke: var(--color-not-applicable);\n}\n\n.lh-fraction__wrapper .lh-fraction__content::before {\n content: '';\n height: var(--score-icon-size);\n width: var(--score-icon-size);\n margin: var(--score-icon-margin);\n display: inline-block;\n}\n.lh-fraction__wrapper--pass .lh-fraction__content {\n color: var(--color-pass-secondary);\n}\n.lh-fraction__wrapper--pass .lh-fraction__background {\n background-color: var(--color-pass);\n}\n.lh-fraction__wrapper--pass .lh-fraction__content::before {\n background-color: var(--color-pass);\n border-radius: 50%;\n}\n.lh-fraction__wrapper--average .lh-fraction__content {\n color: var(--color-average-secondary);\n}\n.lh-fraction__wrapper--average .lh-fraction__background,\n.lh-fraction__wrapper--average .lh-fraction__content::before {\n background-color: var(--color-average);\n}\n.lh-fraction__wrapper--fail .lh-fraction__content {\n color: var(--color-fail);\n}\n.lh-fraction__wrapper--fail .lh-fraction__background {\n background-color: var(--color-fail);\n}\n.lh-fraction__wrapper--fail .lh-fraction__content::before {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n.lh-fraction__wrapper--null .lh-fraction__content {\n color: var(--color-gray-700);\n}\n.lh-fraction__wrapper--null .lh-fraction__background {\n background-color: var(--color-gray-700);\n}\n.lh-fraction__wrapper--null .lh-fraction__content::before {\n border-radius: 50%;\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-700);\n}\n\n.lh-fraction__background {\n position: absolute;\n height: 100%;\n width: 100%;\n border-radius: calc(var(--gauge-circle-size) / 2);\n opacity: 0.1;\n z-index: -1;\n}\n\n.lh-fraction__content-wrapper {\n height: var(--gauge-circle-size);\n display: flex;\n align-items: center;\n}\n\n.lh-fraction__content {\n display: flex;\n position: relative;\n align-items: center;\n justify-content: center;\n font-size: calc(0.3 * var(--gauge-circle-size));\n line-height: calc(0.4 * var(--gauge-circle-size));\n width: max-content;\n min-width: calc(1.5 * var(--gauge-circle-size));\n padding: calc(0.1 * var(--gauge-circle-size)) calc(0.2 * var(--gauge-circle-size));\n --score-icon-size: calc(0.21 * var(--gauge-circle-size));\n --score-icon-margin: 0 calc(0.15 * var(--gauge-circle-size)) 0 0;\n}\n\n.lh-gauge {\n stroke-linecap: round;\n width: var(--gauge-circle-size);\n height: var(--gauge-circle-size);\n}\n\n.lh-category .lh-gauge {\n --gauge-circle-size: var(--gauge-circle-size-big);\n}\n\n.lh-gauge-base {\n opacity: 0.1;\n}\n\n.lh-gauge-arc {\n fill: none;\n transform-origin: 50% 50%;\n animation: load-gauge var(--transition-length) ease forwards;\n animation-delay: 250ms;\n}\n\n.lh-gauge__svg-wrapper {\n position: relative;\n height: var(--gauge-circle-size);\n}\n.lh-category .lh-gauge__svg-wrapper,\n.lh-category .lh-fraction__wrapper {\n --gauge-circle-size: var(--gauge-circle-size-big);\n}\n\n/* The plugin badge overlay */\n.lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {\n width: var(--plugin-badge-size);\n height: var(--plugin-badge-size);\n background-color: var(--plugin-badge-background-color);\n background-image: var(--plugin-icon-url);\n background-repeat: no-repeat;\n background-size: var(--plugin-icon-size);\n background-position: 58% 50%;\n content: \"\";\n position: absolute;\n right: -6px;\n bottom: 0px;\n display: block;\n z-index: 100;\n box-shadow: 0 0 4px rgba(0,0,0,.2);\n border-radius: 25%;\n}\n.lh-category .lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {\n width: var(--plugin-badge-size-big);\n height: var(--plugin-badge-size-big);\n}\n\n@keyframes load-gauge {\n from { stroke-dasharray: 0 352; }\n}\n\n.lh-gauge__percentage {\n width: 100%;\n height: var(--gauge-circle-size);\n position: absolute;\n font-family: var(--report-font-family-monospace);\n font-size: calc(var(--gauge-circle-size) * 0.34 + 1.3px);\n line-height: 0;\n text-align: center;\n top: calc(var(--score-container-padding) + var(--gauge-circle-size) / 2);\n}\n\n.lh-category .lh-gauge__percentage {\n --gauge-circle-size: var(--gauge-circle-size-big);\n --gauge-percentage-font-size: var(--gauge-percentage-font-size-big);\n}\n\n.lh-gauge__wrapper,\n.lh-fraction__wrapper {\n position: relative;\n display: flex;\n align-items: center;\n flex-direction: column;\n text-decoration: none;\n padding: var(--score-container-padding);\n\n --transition-length: 1s;\n\n /* Contain the layout style paint & layers during animation*/\n contain: content;\n will-change: opacity; /* Only using for layer promotion */\n}\n\n.lh-gauge__label,\n.lh-fraction__label {\n font-size: var(--gauge-label-font-size);\n font-weight: 500;\n line-height: var(--gauge-label-line-height);\n margin-top: 10px;\n text-align: center;\n color: var(--report-text-color);\n word-break: keep-all;\n}\n\n/* TODO(#8185) use more BEM (.lh-gauge__label--big) instead of relying on descendant selector */\n.lh-category .lh-gauge__label,\n.lh-category .lh-fraction__label {\n --gauge-label-font-size: var(--gauge-label-font-size-big);\n --gauge-label-line-height: var(--gauge-label-line-height-big);\n margin-top: 14px;\n}\n\n.lh-scores-header .lh-gauge__wrapper,\n.lh-scores-header .lh-fraction__wrapper,\n.lh-scores-header .lh-gauge--pwa__wrapper,\n.lh-sticky-header .lh-gauge__wrapper,\n.lh-sticky-header .lh-fraction__wrapper,\n.lh-sticky-header .lh-gauge--pwa__wrapper {\n width: var(--gauge-wrapper-width);\n}\n\n.lh-scorescale {\n display: inline-flex;\n\n gap: calc(var(--default-padding) * 4);\n margin: 16px auto 0 auto;\n font-size: var(--report-font-size-secondary);\n color: var(--color-gray-700);\n\n}\n\n.lh-scorescale-range {\n display: flex;\n align-items: center;\n font-family: var(--report-font-family-monospace);\n white-space: nowrap;\n}\n\n.lh-category-header__finalscreenshot .lh-scorescale {\n border: 0;\n display: flex;\n justify-content: center;\n}\n\n.lh-category-header__finalscreenshot .lh-scorescale-range {\n font-family: unset;\n font-size: 12px;\n}\n\n.lh-scorescale-wrap {\n display: contents;\n}\n\n/* Hide category score gauages if it's a single category report */\n.lh-header--solo-category .lh-scores-wrapper {\n display: none;\n}\n\n\n.lh-categories {\n width: 100%;\n overflow: hidden;\n}\n\n.lh-category {\n padding: var(--category-padding);\n max-width: var(--report-content-max-width);\n margin: 0 auto;\n\n --sticky-header-height: calc(var(--gauge-circle-size-sm) + var(--score-container-padding) * 2);\n --topbar-plus-sticky-header: calc(var(--topbar-height) + var(--sticky-header-height));\n scroll-margin-top: var(--topbar-plus-sticky-header);\n\n /* Faster recalc style & layout of the report. https://web.dev/content-visibility/ */\n content-visibility: auto;\n contain-intrinsic-size: 1000px;\n}\n\n.lh-category-wrapper {\n border-bottom: 1px solid var(--color-gray-200);\n}\n.lh-category-wrapper:last-of-type {\n border-bottom: 0;\n}\n\n.lh-category-header {\n margin-bottom: var(--section-padding-vertical);\n}\n\n.lh-category-header .lh-score__gauge {\n max-width: 400px;\n width: auto;\n margin: 0px auto;\n}\n\n.lh-category-header__finalscreenshot {\n display: grid;\n grid-template: none / 1fr 1px 1fr;\n justify-items: center;\n align-items: center;\n gap: var(--report-line-height);\n min-height: 288px;\n margin-bottom: var(--default-padding);\n}\n\n.lh-final-ss-image {\n /* constrain the size of the image to not be too large */\n max-height: calc(var(--gauge-circle-size-big) * 2.8);\n max-width: calc(var(--gauge-circle-size-big) * 3.5);\n border: 1px solid var(--color-gray-200);\n padding: 4px;\n border-radius: 3px;\n display: block;\n}\n\n.lh-category-headercol--separator {\n background: var(--color-gray-200);\n width: 1px;\n height: var(--gauge-circle-size-big);\n}\n\n@media screen and (max-width: 780px) {\n .lh-category-header__finalscreenshot {\n grid-template: 1fr 1fr / none\n }\n .lh-category-headercol--separator {\n display: none;\n }\n}\n\n\n/* 964 fits the min-width of the filmstrip */\n@media screen and (max-width: 964px) {\n .lh-report {\n margin-left: 0;\n width: 100%;\n }\n}\n\n@media print {\n body {\n -webkit-print-color-adjust: exact; /* print background colors */\n }\n .lh-container {\n display: block;\n }\n .lh-report {\n margin-left: 0;\n padding-top: 0;\n }\n .lh-categories {\n margin-top: 0;\n }\n}\n\n.lh-table {\n border-collapse: collapse;\n /* Can't assign padding to table, so shorten the width instead. */\n width: calc(100% - var(--audit-description-padding-left) - var(--stackpack-padding-horizontal));\n border: 1px solid var(--report-border-color-secondary);\n\n}\n\n.lh-table thead th {\n font-weight: normal;\n color: var(--color-gray-600);\n /* See text-wrapping comment on .lh-container. */\n word-break: normal;\n}\n\n.lh-row--even {\n background-color: var(--table-higlight-background-color);\n}\n.lh-row--hidden {\n display: none;\n}\n\n.lh-table th,\n.lh-table td {\n padding: var(--default-padding);\n}\n\n.lh-table tr {\n vertical-align: middle;\n}\n\n/* Looks unnecessary, but mostly for keeping the <th>s left-aligned */\n.lh-table-column--text,\n.lh-table-column--source-location,\n.lh-table-column--url,\n/* .lh-table-column--thumbnail, */\n/* .lh-table-column--empty,*/\n.lh-table-column--code,\n.lh-table-column--node {\n text-align: left;\n}\n\n.lh-table-column--code {\n min-width: 100px;\n}\n\n.lh-table-column--bytes,\n.lh-table-column--timespanMs,\n.lh-table-column--ms,\n.lh-table-column--numeric {\n text-align: right;\n word-break: normal;\n}\n\n\n\n.lh-table .lh-table-column--thumbnail {\n width: var(--image-preview-size);\n}\n\n.lh-table-column--url {\n min-width: 250px;\n}\n\n.lh-table-column--text {\n min-width: 80px;\n}\n\n/* Keep columns narrow if they follow the URL column */\n/* 12% was determined to be a decent narrow width, but wide enough for column headings */\n.lh-table-column--url + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--ms,\n.lh-table-column--url + .lh-table-column--ms + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--timespanMs {\n width: 12%;\n}\n\n.lh-text__url-host {\n display: inline;\n}\n\n.lh-text__url-host {\n margin-left: calc(var(--report-font-size) / 2);\n opacity: 0.6;\n font-size: 90%\n}\n\n.lh-thumbnail {\n object-fit: cover;\n width: var(--image-preview-size);\n height: var(--image-preview-size);\n display: block;\n}\n\n.lh-unknown pre {\n overflow: scroll;\n border: solid 1px var(--color-gray-200);\n}\n\n.lh-text__url > a {\n color: inherit;\n text-decoration: none;\n}\n\n.lh-text__url > a:hover {\n text-decoration: underline dotted #999;\n}\n\n.lh-sub-item-row {\n margin-left: 20px;\n margin-bottom: 0;\n color: var(--color-gray-700);\n}\n.lh-sub-item-row td {\n padding-top: 4px;\n padding-bottom: 4px;\n padding-left: 20px;\n}\n\n/* Chevron\n https://codepen.io/paulirish/pen/LmzEmK\n */\n.lh-chevron {\n --chevron-angle: 42deg;\n /* Edge doesn't support transform: rotate(calc(...)), so we define it here */\n --chevron-angle-right: -42deg;\n width: var(--chevron-size);\n height: var(--chevron-size);\n margin-top: calc((var(--report-line-height) - 12px) / 2);\n}\n\n.lh-chevron__lines {\n transition: transform 0.4s;\n transform: translateY(var(--report-line-height));\n}\n.lh-chevron__line {\n stroke: var(--chevron-line-stroke);\n stroke-width: var(--chevron-size);\n stroke-linecap: square;\n transform-origin: 50%;\n transform: rotate(var(--chevron-angle));\n transition: transform 300ms, stroke 300ms;\n}\n\n.lh-expandable-details .lh-chevron__line-right,\n.lh-expandable-details[open] .lh-chevron__line-left {\n transform: rotate(var(--chevron-angle-right));\n}\n\n.lh-expandable-details[open] .lh-chevron__line-right {\n transform: rotate(var(--chevron-angle));\n}\n\n\n.lh-expandable-details[open] .lh-chevron__lines {\n transform: translateY(calc(var(--chevron-size) * -1));\n}\n\n.lh-expandable-details[open] {\n animation: 300ms openDetails forwards;\n padding-bottom: var(--default-padding);\n}\n\n@keyframes openDetails {\n from {\n outline: 1px solid var(--report-background-color);\n }\n to {\n outline: 1px solid;\n box-shadow: 0 2px 4px rgba(0, 0, 0, .24);\n }\n}\n\n@media screen and (max-width: 780px) {\n /* no black outline if we're not confident the entire table can be displayed within bounds */\n .lh-expandable-details[open] {\n animation: none;\n }\n}\n\n.lh-expandable-details[open] summary, details.lh-clump > summary {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\ndetails.lh-clump[open] > summary {\n border-bottom-width: 0;\n}\n\n\n\ndetails .lh-clump-toggletext--hide,\ndetails[open] .lh-clump-toggletext--show { display: none; }\ndetails[open] .lh-clump-toggletext--hide { display: block;}\n\n\n/* Tooltip */\n.lh-tooltip-boundary {\n position: relative;\n}\n\n.lh-tooltip {\n position: absolute;\n display: none; /* Don't retain these layers when not needed */\n opacity: 0;\n background: #ffffff;\n white-space: pre-line; /* Render newlines in the text */\n min-width: 246px;\n max-width: 275px;\n padding: 15px;\n border-radius: 5px;\n text-align: initial;\n line-height: 1.4;\n}\n/* shrink tooltips to not be cutoff on left edge of narrow viewports\n 45vw is chosen to be ~= width of the left column of metrics\n*/\n@media screen and (max-width: 535px) {\n .lh-tooltip {\n min-width: 45vw;\n padding: 3vw;\n }\n}\n\n.lh-tooltip-boundary:hover .lh-tooltip {\n display: block;\n animation: fadeInTooltip 250ms;\n animation-fill-mode: forwards;\n animation-delay: 850ms;\n bottom: 100%;\n z-index: 1;\n will-change: opacity;\n right: 0;\n pointer-events: none;\n}\n\n.lh-tooltip::before {\n content: \"\";\n border: solid transparent;\n border-bottom-color: #fff;\n border-width: 10px;\n position: absolute;\n bottom: -20px;\n right: 6px;\n transform: rotate(180deg);\n pointer-events: none;\n}\n\n@keyframes fadeInTooltip {\n 0% { opacity: 0; }\n 75% { opacity: 1; }\n 100% { opacity: 1; filter: drop-shadow(1px 0px 1px #aaa) drop-shadow(0px 2px 4px hsla(206, 6%, 25%, 0.15)); pointer-events: auto; }\n}\n\n/* Element screenshot */\n.lh-element-screenshot {\n float: left;\n margin-right: 20px;\n}\n.lh-element-screenshot__content {\n overflow: hidden;\n min-width: 110px;\n display: flex;\n justify-content: center;\n background-color: var(--report-background-color);\n}\n.lh-element-screenshot__image {\n position: relative;\n /* Set by ElementScreenshotRenderer.installFullPageScreenshotCssVariable */\n background-image: var(--element-screenshot-url);\n outline: 2px solid #777;\n background-color: white;\n background-repeat: no-repeat;\n}\n.lh-element-screenshot__mask {\n position: absolute;\n background: #555;\n opacity: 0.8;\n}\n.lh-element-screenshot__element-marker {\n position: absolute;\n outline: 2px solid var(--color-lime-400);\n}\n.lh-element-screenshot__overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 2000; /* .lh-topbar is 1000 */\n background: var(--screenshot-overlay-background);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: zoom-out;\n}\n\n.lh-element-screenshot__overlay .lh-element-screenshot {\n margin-right: 0; /* clearing margin used in thumbnail case */\n outline: 1px solid var(--color-gray-700);\n}\n\n.lh-screenshot-overlay--enabled .lh-element-screenshot {\n cursor: zoom-out;\n}\n.lh-screenshot-overlay--enabled .lh-node .lh-element-screenshot {\n cursor: zoom-in;\n}\n\n\n.lh-meta__items {\n --meta-icon-size: calc(var(--report-icon-size) * 0.667);\n padding: var(--default-padding);\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n background-color: var(--env-item-background-color);\n border-radius: 3px;\n margin: 0 0 var(--default-padding) 0;\n font-size: 12px;\n column-gap: var(--default-padding);\n color: var(--color-gray-700);\n}\n\n.lh-meta__item {\n display: block;\n list-style-type: none;\n position: relative;\n padding: 0 0 0 calc(var(--meta-icon-size) + var(--default-padding) * 2);\n cursor: unset; /* disable pointer cursor from report-icon */\n}\n\n.lh-meta__item.lh-tooltip-boundary {\n text-decoration: dotted underline var(--color-gray-500);\n cursor: help;\n}\n\n.lh-meta__item.lh-report-icon::before {\n position: absolute;\n left: var(--default-padding);\n width: var(--meta-icon-size);\n height: var(--meta-icon-size);\n}\n\n.lh-meta__item.lh-report-icon:hover::before {\n opacity: 0.7;\n}\n\n.lh-meta__item .lh-tooltip {\n color: var(--color-gray-800);\n}\n\n.lh-meta__item .lh-tooltip::before {\n right: auto; /* Set the tooltip arrow to the leftside */\n left: 6px;\n}\n\n/* Change the grid for narrow viewport. */\n@media screen and (max-width: 640px) {\n .lh-meta__items {\n grid-template-columns: 1fr 1fr;\n }\n}\n@media screen and (max-width: 535px) {\n .lh-meta__items {\n display: block;\n }\n}\n\n\n/*# sourceURL=report-styles.css */\n");
1221
+ const el1 = dom.createElement('style');
1222
+ el1.append('/**\n * @license\n * Copyright 2017 The Lighthouse Authors. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS-IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n Naming convention:\n\n If a variable is used for a specific component: --{component}-{property name}-{modifier}\n\n Both {component} and {property name} should be kebab-case. If the target is the entire page,\n use \'report\' for the component. The property name should not be abbreviated. Use the\n property name the variable is intended for - if it\'s used for multiple, a common descriptor\n is fine (ex: \'size\' for a variable applied to \'width\' and \'height\'). If a variable is shared\n across multiple components, either create more variables or just drop the "{component}-"\n part of the name. Append any modifiers at the end (ex: \'big\', \'dark\').\n\n For colors: --color-{hue}-{intensity}\n\n {intensity} is the Material Design tag - 700, A700, etc.\n*/\n.lh-vars {\n /* Palette using Material Design Colors\n * https://www.materialui.co/colors */\n --color-amber-50: #FFF8E1;\n --color-blue-200: #90CAF9;\n --color-blue-900: #0D47A1;\n --color-blue-A700: #2962FF;\n --color-blue-primary: #06f;\n --color-cyan-500: #00BCD4;\n --color-gray-100: #F5F5F5;\n --color-gray-300: #CFCFCF;\n --color-gray-200: #E0E0E0;\n --color-gray-400: #BDBDBD;\n --color-gray-50: #FAFAFA;\n --color-gray-500: #9E9E9E;\n --color-gray-600: #757575;\n --color-gray-700: #616161;\n --color-gray-800: #424242;\n --color-gray-900: #212121;\n --color-gray: #000000;\n --color-green-700: #080;\n --color-green: #0c6;\n --color-lime-400: #D3E156;\n --color-orange-50: #FFF3E0;\n --color-orange-700: #C33300;\n --color-orange: #fa3;\n --color-red-700: #c00;\n --color-red: #f33;\n --color-teal-600: #00897B;\n --color-white: #FFFFFF;\n\n /* Context-specific colors */\n --color-average-secondary: var(--color-orange-700);\n --color-average: var(--color-orange);\n --color-fail-secondary: var(--color-red-700);\n --color-fail: var(--color-red);\n --color-hover: var(--color-gray-50);\n --color-informative: var(--color-blue-900);\n --color-pass-secondary: var(--color-green-700);\n --color-pass: var(--color-green);\n --color-not-applicable: var(--color-gray-600);\n\n /* Component variables */\n --audit-description-padding-left: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right));\n --audit-explanation-line-height: 16px;\n --audit-group-margin-bottom: calc(var(--default-padding) * 6);\n --audit-group-padding-vertical: 8px;\n --audit-margin-horizontal: 5px;\n --audit-padding-vertical: 8px;\n --category-padding: calc(var(--default-padding) * 6) var(--edge-gap-padding) calc(var(--default-padding) * 4);\n --chevron-line-stroke: var(--color-gray-600);\n --chevron-size: 12px;\n --default-padding: 8px;\n --edge-gap-padding: calc(var(--default-padding) * 4);\n --env-item-background-color: var(--color-gray-100);\n --env-item-font-size: 28px;\n --env-item-line-height: 36px;\n --env-item-padding: 10px 0px;\n --env-name-min-width: 220px;\n --footer-padding-vertical: 16px;\n --gauge-circle-size-big: 96px;\n --gauge-circle-size: 48px;\n --gauge-circle-size-sm: 32px;\n --gauge-label-font-size-big: 18px;\n --gauge-label-font-size: var(--report-font-size-secondary);\n --gauge-label-line-height-big: 24px;\n --gauge-label-line-height: var(--report-line-height-secondary);\n --gauge-percentage-font-size-big: 38px;\n --gauge-percentage-font-size: var(--report-font-size-secondary);\n --gauge-wrapper-width: 120px;\n --header-line-height: 24px;\n --highlighter-background-color: var(--report-text-color);\n --icon-square-size: calc(var(--score-icon-size) * 0.88);\n --image-preview-size: 48px;\n --link-color: var(--color-blue-primary);\n --locale-selector-background-color: var(--color-white);\n --metric-toggle-lines-fill: #7F7F7F;\n --metric-value-font-size: calc(var(--report-font-size) * 1.8);\n --metrics-toggle-background-color: var(--color-gray-200);\n --plugin-badge-background-color: var(--color-white);\n --plugin-badge-size-big: calc(var(--gauge-circle-size-big) / 2.7);\n --plugin-badge-size: calc(var(--gauge-circle-size) / 2.7);\n --plugin-icon-size: 65%;\n --pwa-icon-margin: 0 var(--default-padding);\n --pwa-icon-size: var(--topbar-logo-size);\n --report-background-color: #fff;\n --report-border-color-secondary: #ebebeb;\n --report-font-family-monospace: \'Roboto Mono\', \'Menlo\', \'dejavu sans mono\', \'Consolas\', \'Lucida Console\', monospace;\n --report-font-family: Roboto, Helvetica, Arial, sans-serif;\n --report-font-size: 14px;\n --report-font-size-secondary: 12px;\n --report-icon-size: var(--score-icon-background-size);\n --report-line-height: 24px;\n --report-line-height-secondary: 20px;\n --report-monospace-font-size: calc(var(--report-font-size) * 0.85);\n --report-text-color-secondary: var(--color-gray-800);\n --report-text-color: var(--color-gray-900);\n --report-content-max-width: calc(60 * var(--report-font-size)); /* defaults to 840px */\n --report-content-min-width: 360px;\n --report-content-max-width-minus-edge-gap: calc(var(--report-content-max-width) - var(--edge-gap-padding) * 2);\n --score-container-padding: 8px;\n --score-icon-background-size: 24px;\n --score-icon-margin-left: 6px;\n --score-icon-margin-right: 14px;\n --score-icon-margin: 0 var(--score-icon-margin-right) 0 var(--score-icon-margin-left);\n --score-icon-size: 12px;\n --score-icon-size-big: 16px;\n --screenshot-overlay-background: rgba(0, 0, 0, 0.3);\n --section-padding-vertical: calc(var(--default-padding) * 6);\n --snippet-background-color: var(--color-gray-50);\n --snippet-color: #0938C2;\n --sparkline-height: 5px;\n --stackpack-padding-horizontal: 10px;\n --sticky-header-background-color: var(--report-background-color);\n --table-higlight-background-color: hsla(210, 17%, 77%, 0.1);\n --tools-icon-color: var(--color-gray-600);\n --topbar-background-color: var(--color-white);\n --topbar-height: 32px;\n --topbar-logo-size: 24px;\n --topbar-padding: 0 8px;\n --toplevel-warning-background-color: hsla(30, 100%, 75%, 10%);\n --toplevel-warning-message-text-color: var(--color-average-secondary);\n --toplevel-warning-padding: 18px;\n --toplevel-warning-text-color: var(--report-text-color);\n\n /* SVGs */\n --plugin-icon-url-dark: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="%23FFFFFF"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/></svg>\');\n --plugin-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="%23757575"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/></svg>\');\n\n --pass-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>check</title><path fill="%23178239" d="M24 4C12.95 4 4 12.95 4 24c0 11.04 8.95 20 20 20 11.04 0 20-8.96 20-20 0-11.05-8.96-20-20-20zm-4 30L10 24l2.83-2.83L20 28.34l15.17-15.17L38 16 20 34z"/></svg>\');\n --average-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>info</title><path fill="%23E67700" d="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm2 30h-4V22h4v12zm0-16h-4v-4h4v4z"/></svg>\');\n --fail-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><title>warn</title><path fill="%23C7221F" d="M2 42h44L24 4 2 42zm24-6h-4v-4h4v4zm0-8h-4v-8h4v8z"/></svg>\');\n\n --pwa-installable-gray-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><circle fill="%23DAE0E3" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>\');\n --pwa-optimized-gray-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%23DAE0E3" width="24" height="24" rx="12"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/><path d="M5 5h14v14H5z"/></g></svg>\');\n\n --pwa-installable-gray-url-dark: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><circle fill="%23424242" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>\');\n --pwa-optimized-gray-url-dark: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%23424242" width="24" height="24" rx="12"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/><path d="M5 5h14v14H5z"/></g></svg>\');\n\n --pwa-installable-color-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><circle fill="%230CCE6B" cx="12" cy="12" r="12"/><path d="M12 5a7 7 0 1 0 0 14 7 7 0 0 0 0-14zm3.5 7.7h-2.8v2.8h-1.4v-2.8H8.5v-1.4h2.8V8.5h1.4v2.8h2.8v1.4z" fill="%23FFF"/></g></svg>\');\n --pwa-optimized-color-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><rect fill="%230CCE6B" width="24" height="24" rx="12"/><path d="M5 5h14v14H5z"/><path fill="%23FFF" d="M12 15.07l3.6 2.18-.95-4.1 3.18-2.76-4.2-.36L12 6.17l-1.64 3.86-4.2.36 3.2 2.76-.96 4.1z"/></g></svg>\');\n\n --swap-locale-icon-url: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"/></svg>\');\n}\n\n@media not print {\n .lh-dark {\n /* Pallete */\n --color-gray-200: var(--color-gray-800);\n --color-gray-300: #616161;\n --color-gray-400: var(--color-gray-600);\n --color-gray-700: var(--color-gray-400);\n --color-gray-50: #757575;\n --color-gray-600: var(--color-gray-500);\n --color-green-700: var(--color-green);\n --color-orange-700: var(--color-orange);\n --color-red-700: var(--color-red);\n --color-teal-600: var(--color-cyan-500);\n\n /* Context-specific colors */\n --color-hover: rgba(0, 0, 0, 0.2);\n --color-informative: var(--color-blue-200);\n\n /* Component variables */\n --env-item-background-color: #393535;\n --link-color: var(--color-blue-200);\n --locale-selector-background-color: var(--color-gray-200);\n --plugin-badge-background-color: var(--color-gray-800);\n --report-background-color: var(--color-gray-900);\n --report-border-color-secondary: var(--color-gray-200);\n --report-text-color-secondary: var(--color-gray-400);\n --report-text-color: var(--color-gray-100);\n --snippet-color: var(--color-cyan-500);\n --topbar-background-color: var(--color-gray);\n --toplevel-warning-background-color: hsl(33deg 14% 18%);\n --toplevel-warning-message-text-color: var(--color-orange-700);\n --toplevel-warning-text-color: var(--color-gray-100);\n\n /* SVGs */\n --plugin-icon-url: var(--plugin-icon-url-dark);\n --pwa-installable-gray-url: var(--pwa-installable-gray-url-dark);\n --pwa-optimized-gray-url: var(--pwa-optimized-gray-url-dark);\n }\n}\n\n@media only screen and (max-width: 480px) {\n .lh-vars {\n --audit-group-margin-bottom: 20px;\n --edge-gap-padding: var(--default-padding);\n --env-name-min-width: 120px;\n --gauge-circle-size-big: 96px;\n --gauge-circle-size: 72px;\n --gauge-label-font-size-big: 22px;\n --gauge-label-font-size: 14px;\n --gauge-label-line-height-big: 26px;\n --gauge-label-line-height: 20px;\n --gauge-percentage-font-size-big: 34px;\n --gauge-percentage-font-size: 26px;\n --gauge-wrapper-width: 112px;\n --header-padding: 16px 0 16px 0;\n --image-preview-size: 24px;\n --plugin-icon-size: 75%;\n --pwa-icon-margin: 0 7px 0 -3px;\n --report-font-size: 14px;\n --report-line-height: 20px;\n --score-icon-margin-left: 2px;\n --score-icon-size: 10px;\n --topbar-height: 28px;\n --topbar-logo-size: 20px;\n }\n\n /* Not enough space to adequately show the relative savings bars. */\n .lh-sparkline {\n display: none;\n }\n}\n\n.lh-vars.lh-devtools {\n --audit-explanation-line-height: 14px;\n --audit-group-margin-bottom: 20px;\n --audit-group-padding-vertical: 12px;\n --audit-padding-vertical: 4px;\n --category-padding: 12px;\n --default-padding: 12px;\n --env-name-min-width: 120px;\n --footer-padding-vertical: 8px;\n --gauge-circle-size-big: 72px;\n --gauge-circle-size: 64px;\n --gauge-label-font-size-big: 22px;\n --gauge-label-font-size: 14px;\n --gauge-label-line-height-big: 26px;\n --gauge-label-line-height: 20px;\n --gauge-percentage-font-size-big: 34px;\n --gauge-percentage-font-size: 26px;\n --gauge-wrapper-width: 97px;\n --header-line-height: 20px;\n --header-padding: 16px 0 16px 0;\n --screenshot-overlay-background: transparent;\n --plugin-icon-size: 75%;\n --pwa-icon-margin: 0 7px 0 -3px;\n --report-font-family-monospace: \'Menlo\', \'dejavu sans mono\', \'Consolas\', \'Lucida Console\', monospace;\n --report-font-family: \'.SFNSDisplay-Regular\', \'Helvetica Neue\', \'Lucida Grande\', sans-serif;\n --report-font-size: 12px;\n --report-line-height: 20px;\n --score-icon-margin-left: 2px;\n --score-icon-size: 10px;\n --section-padding-vertical: 8px;\n}\n\n.lh-devtools.lh-root {\n height: 100%;\n}\n.lh-devtools.lh-root img {\n /* Override devtools default \'min-width: 0\' so svg without size in a flexbox isn\'t collapsed. */\n min-width: auto;\n}\n.lh-devtools .lh-container {\n overflow-y: scroll;\n height: calc(100% - var(--topbar-height));\n}\n@media print {\n .lh-devtools .lh-container {\n overflow: unset;\n }\n}\n.lh-devtools .lh-sticky-header {\n /* This is normally the height of the topbar, but we want it to stick to the top of our scroll container .lh-container` */\n top: 0;\n}\n.lh-devtools .lh-element-screenshot__overlay {\n position: absolute;\n}\n\n@keyframes fadeIn {\n 0% { opacity: 0;}\n 100% { opacity: 0.6;}\n}\n\n.lh-root *, .lh-root *::before, .lh-root *::after {\n box-sizing: border-box;\n}\n\n.lh-root {\n font-family: var(--report-font-family);\n font-size: var(--report-font-size);\n margin: 0;\n line-height: var(--report-line-height);\n background: var(--report-background-color);\n color: var(--report-text-color);\n}\n\n.lh-root :focus {\n outline: -webkit-focus-ring-color auto 3px;\n}\n.lh-root summary:focus {\n outline: none;\n box-shadow: 0 0 0 1px hsl(217, 89%, 61%);\n}\n\n.lh-root [hidden] {\n display: none !important;\n}\n\n.lh-root pre {\n margin: 0;\n}\n\n.lh-root details > summary {\n cursor: pointer;\n}\n\n.lh-hidden {\n display: none !important;\n}\n\n.lh-container {\n /*\n Text wrapping in the report is so much FUN!\n We have a `word-break: break-word;` globally here to prevent a few common scenarios, namely\n long non-breakable text (usually URLs) found in:\n 1. The footer\n 2. .lh-node (outerHTML)\n 3. .lh-code\n\n With that sorted, the next challenge is appropriate column sizing and text wrapping inside our\n .lh-details tables. Even more fun.\n * We don\'t want table headers ("Potential Savings (ms)") to wrap or their column values, but\n we\'d be happy for the URL column to wrap if the URLs are particularly long.\n * We want the narrow columns to remain narrow, providing the most column width for URL\n * We don\'t want the table to extend past 100% width.\n * Long URLs in the URL column can wrap. Util.getURLDisplayName maxes them out at 64 characters,\n but they do not get any overflow:ellipsis treatment.\n */\n word-break: break-word;\n}\n\n.lh-audit-group a,\n.lh-category-header__description a,\n.lh-audit__description a,\n.lh-warnings a,\n.lh-footer a,\n.lh-table-column--link a {\n color: var(--link-color);\n}\n\n.lh-audit__description, .lh-audit__stackpack {\n --inner-audit-padding-right: var(--stackpack-padding-horizontal);\n padding-left: var(--audit-description-padding-left);\n padding-right: var(--inner-audit-padding-right);\n padding-top: 8px;\n padding-bottom: 8px;\n}\n\n.lh-details {\n margin-top: var(--default-padding);\n margin-bottom: var(--default-padding);\n margin-left: var(--audit-description-padding-left);\n /* whatever the .lh-details side margins are */\n width: 100%;\n}\n\n.lh-audit__stackpack {\n display: flex;\n align-items: center;\n}\n\n.lh-audit__stackpack__img {\n max-width: 30px;\n margin-right: var(--default-padding)\n}\n\n/* Report header */\n\n.lh-report-icon {\n display: flex;\n align-items: center;\n padding: 10px 12px;\n cursor: pointer;\n}\n.lh-report-icon[disabled] {\n opacity: 0.3;\n pointer-events: none;\n}\n\n.lh-report-icon::before {\n content: "";\n margin: 4px;\n background-repeat: no-repeat;\n width: var(--report-icon-size);\n height: var(--report-icon-size);\n opacity: 0.7;\n display: inline-block;\n vertical-align: middle;\n}\n.lh-report-icon:hover::before {\n opacity: 1;\n}\n.lh-dark .lh-report-icon::before {\n filter: invert(1);\n}\n.lh-report-icon--print::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/><path fill="none" d="M0 0h24v24H0z"/></svg>\');\n}\n.lh-report-icon--copy::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>\');\n}\n.lh-report-icon--open::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h4v-2H5V8h14v10h-4v2h4c1.1 0 2-.9 2-2V6c0-1.1-.89-2-2-2zm-7 6l-4 4h3v6h2v-6h3l-4-4z"/></svg>\');\n}\n.lh-report-icon--download::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>\');\n}\n.lh-report-icon--dark::before {\n background-image:url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 100 125"><path d="M50 23.587c-16.27 0-22.799 12.574-22.799 21.417 0 12.917 10.117 22.451 12.436 32.471h20.726c2.32-10.02 12.436-19.554 12.436-32.471 0-8.843-6.528-21.417-22.799-21.417zM39.637 87.161c0 3.001 1.18 4.181 4.181 4.181h.426l.41 1.231C45.278 94.449 46.042 95 48.019 95h3.963c1.978 0 2.74-.551 3.365-2.427l.409-1.231h.427c3.002 0 4.18-1.18 4.18-4.181V80.91H39.637v6.251zM50 18.265c1.26 0 2.072-.814 2.072-2.073v-9.12C52.072 5.813 51.26 5 50 5c-1.259 0-2.072.813-2.072 2.073v9.12c0 1.259.813 2.072 2.072 2.072zM68.313 23.727c.994.774 2.135.634 2.91-.357l5.614-7.187c.776-.992.636-2.135-.356-2.909-.992-.776-2.135-.636-2.91.357l-5.613 7.186c-.778.993-.636 2.135.355 2.91zM91.157 36.373c-.306-1.222-1.291-1.815-2.513-1.51l-8.85 2.207c-1.222.305-1.814 1.29-1.51 2.512.305 1.223 1.291 1.814 2.513 1.51l8.849-2.206c1.223-.305 1.816-1.291 1.511-2.513zM86.757 60.48l-8.331-3.709c-1.15-.512-2.225-.099-2.736 1.052-.512 1.151-.1 2.224 1.051 2.737l8.33 3.707c1.15.514 2.225.101 2.736-1.05.513-1.149.1-2.223-1.05-2.737zM28.779 23.37c.775.992 1.917 1.131 2.909.357.992-.776 1.132-1.917.357-2.91l-5.615-7.186c-.775-.992-1.917-1.132-2.909-.357s-1.131 1.917-.356 2.909l5.614 7.187zM21.715 39.583c.305-1.223-.288-2.208-1.51-2.513l-8.849-2.207c-1.222-.303-2.208.289-2.513 1.511-.303 1.222.288 2.207 1.511 2.512l8.848 2.206c1.222.304 2.208-.287 2.513-1.509zM21.575 56.771l-8.331 3.711c-1.151.511-1.563 1.586-1.05 2.735.511 1.151 1.586 1.563 2.736 1.052l8.331-3.711c1.151-.511 1.563-1.586 1.05-2.735-.512-1.15-1.585-1.562-2.736-1.052z"/></svg>\');\n}\n.lh-report-icon--treemap::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="black"><path d="M3 5v14h19V5H3zm2 2h15v4H5V7zm0 10v-4h4v4H5zm6 0v-4h9v4h-9z"/></svg>\');\n}\n.lh-report-icon--date::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 11h2v2H7v-2zm14-5v14a2 2 0 01-2 2H5a2 2 0 01-2-2V6c0-1.1.9-2 2-2h1V2h2v2h8V2h2v2h1a2 2 0 012 2zM5 8h14V6H5v2zm14 12V10H5v10h14zm-4-7h2v-2h-2v2zm-4 0h2v-2h-2v2z"/></svg>\');\n}\n.lh-report-icon--devices::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 6h18V4H4a2 2 0 00-2 2v11H0v3h14v-3H4V6zm19 2h-6a1 1 0 00-1 1v10c0 .6.5 1 1 1h6c.6 0 1-.5 1-1V9c0-.6-.5-1-1-1zm-1 9h-4v-7h4v7z"/></svg>\');\n}\n.lh-report-icon--world::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm7 6h-3c-.3-1.3-.8-2.5-1.4-3.6A8 8 0 0 1 18.9 8zm-7-4a14 14 0 0 1 2 4h-4a14 14 0 0 1 2-4zM4.3 14a8.2 8.2 0 0 1 0-4h3.3a16.5 16.5 0 0 0 0 4H4.3zm.8 2h3a14 14 0 0 0 1.3 3.6A8 8 0 0 1 5.1 16zm3-8H5a8 8 0 0 1 4.3-3.6L8 8zM12 20a14 14 0 0 1-2-4h4a14 14 0 0 1-2 4zm2.3-6H9.7a14.7 14.7 0 0 1 0-4h4.6a14.6 14.6 0 0 1 0 4zm.3 5.6c.6-1.2 1-2.4 1.4-3.6h3a8 8 0 0 1-4.4 3.6zm1.8-5.6a16.5 16.5 0 0 0 0-4h3.3a8.2 8.2 0 0 1 0 4h-3.3z"/></svg>\');\n}\n.lh-report-icon--stopwatch::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15 1H9v2h6V1zm-4 13h2V8h-2v6zm8.1-6.6L20.5 6l-1.4-1.4L17.7 6A9 9 0 0 0 3 13a9 9 0 1 0 16-5.6zm-7 12.6a7 7 0 1 1 0-14 7 7 0 0 1 0 14z"/></svg>\');\n}\n.lh-report-icon--networkspeed::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.9 5c-.2 0-.3 0-.4.2v.2L10.1 17a2 2 0 0 0-.2 1 2 2 0 0 0 4 .4l2.4-12.9c0-.3-.2-.5-.5-.5zM1 9l2 2c2.9-2.9 6.8-4 10.5-3.6l1.2-2.7C10 3.8 4.7 5.3 1 9zm20 2 2-2a15.4 15.4 0 0 0-5.6-3.6L17 8.2c1.5.7 2.9 1.6 4.1 2.8zm-4 4 2-2a9.9 9.9 0 0 0-2.7-1.9l-.5 3 1.2.9zM5 13l2 2a7.1 7.1 0 0 1 4-2l1.3-2.9C9.7 10.1 7 11 5 13z"/></svg>\');\n}\n.lh-report-icon--samples-one::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="7" cy="14" r="3"/><path d="M7 18a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5.6 17.6a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></svg>\');\n}\n.lh-report-icon--samples-many::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 18a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-2a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5.6 17.6a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/><circle cx="7" cy="14" r="3"/><circle cx="11" cy="6" r="3"/></svg>\');\n}\n.lh-report-icon--chrome::before {\n background-image: url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -50 562 562"><path d="M256 25.6v25.6a204 204 0 0 1 144.8 60 204 204 0 0 1 60 144.8 204 204 0 0 1-60 144.8 204 204 0 0 1-144.8 60 204 204 0 0 1-144.8-60 204 204 0 0 1-60-144.8 204 204 0 0 1 60-144.8 204 204 0 0 1 144.8-60V0a256 256 0 1 0 0 512 256 256 0 0 0 0-512v25.6z"/><path d="M256 179.2v25.6a51.3 51.3 0 0 1 0 102.4 51.3 51.3 0 0 1 0-102.4v-51.2a102.3 102.3 0 1 0-.1 204.7 102.3 102.3 0 0 0 .1-204.7v25.6z"/><path d="M256 204.8h217.6a25.6 25.6 0 0 0 0-51.2H256a25.6 25.6 0 0 0 0 51.2m44.3 76.8L191.5 470.1a25.6 25.6 0 1 0 44.4 25.6l108.8-188.5a25.6 25.6 0 1 0-44.4-25.6m-88.6 0L102.9 93.2a25.7 25.7 0 0 0-35-9.4 25.7 25.7 0 0 0-9.4 35l108.8 188.5a25.7 25.7 0 0 0 35 9.4 25.9 25.9 0 0 0 9.4-35.1"/></svg>\');\n}\n\n\n\n.lh-buttons {\n display: flex;\n flex-wrap: wrap;\n margin: var(--default-padding) 0;\n}\n.lh-button {\n height: 32px;\n border: 1px solid var(--report-border-color-secondary);\n border-radius: 3px;\n color: var(--link-color);\n background-color: var(--report-background-color);\n margin: 5px;\n}\n\n.lh-button:first-of-type {\n margin-left: 0;\n}\n\n/* Node */\n.lh-node__snippet {\n font-family: var(--report-font-family-monospace);\n color: var(--snippet-color);\n font-size: var(--report-monospace-font-size);\n line-height: 20px;\n}\n\n/* Score */\n\n.lh-audit__score-icon {\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n margin: var(--score-icon-margin);\n}\n\n.lh-audit--pass .lh-audit__display-text {\n color: var(--color-pass-secondary);\n}\n.lh-audit--pass .lh-audit__score-icon,\n.lh-scorescale-range--pass::before {\n border-radius: 100%;\n background: var(--color-pass);\n}\n\n.lh-audit--average .lh-audit__display-text {\n color: var(--color-average-secondary);\n}\n.lh-audit--average .lh-audit__score-icon,\n.lh-scorescale-range--average::before {\n background: var(--color-average);\n width: var(--icon-square-size);\n height: var(--icon-square-size);\n}\n\n.lh-audit--fail .lh-audit__display-text {\n color: var(--color-fail-secondary);\n}\n.lh-audit--fail .lh-audit__score-icon,\n.lh-audit--error .lh-audit__score-icon,\n.lh-scorescale-range--fail::before {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n\n.lh-audit--manual .lh-audit__display-text,\n.lh-audit--notapplicable .lh-audit__display-text {\n color: var(--color-gray-600);\n}\n.lh-audit--manual .lh-audit__score-icon,\n.lh-audit--notapplicable .lh-audit__score-icon {\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-400);\n border-radius: 100%;\n background: none;\n}\n\n.lh-audit--informative .lh-audit__display-text {\n color: var(--color-gray-600);\n}\n\n.lh-audit--informative .lh-audit__score-icon {\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-400);\n border-radius: 100%;\n}\n\n.lh-audit__description,\n.lh-audit__stackpack {\n color: var(--report-text-color-secondary);\n}\n.lh-audit__adorn {\n border: 1px solid slategray;\n border-radius: 3px;\n margin: 0 3px;\n padding: 0 2px;\n line-height: 1.1;\n display: inline-block;\n font-size: 90%;\n}\n\n.lh-category-header__description {\n text-align: center;\n color: var(--color-gray-700);\n margin: 0px auto;\n max-width: 400px;\n}\n\n\n.lh-audit__display-text,\n.lh-load-opportunity__sparkline,\n.lh-chevron-container {\n margin: 0 var(--audit-margin-horizontal);\n}\n.lh-chevron-container {\n margin-right: 0;\n}\n\n.lh-audit__title-and-text {\n flex: 1;\n}\n\n.lh-audit__title-and-text code {\n color: var(--snippet-color);\n font-size: var(--report-monospace-font-size);\n}\n\n/* Prepend display text with em dash separator. But not in Opportunities. */\n.lh-audit__display-text:not(:empty):before {\n content: \'—\';\n margin-right: var(--audit-margin-horizontal);\n}\n.lh-audit-group.lh-audit-group--load-opportunities .lh-audit__display-text:not(:empty):before {\n display: none;\n}\n\n/* Expandable Details (Audit Groups, Audits) */\n.lh-audit__header {\n display: flex;\n align-items: center;\n padding: var(--default-padding);\n}\n\n.lh-audit--load-opportunity .lh-audit__header {\n display: block;\n}\n\n\n.lh-metricfilter {\n display: grid;\n justify-content: end;\n align-items: center;\n grid-auto-flow: column;\n gap: 4px;\n color: var(--color-gray-700);\n}\n\n.lh-metricfilter__radio {\n position: absolute;\n left: -9999px;\n}\n.lh-metricfilter input[type=\'radio\']:focus-visible + label {\n outline: -webkit-focus-ring-color auto 1px;\n}\n\n.lh-metricfilter__label {\n display: inline-flex;\n padding: 0 4px;\n height: 16px;\n text-decoration: underline;\n align-items: center;\n cursor: pointer;\n font-size: 90%;\n}\n\n.lh-metricfilter__label--active {\n background: var(--color-blue-primary);\n color: var(--color-white);\n border-radius: 3px;\n text-decoration: none;\n}\n/* Give the \'All\' choice a more muted display */\n.lh-metricfilter__label--active[for="metric-All"] {\n background-color: var(--color-blue-200) !important;\n color: black !important;\n}\n\n.lh-metricfilter__text {\n margin-right: 8px;\n}\n\n/* If audits are filtered, hide the itemcount for Passed Audits… */\n.lh-category--filtered .lh-audit-group .lh-audit-group__itemcount {\n display: none;\n}\n\n\n.lh-audit__header:hover {\n background-color: var(--color-hover);\n}\n\n/* We want to hide the browser\'s default arrow marker on summary elements. Admittedly, it\'s complicated. */\n.lh-root details > summary {\n /* Blink 89+ and Firefox will hide the arrow when display is changed from (new) default of `list-item` to block. https://chromestatus.com/feature/6730096436051968*/\n display: block;\n}\n/* Safari and Blink <=88 require using the -webkit-details-marker selector */\n.lh-root details > summary::-webkit-details-marker {\n display: none;\n}\n\n/* Perf Metric */\n\n.lh-metrics-container {\n display: grid;\n grid-auto-rows: 1fr;\n grid-template-columns: 1fr 1fr;\n grid-column-gap: var(--report-line-height);\n margin-bottom: var(--default-padding);\n}\n\n.lh-metric {\n border-top: 1px solid var(--report-border-color-secondary);\n}\n\n.lh-metric:nth-last-child(-n+2) {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\n\n\n.lh-metric__innerwrap {\n display: grid;\n /**\n * Icon -- Metric Name\n * -- Metric Value\n */\n grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 1fr;\n align-items: center;\n padding: var(--default-padding);\n}\n\n.lh-metric__details {\n order: -1;\n}\n\n.lh-metric__title {\n flex: 1;\n}\n\n.lh-calclink {\n padding-left: calc(1ex / 3);\n}\n\n.lh-metric__description {\n display: none;\n grid-column-start: 2;\n grid-column-end: 4;\n color: var(--report-text-color-secondary);\n}\n\n.lh-metric__value {\n font-size: var(--metric-value-font-size);\n margin: calc(var(--default-padding) / 2) 0;\n white-space: nowrap; /* No wrapping between metric value and the icon */\n grid-column-start: 2;\n}\n\n\n@media screen and (max-width: 535px) {\n .lh-metrics-container {\n display: block;\n }\n\n .lh-metric {\n border-bottom: none !important;\n }\n .lh-metric:nth-last-child(1) {\n border-bottom: 1px solid var(--report-border-color-secondary) !important;\n }\n\n /* Change the grid to 3 columns for narrow viewport. */\n .lh-metric__innerwrap {\n /**\n * Icon -- Metric Name -- Metric Value\n */\n grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 2fr 1fr;\n }\n .lh-metric__value {\n justify-self: end;\n grid-column-start: unset;\n }\n}\n\n/* No-JS toggle switch */\n/* Keep this selector sync\'d w/ `magicSelector` in report-ui-features-test.js */\n .lh-metrics-toggle__input:checked ~ .lh-metrics-container .lh-metric__description {\n display: block;\n}\n\n/* TODO get rid of the SVGS and clean up these some more */\n.lh-metrics-toggle__input {\n opacity: 0;\n position: absolute;\n right: 0;\n top: 0px;\n}\n\n.lh-metrics-toggle__input + div > label > .lh-metrics-toggle__labeltext--hide,\n.lh-metrics-toggle__input:checked + div > label > .lh-metrics-toggle__labeltext--show {\n display: none;\n}\n.lh-metrics-toggle__input:checked + div > label > .lh-metrics-toggle__labeltext--hide {\n display: inline;\n}\n.lh-metrics-toggle__input:focus + div > label {\n outline: -webkit-focus-ring-color auto 3px;\n}\n\n.lh-metrics-toggle__label {\n cursor: pointer;\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n color: var(--color-gray-700);\n}\n\n/* Pushes the metric description toggle button to the right. */\n.lh-audit-group--metrics .lh-audit-group__header {\n display: flex;\n justify-content: space-between;\n}\n\n.lh-metric__icon,\n.lh-scorescale-range::before {\n content: \'\';\n width: var(--score-icon-size);\n height: var(--score-icon-size);\n display: inline-block;\n margin: var(--score-icon-margin);\n}\n\n.lh-metric--pass .lh-metric__value {\n color: var(--color-pass-secondary);\n}\n.lh-metric--pass .lh-metric__icon {\n border-radius: 100%;\n background: var(--color-pass);\n}\n\n.lh-metric--average .lh-metric__value {\n color: var(--color-average-secondary);\n}\n.lh-metric--average .lh-metric__icon {\n background: var(--color-average);\n width: var(--icon-square-size);\n height: var(--icon-square-size);\n}\n\n.lh-metric--fail .lh-metric__value {\n color: var(--color-fail-secondary);\n}\n.lh-metric--fail .lh-metric__icon,\n.lh-metric--error .lh-metric__icon {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n\n.lh-metric--error .lh-metric__value,\n.lh-metric--error .lh-metric__description {\n color: var(--color-fail-secondary);\n}\n\n/* Perf load opportunity */\n\n.lh-load-opportunity__cols {\n display: flex;\n align-items: flex-start;\n}\n\n.lh-load-opportunity__header .lh-load-opportunity__col {\n color: var(--color-gray-600);\n display: unset;\n line-height: calc(2.3 * var(--report-font-size));\n}\n\n.lh-load-opportunity__col {\n display: flex;\n}\n\n.lh-load-opportunity__col--one {\n flex: 5;\n align-items: center;\n margin-right: 2px;\n}\n.lh-load-opportunity__col--two {\n flex: 4;\n text-align: right;\n}\n\n.lh-audit--load-opportunity .lh-audit__display-text {\n text-align: right;\n flex: 0 0 calc(3 * var(--report-font-size));\n}\n\n\n/* Sparkline */\n\n.lh-load-opportunity__sparkline {\n flex: 1;\n margin-top: calc((var(--report-line-height) - var(--sparkline-height)) / 2);\n}\n\n.lh-sparkline {\n height: var(--sparkline-height);\n width: 100%;\n}\n\n.lh-sparkline__bar {\n height: 100%;\n float: right;\n}\n\n.lh-audit--pass .lh-sparkline__bar {\n background: var(--color-pass);\n}\n\n.lh-audit--average .lh-sparkline__bar {\n background: var(--color-average);\n}\n\n.lh-audit--fail .lh-sparkline__bar {\n background: var(--color-fail);\n}\n\n/* Filmstrip */\n\n.lh-filmstrip-container {\n /* smaller gap between metrics and filmstrip */\n margin: -8px auto 0 auto;\n}\n\n.lh-filmstrip {\n display: grid;\n justify-content: space-between;\n padding-bottom: var(--default-padding);\n width: 100%;\n grid-template-columns: repeat(auto-fit, 60px);\n}\n\n.lh-filmstrip__frame {\n text-align: right;\n position: relative;\n}\n\n.lh-filmstrip__thumbnail {\n border: 1px solid var(--report-border-color-secondary);\n max-height: 100px;\n max-width: 60px;\n}\n\n/* Audit */\n\n.lh-audit {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\n\n/* Apply border-top to just the first audit. */\n.lh-audit {\n border-top: 1px solid var(--report-border-color-secondary);\n}\n.lh-audit ~ .lh-audit {\n border-top: none;\n}\n\n\n.lh-audit--error .lh-audit__display-text {\n color: var(--color-fail-secondary);\n}\n\n/* Audit Group */\n\n.lh-audit-group {\n margin-bottom: var(--audit-group-margin-bottom);\n position: relative;\n}\n.lh-audit-group--metrics {\n margin-bottom: calc(var(--audit-group-margin-bottom) / 2);\n}\n\n.lh-audit-group__header::before {\n /* By default, groups don\'t get an icon */\n content: none;\n width: var(--pwa-icon-size);\n height: var(--pwa-icon-size);\n margin: var(--pwa-icon-margin);\n display: inline-block;\n vertical-align: middle;\n}\n\n/* Style the "over budget" columns red. */\n.lh-audit-group--budgets #performance-budget tbody tr td:nth-child(4),\n.lh-audit-group--budgets #performance-budget tbody tr td:nth-child(5),\n.lh-audit-group--budgets #timing-budget tbody tr td:nth-child(3) {\n color: var(--color-red-700);\n}\n\n/* Align the "over budget request count" text to be close to the "over budget bytes" column. */\n.lh-audit-group--budgets .lh-table tbody tr td:nth-child(4){\n text-align: right;\n}\n\n.lh-audit-group--budgets .lh-details--budget {\n width: 100%;\n margin: 0 0 var(--default-padding);\n}\n\n.lh-audit-group--pwa-installable .lh-audit-group__header::before {\n content: \'\';\n background-image: var(--pwa-installable-gray-url);\n}\n.lh-audit-group--pwa-optimized .lh-audit-group__header::before {\n content: \'\';\n background-image: var(--pwa-optimized-gray-url);\n}\n.lh-audit-group--pwa-installable.lh-badged .lh-audit-group__header::before {\n background-image: var(--pwa-installable-color-url);\n}\n.lh-audit-group--pwa-optimized.lh-badged .lh-audit-group__header::before {\n background-image: var(--pwa-optimized-color-url);\n}\n\n.lh-audit-group--metrics .lh-audit-group__summary {\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.lh-audit-group__summary {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.lh-audit-group__header .lh-chevron {\n margin-top: calc((var(--report-line-height) - 5px) / 2);\n}\n\n.lh-audit-group__header {\n letter-spacing: 0.8px;\n padding: var(--default-padding);\n padding-left: 0;\n}\n\n.lh-audit-group__header, .lh-audit-group__summary {\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n color: var(--color-gray-700);\n}\n\n.lh-audit-group__title {\n text-transform: uppercase;\n font-weight: 500;\n}\n\n.lh-audit-group__itemcount {\n color: var(--color-gray-600);\n}\n\n.lh-audit-group__footer {\n color: var(--color-gray-600);\n display: block;\n margin-top: var(--default-padding);\n}\n\n.lh-details,\n.lh-category-header__description,\n.lh-load-opportunity__header,\n.lh-audit-group__footer {\n font-size: var(--report-font-size-secondary);\n line-height: var(--report-line-height-secondary);\n}\n\n.lh-audit-explanation {\n margin: var(--audit-padding-vertical) 0 calc(var(--audit-padding-vertical) / 2) var(--audit-margin-horizontal);\n line-height: var(--audit-explanation-line-height);\n display: inline-block;\n}\n\n.lh-audit--fail .lh-audit-explanation {\n color: var(--color-fail-secondary);\n}\n\n/* Report */\n.lh-list > :not(:last-child) {\n margin-bottom: calc(var(--default-padding) * 2);\n}\n\n.lh-header-container {\n display: block;\n margin: 0 auto;\n position: relative;\n word-wrap: break-word;\n}\n\n.lh-header-container .lh-scores-wrapper {\n border-bottom: 1px solid var(--color-gray-200);\n}\n\n\n.lh-report {\n min-width: var(--report-content-min-width);\n}\n\n.lh-exception {\n font-size: large;\n}\n\n.lh-code {\n white-space: normal;\n margin-top: 0;\n font-size: var(--report-monospace-font-size);\n}\n\n.lh-warnings {\n --item-margin: calc(var(--report-line-height) / 6);\n color: var(--color-average-secondary);\n margin: var(--audit-padding-vertical) 0;\n padding: var(--default-padding)\n var(--default-padding)\n var(--default-padding)\n calc(var(--audit-description-padding-left));\n background-color: var(--toplevel-warning-background-color);\n}\n.lh-warnings span {\n font-weight: bold;\n}\n\n.lh-warnings--toplevel {\n --item-margin: calc(var(--header-line-height) / 4);\n color: var(--toplevel-warning-text-color);\n margin-left: auto;\n margin-right: auto;\n max-width: var(--report-content-max-width-minus-edge-gap);\n padding: var(--toplevel-warning-padding);\n border-radius: 8px;\n}\n\n.lh-warnings__msg {\n color: var(--toplevel-warning-message-text-color);\n margin: 0;\n}\n\n.lh-warnings ul {\n margin: 0;\n}\n.lh-warnings li {\n margin: var(--item-margin) 0;\n}\n.lh-warnings li:last-of-type {\n margin-bottom: 0;\n}\n\n.lh-scores-header {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n}\n.lh-scores-header__solo {\n padding: 0;\n border: 0;\n}\n\n/* Gauge */\n\n.lh-gauge__wrapper--pass {\n color: var(--color-pass-secondary);\n fill: var(--color-pass);\n stroke: var(--color-pass);\n}\n\n.lh-gauge__wrapper--average {\n color: var(--color-average-secondary);\n fill: var(--color-average);\n stroke: var(--color-average);\n}\n\n.lh-gauge__wrapper--fail {\n color: var(--color-fail-secondary);\n fill: var(--color-fail);\n stroke: var(--color-fail);\n}\n\n.lh-gauge__wrapper--not-applicable {\n color: var(--color-not-applicable);\n fill: var(--color-not-applicable);\n stroke: var(--color-not-applicable);\n}\n\n.lh-fraction__wrapper .lh-fraction__content::before {\n content: \'\';\n height: var(--score-icon-size);\n width: var(--score-icon-size);\n margin: var(--score-icon-margin);\n display: inline-block;\n}\n.lh-fraction__wrapper--pass .lh-fraction__content {\n color: var(--color-pass-secondary);\n}\n.lh-fraction__wrapper--pass .lh-fraction__background {\n background-color: var(--color-pass);\n}\n.lh-fraction__wrapper--pass .lh-fraction__content::before {\n background-color: var(--color-pass);\n border-radius: 50%;\n}\n.lh-fraction__wrapper--average .lh-fraction__content {\n color: var(--color-average-secondary);\n}\n.lh-fraction__wrapper--average .lh-fraction__background,\n.lh-fraction__wrapper--average .lh-fraction__content::before {\n background-color: var(--color-average);\n}\n.lh-fraction__wrapper--fail .lh-fraction__content {\n color: var(--color-fail);\n}\n.lh-fraction__wrapper--fail .lh-fraction__background {\n background-color: var(--color-fail);\n}\n.lh-fraction__wrapper--fail .lh-fraction__content::before {\n border-left: calc(var(--score-icon-size) / 2) solid transparent;\n border-right: calc(var(--score-icon-size) / 2) solid transparent;\n border-bottom: var(--score-icon-size) solid var(--color-fail);\n}\n.lh-fraction__wrapper--null .lh-fraction__content {\n color: var(--color-gray-700);\n}\n.lh-fraction__wrapper--null .lh-fraction__background {\n background-color: var(--color-gray-700);\n}\n.lh-fraction__wrapper--null .lh-fraction__content::before {\n border-radius: 50%;\n border: calc(0.2 * var(--score-icon-size)) solid var(--color-gray-700);\n}\n\n.lh-fraction__background {\n position: absolute;\n height: 100%;\n width: 100%;\n border-radius: calc(var(--gauge-circle-size) / 2);\n opacity: 0.1;\n z-index: -1;\n}\n\n.lh-fraction__content-wrapper {\n height: var(--gauge-circle-size);\n display: flex;\n align-items: center;\n}\n\n.lh-fraction__content {\n display: flex;\n position: relative;\n align-items: center;\n justify-content: center;\n font-size: calc(0.3 * var(--gauge-circle-size));\n line-height: calc(0.4 * var(--gauge-circle-size));\n width: max-content;\n min-width: calc(1.5 * var(--gauge-circle-size));\n padding: calc(0.1 * var(--gauge-circle-size)) calc(0.2 * var(--gauge-circle-size));\n --score-icon-size: calc(0.21 * var(--gauge-circle-size));\n --score-icon-margin: 0 calc(0.15 * var(--gauge-circle-size)) 0 0;\n}\n\n.lh-gauge {\n stroke-linecap: round;\n width: var(--gauge-circle-size);\n height: var(--gauge-circle-size);\n}\n\n.lh-category .lh-gauge {\n --gauge-circle-size: var(--gauge-circle-size-big);\n}\n\n.lh-gauge-base {\n opacity: 0.1;\n}\n\n.lh-gauge-arc {\n fill: none;\n transform-origin: 50% 50%;\n animation: load-gauge var(--transition-length) ease forwards;\n animation-delay: 250ms;\n}\n\n.lh-gauge__svg-wrapper {\n position: relative;\n height: var(--gauge-circle-size);\n}\n.lh-category .lh-gauge__svg-wrapper,\n.lh-category .lh-fraction__wrapper {\n --gauge-circle-size: var(--gauge-circle-size-big);\n}\n\n/* The plugin badge overlay */\n.lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {\n width: var(--plugin-badge-size);\n height: var(--plugin-badge-size);\n background-color: var(--plugin-badge-background-color);\n background-image: var(--plugin-icon-url);\n background-repeat: no-repeat;\n background-size: var(--plugin-icon-size);\n background-position: 58% 50%;\n content: "";\n position: absolute;\n right: -6px;\n bottom: 0px;\n display: block;\n z-index: 100;\n box-shadow: 0 0 4px rgba(0,0,0,.2);\n border-radius: 25%;\n}\n.lh-category .lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {\n width: var(--plugin-badge-size-big);\n height: var(--plugin-badge-size-big);\n}\n\n@keyframes load-gauge {\n from { stroke-dasharray: 0 352; }\n}\n\n.lh-gauge__percentage {\n width: 100%;\n height: var(--gauge-circle-size);\n position: absolute;\n font-family: var(--report-font-family-monospace);\n font-size: calc(var(--gauge-circle-size) * 0.34 + 1.3px);\n line-height: 0;\n text-align: center;\n top: calc(var(--score-container-padding) + var(--gauge-circle-size) / 2);\n}\n\n.lh-category .lh-gauge__percentage {\n --gauge-circle-size: var(--gauge-circle-size-big);\n --gauge-percentage-font-size: var(--gauge-percentage-font-size-big);\n}\n\n.lh-gauge__wrapper,\n.lh-fraction__wrapper {\n position: relative;\n display: flex;\n align-items: center;\n flex-direction: column;\n text-decoration: none;\n padding: var(--score-container-padding);\n\n --transition-length: 1s;\n\n /* Contain the layout style paint & layers during animation*/\n contain: content;\n will-change: opacity; /* Only using for layer promotion */\n}\n\n.lh-gauge__label,\n.lh-fraction__label {\n font-size: var(--gauge-label-font-size);\n font-weight: 500;\n line-height: var(--gauge-label-line-height);\n margin-top: 10px;\n text-align: center;\n color: var(--report-text-color);\n word-break: keep-all;\n}\n\n/* TODO(#8185) use more BEM (.lh-gauge__label--big) instead of relying on descendant selector */\n.lh-category .lh-gauge__label,\n.lh-category .lh-fraction__label {\n --gauge-label-font-size: var(--gauge-label-font-size-big);\n --gauge-label-line-height: var(--gauge-label-line-height-big);\n margin-top: 14px;\n}\n\n.lh-scores-header .lh-gauge__wrapper,\n.lh-scores-header .lh-fraction__wrapper,\n.lh-scores-header .lh-gauge--pwa__wrapper,\n.lh-sticky-header .lh-gauge__wrapper,\n.lh-sticky-header .lh-fraction__wrapper,\n.lh-sticky-header .lh-gauge--pwa__wrapper {\n width: var(--gauge-wrapper-width);\n}\n\n.lh-scorescale {\n display: inline-flex;\n\n gap: calc(var(--default-padding) * 4);\n margin: 16px auto 0 auto;\n font-size: var(--report-font-size-secondary);\n color: var(--color-gray-700);\n\n}\n\n.lh-scorescale-range {\n display: flex;\n align-items: center;\n font-family: var(--report-font-family-monospace);\n white-space: nowrap;\n}\n\n.lh-category-header__finalscreenshot .lh-scorescale {\n border: 0;\n display: flex;\n justify-content: center;\n}\n\n.lh-category-header__finalscreenshot .lh-scorescale-range {\n font-family: unset;\n font-size: 12px;\n}\n\n.lh-scorescale-wrap {\n display: contents;\n}\n\n/* Hide category score gauages if it\'s a single category report */\n.lh-header--solo-category .lh-scores-wrapper {\n display: none;\n}\n\n\n.lh-categories {\n width: 100%;\n overflow: hidden;\n}\n\n.lh-category {\n padding: var(--category-padding);\n max-width: var(--report-content-max-width);\n margin: 0 auto;\n\n --sticky-header-height: calc(var(--gauge-circle-size-sm) + var(--score-container-padding) * 2);\n --topbar-plus-sticky-header: calc(var(--topbar-height) + var(--sticky-header-height));\n scroll-margin-top: var(--topbar-plus-sticky-header);\n\n /* Faster recalc style & layout of the report. https://web.dev/content-visibility/ */\n content-visibility: auto;\n contain-intrinsic-size: 1000px;\n}\n\n.lh-category-wrapper {\n border-bottom: 1px solid var(--color-gray-200);\n}\n\n.lh-category-header {\n margin-bottom: var(--section-padding-vertical);\n}\n\n.lh-category-header .lh-score__gauge {\n max-width: 400px;\n width: auto;\n margin: 0px auto;\n}\n\n.lh-category-header__finalscreenshot {\n display: grid;\n grid-template: none / 1fr 1px 1fr;\n justify-items: center;\n align-items: center;\n gap: var(--report-line-height);\n min-height: 288px;\n margin-bottom: var(--default-padding);\n}\n\n.lh-final-ss-image {\n /* constrain the size of the image to not be too large */\n max-height: calc(var(--gauge-circle-size-big) * 2.8);\n max-width: calc(var(--gauge-circle-size-big) * 3.5);\n border: 1px solid var(--color-gray-200);\n padding: 4px;\n border-radius: 3px;\n display: block;\n}\n\n.lh-category-headercol--separator {\n background: var(--color-gray-200);\n width: 1px;\n height: var(--gauge-circle-size-big);\n}\n\n@media screen and (max-width: 780px) {\n .lh-category-header__finalscreenshot {\n grid-template: 1fr 1fr / none\n }\n .lh-category-headercol--separator {\n display: none;\n }\n}\n\n\n/* 964 fits the min-width of the filmstrip */\n@media screen and (max-width: 964px) {\n .lh-report {\n margin-left: 0;\n width: 100%;\n }\n}\n\n@media print {\n body {\n -webkit-print-color-adjust: exact; /* print background colors */\n }\n .lh-container {\n display: block;\n }\n .lh-report {\n margin-left: 0;\n padding-top: 0;\n }\n .lh-categories {\n margin-top: 0;\n }\n}\n\n.lh-table {\n border-collapse: collapse;\n /* Can\'t assign padding to table, so shorten the width instead. */\n width: calc(100% - var(--audit-description-padding-left) - var(--stackpack-padding-horizontal));\n border: 1px solid var(--report-border-color-secondary);\n\n}\n\n.lh-table thead th {\n font-weight: normal;\n color: var(--color-gray-600);\n /* See text-wrapping comment on .lh-container. */\n word-break: normal;\n}\n\n.lh-row--even {\n background-color: var(--table-higlight-background-color);\n}\n.lh-row--hidden {\n display: none;\n}\n\n.lh-table th,\n.lh-table td {\n padding: var(--default-padding);\n}\n\n.lh-table tr {\n vertical-align: middle;\n}\n\n/* Looks unnecessary, but mostly for keeping the <th>s left-aligned */\n.lh-table-column--text,\n.lh-table-column--source-location,\n.lh-table-column--url,\n/* .lh-table-column--thumbnail, */\n/* .lh-table-column--empty,*/\n.lh-table-column--code,\n.lh-table-column--node {\n text-align: left;\n}\n\n.lh-table-column--code {\n min-width: 100px;\n}\n\n.lh-table-column--bytes,\n.lh-table-column--timespanMs,\n.lh-table-column--ms,\n.lh-table-column--numeric {\n text-align: right;\n word-break: normal;\n}\n\n\n\n.lh-table .lh-table-column--thumbnail {\n width: var(--image-preview-size);\n}\n\n.lh-table-column--url {\n min-width: 250px;\n}\n\n.lh-table-column--text {\n min-width: 80px;\n}\n\n/* Keep columns narrow if they follow the URL column */\n/* 12% was determined to be a decent narrow width, but wide enough for column headings */\n.lh-table-column--url + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--ms,\n.lh-table-column--url + .lh-table-column--ms + th.lh-table-column--bytes,\n.lh-table-column--url + .lh-table-column--bytes + th.lh-table-column--timespanMs {\n width: 12%;\n}\n\n.lh-text__url-host {\n display: inline;\n}\n\n.lh-text__url-host {\n margin-left: calc(var(--report-font-size) / 2);\n opacity: 0.6;\n font-size: 90%\n}\n\n.lh-thumbnail {\n object-fit: cover;\n width: var(--image-preview-size);\n height: var(--image-preview-size);\n display: block;\n}\n\n.lh-unknown pre {\n overflow: scroll;\n border: solid 1px var(--color-gray-200);\n}\n\n.lh-text__url > a {\n color: inherit;\n text-decoration: none;\n}\n\n.lh-text__url > a:hover {\n text-decoration: underline dotted #999;\n}\n\n.lh-sub-item-row {\n margin-left: 20px;\n margin-bottom: 0;\n color: var(--color-gray-700);\n}\n.lh-sub-item-row td {\n padding-top: 4px;\n padding-bottom: 4px;\n padding-left: 20px;\n}\n\n/* Chevron\n https://codepen.io/paulirish/pen/LmzEmK\n */\n.lh-chevron {\n --chevron-angle: 42deg;\n /* Edge doesn\'t support transform: rotate(calc(...)), so we define it here */\n --chevron-angle-right: -42deg;\n width: var(--chevron-size);\n height: var(--chevron-size);\n margin-top: calc((var(--report-line-height) - 12px) / 2);\n}\n\n.lh-chevron__lines {\n transition: transform 0.4s;\n transform: translateY(var(--report-line-height));\n}\n.lh-chevron__line {\n stroke: var(--chevron-line-stroke);\n stroke-width: var(--chevron-size);\n stroke-linecap: square;\n transform-origin: 50%;\n transform: rotate(var(--chevron-angle));\n transition: transform 300ms, stroke 300ms;\n}\n\n.lh-expandable-details .lh-chevron__line-right,\n.lh-expandable-details[open] .lh-chevron__line-left {\n transform: rotate(var(--chevron-angle-right));\n}\n\n.lh-expandable-details[open] .lh-chevron__line-right {\n transform: rotate(var(--chevron-angle));\n}\n\n\n.lh-expandable-details[open] .lh-chevron__lines {\n transform: translateY(calc(var(--chevron-size) * -1));\n}\n\n.lh-expandable-details[open] {\n animation: 300ms openDetails forwards;\n padding-bottom: var(--default-padding);\n}\n\n@keyframes openDetails {\n from {\n outline: 1px solid var(--report-background-color);\n }\n to {\n outline: 1px solid;\n box-shadow: 0 2px 4px rgba(0, 0, 0, .24);\n }\n}\n\n@media screen and (max-width: 780px) {\n /* no black outline if we\'re not confident the entire table can be displayed within bounds */\n .lh-expandable-details[open] {\n animation: none;\n }\n}\n\n.lh-expandable-details[open] summary, details.lh-clump > summary {\n border-bottom: 1px solid var(--report-border-color-secondary);\n}\ndetails.lh-clump[open] > summary {\n border-bottom-width: 0;\n}\n\n\n\ndetails .lh-clump-toggletext--hide,\ndetails[open] .lh-clump-toggletext--show { display: none; }\ndetails[open] .lh-clump-toggletext--hide { display: block;}\n\n\n/* Tooltip */\n.lh-tooltip-boundary {\n position: relative;\n}\n\n.lh-tooltip {\n position: absolute;\n display: none; /* Don\'t retain these layers when not needed */\n opacity: 0;\n background: #ffffff;\n white-space: pre-line; /* Render newlines in the text */\n min-width: 246px;\n max-width: 275px;\n padding: 15px;\n border-radius: 5px;\n text-align: initial;\n line-height: 1.4;\n}\n/* shrink tooltips to not be cutoff on left edge of narrow viewports\n 45vw is chosen to be ~= width of the left column of metrics\n*/\n@media screen and (max-width: 535px) {\n .lh-tooltip {\n min-width: 45vw;\n padding: 3vw;\n }\n}\n\n.lh-tooltip-boundary:hover .lh-tooltip {\n display: block;\n animation: fadeInTooltip 250ms;\n animation-fill-mode: forwards;\n animation-delay: 850ms;\n bottom: 100%;\n z-index: 1;\n will-change: opacity;\n right: 0;\n pointer-events: none;\n}\n\n.lh-tooltip::before {\n content: "";\n border: solid transparent;\n border-bottom-color: #fff;\n border-width: 10px;\n position: absolute;\n bottom: -20px;\n right: 6px;\n transform: rotate(180deg);\n pointer-events: none;\n}\n\n@keyframes fadeInTooltip {\n 0% { opacity: 0; }\n 75% { opacity: 1; }\n 100% { opacity: 1; filter: drop-shadow(1px 0px 1px #aaa) drop-shadow(0px 2px 4px hsla(206, 6%, 25%, 0.15)); pointer-events: auto; }\n}\n\n/* Element screenshot */\n.lh-element-screenshot {\n position: relative;\n overflow: hidden;\n float: left;\n margin-right: 20px;\n}\n.lh-element-screenshot__content {\n overflow: hidden;\n}\n.lh-element-screenshot__image {\n /* Set by ElementScreenshotRenderer.installFullPageScreenshotCssVariable */\n background-image: var(--element-screenshot-url);\n outline: 2px solid #777;\n background-color: white;\n background-repeat: no-repeat;\n}\n.lh-element-screenshot__mask {\n position: absolute;\n background: #555;\n opacity: 0.8;\n}\n.lh-element-screenshot__element-marker {\n position: absolute;\n outline: 2px solid var(--color-lime-400);\n}\n.lh-element-screenshot__overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 2000; /* .lh-topbar is 1000 */\n background: var(--screenshot-overlay-background);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: zoom-out;\n}\n\n.lh-element-screenshot__overlay .lh-element-screenshot {\n margin-right: 0; /* clearing margin used in thumbnail case */\n outline: 1px solid var(--color-gray-700);\n}\n\n.lh-screenshot-overlay--enabled .lh-element-screenshot {\n cursor: zoom-out;\n}\n.lh-screenshot-overlay--enabled .lh-node .lh-element-screenshot {\n cursor: zoom-in;\n}\n\n\n.lh-meta__items {\n --meta-icon-size: calc(var(--report-icon-size) * 0.667);\n padding: var(--default-padding);\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n background-color: var(--env-item-background-color);\n border-radius: 3px;\n margin: 0 0 var(--default-padding) 0;\n font-size: 12px;\n column-gap: var(--default-padding);\n color: var(--color-gray-700);\n}\n\n.lh-meta__item {\n display: block;\n list-style-type: none;\n position: relative;\n padding: 0 0 0 calc(var(--meta-icon-size) + var(--default-padding) * 2);\n cursor: unset; /* disable pointer cursor from report-icon */\n}\n\n.lh-meta__item.lh-tooltip-boundary {\n text-decoration: dotted underline var(--color-gray-500);\n cursor: help;\n}\n\n.lh-meta__item.lh-report-icon::before {\n position: absolute;\n left: var(--default-padding);\n width: var(--meta-icon-size);\n height: var(--meta-icon-size);\n}\n\n.lh-meta__item.lh-report-icon:hover::before {\n opacity: 0.7;\n}\n\n.lh-meta__item .lh-tooltip {\n color: var(--color-gray-800);\n}\n\n.lh-meta__item .lh-tooltip::before {\n right: auto; /* Set the tooltip arrow to the leftside */\n left: 6px;\n}\n\n/* Change the grid for narrow viewport. */\n@media screen and (max-width: 640px) {\n .lh-meta__items {\n grid-template-columns: 1fr 1fr;\n }\n}\n@media screen and (max-width: 535px) {\n .lh-meta__items {\n display: block;\n }\n}\n\n\n/*# sourceURL=report-styles.css */\n');
1226
1223
  el0.append(el1);
1227
1224
  return el0;
1228
1225
  }
@@ -1232,214 +1229,214 @@ function createStylesComponent(dom) {
1232
1229
  */
1233
1230
  function createTopbarComponent(dom) {
1234
1231
  const el0 = dom.createFragment();
1235
- const el1 = dom.createElement("style");
1236
- el1.append("\n .lh-topbar {\n position: sticky;\n top: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n display: flex;\n align-items: center;\n height: var(--topbar-height);\n padding: var(--topbar-padding);\n font-size: var(--report-font-size-secondary);\n background-color: var(--topbar-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n }\n\n .lh-topbar__logo {\n width: var(--topbar-logo-size);\n height: var(--topbar-logo-size);\n user-select: none;\n flex: none;\n }\n\n .lh-topbar__url {\n margin: var(--topbar-padding);\n text-decoration: none;\n color: var(--report-text-color);\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n }\n\n .lh-tools {\n display: flex;\n align-items: center;\n margin-left: auto;\n will-change: transform;\n min-width: var(--report-icon-size);\n }\n .lh-tools__button {\n width: var(--report-icon-size);\n min-width: 24px;\n height: var(--report-icon-size);\n cursor: pointer;\n margin-right: 5px;\n /* This is actually a button element, but we want to style it like a transparent div. */\n display: flex;\n background: none;\n color: inherit;\n border: none;\n padding: 0;\n font: inherit;\n outline: inherit;\n }\n .lh-tools__button svg {\n fill: var(--tools-icon-color);\n }\n .lh-dark .lh-tools__button svg {\n filter: invert(1);\n }\n .lh-tools__button.lh-active + .lh-tools__dropdown {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n }\n .lh-tools__dropdown {\n position: absolute;\n background-color: var(--report-background-color);\n border: 1px solid var(--report-border-color);\n border-radius: 3px;\n padding: calc(var(--default-padding) / 2) 0;\n cursor: pointer;\n top: 36px;\n right: 0;\n box-shadow: 1px 1px 3px #ccc;\n min-width: 125px;\n clip: rect(0, 164px, 0, 0);\n visibility: hidden;\n opacity: 0;\n transition: all 200ms cubic-bezier(0,0,0.2,1);\n }\n .lh-tools__dropdown a {\n color: currentColor;\n text-decoration: none;\n white-space: nowrap;\n padding: 0 6px;\n line-height: 2;\n }\n .lh-tools__dropdown a:hover,\n .lh-tools__dropdown a:focus {\n background-color: var(--color-gray-200);\n outline: none;\n }\n /* save-gist option hidden in report. */\n .lh-tools__dropdown a[data-action='save-gist'] {\n display: none;\n }\n\n .lh-locale-selector {\n width: 100%;\n color: var(--report-text-color);\n background-color: var(--locale-selector-background-color);\n padding: 2px;\n }\n .lh-tools-locale {\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n }\n .lh-tools-locale__selector-wrapper {\n transition: opacity 0.15s;\n opacity: 0;\n max-width: 200px;\n }\n .lh-button.lh-tool-locale__button {\n height: var(--topbar-height);\n color: var(--tools-icon-color);\n padding: calc(var(--default-padding) / 2);\n }\n .lh-tool-locale__button.lh-active + .lh-tools-locale__selector-wrapper {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n margin: 0 4px;\n }\n\n @media screen and (max-width: 964px) {\n .lh-tools__dropdown {\n right: 0;\n left: initial;\n }\n }\n @media print {\n .lh-topbar {\n position: static;\n margin-left: 0;\n }\n\n .lh-tools__dropdown {\n display: none;\n }\n }\n ");
1232
+ const el1 = dom.createElement('style');
1233
+ el1.append('\n .lh-topbar {\n position: sticky;\n top: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n display: flex;\n align-items: center;\n height: var(--topbar-height);\n padding: var(--topbar-padding);\n font-size: var(--report-font-size-secondary);\n background-color: var(--topbar-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n }\n\n .lh-topbar__logo {\n width: var(--topbar-logo-size);\n height: var(--topbar-logo-size);\n user-select: none;\n flex: none;\n }\n\n .lh-topbar__url {\n margin: var(--topbar-padding);\n text-decoration: none;\n color: var(--report-text-color);\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n }\n\n .lh-tools {\n display: flex;\n align-items: center;\n margin-left: auto;\n will-change: transform;\n min-width: var(--report-icon-size);\n }\n .lh-tools__button {\n width: var(--report-icon-size);\n min-width: 24px;\n height: var(--report-icon-size);\n cursor: pointer;\n margin-right: 5px;\n /* This is actually a button element, but we want to style it like a transparent div. */\n display: flex;\n background: none;\n color: inherit;\n border: none;\n padding: 0;\n font: inherit;\n outline: inherit;\n }\n .lh-tools__button svg {\n fill: var(--tools-icon-color);\n }\n .lh-dark .lh-tools__button svg {\n filter: invert(1);\n }\n .lh-tools__button.lh-active + .lh-tools__dropdown {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n }\n .lh-tools__dropdown {\n position: absolute;\n background-color: var(--report-background-color);\n border: 1px solid var(--report-border-color);\n border-radius: 3px;\n padding: calc(var(--default-padding) / 2) 0;\n cursor: pointer;\n top: 36px;\n right: 0;\n box-shadow: 1px 1px 3px #ccc;\n min-width: 125px;\n clip: rect(0, 164px, 0, 0);\n visibility: hidden;\n opacity: 0;\n transition: all 200ms cubic-bezier(0,0,0.2,1);\n }\n .lh-tools__dropdown a {\n color: currentColor;\n text-decoration: none;\n white-space: nowrap;\n padding: 0 6px;\n line-height: 2;\n }\n .lh-tools__dropdown a:hover,\n .lh-tools__dropdown a:focus {\n background-color: var(--color-gray-200);\n outline: none;\n }\n /* save-gist option hidden in report. */\n .lh-tools__dropdown a[data-action=\'save-gist\'] {\n display: none;\n }\n\n .lh-locale-selector {\n width: 100%;\n color: var(--report-text-color);\n background-color: var(--locale-selector-background-color);\n padding: 2px;\n }\n .lh-tools-locale {\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n }\n .lh-tools-locale__selector-wrapper {\n transition: opacity 0.15s;\n opacity: 0;\n max-width: 200px;\n }\n .lh-button.lh-tool-locale__button {\n height: var(--topbar-height);\n color: var(--tools-icon-color);\n padding: calc(var(--default-padding) / 2);\n }\n .lh-tool-locale__button.lh-active + .lh-tools-locale__selector-wrapper {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n margin: 0 4px;\n }\n\n @media screen and (max-width: 964px) {\n .lh-tools__dropdown {\n right: 0;\n left: initial;\n }\n }\n @media print {\n .lh-topbar {\n position: static;\n margin-left: 0;\n }\n\n .lh-tools__dropdown {\n display: none;\n }\n }\n ');
1237
1234
  el0.append(el1);
1238
- const el2 = dom.createElement("div", "lh-topbar");
1239
- const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-topbar__logo");
1235
+ const el2 = dom.createElement('div', 'lh-topbar');
1236
+ const el3 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg', 'lh-topbar__logo');
1240
1237
  el3.setAttribute('viewBox', '0 0 24 24');
1241
- const el4 = dom.createElementNS("http://www.w3.org/2000/svg", "defs");
1242
- const el5 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1238
+ const el4 = dom.createElementNS('http://www.w3.org/2000/svg', 'defs');
1239
+ const el5 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
1243
1240
  el5.setAttribute('x1', '57.456%');
1244
1241
  el5.setAttribute('y1', '13.086%');
1245
1242
  el5.setAttribute('x2', '18.259%');
1246
1243
  el5.setAttribute('y2', '72.322%');
1247
1244
  el5.setAttribute('id', 'lh-topbar__logo--a');
1248
- const el6 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1245
+ const el6 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1249
1246
  el6.setAttribute('stop-color', '#262626');
1250
1247
  el6.setAttribute('stop-opacity', '.1');
1251
1248
  el6.setAttribute('offset', '0%');
1252
- const el7 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1249
+ const el7 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1253
1250
  el7.setAttribute('stop-color', '#262626');
1254
1251
  el7.setAttribute('stop-opacity', '0');
1255
1252
  el7.setAttribute('offset', '100%');
1256
- el5.append(" ",el6," ",el7," ");
1257
- const el8 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1253
+ el5.append(' ', el6, ' ', el7, ' ');
1254
+ const el8 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
1258
1255
  el8.setAttribute('x1', '100%');
1259
1256
  el8.setAttribute('y1', '50%');
1260
1257
  el8.setAttribute('x2', '0%');
1261
1258
  el8.setAttribute('y2', '50%');
1262
1259
  el8.setAttribute('id', 'lh-topbar__logo--b');
1263
- const el9 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1260
+ const el9 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1264
1261
  el9.setAttribute('stop-color', '#262626');
1265
1262
  el9.setAttribute('stop-opacity', '.1');
1266
1263
  el9.setAttribute('offset', '0%');
1267
- const el10 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1264
+ const el10 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1268
1265
  el10.setAttribute('stop-color', '#262626');
1269
1266
  el10.setAttribute('stop-opacity', '0');
1270
1267
  el10.setAttribute('offset', '100%');
1271
- el8.append(" ",el9," ",el10," ");
1272
- const el11 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1268
+ el8.append(' ', el9, ' ', el10, ' ');
1269
+ const el11 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
1273
1270
  el11.setAttribute('x1', '58.764%');
1274
1271
  el11.setAttribute('y1', '65.756%');
1275
1272
  el11.setAttribute('x2', '36.939%');
1276
1273
  el11.setAttribute('y2', '50.14%');
1277
1274
  el11.setAttribute('id', 'lh-topbar__logo--c');
1278
- const el12 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1275
+ const el12 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1279
1276
  el12.setAttribute('stop-color', '#262626');
1280
1277
  el12.setAttribute('stop-opacity', '.1');
1281
1278
  el12.setAttribute('offset', '0%');
1282
- const el13 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1279
+ const el13 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1283
1280
  el13.setAttribute('stop-color', '#262626');
1284
1281
  el13.setAttribute('stop-opacity', '0');
1285
1282
  el13.setAttribute('offset', '100%');
1286
- el11.append(" ",el12," ",el13," ");
1287
- const el14 = dom.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1283
+ el11.append(' ', el12, ' ', el13, ' ');
1284
+ const el14 = dom.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
1288
1285
  el14.setAttribute('x1', '41.635%');
1289
1286
  el14.setAttribute('y1', '20.358%');
1290
1287
  el14.setAttribute('x2', '72.863%');
1291
1288
  el14.setAttribute('y2', '85.424%');
1292
1289
  el14.setAttribute('id', 'lh-topbar__logo--d');
1293
- const el15 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1290
+ const el15 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1294
1291
  el15.setAttribute('stop-color', '#FFF');
1295
1292
  el15.setAttribute('stop-opacity', '.1');
1296
1293
  el15.setAttribute('offset', '0%');
1297
- const el16 = dom.createElementNS("http://www.w3.org/2000/svg", "stop");
1294
+ const el16 = dom.createElementNS('http://www.w3.org/2000/svg', 'stop');
1298
1295
  el16.setAttribute('stop-color', '#FFF');
1299
1296
  el16.setAttribute('stop-opacity', '0');
1300
1297
  el16.setAttribute('offset', '100%');
1301
- el14.append(" ",el15," ",el16," ");
1302
- el4.append(" ",el5," ",el8," ",el11," ",el14," ");
1303
- const el17 = dom.createElementNS("http://www.w3.org/2000/svg", "g");
1298
+ el14.append(' ', el15, ' ', el16, ' ');
1299
+ el4.append(' ', el5, ' ', el8, ' ', el11, ' ', el14, ' ');
1300
+ const el17 = dom.createElementNS('http://www.w3.org/2000/svg', 'g');
1304
1301
  el17.setAttribute('fill', 'none');
1305
1302
  el17.setAttribute('fill-rule', 'evenodd');
1306
- const el18 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1303
+ const el18 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1307
1304
  el18.setAttribute('d', 'M12 3l4.125 2.625v3.75H18v2.25h-1.688l1.5 9.375H6.188l1.5-9.375H6v-2.25h1.875V5.648L12 3zm2.201 9.938L9.54 14.633 9 18.028l5.625-2.062-.424-3.028zM12.005 5.67l-1.88 1.207v2.498h3.75V6.86l-1.87-1.19z');
1308
1305
  el18.setAttribute('fill', '#F44B21');
1309
- const el19 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1306
+ const el19 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1310
1307
  el19.setAttribute('fill', '#FFF');
1311
1308
  el19.setAttribute('d', 'M14.201 12.938L9.54 14.633 9 18.028l5.625-2.062z');
1312
- const el20 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1309
+ const el20 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1313
1310
  el20.setAttribute('d', 'M6 18c-2.042 0-3.95-.01-5.813 0l1.5-9.375h4.326L6 18z');
1314
1311
  el20.setAttribute('fill', 'url(#lh-topbar__logo--a)');
1315
1312
  el20.setAttribute('fill-rule', 'nonzero');
1316
1313
  el20.setAttribute('transform', 'translate(6 3)');
1317
- const el21 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1314
+ const el21 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1318
1315
  el21.setAttribute('fill', '#FFF176');
1319
1316
  el21.setAttribute('fill-rule', 'nonzero');
1320
1317
  el21.setAttribute('d', 'M13.875 9.375v-2.56l-1.87-1.19-1.88 1.207v2.543z');
1321
- const el22 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1318
+ const el22 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1322
1319
  el22.setAttribute('fill', 'url(#lh-topbar__logo--b)');
1323
1320
  el22.setAttribute('fill-rule', 'nonzero');
1324
1321
  el22.setAttribute('d', 'M0 6.375h6v2.25H0z');
1325
1322
  el22.setAttribute('transform', 'translate(6 3)');
1326
- const el23 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1323
+ const el23 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1327
1324
  el23.setAttribute('fill', 'url(#lh-topbar__logo--c)');
1328
1325
  el23.setAttribute('fill-rule', 'nonzero');
1329
1326
  el23.setAttribute('d', 'M6 6.375H1.875v-3.75L6 0z');
1330
1327
  el23.setAttribute('transform', 'translate(6 3)');
1331
- const el24 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1328
+ const el24 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1332
1329
  el24.setAttribute('fill', 'url(#lh-topbar__logo--d)');
1333
1330
  el24.setAttribute('fill-rule', 'nonzero');
1334
1331
  el24.setAttribute('d', 'M6 0l4.125 2.625v3.75H12v2.25h-1.688l1.5 9.375H.188l1.5-9.375H0v-2.25h1.875V2.648z');
1335
1332
  el24.setAttribute('transform', 'translate(6 3)');
1336
- el17.append(" ",el18," ",el19," ",el20," ",el21," ",el22," ",el23," ",el24," ");
1337
- el3.append(" ",el4," ",el17," ");
1338
- const el25 = dom.createElement("a", "lh-topbar__url");
1333
+ el17.append(' ', el18, ' ', el19, ' ', el20, ' ', el21, ' ', el22, ' ', el23, ' ', el24, ' ');
1334
+ el3.append(' ', el4, ' ', el17, ' ');
1335
+ const el25 = dom.createElement('a', 'lh-topbar__url');
1339
1336
  el25.setAttribute('href', '');
1340
1337
  el25.setAttribute('target', '_blank');
1341
1338
  el25.setAttribute('rel', 'noopener');
1342
- const el26 = dom.createElement("div", "lh-tools");
1343
- const el27 = dom.createElement("div", "lh-tools-locale lh-hidden");
1344
- const el28 = dom.createElement("button", "lh-button lh-tool-locale__button");
1339
+ const el26 = dom.createElement('div', 'lh-tools');
1340
+ const el27 = dom.createElement('div', 'lh-tools-locale lh-hidden');
1341
+ const el28 = dom.createElement('button', 'lh-button lh-tool-locale__button');
1345
1342
  el28.setAttribute('id', 'lh-button__swap-locales');
1346
1343
  el28.setAttribute('title', 'Show Language Picker');
1347
1344
  el28.setAttribute('aria-label', 'Toggle language picker');
1348
1345
  el28.setAttribute('aria-haspopup', 'menu');
1349
1346
  el28.setAttribute('aria-expanded', 'false');
1350
1347
  el28.setAttribute('aria-controls', 'lh-tools-locale__selector-wrapper');
1351
- const el29 = dom.createElementNS("http://www.w3.org/2000/svg", "svg");
1348
+ const el29 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg');
1352
1349
  el29.setAttribute('width', '20px');
1353
1350
  el29.setAttribute('height', '20px');
1354
1351
  el29.setAttribute('viewBox', '0 0 24 24');
1355
1352
  el29.setAttribute('fill', 'currentColor');
1356
- const el30 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1353
+ const el30 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1357
1354
  el30.setAttribute('d', 'M0 0h24v24H0V0z');
1358
1355
  el30.setAttribute('fill', 'none');
1359
- const el31 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1356
+ const el31 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1360
1357
  el31.setAttribute('d', 'M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z');
1361
- el29.append(el30,el31);
1362
- el28.append(" ",el29," ");
1363
- const el32 = dom.createElement("div", "lh-tools-locale__selector-wrapper");
1358
+ el29.append(el30, el31);
1359
+ el28.append(' ', el29, ' ');
1360
+ const el32 = dom.createElement('div', 'lh-tools-locale__selector-wrapper');
1364
1361
  el32.setAttribute('id', 'lh-tools-locale__selector-wrapper');
1365
1362
  el32.setAttribute('role', 'menu');
1366
1363
  el32.setAttribute('aria-labelledby', 'lh-button__swap-locales');
1367
1364
  el32.setAttribute('aria-hidden', 'true');
1368
- el32.append(" "," ");
1369
- el27.append(" ",el28," ",el32," ");
1370
- const el33 = dom.createElement("button", "lh-tools__button");
1365
+ el32.append(' ', ' ');
1366
+ el27.append(' ', el28, ' ', el32, ' ');
1367
+ const el33 = dom.createElement('button', 'lh-tools__button');
1371
1368
  el33.setAttribute('id', 'lh-tools-button');
1372
1369
  el33.setAttribute('title', 'Tools menu');
1373
1370
  el33.setAttribute('aria-label', 'Toggle report tools menu');
1374
1371
  el33.setAttribute('aria-haspopup', 'menu');
1375
1372
  el33.setAttribute('aria-expanded', 'false');
1376
1373
  el33.setAttribute('aria-controls', 'lh-tools-dropdown');
1377
- const el34 = dom.createElementNS("http://www.w3.org/2000/svg", "svg");
1374
+ const el34 = dom.createElementNS('http://www.w3.org/2000/svg', 'svg');
1378
1375
  el34.setAttribute('width', '100%');
1379
1376
  el34.setAttribute('height', '100%');
1380
1377
  el34.setAttribute('viewBox', '0 0 24 24');
1381
- const el35 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1378
+ const el35 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1382
1379
  el35.setAttribute('d', 'M0 0h24v24H0z');
1383
1380
  el35.setAttribute('fill', 'none');
1384
- const el36 = dom.createElementNS("http://www.w3.org/2000/svg", "path");
1381
+ const el36 = dom.createElementNS('http://www.w3.org/2000/svg', 'path');
1385
1382
  el36.setAttribute('d', 'M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z');
1386
- el34.append(" ",el35," ",el36," ");
1387
- el33.append(" ",el34," ");
1388
- const el37 = dom.createElement("div", "lh-tools__dropdown");
1383
+ el34.append(' ', el35, ' ', el36, ' ');
1384
+ el33.append(' ', el34, ' ');
1385
+ const el37 = dom.createElement('div', 'lh-tools__dropdown');
1389
1386
  el37.setAttribute('id', 'lh-tools-dropdown');
1390
1387
  el37.setAttribute('role', 'menu');
1391
1388
  el37.setAttribute('aria-labelledby', 'lh-tools-button');
1392
- const el38 = dom.createElement("a", "lh-report-icon lh-report-icon--print");
1389
+ const el38 = dom.createElement('a', 'lh-report-icon lh-report-icon--print');
1393
1390
  el38.setAttribute('role', 'menuitem');
1394
1391
  el38.setAttribute('tabindex', '-1');
1395
1392
  el38.setAttribute('href', '#');
1396
1393
  el38.setAttribute('data-i18n', 'dropdownPrintSummary');
1397
1394
  el38.setAttribute('data-action', 'print-summary');
1398
- const el39 = dom.createElement("a", "lh-report-icon lh-report-icon--print");
1395
+ const el39 = dom.createElement('a', 'lh-report-icon lh-report-icon--print');
1399
1396
  el39.setAttribute('role', 'menuitem');
1400
1397
  el39.setAttribute('tabindex', '-1');
1401
1398
  el39.setAttribute('href', '#');
1402
1399
  el39.setAttribute('data-i18n', 'dropdownPrintExpanded');
1403
1400
  el39.setAttribute('data-action', 'print-expanded');
1404
- const el40 = dom.createElement("a", "lh-report-icon lh-report-icon--copy");
1401
+ const el40 = dom.createElement('a', 'lh-report-icon lh-report-icon--copy');
1405
1402
  el40.setAttribute('role', 'menuitem');
1406
1403
  el40.setAttribute('tabindex', '-1');
1407
1404
  el40.setAttribute('href', '#');
1408
1405
  el40.setAttribute('data-i18n', 'dropdownCopyJSON');
1409
1406
  el40.setAttribute('data-action', 'copy');
1410
- const el41 = dom.createElement("a", "lh-report-icon lh-report-icon--download lh-hidden");
1407
+ const el41 = dom.createElement('a', 'lh-report-icon lh-report-icon--download lh-hidden');
1411
1408
  el41.setAttribute('role', 'menuitem');
1412
1409
  el41.setAttribute('tabindex', '-1');
1413
1410
  el41.setAttribute('href', '#');
1414
1411
  el41.setAttribute('data-i18n', 'dropdownSaveHTML');
1415
1412
  el41.setAttribute('data-action', 'save-html');
1416
- const el42 = dom.createElement("a", "lh-report-icon lh-report-icon--download");
1413
+ const el42 = dom.createElement('a', 'lh-report-icon lh-report-icon--download');
1417
1414
  el42.setAttribute('role', 'menuitem');
1418
1415
  el42.setAttribute('tabindex', '-1');
1419
1416
  el42.setAttribute('href', '#');
1420
1417
  el42.setAttribute('data-i18n', 'dropdownSaveJSON');
1421
1418
  el42.setAttribute('data-action', 'save-json');
1422
- const el43 = dom.createElement("a", "lh-report-icon lh-report-icon--open");
1419
+ const el43 = dom.createElement('a', 'lh-report-icon lh-report-icon--open');
1423
1420
  el43.setAttribute('role', 'menuitem');
1424
1421
  el43.setAttribute('tabindex', '-1');
1425
1422
  el43.setAttribute('href', '#');
1426
1423
  el43.setAttribute('data-i18n', 'dropdownViewer');
1427
1424
  el43.setAttribute('data-action', 'open-viewer');
1428
- const el44 = dom.createElement("a", "lh-report-icon lh-report-icon--open");
1425
+ const el44 = dom.createElement('a', 'lh-report-icon lh-report-icon--open');
1429
1426
  el44.setAttribute('role', 'menuitem');
1430
1427
  el44.setAttribute('tabindex', '-1');
1431
1428
  el44.setAttribute('href', '#');
1432
1429
  el44.setAttribute('data-i18n', 'dropdownSaveGist');
1433
1430
  el44.setAttribute('data-action', 'save-gist');
1434
- const el45 = dom.createElement("a", "lh-report-icon lh-report-icon--dark");
1431
+ const el45 = dom.createElement('a', 'lh-report-icon lh-report-icon--dark');
1435
1432
  el45.setAttribute('role', 'menuitem');
1436
1433
  el45.setAttribute('tabindex', '-1');
1437
1434
  el45.setAttribute('href', '#');
1438
1435
  el45.setAttribute('data-i18n', 'dropdownDarkTheme');
1439
1436
  el45.setAttribute('data-action', 'toggle-dark');
1440
- el37.append(" ",el38," ",el39," ",el40," "," ",el41," ",el42," ",el43," ",el44," ",el45," ");
1441
- el26.append(" ",el27," ",el33," ",el37," ");
1442
- el2.append(" "," ",el3," ",el25," ",el26," ");
1437
+ el37.append(' ', el38, ' ', el39, ' ', el40, ' ', ' ', el41, ' ', el42, ' ', el43, ' ', el44, ' ', el45, ' ');
1438
+ el26.append(' ', el27, ' ', el33, ' ', el37, ' ');
1439
+ el2.append(' ', ' ', el3, ' ', el25, ' ', el26, ' ');
1443
1440
  el0.append(el2);
1444
1441
  return el0;
1445
1442
  }
@@ -1449,10 +1446,10 @@ function createTopbarComponent(dom) {
1449
1446
  */
1450
1447
  function createWarningsToplevelComponent(dom) {
1451
1448
  const el0 = dom.createFragment();
1452
- const el1 = dom.createElement("div", "lh-warnings lh-warnings--toplevel");
1453
- const el2 = dom.createElement("p", "lh-warnings__msg");
1454
- const el3 = dom.createElement("ul");
1455
- el1.append(" ",el2," ",el3," ");
1449
+ const el1 = dom.createElement('div', 'lh-warnings lh-warnings--toplevel');
1450
+ const el2 = dom.createElement('p', 'lh-warnings__msg');
1451
+ const el3 = dom.createElement('ul');
1452
+ el1.append(' ', el2, ' ', el3, ' ');
1456
1453
  el0.append(el1);
1457
1454
  return el0;
1458
1455
  }
@@ -1586,7 +1583,7 @@ class DOM {
1586
1583
  */
1587
1584
  createChildOf(parentElem, elementName, className) {
1588
1585
  const element = this.createElement(elementName, className);
1589
- parentElem.append(element);
1586
+ parentElem.appendChild(element);
1590
1587
  return element;
1591
1588
  }
1592
1589
 
@@ -1624,7 +1621,7 @@ class DOM {
1624
1621
  for (const segment of Util.splitMarkdownLink(text)) {
1625
1622
  if (!segment.isLink) {
1626
1623
  // Plain text segment.
1627
- element.append(this._document.createTextNode(segment.text));
1624
+ element.appendChild(this._document.createTextNode(segment.text));
1628
1625
  continue;
1629
1626
  }
1630
1627
 
@@ -1642,7 +1639,7 @@ class DOM {
1642
1639
  a.target = '_blank';
1643
1640
  a.textContent = segment.text;
1644
1641
  this.safelySetHref(a, url.href);
1645
- element.append(a);
1642
+ element.appendChild(a);
1646
1643
  }
1647
1644
 
1648
1645
  return element;
@@ -1699,9 +1696,9 @@ class DOM {
1699
1696
  if (segment.isCode) {
1700
1697
  const pre = this.createElement('code');
1701
1698
  pre.textContent = segment.text;
1702
- element.append(pre);
1699
+ element.appendChild(pre);
1703
1700
  } else {
1704
- element.append(this._document.createTextNode(segment.text));
1701
+ element.appendChild(this._document.createTextNode(segment.text));
1705
1702
  }
1706
1703
  }
1707
1704
 
@@ -1784,7 +1781,7 @@ class DOM {
1784
1781
  const a = this.createElement('a');
1785
1782
  a.download = filename;
1786
1783
  this.safelySetBlobHref(a, blob);
1787
- this._document.body.append(a); // Firefox requires anchor to be in the DOM.
1784
+ this._document.body.appendChild(a); // Firefox requires anchor to be in the DOM.
1788
1785
  a.click();
1789
1786
 
1790
1787
  // cleanup.
@@ -1860,9 +1857,9 @@ class CategoryRenderer {
1860
1857
  }
1861
1858
 
1862
1859
  const titleEl = this.dom.find('.lh-audit__title', auditEl);
1863
- titleEl.append(this.dom.convertMarkdownCodeSnippets(audit.result.title));
1860
+ titleEl.appendChild(this.dom.convertMarkdownCodeSnippets(audit.result.title));
1864
1861
  const descEl = this.dom.find('.lh-audit__description', auditEl);
1865
- descEl.append(this.dom.convertMarkdownLinkSnippets(audit.result.description));
1862
+ descEl.appendChild(this.dom.convertMarkdownLinkSnippets(audit.result.description));
1866
1863
 
1867
1864
  for (const relevantMetric of audit.relevantMetrics || []) {
1868
1865
  const adornEl = this.dom.createChildOf(descEl, 'span', 'lh-audit__adorn');
@@ -1872,16 +1869,19 @@ class CategoryRenderer {
1872
1869
 
1873
1870
  if (audit.stackPacks) {
1874
1871
  audit.stackPacks.forEach(pack => {
1875
- const packElmImg = this.dom.createElement('img', 'lh-audit__stackpack__img');
1872
+ const packElm = this.dom.createElement('div');
1873
+ packElm.classList.add('lh-audit__stackpack');
1874
+
1875
+ const packElmImg = this.dom.createElement('img');
1876
+ packElmImg.classList.add('lh-audit__stackpack__img');
1876
1877
  packElmImg.src = pack.iconDataURL;
1877
1878
  packElmImg.alt = pack.title;
1879
+ packElm.appendChild(packElmImg);
1878
1880
 
1879
- const snippets = this.dom.convertMarkdownLinkSnippets(pack.description);
1880
- const packElm = this.dom.createElement('div', 'lh-audit__stackpack');
1881
- packElm.append(packElmImg, snippets);
1881
+ packElm.appendChild(this.dom.convertMarkdownLinkSnippets(pack.description));
1882
1882
 
1883
1883
  this.dom.find('.lh-audit__stackpacks', auditEl)
1884
- .append(packElm);
1884
+ .appendChild(packElm);
1885
1885
  });
1886
1886
  }
1887
1887
 
@@ -1890,12 +1890,12 @@ class CategoryRenderer {
1890
1890
  const elem = this.detailsRenderer.render(audit.result.details);
1891
1891
  if (elem) {
1892
1892
  elem.classList.add('lh-details');
1893
- header.append(elem);
1893
+ header.appendChild(elem);
1894
1894
  }
1895
1895
  }
1896
1896
 
1897
1897
  // Add chevron SVG to the end of the summary
1898
- this.dom.find('.lh-chevron-container', auditEl).append(this._createChevron());
1898
+ this.dom.find('.lh-chevron-container', auditEl).appendChild(this._createChevron());
1899
1899
  this._setRatingClass(auditEl, audit.result.score, scoreDisplayMode);
1900
1900
 
1901
1901
  if (audit.result.scoreDisplayMode === 'error') {
@@ -1917,7 +1917,7 @@ class CategoryRenderer {
1917
1917
  const warningsEl = this.dom.createChildOf(summaryEl, 'div', 'lh-warnings');
1918
1918
  this.dom.createChildOf(warningsEl, 'span').textContent = strings.warningHeader;
1919
1919
  if (warnings.length === 1) {
1920
- warningsEl.append(this.dom.createTextNode(warnings.join('')));
1920
+ warningsEl.appendChild(this.dom.createTextNode(warnings.join('')));
1921
1921
  } else {
1922
1922
  const warningsUl = this.dom.createChildOf(warningsEl, 'ul');
1923
1923
  for (const warning of warnings) {
@@ -1992,11 +1992,11 @@ class CategoryRenderer {
1992
1992
 
1993
1993
  const gaugeContainerEl = this.dom.find('.lh-score__gauge', component);
1994
1994
  const gaugeEl = this.renderCategoryScore(category, groupDefinitions, options);
1995
- gaugeContainerEl.append(gaugeEl);
1995
+ gaugeContainerEl.appendChild(gaugeEl);
1996
1996
 
1997
1997
  if (category.description) {
1998
1998
  const descEl = this.dom.convertMarkdownLinkSnippets(category.description);
1999
- this.dom.find('.lh-category-header__description', component).append(descEl);
1999
+ this.dom.find('.lh-category-header__description', component).appendChild(descEl);
2000
2000
  }
2001
2001
 
2002
2002
  return component;
@@ -2015,13 +2015,13 @@ class CategoryRenderer {
2015
2015
 
2016
2016
  this.dom.createChildOf(auditGroupHeader, 'span', 'lh-audit-group__title')
2017
2017
  .textContent = group.title;
2018
- groupEl.append(auditGroupHeader);
2018
+ groupEl.appendChild(auditGroupHeader);
2019
2019
 
2020
2020
  let footerEl = null;
2021
2021
  if (group.description) {
2022
2022
  footerEl = this.dom.convertMarkdownLinkSnippets(group.description);
2023
2023
  footerEl.classList.add('lh-audit-group__description', 'lh-audit-group__footer');
2024
- groupEl.append(footerEl);
2024
+ groupEl.appendChild(footerEl);
2025
2025
  }
2026
2026
 
2027
2027
  return [groupEl, footerEl];
@@ -2085,7 +2085,7 @@ class CategoryRenderer {
2085
2085
  renderUnexpandableClump(auditRefs, groupDefinitions) {
2086
2086
  const clumpElement = this.dom.createElement('div');
2087
2087
  const elements = this._renderGroupedAudits(auditRefs, groupDefinitions);
2088
- elements.forEach(elem => clumpElement.append(elem));
2088
+ elements.forEach(elem => clumpElement.appendChild(elem));
2089
2089
  return clumpElement;
2090
2090
  }
2091
2091
 
@@ -2119,7 +2119,7 @@ class CategoryRenderer {
2119
2119
  if (description) {
2120
2120
  const descriptionEl = this.dom.convertMarkdownLinkSnippets(description);
2121
2121
  descriptionEl.classList.add('lh-audit-group__description', 'lh-audit-group__footer');
2122
- el.append(descriptionEl);
2122
+ el.appendChild(descriptionEl);
2123
2123
  }
2124
2124
 
2125
2125
  this.dom.find('.lh-clump-toggletext--show', el).textContent = Util.i18n.strings.show;
@@ -2211,7 +2211,7 @@ class CategoryRenderer {
2211
2211
  const content = this.dom.find('.lh-fraction__content', tmpl);
2212
2212
  const text = this.dom.createElement('span');
2213
2213
  text.textContent = `${numPassed}/${numPassableAudits}`;
2214
- content.append(text);
2214
+ content.appendChild(text);
2215
2215
 
2216
2216
  let rating = Util.calculateRating(fraction);
2217
2217
 
@@ -2315,7 +2315,7 @@ class CategoryRenderer {
2315
2315
  render(category, groupDefinitions = {}, options) {
2316
2316
  const element = this.dom.createElement('div', 'lh-category');
2317
2317
  element.id = category.id;
2318
- element.append(this.renderCategoryHeader(category, groupDefinitions, options));
2318
+ element.appendChild(this.renderCategoryHeader(category, groupDefinitions, options));
2319
2319
 
2320
2320
  // Top level clumps for audits, in order they will appear in the report.
2321
2321
  /** @type {Map<TopLevelClumpId, Array<LH.ReportResult.AuditRef>>} */
@@ -2348,13 +2348,13 @@ class CategoryRenderer {
2348
2348
  if (clumpId === 'failed') {
2349
2349
  const clumpElem = this.renderUnexpandableClump(auditRefs, groupDefinitions);
2350
2350
  clumpElem.classList.add(`lh-clump--failed`);
2351
- element.append(clumpElem);
2351
+ element.appendChild(clumpElem);
2352
2352
  continue;
2353
2353
  }
2354
2354
 
2355
2355
  const description = clumpId === 'manual' ? category.manualDescription : undefined;
2356
2356
  const clumpElem = this.renderClump(clumpId, {auditRefs, description});
2357
- element.append(clumpElem);
2357
+ element.appendChild(clumpElem);
2358
2358
  }
2359
2359
 
2360
2360
  return element;
@@ -2461,33 +2461,34 @@ class CriticalRequestChainRenderer {
2461
2461
 
2462
2462
  // Construct lines and add spacers for sub requests.
2463
2463
  segment.treeMarkers.forEach(separator => {
2464
- const classSeparator = separator ?
2465
- 'lh-tree-marker lh-vert' :
2466
- 'lh-tree-marker';
2467
- treeMarkeEl.append(
2468
- dom.createElement('span', classSeparator),
2469
- dom.createElement('span', 'lh-tree-marker')
2470
- );
2464
+ if (separator) {
2465
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker lh-vert'));
2466
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker'));
2467
+ } else {
2468
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker'));
2469
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker'));
2470
+ }
2471
2471
  });
2472
2472
 
2473
- const classLastChild = segment.isLastChild ?
2474
- 'lh-tree-marker lh-up-right' :
2475
- 'lh-tree-marker lh-vert-right';
2476
- const classHasChildren = segment.hasChildren ?
2477
- 'lh-tree-marker lh-horiz-down' :
2478
- 'lh-tree-marker lh-right';
2479
-
2480
- treeMarkeEl.append(
2481
- dom.createElement('span', classLastChild),
2482
- dom.createElement('span', 'lh-tree-marker lh-right'),
2483
- dom.createElement('span', classHasChildren)
2484
- );
2473
+ if (segment.isLastChild) {
2474
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker lh-up-right'));
2475
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker lh-right'));
2476
+ } else {
2477
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker lh-vert-right'));
2478
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker lh-right'));
2479
+ }
2480
+
2481
+ if (segment.hasChildren) {
2482
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker lh-horiz-down'));
2483
+ } else {
2484
+ treeMarkeEl.appendChild(dom.createElement('span', 'lh-tree-marker lh-right'));
2485
+ }
2485
2486
 
2486
2487
  // Fill in url, host, and request size information.
2487
2488
  const url = segment.node.request.url;
2488
2489
  const linkEl = detailsRenderer.renderTextURL(url);
2489
2490
  const treevalEl = dom.find('.lh-crc-node__tree-value', chainEl);
2490
- treevalEl.append(linkEl);
2491
+ treevalEl.appendChild(linkEl);
2491
2492
 
2492
2493
  if (!segment.hasChildren) {
2493
2494
  const {startTime, endTime, transferSize} = segment.node.request;
@@ -2496,7 +2497,8 @@ class CriticalRequestChainRenderer {
2496
2497
  const span2 = dom.createElement('span', 'lh-crc-node__chain-duration');
2497
2498
  span2.textContent = Util.i18n.formatBytesToKiB(transferSize, 0.01);
2498
2499
 
2499
- treevalEl.append(span, span2);
2500
+ treevalEl.appendChild(span);
2501
+ treevalEl.appendChild(span2);
2500
2502
  }
2501
2503
 
2502
2504
  return chainEl;
@@ -2512,7 +2514,7 @@ class CriticalRequestChainRenderer {
2512
2514
  * @param {DetailsRenderer} detailsRenderer
2513
2515
  */
2514
2516
  static buildTree(dom, tmpl, segment, elem, details, detailsRenderer) {
2515
- elem.append(CRCRenderer.createChainNode(dom, segment, detailsRenderer));
2517
+ elem.appendChild(CRCRenderer.createChainNode(dom, segment, detailsRenderer));
2516
2518
  if (segment.node.children) {
2517
2519
  for (const key of Object.keys(segment.node.children)) {
2518
2520
  const childSegment = CRCRenderer.createSegment(segment.node.children, key,
@@ -2721,7 +2723,7 @@ class ElementScreenshotRenderer {
2721
2723
  overlay.remove();
2722
2724
  return;
2723
2725
  }
2724
- overlay.append(screenshotElement);
2726
+ overlay.appendChild(screenshotElement);
2725
2727
  overlay.addEventListener('click', () => overlay.remove());
2726
2728
  });
2727
2729
  }
@@ -2787,6 +2789,9 @@ class ElementScreenshotRenderer {
2787
2789
  {width: screenshot.width, height: screenshot.height}
2788
2790
  );
2789
2791
 
2792
+ const contentEl = dom.find('div.lh-element-screenshot__content', containerEl);
2793
+ contentEl.style.top = `-${elementPreviewSizeDC.height}px`;
2794
+
2790
2795
  const imageEl = dom.find('div.lh-element-screenshot__image', containerEl);
2791
2796
  imageEl.style.width = elementPreviewSizeDC.width + 'px';
2792
2797
  imageEl.style.height = elementPreviewSizeDC.height + 'px';
@@ -2884,8 +2889,9 @@ class DetailsRenderer {
2884
2889
  * @return {Element}
2885
2890
  */
2886
2891
  _renderBytes(details) {
2887
- // TODO: handle displayUnit once we have something other than 'KiB'
2888
- const value = Util.i18n.formatBytesToKiB(details.value, details.granularity || 0.1);
2892
+ // TODO: handle displayUnit once we have something other than 'kb'
2893
+ // Note that 'kb' is historical and actually represents KiB.
2894
+ const value = Util.i18n.formatBytesToKiB(details.value, details.granularity);
2889
2895
  const textEl = this._renderText(value);
2890
2896
  textEl.title = Util.i18n.formatBytes(details.value);
2891
2897
  return textEl;
@@ -2896,11 +2902,9 @@ class DetailsRenderer {
2896
2902
  * @return {Element}
2897
2903
  */
2898
2904
  _renderMilliseconds(details) {
2899
- let value;
2905
+ let value = Util.i18n.formatMilliseconds(details.value, details.granularity);
2900
2906
  if (details.displayUnit === 'duration') {
2901
2907
  value = Util.i18n.formatDuration(details.value);
2902
- } else {
2903
- value = Util.i18n.formatMilliseconds(details.value, details.granularity || 10);
2904
2908
  }
2905
2909
 
2906
2910
  return this._renderText(value);
@@ -2926,12 +2930,12 @@ class DetailsRenderer {
2926
2930
  }
2927
2931
 
2928
2932
  const element = this._dom.createElement('div', 'lh-text__url');
2929
- element.append(this._renderLink({text: displayedPath, url}));
2933
+ element.appendChild(this._renderLink({text: displayedPath, url}));
2930
2934
 
2931
2935
  if (displayedHost) {
2932
2936
  const hostElem = this._renderText(displayedHost);
2933
2937
  hostElem.classList.add('lh-text__url-host');
2934
- element.append(hostElem);
2938
+ element.appendChild(hostElem);
2935
2939
  }
2936
2940
 
2937
2941
  if (title) {
@@ -2979,7 +2983,7 @@ class DetailsRenderer {
2979
2983
  * @return {Element}
2980
2984
  */
2981
2985
  _renderNumeric(details) {
2982
- const value = Util.i18n.formatNumber(details.value, details.granularity || 0.1);
2986
+ const value = Util.i18n.formatNumber(details.value, details.granularity);
2983
2987
  const element = this._dom.createElement('div', 'lh-numeric');
2984
2988
  element.textContent = value;
2985
2989
  return element;
@@ -3204,7 +3208,7 @@ class DetailsRenderer {
3204
3208
 
3205
3209
  if (valueElement) {
3206
3210
  const classes = `lh-table-column--${heading.valueType}`;
3207
- this._dom.createChildOf(rowElem, 'td', classes).append(valueElement);
3211
+ this._dom.createChildOf(rowElem, 'td', classes).appendChild(valueElement);
3208
3212
  } else {
3209
3213
  // Empty cell is rendered for a column if:
3210
3214
  // - the pair is null
@@ -3259,7 +3263,7 @@ class DetailsRenderer {
3259
3263
  const classes = `lh-table-column--${valueType}`;
3260
3264
  const labelEl = this._dom.createElement('div', 'lh-text');
3261
3265
  labelEl.textContent = heading.label;
3262
- this._dom.createChildOf(theadTrElem, 'th', classes).append(labelEl);
3266
+ this._dom.createChildOf(theadTrElem, 'th', classes).appendChild(labelEl);
3263
3267
  }
3264
3268
 
3265
3269
  const tbodyElem = this._dom.createChildOf(tableElem, 'tbody');
@@ -3302,13 +3306,13 @@ class DetailsRenderer {
3302
3306
  if (item.nodeLabel) {
3303
3307
  const nodeLabelEl = this._dom.createElement('div');
3304
3308
  nodeLabelEl.textContent = item.nodeLabel;
3305
- element.append(nodeLabelEl);
3309
+ element.appendChild(nodeLabelEl);
3306
3310
  }
3307
3311
  if (item.snippet) {
3308
3312
  const snippetEl = this._dom.createElement('div');
3309
3313
  snippetEl.classList.add('lh-node__snippet');
3310
3314
  snippetEl.textContent = item.snippet;
3311
- element.append(snippetEl);
3315
+ element.appendChild(snippetEl);
3312
3316
  }
3313
3317
  if (item.selector) {
3314
3318
  element.title = item.selector;
@@ -3431,7 +3435,9 @@ class I18n {
3431
3435
  // When testing, use a locale with more exciting numeric formatting.
3432
3436
  if (locale === 'en-XA') locale = 'de';
3433
3437
 
3434
- this._locale = locale;
3438
+ this._numberDateLocale = locale;
3439
+ this._numberFormatter = new Intl.NumberFormat(locale);
3440
+ this._percentFormatter = new Intl.NumberFormat(locale, {style: 'percent'});
3435
3441
  this._strings = strings;
3436
3442
  }
3437
3443
 
@@ -3439,58 +3445,15 @@ class I18n {
3439
3445
  return this._strings;
3440
3446
  }
3441
3447
 
3442
- /**
3443
- * @param {number} number
3444
- * @param {number|undefined} granularity
3445
- * @param {Intl.NumberFormatOptions=} opts
3446
- * @return {string}
3447
- */
3448
- _formatNumberWithGranularity(number, granularity, opts = {}) {
3449
- if (granularity !== undefined) {
3450
- const log10 = -Math.log10(granularity);
3451
- if (!Number.isInteger(log10)) {
3452
- console.warn(`granularity of ${granularity} is invalid. Using 1 instead`);
3453
- granularity = 1;
3454
- }
3455
-
3456
- if (granularity < 1) {
3457
- opts = {...opts};
3458
- opts.minimumFractionDigits = opts.maximumFractionDigits = Math.ceil(log10);
3459
- }
3460
-
3461
- number = Math.round(number / granularity) * granularity;
3462
-
3463
- // Avoid displaying a negative value that rounds to zero as "0".
3464
- if (Object.is(number, -0)) number = 0;
3465
- } else if (Math.abs(number) < 0.0005) {
3466
- // Also avoids "-0".
3467
- number = 0;
3468
- }
3469
-
3470
- return new Intl.NumberFormat(this._locale, opts).format(number).replace(' ', NBSP2);
3471
- }
3472
-
3473
3448
  /**
3474
3449
  * Format number.
3475
3450
  * @param {number} number
3476
- * @param {number=} granularity Controls how coarse the displayed value is.
3477
- * If undefined, the number will be displayed as described
3478
- * by the Intl defaults: tinyurl.com/7s67w5x7
3479
- * @return {string}
3480
- */
3481
- formatNumber(number, granularity) {
3482
- return this._formatNumberWithGranularity(number, granularity);
3483
- }
3484
-
3485
- /**
3486
- * Format integer.
3487
- * Just like {@link formatNumber} but uses a granularity of 1, rounding to the nearest
3488
- * whole number.
3489
- * @param {number} number
3451
+ * @param {number=} granularity Number of decimal places to include. Defaults to 0.1.
3490
3452
  * @return {string}
3491
3453
  */
3492
- formatInteger(number) {
3493
- return this._formatNumberWithGranularity(number, 1);
3454
+ formatNumber(number, granularity = 0.1) {
3455
+ const coarseValue = Math.round(number / granularity) * granularity;
3456
+ return this._numberFormatter.format(coarseValue);
3494
3457
  }
3495
3458
 
3496
3459
  /**
@@ -3499,99 +3462,92 @@ class I18n {
3499
3462
  * @return {string}
3500
3463
  */
3501
3464
  formatPercent(number) {
3502
- return new Intl.NumberFormat(this._locale, {style: 'percent'}).format(number);
3465
+ return this._percentFormatter.format(number);
3503
3466
  }
3504
3467
 
3505
3468
  /**
3506
3469
  * @param {number} size
3507
- * @param {number=} granularity Controls how coarse the displayed value is.
3508
- * If undefined, the number will be displayed in full.
3470
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
3509
3471
  * @return {string}
3510
3472
  */
3511
- formatBytesToKiB(size, granularity = undefined) {
3512
- return this._formatNumberWithGranularity(size / KiB, granularity) + `${NBSP2}KiB`;
3473
+ formatBytesToKiB(size, granularity = 0.1) {
3474
+ const formatter = this._byteFormatterForGranularity(granularity);
3475
+ const kbs = formatter.format(Math.round(size / 1024 / granularity) * granularity);
3476
+ return `${kbs}${NBSP2}KiB`;
3513
3477
  }
3514
3478
 
3515
3479
  /**
3516
3480
  * @param {number} size
3517
- * @param {number=} granularity Controls how coarse the displayed value is.
3518
- * If undefined, the number will be displayed in full.
3481
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
3519
3482
  * @return {string}
3520
3483
  */
3521
- formatBytesToMiB(size, granularity = undefined) {
3522
- return this._formatNumberWithGranularity(size / MiB, granularity) + `${NBSP2}MiB`;
3484
+ formatBytesToMiB(size, granularity = 0.1) {
3485
+ const formatter = this._byteFormatterForGranularity(granularity);
3486
+ const kbs = formatter.format(Math.round(size / (1024 ** 2) / granularity) * granularity);
3487
+ return `${kbs}${NBSP2}MiB`;
3523
3488
  }
3524
3489
 
3525
3490
  /**
3526
3491
  * @param {number} size
3527
- * @param {number=} granularity Controls how coarse the displayed value is.
3528
- * If undefined, the number will be displayed in full.
3492
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 1
3529
3493
  * @return {string}
3530
3494
  */
3531
3495
  formatBytes(size, granularity = 1) {
3532
- return this._formatNumberWithGranularity(size, granularity, {
3533
- style: 'unit',
3534
- unit: 'byte',
3535
- unitDisplay: 'long',
3536
- });
3496
+ const formatter = this._byteFormatterForGranularity(granularity);
3497
+ const kbs = formatter.format(Math.round(size / granularity) * granularity);
3498
+ return `${kbs}${NBSP2}bytes`;
3537
3499
  }
3538
3500
 
3539
3501
  /**
3540
3502
  * @param {number} size
3541
- * @param {number=} granularity Controls how coarse the displayed value is.
3542
- * If undefined, the number will be displayed in full.
3503
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
3543
3504
  * @return {string}
3544
3505
  */
3545
- formatBytesWithBestUnit(size, granularity = undefined) {
3506
+ formatBytesWithBestUnit(size, granularity = 0.1) {
3546
3507
  if (size >= MiB) return this.formatBytesToMiB(size, granularity);
3547
3508
  if (size >= KiB) return this.formatBytesToKiB(size, granularity);
3548
- return this._formatNumberWithGranularity(size, granularity, {
3549
- style: 'unit',
3550
- unit: 'byte',
3551
- unitDisplay: 'narrow',
3552
- });
3509
+ return this.formatNumber(size, granularity) + '\xa0B';
3553
3510
  }
3554
3511
 
3555
3512
  /**
3556
- * @param {number} size
3557
- * @param {number=} granularity Controls how coarse the displayed value is.
3558
- * If undefined, the number will be displayed in full.
3559
- * @return {string}
3513
+ * Format bytes with a constant number of fractional digits, i.e. for a granularity of 0.1, 10 becomes '10.0'
3514
+ * @param {number} granularity Controls how coarse the displayed value is
3515
+ * @return {Intl.NumberFormat}
3560
3516
  */
3561
- formatKbps(size, granularity = undefined) {
3562
- return this._formatNumberWithGranularity(size, granularity, {
3563
- style: 'unit',
3564
- unit: 'kilobit-per-second',
3565
- unitDisplay: 'short',
3517
+ _byteFormatterForGranularity(granularity) {
3518
+ // assume any granularity above 1 will not contain fractional parts, i.e. will never be 1.5
3519
+ let numberOfFractionDigits = 0;
3520
+ if (granularity < 1) {
3521
+ numberOfFractionDigits = -Math.floor(Math.log10(granularity));
3522
+ }
3523
+
3524
+ return new Intl.NumberFormat(this._numberDateLocale, {
3525
+ ...this._numberFormatter.resolvedOptions(),
3526
+ maximumFractionDigits: numberOfFractionDigits,
3527
+ minimumFractionDigits: numberOfFractionDigits,
3566
3528
  });
3567
3529
  }
3568
3530
 
3569
3531
  /**
3570
3532
  * @param {number} ms
3571
- * @param {number=} granularity Controls how coarse the displayed value is.
3572
- * If undefined, the number will be displayed in full.
3533
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 10
3573
3534
  * @return {string}
3574
3535
  */
3575
- formatMilliseconds(ms, granularity = undefined) {
3576
- return this._formatNumberWithGranularity(ms, granularity, {
3577
- style: 'unit',
3578
- unit: 'millisecond',
3579
- unitDisplay: 'short',
3580
- });
3536
+ formatMilliseconds(ms, granularity = 10) {
3537
+ const coarseTime = Math.round(ms / granularity) * granularity;
3538
+ return coarseTime === 0
3539
+ ? `${this._numberFormatter.format(0)}${NBSP2}ms`
3540
+ : `${this._numberFormatter.format(coarseTime)}${NBSP2}ms`;
3581
3541
  }
3582
3542
 
3583
3543
  /**
3584
3544
  * @param {number} ms
3585
- * @param {number=} granularity Controls how coarse the displayed value is.
3586
- * If undefined, the number will be displayed in full.
3545
+ * @param {number=} granularity Controls how coarse the displayed value is, defaults to 0.1
3587
3546
  * @return {string}
3588
3547
  */
3589
- formatSeconds(ms, granularity = undefined) {
3590
- return this._formatNumberWithGranularity(ms / 1000, granularity, {
3591
- style: 'unit',
3592
- unit: 'second',
3593
- unitDisplay: 'short',
3594
- });
3548
+ formatSeconds(ms, granularity = 0.1) {
3549
+ const coarseTime = Math.round(ms / 1000 / granularity) * granularity;
3550
+ return `${this._numberFormatter.format(coarseTime)}${NBSP2}s`;
3595
3551
  }
3596
3552
 
3597
3553
  /**
@@ -3611,10 +3567,10 @@ class I18n {
3611
3567
  // and https://github.com/GoogleChrome/lighthouse/pull/9822
3612
3568
  let formatter;
3613
3569
  try {
3614
- formatter = new Intl.DateTimeFormat(this._locale, options);
3570
+ formatter = new Intl.DateTimeFormat(this._numberDateLocale, options);
3615
3571
  } catch (err) {
3616
3572
  options.timeZone = 'UTC';
3617
- formatter = new Intl.DateTimeFormat(this._locale, options);
3573
+ formatter = new Intl.DateTimeFormat(this._numberDateLocale, options);
3618
3574
  }
3619
3575
 
3620
3576
  return formatter.format(new Date(date));
@@ -3626,10 +3582,6 @@ class I18n {
3626
3582
  * @return {string}
3627
3583
  */
3628
3584
  formatDuration(timeInMilliseconds) {
3629
- // There is a proposal for a Intl.DurationFormat.
3630
- // https://github.com/tc39/proposal-intl-duration-format
3631
- // Until then, we do things a bit more manually.
3632
-
3633
3585
  let timeInSeconds = timeInMilliseconds / 1000;
3634
3586
  if (Math.round(timeInSeconds) === 0) {
3635
3587
  return 'None';
@@ -3638,24 +3590,19 @@ class I18n {
3638
3590
  /** @type {Array<string>} */
3639
3591
  const parts = [];
3640
3592
  /** @type {Record<string, number>} */
3641
- const unitToSecondsPer = {
3642
- day: 60 * 60 * 24,
3643
- hour: 60 * 60,
3644
- minute: 60,
3645
- second: 1,
3593
+ const unitLabels = {
3594
+ d: 60 * 60 * 24,
3595
+ h: 60 * 60,
3596
+ m: 60,
3597
+ s: 1,
3646
3598
  };
3647
3599
 
3648
- Object.keys(unitToSecondsPer).forEach(unit => {
3649
- const secondsPerUnit = unitToSecondsPer[unit];
3650
- const numberOfUnits = Math.floor(timeInSeconds / secondsPerUnit);
3600
+ Object.keys(unitLabels).forEach(label => {
3601
+ const unit = unitLabels[label];
3602
+ const numberOfUnits = Math.floor(timeInSeconds / unit);
3651
3603
  if (numberOfUnits > 0) {
3652
- timeInSeconds -= numberOfUnits * secondsPerUnit;
3653
- const part = this._formatNumberWithGranularity(numberOfUnits, 1, {
3654
- style: 'unit',
3655
- unit,
3656
- unitDisplay: 'narrow',
3657
- });
3658
- parts.push(part);
3604
+ timeInSeconds -= numberOfUnits * unit;
3605
+ parts.push(`${numberOfUnits}\xa0${label}`);
3659
3606
  }
3660
3607
  });
3661
3608
 
@@ -3699,7 +3646,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3699
3646
  valueEl.textContent = audit.result.displayValue || '';
3700
3647
 
3701
3648
  const descriptionEl = this.dom.find('.lh-metric__description', tmpl);
3702
- descriptionEl.append(this.dom.convertMarkdownLinkSnippets(audit.result.description));
3649
+ descriptionEl.appendChild(this.dom.convertMarkdownLinkSnippets(audit.result.description));
3703
3650
 
3704
3651
  if (audit.result.scoreDisplayMode === 'error') {
3705
3652
  descriptionEl.textContent = '';
@@ -3839,7 +3786,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3839
3786
  const strings = Util.i18n.strings;
3840
3787
  const element = this.dom.createElement('div', 'lh-category');
3841
3788
  element.id = category.id;
3842
- element.append(this.renderCategoryHeader(category, groups, options));
3789
+ element.appendChild(this.renderCategoryHeader(category, groups, options));
3843
3790
 
3844
3791
  // Metrics.
3845
3792
  const metricAudits = category.auditRefs.filter(audit => audit.group === 'metrics');
@@ -3864,7 +3811,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3864
3811
  const metricsBoxesEl = this.dom.createElement('div', 'lh-metrics-container');
3865
3812
  metricsGroupEl.insertBefore(metricsBoxesEl, metricsFooterEl);
3866
3813
  metricAudits.forEach(item => {
3867
- metricsBoxesEl.append(this._renderMetric(item));
3814
+ metricsBoxesEl.appendChild(this._renderMetric(item));
3868
3815
  });
3869
3816
 
3870
3817
  // Only add the disclaimer with the score calculator link if the category was rendered with a score gauge.
@@ -3872,7 +3819,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3872
3819
  const descriptionEl = this.dom.find('.lh-category-header__description', element);
3873
3820
  const estValuesEl = this.dom.createChildOf(descriptionEl, 'div', 'lh-metrics__disclaimer');
3874
3821
  const disclaimerEl = this.dom.convertMarkdownLinkSnippets(strings.varianceDisclaimer);
3875
- estValuesEl.append(disclaimerEl);
3822
+ estValuesEl.appendChild(disclaimerEl);
3876
3823
 
3877
3824
  // Add link to score calculator.
3878
3825
  const calculatorLink = this.dom.createChildOf(estValuesEl, 'a', 'lh-calclink');
@@ -3882,7 +3829,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3882
3829
  }
3883
3830
 
3884
3831
  metricsGroupEl.classList.add('lh-audit-group--metrics');
3885
- element.append(metricsGroupEl);
3832
+ element.appendChild(metricsGroupEl);
3886
3833
  }
3887
3834
 
3888
3835
  // Filmstrip
@@ -3892,7 +3839,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3892
3839
  if (thumbnailResult?.details) {
3893
3840
  timelineEl.id = thumbnailResult.id;
3894
3841
  const filmstripEl = this.detailsRenderer.render(thumbnailResult.details);
3895
- filmstripEl && timelineEl.append(filmstripEl);
3842
+ filmstripEl && timelineEl.appendChild(filmstripEl);
3896
3843
  }
3897
3844
 
3898
3845
  // Opportunities
@@ -3926,7 +3873,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3926
3873
  opportunityAudits.forEach(item =>
3927
3874
  groupEl.insertBefore(this._renderOpportunity(item, scale), footerEl));
3928
3875
  groupEl.classList.add('lh-audit-group--load-opportunities');
3929
- element.append(groupEl);
3876
+ element.appendChild(groupEl);
3930
3877
  }
3931
3878
 
3932
3879
  // Diagnostics
@@ -3943,7 +3890,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3943
3890
  const [groupEl, footerEl] = this.renderAuditGroup(groups['diagnostics']);
3944
3891
  diagnosticAudits.forEach(item => groupEl.insertBefore(this.renderAudit(item), footerEl));
3945
3892
  groupEl.classList.add('lh-audit-group--diagnostics');
3946
- element.append(groupEl);
3893
+ element.appendChild(groupEl);
3947
3894
  }
3948
3895
 
3949
3896
  // Passed audits
@@ -3957,7 +3904,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3957
3904
  groupDefinitions: groups,
3958
3905
  };
3959
3906
  const passedElem = this.renderClump('passed', clumpOpts);
3960
- element.append(passedElem);
3907
+ element.appendChild(passedElem);
3961
3908
 
3962
3909
  // Budgets
3963
3910
  /** @type {Array<Element>} */
@@ -3977,7 +3924,7 @@ class PerformanceCategoryRenderer extends CategoryRenderer {
3977
3924
  const [groupEl, footerEl] = this.renderAuditGroup(groups.budgets);
3978
3925
  budgetTableEls.forEach(table => groupEl.insertBefore(table, footerEl));
3979
3926
  groupEl.classList.add('lh-audit-group--budgets');
3980
- element.append(groupEl);
3927
+ element.appendChild(groupEl);
3981
3928
  }
3982
3929
 
3983
3930
  return element;
@@ -4077,7 +4024,7 @@ class PwaCategoryRenderer extends CategoryRenderer {
4077
4024
  render(category, groupDefinitions = {}) {
4078
4025
  const categoryElem = this.dom.createElement('div', 'lh-category');
4079
4026
  categoryElem.id = category.id;
4080
- categoryElem.append(this.renderCategoryHeader(category, groupDefinitions));
4027
+ categoryElem.appendChild(this.renderCategoryHeader(category, groupDefinitions));
4081
4028
 
4082
4029
  const auditRefs = category.auditRefs;
4083
4030
 
@@ -4085,13 +4032,13 @@ class PwaCategoryRenderer extends CategoryRenderer {
4085
4032
  // all put in a top-level clump that isn't expandable/collapsible.
4086
4033
  const regularAuditRefs = auditRefs.filter(ref => ref.result.scoreDisplayMode !== 'manual');
4087
4034
  const auditsElem = this._renderAudits(regularAuditRefs, groupDefinitions);
4088
- categoryElem.append(auditsElem);
4035
+ categoryElem.appendChild(auditsElem);
4089
4036
 
4090
4037
  // Manual audits are still in a manual clump.
4091
4038
  const manualAuditRefs = auditRefs.filter(ref => ref.result.scoreDisplayMode === 'manual');
4092
4039
  const manualElem = this.renderClump('manual',
4093
4040
  {auditRefs: manualAuditRefs, description: category.manualDescription});
4094
- categoryElem.append(manualElem);
4041
+ categoryElem.appendChild(manualElem);
4095
4042
 
4096
4043
  return categoryElem;
4097
4044
  }
@@ -4296,7 +4243,7 @@ class ReportRenderer {
4296
4243
  const report = Util.prepareReportResult(lhr);
4297
4244
 
4298
4245
  this._dom.rootEl.textContent = ''; // Remove previous report.
4299
- this._dom.rootEl.append(this._renderReport(report));
4246
+ this._dom.rootEl.appendChild(this._renderReport(report));
4300
4247
 
4301
4248
  return this._dom.rootEl;
4302
4249
  }
@@ -4404,13 +4351,11 @@ class ReportRenderer {
4404
4351
  const message = this._dom.find('.lh-warnings__msg', container);
4405
4352
  message.textContent = Util.i18n.strings.toplevelWarningsMessage;
4406
4353
 
4407
- const warnings = [];
4354
+ const warnings = this._dom.find('ul', container);
4408
4355
  for (const warningString of report.runWarnings) {
4409
- const warning = this._dom.createElement('li');
4410
- warning.append(this._dom.convertMarkdownLinkSnippets(warningString));
4411
- warnings.push(warning);
4356
+ const warning = warnings.appendChild(this._dom.createElement('li'));
4357
+ warning.appendChild(this._dom.convertMarkdownLinkSnippets(warningString));
4412
4358
  }
4413
- this._dom.find('ul', container).append(...warnings);
4414
4359
 
4415
4360
  return container;
4416
4361
  }
@@ -4503,11 +4448,11 @@ class ReportRenderer {
4503
4448
  };
4504
4449
 
4505
4450
  const headerContainer = this._dom.createElement('div');
4506
- headerContainer.append(this._renderReportHeader());
4451
+ headerContainer.appendChild(this._renderReportHeader());
4507
4452
 
4508
4453
  const reportContainer = this._dom.createElement('div', 'lh-container');
4509
4454
  const reportSection = this._dom.createElement('div', 'lh-report');
4510
- reportSection.append(this._renderReportWarnings(report));
4455
+ reportSection.appendChild(this._renderReportWarnings(report));
4511
4456
 
4512
4457
  let scoreHeader;
4513
4458
  const isSoloCategory = Object.keys(report.categories).length === 1;
@@ -4524,23 +4469,23 @@ class ReportRenderer {
4524
4469
  const scoresContainer = this._dom.find('.lh-scores-container', headerContainer);
4525
4470
  scoreHeader.append(
4526
4471
  ...this._renderScoreGauges(report, categoryRenderer, specificCategoryRenderers));
4527
- scoresContainer.append(scoreHeader, scoreScale);
4472
+ scoresContainer.appendChild(scoreHeader);
4473
+ scoresContainer.appendChild(scoreScale);
4528
4474
 
4529
4475
  const stickyHeader = this._dom.createElement('div', 'lh-sticky-header');
4530
4476
  stickyHeader.append(
4531
4477
  ...this._renderScoreGauges(report, categoryRenderer, specificCategoryRenderers));
4532
- reportContainer.append(stickyHeader);
4478
+ reportContainer.appendChild(stickyHeader);
4533
4479
  }
4534
4480
 
4535
- const categories = this._dom.createElement('div', 'lh-categories');
4536
- reportSection.append(categories);
4481
+ const categories = reportSection.appendChild(this._dom.createElement('div', 'lh-categories'));
4537
4482
  const categoryOptions = {gatherMode: report.gatherMode};
4538
4483
  for (const category of Object.values(report.categories)) {
4539
4484
  const renderer = specificCategoryRenderers[category.id] || categoryRenderer;
4540
4485
  // .lh-category-wrapper is full-width and provides horizontal rules between categories.
4541
4486
  // .lh-category within has the max-width: var(--report-content-max-width);
4542
4487
  const wrapper = renderer.dom.createChildOf(categories, 'div', 'lh-category-wrapper');
4543
- wrapper.append(renderer.render(
4488
+ wrapper.appendChild(renderer.render(
4544
4489
  category,
4545
4490
  report.categoryGroups,
4546
4491
  categoryOptions
@@ -4555,12 +4500,13 @@ class ReportRenderer {
4555
4500
  }
4556
4501
 
4557
4502
  if (!this._opts.omitTopbar) {
4558
- reportFragment.append(this._renderReportTopbar(report));
4503
+ reportFragment.appendChild(this._renderReportTopbar(report));
4559
4504
  }
4560
4505
 
4561
- reportFragment.append(reportContainer);
4562
- reportSection.append(this._renderReportFooter(report));
4563
- reportContainer.append(headerContainer, reportSection);
4506
+ reportFragment.appendChild(reportContainer);
4507
+ reportContainer.appendChild(headerContainer);
4508
+ reportContainer.appendChild(reportSection);
4509
+ reportSection.appendChild(this._renderReportFooter(report));
4564
4510
 
4565
4511
  if (fullPageScreenshot) {
4566
4512
  ElementScreenshotRenderer.installFullPageScreenshot(
@@ -4708,7 +4654,7 @@ function computeWindowNameSuffix(json) {
4708
4654
  // @ts-expect-error - If this is a v2 LHR, use old `generatedTime`.
4709
4655
  const fallbackFetchTime = /** @type {string} */ (json.generatedTime);
4710
4656
  const fetchTime = json.fetchTime || fallbackFetchTime;
4711
- return `${json.lighthouseVersion}-${json.finalUrl}-${fetchTime}`;
4657
+ return `${json.lighthouseVersion}-${json.requestedUrl}-${fetchTime}`;
4712
4658
  }
4713
4659
 
4714
4660
  /**
@@ -4790,6 +4736,7 @@ function openTreemap(json) {
4790
4736
  /** @type {LH.Treemap.Options} */
4791
4737
  const treemapOptions = {
4792
4738
  lhr: {
4739
+ requestedUrl: json.requestedUrl,
4793
4740
  finalUrl: json.finalUrl,
4794
4741
  audits: {
4795
4742
  'script-treemap-data': json.audits['script-treemap-data'],