UNPKG

@dcloudio/uni-debugger

Version:

uni-app debugger

2,309 lines (1,111 loc) 1.45 MB
// lighthouse, browserified. 3.0.3 (d1cae24fda4182406e02d3f4df6309d48878fc50) require=function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a;}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r);},p,p.exports,r,e,n,t);}return n[i].exports;}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o;}return r;}()({"../audits/accessibility/accesskeys":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class Accesskeys extends AxeAudit{ static get meta(){ return{ id:'accesskeys', title:'`[accesskey]` values are unique', failureTitle:'`[accesskey]` values are not unique', description:'Access keys let users quickly focus a part of the page. For proper '+ 'navigation, each access key must be unique. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/accesskeys?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=Accesskeys; },{"./axe-audit":1}],"../audits/accessibility/aria-allowed-attr":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ARIAAllowedAttr extends AxeAudit{ static get meta(){ return{ id:'aria-allowed-attr', title:'`[aria-*]` attributes match their roles', failureTitle:'`[aria-*]` attributes do not match their roles', description:'Each ARIA `role` supports a specific subset of `aria-*` attributes. '+ 'Mismatching these invalidates the `aria-*` attributes. [Learn '+ 'more](https://dequeuniversity.com/rules/axe/2.2/aria-allowed-attr?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ARIAAllowedAttr; },{"./axe-audit":1}],"../audits/accessibility/aria-required-attr":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ARIARequiredAttr extends AxeAudit{ static get meta(){ return{ id:'aria-required-attr', title:'`[role]`s have all required `[aria-*]` attributes', failureTitle:'`[role]`s do not have all required `[aria-*]` attributes', description:'Some ARIA roles have required attributes that describe the state '+ 'of the element to screen readers. [Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-attr?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ARIARequiredAttr; },{"./axe-audit":1}],"../audits/accessibility/aria-required-children":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class AriaRequiredChildren extends AxeAudit{ static get meta(){ return{ id:'aria-required-children', title:'Elements with `[role]` that require specific children `[role]`s, are present', failureTitle:'Elements with `[role]` that require specific children `[role]`s, '+ 'are missing.', description:'Some ARIA parent roles must contain specific child roles to perform '+ 'their intended accessibility functions. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-children?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=AriaRequiredChildren; },{"./axe-audit":1}],"../audits/accessibility/aria-required-parent":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class AriaRequiredParent extends AxeAudit{ static get meta(){ return{ id:'aria-required-parent', title:'`[role]`s are contained by their required parent element', failureTitle:'`[role]`s are not contained by their required parent element', description:'Some ARIA child roles must be contained by specific parent roles to '+ 'properly perform their intended accessibility functions. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-required-parent?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=AriaRequiredParent; },{"./axe-audit":1}],"../audits/accessibility/aria-roles":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class AriaRoles extends AxeAudit{ static get meta(){ return{ id:'aria-roles', title:'`[role]` values are valid', failureTitle:'`[role]` values are not valid', description:'ARIA roles must have valid values in order to perform their '+ 'intended accessibility functions. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/aria-roles?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=AriaRoles; },{"./axe-audit":1}],"../audits/accessibility/aria-valid-attr-value":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ARIAValidAttr extends AxeAudit{ static get meta(){ return{ id:'aria-valid-attr-value', title:'`[aria-*]` attributes have valid values', failureTitle:'`[aria-*]` attributes do not have valid values', description:'Assistive technologies, like screen readers, can\'t interpret ARIA '+ 'attributes with invalid values. [Learn '+ 'more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr-value?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ARIAValidAttr; },{"./axe-audit":1}],"../audits/accessibility/aria-valid-attr":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ARIAValidAttr extends AxeAudit{ static get meta(){ return{ id:'aria-valid-attr', title:'`[aria-*]` attributes are valid and not misspelled', failureTitle:'`[aria-*]` attributes are not valid or misspelled', description:'Assistive technologies, like screen readers, can\'t interpret ARIA '+ 'attributes with invalid names. [Learn '+ 'more](https://dequeuniversity.com/rules/axe/2.2/aria-valid-attr?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ARIAValidAttr; },{"./axe-audit":1}],"../audits/accessibility/audio-caption":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class AudioCaption extends AxeAudit{ static get meta(){ return{ id:'audio-caption', title:'`<audio>` elements contain a `<track>` element with `[kind="captions"]`', failureTitle:'`<audio>` elements are missing a `<track>` element with '+ '`[kind="captions"]`.', description:'Captions make audio elements usable for deaf or hearing-impaired users, '+ 'providing critical information such as who is talking, what they\'re saying, '+ 'and other non-speech information. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/audio-caption?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=AudioCaption; },{"./axe-audit":1}],"../audits/accessibility/button-name":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ButtonName extends AxeAudit{ static get meta(){ return{ id:'button-name', title:'Buttons have an accessible name', failureTitle:'Buttons do not have an accessible name', description:'When a button doesn\'t have an accessible name, screen readers announce it '+ 'as "button", making it unusable for users who rely on screen readers. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/button-name?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ButtonName; },{"./axe-audit":1}],"../audits/accessibility/bypass":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class Bypass extends AxeAudit{ static get meta(){ return{ id:'bypass', title:'The page contains a heading, skip link, or landmark region', failureTitle:'The page does not contain a heading, skip link, or landmark region', description:'Adding ways to bypass repetitive content lets keyboard users navigate the '+ 'page more efficiently. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/bypass?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=Bypass; },{"./axe-audit":1}],"../audits/accessibility/color-contrast":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ColorContrast extends AxeAudit{ static get meta(){ return{ id:'color-contrast', title:'Background and foreground colors have a sufficient contrast ratio', failureTitle:'Background and foreground colors do not have a '+ 'sufficient contrast ratio.', description:'Low-contrast text is difficult or impossible for many users to read. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/color-contrast?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ColorContrast; },{"./axe-audit":1}],"../audits/accessibility/definition-list":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class DefinitionList extends AxeAudit{ static get meta(){ return{ id:'definition-list', title:'`<dl>`\'s contain only properly-ordered `<dt>` and `<dd>` groups, `<script>` '+ 'or `<template>` elements.', failureTitle:'`<dl>`\'s do not contain only properly-ordered `<dt>` and `<dd>` '+ 'groups, `<script>` or `<template>` elements.', description:'When definition lists are not properly marked up, screen readers may produce '+ 'confusing or inaccurate output. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/definition-list?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=DefinitionList; },{"./axe-audit":1}],"../audits/accessibility/dlitem":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class DLItem extends AxeAudit{ static get meta(){ return{ id:'dlitem', title:'Definition list items are wrapped in `<dl>` elements', failureTitle:'Definition list items are not wrapped in `<dl>` elements', description:'Definition list items (`<dt>` and `<dd>`) must be wrapped in a '+ 'parent `<dl>` element to ensure that screen readers can properly announce them. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/dlitem?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=DLItem; },{"./axe-audit":1}],"../audits/accessibility/document-title":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class DocumentTitle extends AxeAudit{ static get meta(){ return{ id:'document-title', title:'Document has a `<title>` element', failureTitle:'Document doesn\'t have a `<title>` element', description:'The title gives screen reader users an overview of the page, and search '+ 'engine users rely on it heavily to determine if a page is relevant to their search. '+ '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/title).', requiredArtifacts:['Accessibility']}; }} module.exports=DocumentTitle; },{"./axe-audit":1}],"../audits/accessibility/duplicate-id":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class DuplicateId extends AxeAudit{ static get meta(){ return{ id:'duplicate-id', title:'`[id]` attributes on the page are unique', failureTitle:'`[id]` attributes on the page are not unique', description:'The value of an id attribute must be unique to prevent '+ 'other instances from being overlooked by assistive technologies. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/duplicate-id?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=DuplicateId; },{"./axe-audit":1}],"../audits/accessibility/frame-title":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class FrameTitle extends AxeAudit{ static get meta(){ return{ id:'frame-title', title:'`<frame>` or `<iframe>` elements have a title', failureTitle:'`<frame>` or `<iframe>` elements do not have a title', description:'Screen reader users rely on frame titles to describe the contents of frames. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/frame-title?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=FrameTitle; },{"./axe-audit":1}],"../audits/accessibility/html-has-lang":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class HTMLHasLang extends AxeAudit{ static get meta(){ return{ id:'html-has-lang', title:'`<html>` element has a `[lang]` attribute', failureTitle:'`<html>` element does not have a `[lang]` attribute', description:'If a page doesn\'t specify a lang attribute, a screen reader assumes '+ 'that the page is in the default language that the user chose when setting up the '+ 'screen reader. If the page isn\'t actually in the default language, then the screen '+ 'reader might not announce the page\'s text correctly. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/html-lang?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=HTMLHasLang; },{"./axe-audit":1}],"../audits/accessibility/html-lang-valid":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class HTMLLangValid extends AxeAudit{ static get meta(){ return{ id:'html-lang-valid', title:'`<html>` element has a valid value for its `[lang]` attribute', failureTitle:'`<html>` element does not have a valid value for '+ 'its `[lang]` attribute.', description:'Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) '+ 'helps screen readers announce text properly. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/valid-lang?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=HTMLLangValid; },{"./axe-audit":1}],"../audits/accessibility/image-alt":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ImageAlt extends AxeAudit{ static get meta(){ return{ id:'image-alt', title:'Image elements have `[alt]` attributes', failureTitle:'Image elements do not have `[alt]` attributes', description:'Informative elements should aim for short, descriptive alternate text. '+ 'Decorative elements can be ignored with an empty alt attribute. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/image-alt?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ImageAlt; },{"./axe-audit":1}],"../audits/accessibility/input-image-alt":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class InputImageAlt extends AxeAudit{ static get meta(){ return{ id:'input-image-alt', title:'`<input type="image">` elements have `[alt]` text', failureTitle:'`<input type="image">` elements do not have `[alt]` text', description:'When an image is being used as an `<input>` button, providing alternative '+ 'text can help screen reader users understand the purpose of the button. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/input-image-alt?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=InputImageAlt; },{"./axe-audit":1}],"../audits/accessibility/label":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class Label extends AxeAudit{ static get meta(){ return{ id:'label', title:'Form elements have associated labels', failureTitle:'Form elements do not have associated labels', description:'Labels ensure that form controls are announced properly by assistive '+ 'technologies, like screen readers. [Learn '+ 'more](https://dequeuniversity.com/rules/axe/2.2/label?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=Label; },{"./axe-audit":1}],"../audits/accessibility/layout-table":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class LayoutTable extends AxeAudit{ static get meta(){ return{ id:'layout-table', title:'Presentational `<table>` elements avoid using `<th>`, `<caption>` or the '+ '`[summary]` attribute.', failureTitle:'Presentational `<table>` elements do not avoid using `<th>`, '+ '`<caption>` or the `[summary]` attribute.', description:'A table being used for layout purposes should not include data elements, '+ 'such as the th or caption elements or the summary attribute, because this can '+ 'create a confusing experience for screen reader users. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/layout-table?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=LayoutTable; },{"./axe-audit":1}],"../audits/accessibility/link-name":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class LinkName extends AxeAudit{ static get meta(){ return{ id:'link-name', title:'Links have a discernible name', failureTitle:'Links do not have a discernible name', description:'Link text (and alternate text for images, when used as links) that is '+ 'discernible, unique, and focusable improves the navigation experience for '+ 'screen reader users. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/link-name?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=LinkName; },{"./axe-audit":1}],"../audits/accessibility/listitem":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ListItem extends AxeAudit{ static get meta(){ return{ id:'listitem', title:'List items (`<li>`) are contained within `<ul>` or `<ol>` parent elements', failureTitle:'List items (`<li>`) are not contained within `<ul>` '+ 'or `<ol>` parent elements.', description:'Screen readers require list items (`<li>`) to be contained within a '+ 'parent `<ul>` or `<ol>` to be announced properly. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/listitem?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ListItem; },{"./axe-audit":1}],"../audits/accessibility/list":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class List extends AxeAudit{ static get meta(){ return{ id:'list', title:'Lists contain only `<li>` elements and script supporting elements '+ '(`<script>` and `<template>`).', failureTitle:'Lists do not contain only `<li>` elements and script '+ 'supporting elements (`<script>` and `<template>`).', description:'Screen readers have a specific way of announcing lists. Ensuring proper list '+ 'structure aids screen reader output. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/list?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=List; },{"./axe-audit":1}],"../audits/accessibility/manual/custom-controls-labels":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class CustomControlsLabels extends ManualAudit{ static get meta(){ return Object.assign({ id:'custom-controls-labels', description:'Custom interactive controls have associated labels, provided by aria-label or aria-labelledby. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#try_it_with_a_screen_reader).', title:'Custom controls have associated labels'}, super.partialMeta); }} module.exports=CustomControlsLabels; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/custom-controls-roles":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class CustomControlsRoles extends ManualAudit{ static get meta(){ return Object.assign({ id:'custom-controls-roles', description:'Custom interactive controls have appropriate ARIA roles. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#try_it_with_a_screen_reader).', title:'Custom controls have ARIA roles'}, super.partialMeta); }} module.exports=CustomControlsRoles; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/focus-traps":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class FocusTraps extends ManualAudit{ static get meta(){ return Object.assign({ id:'focus-traps', description:'A user can tab into and out of any control or region without accidentally trapping their focus. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#start_with_the_keyboard).', title:'User focus is not accidentally trapped in a region'}, super.partialMeta); }} module.exports=FocusTraps; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/focusable-controls":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class FocusableControls extends ManualAudit{ static get meta(){ return Object.assign({ id:'focusable-controls', description:'Custom interactive controls are keyboard focusable and display a focus indicator. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#start_with_the_keyboard).', title:'Interactive controls are keyboard focusable'}, super.partialMeta); }} module.exports=FocusableControls; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/heading-levels":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class HeadingLevels extends ManualAudit{ static get meta(){ return Object.assign({ id:'heading-levels', description:'Headings are used to create an outline for the page and heading levels are not skipped. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#take_advantage_of_headings_and_landmarks).', title:'Headings don\'t skip levels'}, super.partialMeta); }} module.exports=HeadingLevels; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/logical-tab-order":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class LogicalTabOrder extends ManualAudit{ static get meta(){ return Object.assign({ id:'logical-tab-order', description:'Tabbing through the page follows the visual layout. Users cannot focus elements that are offscreen. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#start_with_the_keyboard).', title:'The page has a logical tab order'}, super.partialMeta); }} module.exports=LogicalTabOrder; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/managed-focus":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class ManagedFocus extends ManualAudit{ static get meta(){ return Object.assign({ id:'managed-focus', description:'If new content, such as a dialog, is added to the page, the user\'s focus is directed to it. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#start_with_the_keyboard).', title:'The user\'s focus is directed to new content added to the page'}, super.partialMeta); }} module.exports=ManagedFocus; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/offscreen-content-hidden":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class OffscreenContentHidden extends ManualAudit{ static get meta(){ return Object.assign({ id:'offscreen-content-hidden', description:'Offscreen content is hidden with display: none or aria-hidden=true. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#try_it_with_a_screen_reader).', title:'Offscreen content is hidden from assistive technology'}, super.partialMeta); }} module.exports=OffscreenContentHidden; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/use-landmarks":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class UseLandmarks extends ManualAudit{ static get meta(){ return Object.assign({ id:'use-landmarks', description:'Landmark elements (<main>, <nav>, etc.) are used to improve the keyboard navigation of the page for assistive technology. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#take_advantage_of_headings_and_landmarks).', title:'HTML5 landmark elements are used to improve navigation'}, super.partialMeta); }} module.exports=UseLandmarks; },{"../../manual/manual-audit":4}],"../audits/accessibility/manual/visual-order-follows-dom":[function(require,module,exports){ 'use strict'; const ManualAudit=require('../../manual/manual-audit'); class VisualOrderFollowsDOM extends ManualAudit{ static get meta(){ return Object.assign({ id:'visual-order-follows-dom', description:'DOM order matches the visual order, improving navigation for assistive technology. [Learn more](https://developers.google.com/web/fundamentals/accessibility/how-to-review#try_it_with_a_screen_reader).', title:'Visual order on the page follows DOM order'}, super.partialMeta); }} module.exports=VisualOrderFollowsDOM; },{"../../manual/manual-audit":4}],"../audits/accessibility/meta-refresh":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class MetaRefresh extends AxeAudit{ static get meta(){ return{ id:'meta-refresh', title:'The document does not use `<meta http-equiv="refresh">`', failureTitle:'The document uses `<meta http-equiv="refresh">`', description:'Users do not expect a page to refresh automatically, and doing so will move '+ 'focus back to the top of the page. This may create a frustrating or '+ 'confusing experience. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/meta-refresh?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=MetaRefresh; },{"./axe-audit":1}],"../audits/accessibility/meta-viewport":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class MetaViewport extends AxeAudit{ static get meta(){ return{ id:'meta-viewport', title:'`[user-scalable="no"]` is not used in the `<meta name="viewport">` '+ 'element and the `[maximum-scale]` attribute is not less than 5.', failureTitle:'`[user-scalable="no"]` is used in the `<meta name="viewport">` '+ 'element or the `[maximum-scale]` attribute is less than 5.', description:'Disabling zooming is problematic for users with low vision who rely on '+ 'screen magnification to properly see the contents of a web page. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/meta-viewport?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=MetaViewport; },{"./axe-audit":1}],"../audits/accessibility/object-alt":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ObjectAlt extends AxeAudit{ static get meta(){ return{ id:'object-alt', title:'`<object>` elements have `[alt]` text', failureTitle:'`<object>` elements do not have `[alt]` text', description:'Screen readers cannot translate non-text content. Adding alt text to '+ '`<object>` elements helps screen readers convey meaning to users. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/object-alt?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ObjectAlt; },{"./axe-audit":1}],"../audits/accessibility/tabindex":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class TabIndex extends AxeAudit{ static get meta(){ return{ id:'tabindex', title:'No element has a `[tabindex]` value greater than 0', failureTitle:'Some elements have a `[tabindex]` value greater than 0', description:'A value greater than 0 implies an explicit navigation ordering. '+ 'Although technically valid, this often creates frustrating experiences '+ 'for users who rely on assistive technologies. [Learn more](https://dequeuniversity.com/rules/axe/2.2/tabindex?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=TabIndex; },{"./axe-audit":1}],"../audits/accessibility/td-headers-attr":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class TDHeadersAttr extends AxeAudit{ static get meta(){ return{ id:'td-headers-attr', title:'Cells in a `<table>` element that use the `[headers]` attribute only refer '+ 'to other cells of that same table.', failureTitle:'Cells in a `<table>` element that use the `[headers]` '+ 'attribute refers to other cells of that same table.', description:'Screen readers have features to make navigating tables easier. Ensuring '+ '`<td>` cells using the `[headers]` attribute only refer to other cells in the same '+ 'table may improve the experience for screen reader users. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/td-headers-attr?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=TDHeadersAttr; },{"./axe-audit":1}],"../audits/accessibility/th-has-data-cells":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class THHasDataCells extends AxeAudit{ static get meta(){ return{ id:'th-has-data-cells', title:'`<th>` elements and elements with `[role="columnheader"/"rowheader"]` have '+ 'data cells they describe.', failureTitle:'`<th>` elements and elements with '+ '`[role="columnheader"/"rowheader"]` do not have data cells they describe.', description:'Screen readers have features to make navigating tables easier. Ensuring '+ 'table headers always refer to some set of cells may improve the experience for screen '+ 'reader users. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/th-has-data-cells?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=THHasDataCells; },{"./axe-audit":1}],"../audits/accessibility/valid-lang":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class ValidLang extends AxeAudit{ static get meta(){ return{ id:'valid-lang', title:'`[lang]` attributes have a valid value', failureTitle:'`[lang]` attributes do not have a valid value', description:'Specifying a valid [BCP 47 language](https://www.w3.org/International/questions/qa-choosing-language-tags#question) '+ 'on elements helps ensure that text is pronounced correctly by a screen reader. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/valid-lang?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=ValidLang; },{"./axe-audit":1}],"../audits/accessibility/video-caption":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class VideoCaption extends AxeAudit{ static get meta(){ return{ id:'video-caption', title:'`<video>` elements contain a `<track>` element with `[kind="captions"]`', failureTitle:'`<video>` elements do not contain a `<track>` element '+ 'with `[kind="captions"]`.', description:'When a video provides a caption it is easier for deaf and hearing impaired '+ 'users to access its information. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/video-caption?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=VideoCaption; },{"./axe-audit":1}],"../audits/accessibility/video-description":[function(require,module,exports){ 'use strict'; const AxeAudit=require('./axe-audit'); class VideoDescription extends AxeAudit{ static get meta(){ return{ id:'video-description', title:'`<video>` elements contain a `<track>` element with `[kind="description"]`', failureTitle:'`<video>` elements do not contain a `<track>` element with '+ '`[kind="description"]`.', description:'Audio descriptions provide relevant information for videos that dialogue '+ 'cannot, such as facial expressions and scenes. '+ '[Learn more](https://dequeuniversity.com/rules/axe/2.2/video-description?application=lighthouse).', requiredArtifacts:['Accessibility']}; }} module.exports=VideoDescription; },{"./axe-audit":1}],"../audits/bootup-time":[function(require,module,exports){ 'use strict'; const Audit=require('./audit'); const Util=require('../report/html/renderer/util'); const NetworkRequest=require('../lib/network-request'); const{taskGroups}=require('../lib/task-groups'); class BootupTime extends Audit{ static get meta(){ return{ id:'bootup-time', title:'JavaScript boot-up time', failureTitle:'JavaScript boot-up time is too high', scoreDisplayMode:Audit.SCORING_MODES.NUMERIC, description:'Consider reducing the time spent parsing, compiling, and executing JS. '+ 'You may find delivering smaller JS payloads helps with this. [Learn '+ 'more](https://developers.google.com/web/tools/lighthouse/audits/bootup).', requiredArtifacts:['traces']}; } static get defaultOptions(){ return{ scorePODR:600, scoreMedian:3500, thresholdInMs:50}; } static getJavaScriptURLs(records){ const urls=new Set(); for(const record of records){ if(record.resourceType===NetworkRequest.TYPES.Script){ urls.add(record.url); } } return urls; } static getExecutionTimingsByURL(tasks,jsURLs){ const result=new Map(); for(const task of tasks){ const jsURL=task.attributableURLs.find(url=>jsURLs.has(url)); const fallbackURL=task.attributableURLs[0]; const attributableURL=jsURL||fallbackURL; if(!attributableURL||attributableURL==='about:blank')continue; const timingByGroupId=result.get(attributableURL)||{}; const originalTime=timingByGroupId[task.group.id]||0; timingByGroupId[task.group.id]=originalTime+task.selfTime; result.set(attributableURL,timingByGroupId); } return result; } static async audit(artifacts,context){ const settings=context.settings||{}; const trace=artifacts.traces[BootupTime.DEFAULT_PASS]; const devtoolsLog=artifacts.devtoolsLogs[BootupTime.DEFAULT_PASS]; const networkRecords=await artifacts.requestNetworkRecords(devtoolsLog); const tasks=await artifacts.requestMainThreadTasks(trace); const multiplier=settings.throttlingMethod==='simulate'? settings.throttling.cpuSlowdownMultiplier:1; const jsURLs=BootupTime.getJavaScriptURLs(networkRecords); const executionTimings=BootupTime.getExecutionTimingsByURL(tasks,jsURLs); let totalBootupTime=0; const results=Array.from(executionTimings). map(([url,timingByGroupId])=>{ let bootupTimeForURL=0; for(const[groupId,timespanMs]of Object.entries(timingByGroupId)){ timingByGroupId[groupId]=timespanMs*multiplier; bootupTimeForURL+=timespanMs*multiplier; } if(bootupTimeForURL>=context.options.thresholdInMs){ totalBootupTime+=bootupTimeForURL; } const scriptingTotal=timingByGroupId[taskGroups.scriptEvaluation.id]||0; const parseCompileTotal=timingByGroupId[taskGroups.scriptParseCompile.id]||0; return{ url:url, total:bootupTimeForURL, scripting:scriptingTotal, scriptParseCompile:parseCompileTotal}; }). filter(result=>result.total>=context.options.thresholdInMs). sort((a,b)=>b.total-a.total); const summary={wastedMs:totalBootupTime}; const headings=[ {key:'url',itemType:'url',text:'URL'}, {key:'total',granularity:1,itemType:'ms',text:'Total'}, {key:'scripting',granularity:1,itemType:'ms',text:taskGroups.scriptEvaluation.label}, {key:'scriptParseCompile',granularity:1,itemType:'ms', text:taskGroups.scriptParseCompile.label}]; const details=BootupTime.makeTableDetails(headings,results,summary); const score=Audit.computeLogNormalScore( totalBootupTime, context.options.scorePODR, context.options.scoreMedian); return{ score, rawValue:totalBootupTime, displayValue:[Util.MS_DISPLAY_VALUE,totalBootupTime], details}; }} module.exports=BootupTime; },{"../lib/network-request":38,"../lib/task-groups":43,"../report/html/renderer/util":48,"./audit":2}],"../audits/byte-efficiency/efficient-animated-content":[function(require,module,exports){ 'use strict'; const NetworkRequest=require('../../lib/network-request'); const ByteEfficiencyAudit=require('./byte-efficiency-audit'); const GIF_BYTE_THRESHOLD=100*1024; class EfficientAnimatedContent extends ByteEfficiencyAudit{ static get meta(){ return{ id:'efficient-animated-content', scoreDisplayMode:ByteEfficiencyAudit.SCORING_MODES.NUMERIC, title:'Use video formats for animated content', description:'Large GIFs are inefficient for delivering animated content. Consider using '+ 'MPEG4/WebM videos for animations and PNG/WebP for static images instead of GIF to save '+ 'network bytes. [Learn more](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/replace-animated-gifs-with-video/)', requiredArtifacts:['devtoolsLogs']}; } static getPercentSavings(bytes){ return Math.round(29.1*Math.log10(bytes)-100.7)/100; } static audit_(artifacts,networkRecords){ const unoptimizedContent=networkRecords.filter( record=>record.mimeType==='image/gif'&& record.resourceType===NetworkRequest.TYPES.Image&& (record.resourceSize||0)>GIF_BYTE_THRESHOLD); const items=unoptimizedContent.map(record=>{ const resourceSize=record.resourceSize||0; return{ url:record.url, totalBytes:resourceSize, wastedBytes:Math.round(resourceSize* EfficientAnimatedContent.getPercentSavings(resourceSize))}; }); const headings=[ {key:'url',valueType:'url',label:'URL'}, {key:'totalBytes',valueType:'bytes',label:'Transfer Size'}, {key:'wastedBytes',valueType:'bytes',label:'Byte Savings'}]; return{ items, headings}; }} module.exports=EfficientAnimatedContent; },{"../../lib/network-request":38,"./byte-efficiency-audit":3}],"../audits/byte-efficiency/offscreen-images":[function(require,module,exports){ 'use strict'; const ByteEfficiencyAudit=require('./byte-efficiency-audit'); const Sentry=require('../../lib/sentry'); const URL=require('../../lib/url-shim'); const ALLOWABLE_OFFSCREEN_X=100; const ALLOWABLE_OFFSCREEN_Y=200; const IGNORE_THRESHOLD_IN_BYTES=2048; const IGNORE_THRESHOLD_IN_PERCENT=75; const IGNORE_THRESHOLD_IN_MS=50; class OffscreenImages extends ByteEfficiencyAudit{ static get meta(){ return{ id:'offscreen-images', title:'Defer offscreen images', scoreDisplayMode:ByteEfficiencyAudit.SCORING_MODES.NUMERIC, description: 'Consider lazy-loading offscreen and hidden images after all critical resources have '+ 'finished loading to lower time to interactive. '+ '[Learn more](https://developers.google.com/web/tools/lighthouse/audits/offscreen-images).', requiredArtifacts:['ImageUsage','ViewportDimensions','traces','devtoolsLogs']}; } static computeVisiblePixels(imageRect,viewportDimensions){ const innerWidth=viewportDimensions.innerWidth; const innerHeight=viewportDimensions.innerHeight; const top=Math.max(imageRect.top,-1*ALLOWABLE_OFFSCREEN_Y); const right=Math.min(imageRect.right,innerWidth+ALLOWABLE_OFFSCREEN_X); const bottom=Math.min(imageRect.bottom,innerHeight+ALLOWABLE_OFFSCREEN_Y); const left=Math.max(imageRect.left,-1*ALLOWABLE_OFFSCREEN_X); return Math.max(right-left,0)*Math.max(bottom-top,0); } static computeWaste(image,viewportDimensions){ if(!image.networkRecord){ return null; } const url=URL.elideDataURI(image.src); const totalPixels=image.clientWidth*image.clientHeight; const visiblePixels=this.computeVisiblePixels(image.clientRect,viewportDimensions); const wastedRatio=totalPixels===0?1:1-visiblePixels/totalPixels; const totalBytes=image.networkRecord.resourceSize; const wastedBytes=Math.round(totalBytes*wastedRatio); if(!Number.isFinite(wastedRatio)){ return new Error(`Invalid image sizing information ${url}`); } return{ url, requestStartTime:image.networkRecord.startTime, totalBytes, wastedBytes, wastedPercent:100*wastedRatio}; } static filterLanternResults(images,lanternMetricData){ const nodeTimings=lanternMetricData.pessimisticEstimate.nodeTimings; let lastLongTaskStartTime=0; const startTimesByURL=new Map(); for(const[node,timing]of nodeTimings){ if(node.type==='cpu'&&timing.duration>=50){ lastLongTaskStartTime=Math.max(lastLongTaskStartTime,timing.startTime); }else if(node.type==='network'){ const networkNode=node; startTimesByURL.set(networkNode.record.url,timing.startTime); } } return images.filter(image=>{ if(image.wastedBytes<IGNORE_THRESHOLD_IN_BYTES)return false; if(image.wastedPercent<IGNORE_THRESHOLD_IN_PERCENT)return false; const imageRequestStartTime=startTimesByURL.get(image.url)||0; return imageRequestStartTime<lastLongTaskStartTime-IGNORE_THRESHOLD_IN_MS; }); } static filterObservedResults(images,interactiveTimestamp){ return images.filter(image=>{ if(image.wastedBytes<IGNORE_THRESHOLD_IN_BYTES)return false; if(image.wastedPercent<IGNORE_THRESHOLD_IN_PERCENT)return false; return image.requestStartTime<interactiveTimestamp/1e6-IGNORE_THRESHOLD_IN_MS/1000; }); } static computeWasteWithTTIGraph(results,graph,simulator){ return super.computeWasteWithTTIGraph(results,graph,simulator, {includeLoad:false}); } static audit_(artifacts,networkRecords,context){ const images=artifacts.ImageUsage; const viewportDimensions=artifacts.ViewportDimensions; const trace=artifacts.traces[ByteEfficiencyAudit.DEFAULT_PASS]; const devtoolsLog=artifacts.devtoolsLogs[ByteEfficiencyAudit.DEFAULT_PASS]; const warnings=[]; const resultsMap=images.reduce((results,image)=>{ const processed=OffscreenImages.computeWaste(image,viewportDimensions); if(processed===null){ return results; } if(processed instanceof Error){ warnings.push(processed.message); Sentry.captureException(processed,{tags:{audit:this.meta.id},level:'warning'}); return results; } const existing=results.get(processed.url); if(!existing||existing.wastedBytes>processed.wastedBytes){ results.set(processed.url,processed); } return results; },new Map()); const settings=context.settings; return artifacts.requestInteractive({trace,devtoolsLog,settings}).then(interactive=>{ const unfilteredResults=Array.from(resultsMap.values()); const lanternInteractive=interactive; const items=context.settings.throttlingMethod==='simulate'? OffscreenImages.filterLanternResults(unfilteredResults,lanternInteractive): OffscreenImages.filterObservedResults(unfilteredResults,interactive.timestamp); const headings=[ {key:'url',valueType:'thumbnail',label:''}, {key:'url',valueType:'url',label:'URL'}, {key:'totalBytes',valueType:'bytes',label:'Original'}, {key:'wastedBytes',valueType:'bytes',label:'Potential Savings'}]; return{ warnings, items, headings}; }); }} module.exports=OffscreenImages; },{"../../lib/sentry":40,"../../lib/url-shim":"url","./byte-efficiency-audit":3}],"../audits/byte-efficiency/render-blocking-resources":[function(require,module,exports){ 'use strict'; const Audit=require('../audit'); const BaseNode=require('../../lib/dependency-graph/base-node'); const ByteEfficiencyAudit=require('./byte-efficiency-audit'); const UnusedCSS=require('./unused-css-rules'); const NetworkRequest=require('../../lib/network-request'); const MINIMUM_WASTED_MS=50; function getNodesAndTimingByUrl(nodeTimings){ const urlMap={}; const nodes=Array.from(nodeTimings.keys()); nodes.forEach(node=>{ if(node.type!=='network')return; const nodeTiming=nodeTimings.get(node); if(!nodeTiming)return; urlMap[node.record.url]={node,nodeTiming}; }); return urlMap; } class RenderBlockingResources extends Audit{ static get meta(){ return{ id:'render-blocking-resources', title:'Eliminate render-blocking resources', scoreDisplayMode:Audit.SCORING_MODES.NUMERIC, description: 'Resources are blocking the first paint of your page. Consider '+ 'delivering critical JS/CSS inline and deferring all non-critical '+ 'JS/styles. [Learn more](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources).', requiredArtifacts:['URL','TagsBlockingFirstPaint','traces']}; } static async computeResults(artifacts,context){ const trace=artifacts.traces[Audit.DEFAULT_PASS]; const devtoolsLog=artifacts.devtoolsLogs[Audit.DEFAULT_PASS]; const simulatorData={devtoolsLog,settings:context.settings}; const traceOfTab=await artifacts.requestTraceOfTab(trace); const simulator=await artifacts.requestLoadSimulator(simulatorData); const wastedCssBytes=await RenderBlockingResources.computeWastedCSSBytes(artifacts,context); const metricSettings={throttlingMethod:'simulate'}; const metricComputationData={trace,devtoolsLog,simulator,settings:metricSettings}; const fcpSimulation=await artifacts.requestFirstContentfulPaint(metricComputationData); const fcpTsInMs=traceOfTab.timestamps.firstContentfulPaint/1000; const nodesByUrl=getNodesAndTimingByUrl(fcpSimulation.optimisticEstimate.nodeTimings); const results=[]; const deferredNodeIds=new Set(); for(const resource of artifacts.TagsBlockingFirstPaint){ if(resource.endTime*1000>fcpTsInMs)continue; if(!nodesByUrl[resource.tag.url])continue; const{node,nodeTiming}=nodesByUrl[resource.tag.url]; node.traverse(node=>deferredNodeIds.add(node.id)); const wastedMs=Math.round(nodeTiming.duration); if(wastedMs<MINIMUM_WASTED_MS)continue; results.push({ url:resource.tag.url, totalBytes:resource.transferSize, wastedMs}); } if(!results.length){ return{results,wastedMs:0}; } const wastedMs=RenderBlockingResources.estimateSavingsWithGraphs( simulator, fcpSimulation.optimisticGraph, deferredNodeIds, wastedCssBytes); return{results,wastedMs}; } static estimateSavingsWithGraphs(simulator,fcpGraph,deferredIds,wastedCssBytesByUrl){ const originalEstimate=simulator.simulate(fcpGraph).timeInMs; let totalChildNetworkBytes=0; const minimalFCPGraph=fcpGraph.cloneWithRelationships(node=>{ const canDeferRequest=deferredIds.has(node.id); if(node.type!==BaseNode.TYPES.NETWORK)return!canDeferRequest; const isStylesheet= node.record.resourceType===NetworkRequest.TYPES.Stylesheet; if(canDeferRequest&&isStylesheet){ const wastedBytes=wastedCssBytesByUrl.get(node.record.url)||0; totalChildNetworkBytes+=(node.record.transferSize||0)-wastedBytes; } return!canDeferRequest; }); const originalTransferSize=minimalFCPGraph.record.transferSize; const safeTransferSize=originalTransferSize||0; minimalFCPGraph.record.transferSize=safeTransferSize+totalChildNetworkBytes; const estimateAfterInline=simulator.simulate(minimalFCPGraph).timeInMs; minimalFCPGraph.record.transferSize=originalTransferSize; return Math.round(Math.max(originalEstimate-estimateAfterInline,0)); } static async computeWastedCSSBytes(artifacts,context){ const wastedBytesByUrl=new Map(); try{ const results=await UnusedCSS.audit(artifacts,context); for(const item of results.details.items){ wastedBytesByUrl.set(item.url,item.wastedBytes); } }catch(_){} return wastedBytesByUrl; } static async audit(artifacts,context){ const{results,wastedMs}=await RenderBlockingResources.computeResults(artifacts,context); let displayValue=''; if(results.length>1){ displayValue=`${results.length} resources delayed first paint by ${wastedMs}ms`; }else if(results.length===1){ displayValue=`${results.length} resource delayed first paint by ${wastedMs}ms`; } const headings=[ {key:'url',valueType:'url',label:'URL'}, {key:'totalBytes',valueType:'bytes',label:'Size (KB)'}, {key:'wastedMs',valueType:'timespanMs',label:'Download Time (ms)'}]; const details=Audit.makeOpportunityDetails(headings,results,wastedMs); return{ displayValue, score:ByteEfficiencyAudit.scoreForWastedMs(wastedMs), rawValue:wastedMs, details}; }} module.exports=RenderBlockingResources; },{"../../lib/dependency-graph/base-node":22,"../../lib/network-request":38,"../audit":2,"./byte-efficiency-audit":3,"./unused-css-rules":"../audits/byte-efficiency/unused-css-rules"}],"../audits/byte-efficiency/total-byte-weight":[function(require,module,exports){ 'use strict'; const ByteEfficiencyAudit=require('./byte-efficiency-audit'); class TotalByteWeight extends ByteEfficiencyAudit{ static get meta(){ return{ id:'total-byte-weight', title:'Avoids enormous network payloads', failureTitle:'Has enormous network payloads', scoreDisplayMode:ByteEfficiencyAudit.SCORING_MODES.NUMERIC, description: 'Large network payloads cost users real money and are highly correlated with '+ 'long load times. [Learn '+ 'more](https://developers.google.com/web/tools/lighthouse/audits/network-payloads).', requiredArtifacts:['devtoolsLogs']}; } static get defaultOptions(){ return{ scorePODR:2500*1024, scoreMedian:4000*1024}; } static async audit(artifacts,context){ const devtoolsLogs=artifacts.devtoolsLogs[ByteEfficiencyAudit.DEFAULT_PASS]; const[networkRecords,networkThroughput]=await Promise.all([ artifacts.requestNetworkRecords(devtoolsLogs), artifacts.requestNetworkThroughput(devtoolsLogs)]); let totalBytes=0; let results=[]; networkRecords.forEach(record=>{ if(record.parsedURL.scheme==='data'||!record.finished)return; const result={ url:record.url, totalBytes:record.transferSize, totalMs:ByteEfficiencyAudit.bytesToMs(record.transferSize,networkThroughput)}; totalBytes+=result.totalBytes; results.push(result); }); const totalCompletedRequests=results.length; results=results.sort((itemA,itemB)=>itemB.totalBytes-itemA.totalBytes).slice(0,10); const score=ByteEfficiencyAudit.computeLogNormalScore( totalBytes, context.options.scorePODR, context.options.scoreMedian); const headings=[ {key:'url',itemType:'url',text:'URL'}, { key:'totalBytes', itemType:'bytes', displayUnit:'kb', granularity:1, text:'Total Size'}, {key:'totalMs',itemType:'ms',text:'Transfer Time'}]; const tableDetails=ByteEfficiencyAudit.makeTableDetails(headings,results); return{ score, rawValue:totalBytes, displayValue:[ 'Total size was %d\xa0KB', totalBytes/1024], extendedInfo:{ value:{ results, totalCompletedRequests