_renderScoreGauges(report, categoryRenderer, specificCategoryRenderers) {
    // Group gauges in this order: default, plugins.
    const defaultGauges = [];
    const pluginGauges = [];

    for (const category of Object.values(report.categories)) {
      const renderer = specificCategoryRenderers[category.id] || categoryRenderer;
      const categoryGauge = renderer.renderCategoryScore(
        category,
        report.categoryGroups || {},
        {gatherMode: report.gatherMode}
      );

      const gaugeWrapperEl = this._dom.find('a.lh-gauge__wrapper, a.lh-fraction__wrapper',
        categoryGauge);
      if (gaugeWrapperEl) {
        this._dom.safelySetHref(gaugeWrapperEl, `#${category.id}`);
        // Handle navigation clicks by scrolling to target without changing the page's URL.
        // Why? Some report embedding clients have their own routing and updating the location.hash
        // can introduce problems. Others may have an unpredictable `<base>` URL which ensures
        // navigation to `${baseURL}#categoryid` will be unintended.
        gaugeWrapperEl.addEventListener('click', e => {
          if (!gaugeWrapperEl.matches('[href^="#"]')) return;
          const selector = gaugeWrapperEl.getAttribute('href');
          const reportRoot = this._dom.rootEl;
          if (!selector || !reportRoot) return;
          const destEl = this._dom.find(selector, reportRoot);
          e.preventDefault();
          destEl.scrollIntoView();
        });
        this._opts.onPageAnchorRendered?.(gaugeWrapperEl);
      }


      if (ReportUtils.isPluginCategory(category.id)) {
        pluginGauges.push(categoryGauge);
      } else {
        defaultGauges.push(categoryGauge);
      }
    }

    return [...defaultGauges, ...pluginGauges];
  }
@param {LH.ReportResult} report
@param {CategoryRenderer} categoryRenderer
@param {Record<string, CategoryRenderer>} specificCategoryRenderers
@return {!DocumentFragment[]}