Showing preview only (4,499K chars total). Download the full file or copy to clipboard to get everything.
Repository: nature/pa11y-dashboard
Branch: main
Commit: 2327a1b664fb
Files: 369
Total size: 4.2 MB
Directory structure:
gitextract_db6hdddw/
├── .bowerrc
├── .dockerignore
├── .editorconfig
├── .github/
│ ├── issue_template.md
│ └── workflows/
│ └── tests.yml
├── .gitignore
├── .npmrc
├── .nvmrc
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile.example
├── LICENSE
├── MIGRATION.md
├── Makefile
├── README.md
├── app.js
├── bower.json
├── config/
│ ├── development.sample.json
│ ├── production.sample.json
│ └── test.sample.json
├── config.js
├── data/
│ ├── standards.js
│ └── techniques.js
├── eslint.config.js
├── index.js
├── package.json
├── public/
│ ├── js/
│ │ ├── site.js
│ │ └── vendor/
│ │ ├── bootstrap/
│ │ │ ├── .bower.json
│ │ │ ├── CNAME
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── DOCS-LICENSE
│ │ │ ├── Gruntfile.js
│ │ │ ├── LICENSE
│ │ │ ├── LICENSE-MIT
│ │ │ ├── README.md
│ │ │ ├── _config.yml
│ │ │ ├── _includes/
│ │ │ │ ├── ads.html
│ │ │ │ ├── footer.html
│ │ │ │ ├── header.html
│ │ │ │ ├── nav-about.html
│ │ │ │ ├── nav-components.html
│ │ │ │ ├── nav-css.html
│ │ │ │ ├── nav-customize.html
│ │ │ │ ├── nav-getting-started.html
│ │ │ │ ├── nav-javascript.html
│ │ │ │ ├── nav-main.html
│ │ │ │ ├── old-bs-docs.html
│ │ │ │ └── social-buttons.html
│ │ │ ├── _layouts/
│ │ │ │ ├── default.html
│ │ │ │ └── home.html
│ │ │ ├── about.html
│ │ │ ├── bower.json
│ │ │ ├── browserstack.json
│ │ │ ├── components.html
│ │ │ ├── composer.json
│ │ │ ├── css.html
│ │ │ ├── customize.html
│ │ │ ├── dist/
│ │ │ │ ├── css/
│ │ │ │ │ ├── bootstrap-theme.css
│ │ │ │ │ └── bootstrap.css
│ │ │ │ └── js/
│ │ │ │ └── bootstrap.js
│ │ │ ├── docs-assets/
│ │ │ │ ├── css/
│ │ │ │ │ ├── docs.css
│ │ │ │ │ └── pygments-manni.css
│ │ │ │ └── js/
│ │ │ │ ├── application.js
│ │ │ │ ├── customizer.js
│ │ │ │ ├── filesaver.js
│ │ │ │ ├── holder.js
│ │ │ │ ├── ie8-responsive-file-warning.js
│ │ │ │ ├── jszip.js
│ │ │ │ ├── less.js
│ │ │ │ ├── raw-files.js
│ │ │ │ └── uglify.js
│ │ │ ├── examples/
│ │ │ │ ├── carousel/
│ │ │ │ │ ├── carousel.css
│ │ │ │ │ └── index.html
│ │ │ │ ├── grid/
│ │ │ │ │ ├── grid.css
│ │ │ │ │ └── index.html
│ │ │ │ ├── jumbotron/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── jumbotron.css
│ │ │ │ ├── jumbotron-narrow/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── jumbotron-narrow.css
│ │ │ │ ├── justified-nav/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── justified-nav.css
│ │ │ │ ├── navbar/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar.css
│ │ │ │ ├── navbar-fixed-top/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar-fixed-top.css
│ │ │ │ ├── navbar-static-top/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar-static-top.css
│ │ │ │ ├── non-responsive/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── non-responsive.css
│ │ │ │ ├── offcanvas/
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── offcanvas.css
│ │ │ │ │ └── offcanvas.js
│ │ │ │ ├── signin/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── signin.css
│ │ │ │ ├── starter-template/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── starter-template.css
│ │ │ │ ├── sticky-footer/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── sticky-footer.css
│ │ │ │ ├── sticky-footer-navbar/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── sticky-footer-navbar.css
│ │ │ │ └── theme/
│ │ │ │ ├── index.html
│ │ │ │ └── theme.css
│ │ │ ├── getting-started.html
│ │ │ ├── index.html
│ │ │ ├── javascript.html
│ │ │ ├── js/
│ │ │ │ ├── affix.js
│ │ │ │ ├── alert.js
│ │ │ │ ├── button.js
│ │ │ │ ├── carousel.js
│ │ │ │ ├── collapse.js
│ │ │ │ ├── dropdown.js
│ │ │ │ ├── modal.js
│ │ │ │ ├── popover.js
│ │ │ │ ├── scrollspy.js
│ │ │ │ ├── tab.js
│ │ │ │ ├── tests/
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── unit/
│ │ │ │ │ │ ├── affix.js
│ │ │ │ │ │ ├── alert.js
│ │ │ │ │ │ ├── button.js
│ │ │ │ │ │ ├── carousel.js
│ │ │ │ │ │ ├── collapse.js
│ │ │ │ │ │ ├── dropdown.js
│ │ │ │ │ │ ├── modal.js
│ │ │ │ │ │ ├── phantom.js
│ │ │ │ │ │ ├── popover.js
│ │ │ │ │ │ ├── scrollspy.js
│ │ │ │ │ │ ├── tab.js
│ │ │ │ │ │ ├── tooltip.js
│ │ │ │ │ │ └── transition.js
│ │ │ │ │ └── vendor/
│ │ │ │ │ ├── jquery.js
│ │ │ │ │ ├── qunit.css
│ │ │ │ │ └── qunit.js
│ │ │ │ ├── tooltip.js
│ │ │ │ └── transition.js
│ │ │ ├── less/
│ │ │ │ ├── alerts.less
│ │ │ │ ├── badges.less
│ │ │ │ ├── bootstrap.less
│ │ │ │ ├── breadcrumbs.less
│ │ │ │ ├── button-groups.less
│ │ │ │ ├── buttons.less
│ │ │ │ ├── carousel.less
│ │ │ │ ├── close.less
│ │ │ │ ├── code.less
│ │ │ │ ├── component-animations.less
│ │ │ │ ├── dropdowns.less
│ │ │ │ ├── forms.less
│ │ │ │ ├── glyphicons.less
│ │ │ │ ├── grid.less
│ │ │ │ ├── input-groups.less
│ │ │ │ ├── jumbotron.less
│ │ │ │ ├── labels.less
│ │ │ │ ├── list-group.less
│ │ │ │ ├── media.less
│ │ │ │ ├── mixins.less
│ │ │ │ ├── modals.less
│ │ │ │ ├── navbar.less
│ │ │ │ ├── navs.less
│ │ │ │ ├── normalize.less
│ │ │ │ ├── pager.less
│ │ │ │ ├── pagination.less
│ │ │ │ ├── panels.less
│ │ │ │ ├── popovers.less
│ │ │ │ ├── print.less
│ │ │ │ ├── progress-bars.less
│ │ │ │ ├── responsive-utilities.less
│ │ │ │ ├── scaffolding.less
│ │ │ │ ├── tables.less
│ │ │ │ ├── theme.less
│ │ │ │ ├── thumbnails.less
│ │ │ │ ├── tooltip.less
│ │ │ │ ├── type.less
│ │ │ │ ├── utilities.less
│ │ │ │ ├── variables.less
│ │ │ │ └── wells.less
│ │ │ └── package.json
│ │ ├── flot/
│ │ │ ├── .bower.json
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── API.md
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── FAQ.md
│ │ │ ├── LICENSE.txt
│ │ │ ├── Makefile
│ │ │ ├── NEWS.md
│ │ │ ├── PLUGINS.md
│ │ │ ├── README.md
│ │ │ ├── component.json
│ │ │ ├── examples/
│ │ │ │ ├── ajax/
│ │ │ │ │ ├── data-eu-gdp-growth-1.json
│ │ │ │ │ ├── data-eu-gdp-growth-2.json
│ │ │ │ │ ├── data-eu-gdp-growth-3.json
│ │ │ │ │ ├── data-eu-gdp-growth-4.json
│ │ │ │ │ ├── data-eu-gdp-growth-5.json
│ │ │ │ │ ├── data-eu-gdp-growth.json
│ │ │ │ │ ├── data-japan-gdp-growth.json
│ │ │ │ │ ├── data-usa-gdp-growth.json
│ │ │ │ │ └── index.html
│ │ │ │ ├── annotating/
│ │ │ │ │ └── index.html
│ │ │ │ ├── axes-interacting/
│ │ │ │ │ └── index.html
│ │ │ │ ├── axes-multiple/
│ │ │ │ │ └── index.html
│ │ │ │ ├── axes-time/
│ │ │ │ │ └── index.html
│ │ │ │ ├── axes-time-zones/
│ │ │ │ │ ├── date.js
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── tz/
│ │ │ │ │ ├── africa
│ │ │ │ │ ├── antarctica
│ │ │ │ │ ├── asia
│ │ │ │ │ ├── australasia
│ │ │ │ │ ├── backward
│ │ │ │ │ ├── etcetera
│ │ │ │ │ ├── europe
│ │ │ │ │ ├── factory
│ │ │ │ │ ├── iso3166.tab
│ │ │ │ │ ├── leapseconds
│ │ │ │ │ ├── northamerica
│ │ │ │ │ ├── pacificnew
│ │ │ │ │ ├── solar87
│ │ │ │ │ ├── solar88
│ │ │ │ │ ├── solar89
│ │ │ │ │ ├── southamerica
│ │ │ │ │ ├── systemv
│ │ │ │ │ ├── yearistype.sh
│ │ │ │ │ └── zone.tab
│ │ │ │ ├── basic-options/
│ │ │ │ │ └── index.html
│ │ │ │ ├── basic-usage/
│ │ │ │ │ └── index.html
│ │ │ │ ├── canvas/
│ │ │ │ │ └── index.html
│ │ │ │ ├── categories/
│ │ │ │ │ └── index.html
│ │ │ │ ├── examples.css
│ │ │ │ ├── image/
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ ├── interacting/
│ │ │ │ │ └── index.html
│ │ │ │ ├── navigate/
│ │ │ │ │ └── index.html
│ │ │ │ ├── percentiles/
│ │ │ │ │ └── index.html
│ │ │ │ ├── realtime/
│ │ │ │ │ └── index.html
│ │ │ │ ├── resize/
│ │ │ │ │ └── index.html
│ │ │ │ ├── selection/
│ │ │ │ │ └── index.html
│ │ │ │ ├── series-errorbars/
│ │ │ │ │ └── index.html
│ │ │ │ ├── series-pie/
│ │ │ │ │ └── index.html
│ │ │ │ ├── series-toggle/
│ │ │ │ │ └── index.html
│ │ │ │ ├── series-types/
│ │ │ │ │ └── index.html
│ │ │ │ ├── stacking/
│ │ │ │ │ └── index.html
│ │ │ │ ├── symbols/
│ │ │ │ │ └── index.html
│ │ │ │ ├── threshold/
│ │ │ │ │ └── index.html
│ │ │ │ ├── tracking/
│ │ │ │ │ └── index.html
│ │ │ │ ├── visitors/
│ │ │ │ │ └── index.html
│ │ │ │ └── zooming/
│ │ │ │ └── index.html
│ │ │ ├── excanvas.js
│ │ │ ├── excanvas.min.js
│ │ │ ├── flot.jquery.json
│ │ │ ├── jquery.colorhelpers.js
│ │ │ ├── jquery.flot.canvas.js
│ │ │ ├── jquery.flot.categories.js
│ │ │ ├── jquery.flot.crosshair.js
│ │ │ ├── jquery.flot.dashes.js
│ │ │ ├── jquery.flot.errorbars.js
│ │ │ ├── jquery.flot.fillbetween.js
│ │ │ ├── jquery.flot.image.js
│ │ │ ├── jquery.flot.js
│ │ │ ├── jquery.flot.navigate.js
│ │ │ ├── jquery.flot.pie.js
│ │ │ ├── jquery.flot.resize.js
│ │ │ ├── jquery.flot.selection.js
│ │ │ ├── jquery.flot.stack.js
│ │ │ ├── jquery.flot.symbol.js
│ │ │ ├── jquery.flot.threshold.js
│ │ │ ├── jquery.flot.time.js
│ │ │ ├── jquery.js
│ │ │ └── package.json
│ │ └── jquery/
│ │ ├── .bower.json
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── bower.json
│ │ ├── component.json
│ │ ├── composer.json
│ │ ├── jquery-migrate.js
│ │ ├── jquery.js
│ │ └── package.json
│ └── less/
│ ├── alerts.less
│ ├── badges.less
│ ├── bootswatch.less
│ ├── breadcrumbs.less
│ ├── button-groups.less
│ ├── buttons.less
│ ├── carousel.less
│ ├── close.less
│ ├── code.less
│ ├── component-animations.less
│ ├── dropdowns.less
│ ├── forms.less
│ ├── glyphicons.less
│ ├── grid.less
│ ├── ie8and.less
│ ├── input-groups.less
│ ├── jumbotron.less
│ ├── labels.less
│ ├── list-group.less
│ ├── main.less
│ ├── media.less
│ ├── mixins.less
│ ├── modals.less
│ ├── navbar.less
│ ├── navs.less
│ ├── normalize.less
│ ├── pager.less
│ ├── pagination.less
│ ├── panels.less
│ ├── popovers.less
│ ├── print.less
│ ├── progress-bars.less
│ ├── responsive-utilities.less
│ ├── scaffolding.less
│ ├── site-ie8and.less
│ ├── site-nojavascript.less
│ ├── site-responsive.less
│ ├── site.less
│ ├── tables.less
│ ├── theme.less
│ ├── thumbnails.less
│ ├── tooltip.less
│ ├── type.less
│ ├── utilities.less
│ ├── variables-flatly.less
│ ├── variables.less
│ └── wells.less
├── route/
│ ├── health.js
│ ├── index.js
│ ├── new.js
│ ├── result/
│ │ ├── download.js
│ │ └── index.js
│ └── task/
│ ├── delete.js
│ ├── edit.js
│ ├── ignore.js
│ ├── index.js
│ ├── run.js
│ └── unignore.js
├── test/
│ └── integration/
│ ├── helper/
│ │ └── navigate.js
│ ├── route/
│ │ ├── health.js
│ │ ├── index.js
│ │ ├── new.js
│ │ ├── result/
│ │ │ ├── download.js
│ │ │ └── index.js
│ │ └── task/
│ │ ├── delete.js
│ │ ├── edit.js
│ │ ├── index.js
│ │ └── run.js
│ └── setup.js
└── view/
├── 404.html
├── 500.html
├── helper/
│ ├── conditionals.js
│ ├── date.js
│ ├── string.js
│ └── url.js
├── index.html
├── layout/
│ └── default.html
├── new.html
├── partial/
│ ├── breadcrumb.html
│ ├── graph.html
│ ├── page-footer.html
│ ├── page-header.html
│ ├── result-header.html
│ ├── result.html
│ ├── task-header.html
│ └── tasks.html
├── presenter/
│ ├── ignore.js
│ ├── result-list.js
│ ├── result.js
│ └── task.js
├── result/
│ └── index.html
└── task/
├── delete.html
├── edit.html
└── index.html
================================================
FILE CONTENTS
================================================
================================================
FILE: .bowerrc
================================================
{
"directory" : "public/js/vendor"
}
================================================
FILE: .dockerignore
================================================
# Version control
.git
.github
# Dependencies (must be rebuilt inside the container)
node_modules
# Tests
test
# Build tooling and dev config
Makefile
bower.json
eslint.config.js
.bowerrc
.editorconfig
.markdownlint.jsonc
.npmrc
.nvmrc
# LESS source files (compiled CSS is in public/css)
public/less
# Config files (may contain credentials; samples are kept)
config/development.json
config/production.json
config/test.json
# Documentation
*.md
# Debug logs
npm-debug.log
================================================
FILE: .editorconfig
================================================
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
indent_style = space
trim_trailing_whitespace = false
[*.yml]
indent_style = space
indent_size = 2
[package.json]
indent_style = space
indent_size = 2
================================================
FILE: .github/issue_template.md
================================================
**This repository's issues are reserved for feature requests, bug reports, and other issues with Pa11y Dashboard itself.**
If you need help using Pa11y Dashboard, we recommend using [Stack Overflow](https://stackoverflow.com/questions/tagged/pa11y).
For a bug report, please use the template below. To keep the backlog clean and actionable, issues may be immediately closed if they do not follow one this template.
---
## Expected behaviour
## Actual behaviour
## Steps to reproduce
## Environment
_Please specify the versions of Pa11y Dashboard, MongoDB, and Node.js that can be sued to reproduce this issue._
================================================
FILE: .github/workflows/tests.yml
================================================
on:
push:
branches:
- main
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: 20
- run: npm ci
- run: npm run lint
test:
name: test (node ${{ matrix.node }}, mongodb ${{ matrix.mongo }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [20, 22, 24]
mongo: [latest]
include:
- { node: 20, mongo: 7.0.25 }
- { node: 20, mongo: 6.0.11 }
- { node: 20, mongo: 5.0.22 }
- { node: 20, mongo: 4.4.25 }
- { node: 20, mongo: 3.6.23 }
- { node: 20, mongo: 2.6.12 }
steps:
- name: Disable AppArmor User Namespace Restrictions, required to open
Chrome on Ubuntu 23.10+ without --no-sandbox). See
https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md.
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node }}
- run: npm ci
- name: Supply MongoDB ${{ matrix.mongo }}
uses: supercharge/mongodb-github-action@1.12.0
with:
mongodb-version: ${{ matrix.mongo }}
- name: Supply integration test configuration file
run: cp config/test.sample.json config/test.json
- name: Make dashboard available to be integration-tested
run: NODE_ENV=test node index.js &
- name: Wait for dashboard to respond
uses: iFaxity/wait-on-action@v1.1.0
with:
resource: http://localhost:4000
delay: 1000
timeout: 30000
log: true
- run: NODE_ENV=test npm test
================================================
FILE: .gitignore
================================================
# Logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids/
*.pid
*.seed
*.pid.lock
# Coverage directories and files
coverage/
*.lcov
.nyc_output/
lib-cov/
# Dependency directories
node_modules/
jspm_packages/
bower_components/
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# node-waf configuration
.lock-wscript
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
/package
# Yarn
.yarn-integrity
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# pnpm
.pnpm-store/
# dotenv environment variable files
.env
.env.*
!.env.example
!.env.sample
# macOS
.DS_Store
.AppleDouble
.LSOverride
._*
__MACOSX/
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Editors
.idea/
.vscode/
*.swp
*.swo
*~
# Config files (ignore credentials, keep samples)
config/*.json
!config/*.sample.json
================================================
FILE: .npmrc
================================================
lockfile-version=2
================================================
FILE: .nvmrc
================================================
24
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## 5.2.0 (2026-03-25)
Additional containerisation-related improvements.
* Add new /health health check endpoint to help containerisation
* Minor refactoring of initialisation code
* Add example Dockerfile and containerisation tips
* Minor documentation improvements
**Full Changelog**: https://github.com/pa11y/pa11y-dashboard/compare/5.1.0...5.2.0
## 5.1.0 (2026-03-10)
Improve compatibility with Twelve-Factor App methodology
* Add support for passing Chrome/Chromium config as environment variables, as currently this was only possible via a config file. These are part of the browser config that is sent to webservice and it's usually required in containerised environments.
* Improve documentation around containerisation.
* Improve SIGTERM and SIGINT signal handling for a more graceful shutdown process.
**Full Changelog**: https://github.com/pa11y/pa11y-dashboard/compare/5.0.1...5.1.0
## 5.0.1 (2026-03-03)
* Update dependencies to latest compatible versions by @josebolos in https://github.com/pa11y/pa11y-dashboard/pull/349
**Full Changelog**: https://github.com/pa11y/pa11y-dashboard/compare/5.0.0...5.0.1
## 5.0.0 (commited 2025-11-12, tagged 2026-03-03)
### Changes
* Improve console messaging (thanks @sangitamane)
* Address linting issues (thanks @josebolos and @hollsk)
* Various accessibility improvements to dashboard pages (thanks @sangitamane)
* Improve version support and its verification
* **Major:** Use `pa11y-webservice@5` (which uses `pa11y@9`)
* **Major:** Support Node `20`, `22`, `24` (support for `< 20` dropped)
* Support MongoDB `2`, `4`, `5`, `6`, `7`, `latest`
* Fix various integration test issues
* Other minor dependency upgrades
* Update support policy
### New contributors
+* @danyalaytekin made their first contribution in https://github.com/pa11y/a11y-dashboard/pull/315
### Full diff
* [4.2.0...5.0.0](https://github.com/pa11y/pa11y-dashboard/compare/4.2.0...5.0.0)
## 4.2.0 (2022-03-30)
* Add request logging for easier debugging
* Dependencies update
## 4.1.0 (2021-11-26)
* Add support for new WCAG 2.1 rules and remove all references to Section 508.
* Move troubleshooting guide to the README.
## 4.0.0 (2021-11-26)
* Update pa11y to version 6.
* Drop support for versions of Node.js older than 12.
* Update MongoDB Node driver from v2 to v3, which adds support for MongoDB v4 databases.
## 3.3.0 (2021-04-27)
* Add new list view to the dashboard (thanks @sangitamane)
* Upgrade express-hbs to the latest version in order to address several potential vulnerabilities
* Fixes a MongoDB "ObjectID generation failed" error.
* Update pa11y-webservice to version 3.2.1 and pa11y to version 5.3.1
## 3.2.0 (2020-10-05)
* Update pa11y to version 5.3.0, which means better compatibility with sites using AMD modules
* Update pa11y-webservice to version 3.2.0, which adds the ability to configure the number of workers running pa11y tests
* Update several dependencies
* Replace chalk with kleur
## 3.1.0 (2019-09-27)
* Display the task ID before each line of output, so it's clear to which task a line of output belongs to when they run in parallel.
* Bump pa11y-webservice version, which fixes an issue with some pages failing to run.
* Fix incorrect routes passing an invalid value to Mongo's ObjectID.
## 3.0.0 (2019-07-16)
* Update pa11y to v5, which replaces Phantomjs with Headless Chrome
* Update dependencies
* Several bug fixes and documentation updates
* See the [migration guide](https://github.com/pa11y/pa11y-dashboard/blob/master/MIGRATION.md#migrating-from-20-to-30) for details of the breaking changes in this release
## 2.4.2 (2018-06-21)
* Update dependencies
* body-parser: ~1.17.1 to ^1.18.3
* compression: ~1.6 to ^1.7.2
* express: ~4.15.2 to ^4.16.3
* moment: ~2.15.2 to ^2.22.2
## 2.4.1 (2017-11-28)
* Update dependencies
* pa11y-webservice: ^2.3.0 to ^2.3.1
## 2.4.0 (2017-11-23)
* Add the ability to export the results graph as a PNG, see #197 for more information
## 2.3.0 (2017-10-31)
* Large overhaul of the results page, see #196 for more information
## 2.2.2 (2017-03-23)
* Upgrades `body-parser` and `express`. Fixes a vulnerability in `qs`: https://snyk.io/vuln/npm:qs:20170213
## 2.2.1 (2017-02-07)
* Fix task editing when no actions are specified
## 2.2.0 (2017-01-27)
* Add support for Pa11y actions
* Update dependencies
* pa11y-webservice: ~2.1.2 to ^2.3.0
## 2.1.2 (2016-12-12)
* Hide the "add" button in readonly mode
* Add a contributing guide
## 2.1.1 (2016-11-20)
* Use arrows instead of plus and minus for collapsibles/expanders
* Supply more detailed 500 messages
## 2.1.0 (2016-11-07)
* Allow for configuration files to be JavaScript rather than JSON
* Allow setting of HTTP headers for task runs
* Allow hiding/ignoring elements for task runs
* Update dependencies and devDependencies
* pa11y-webservice: ~2.0.1 to ^2.1.2
* mocha: ^3 to ^2 (temporary – tests weren't running)
## 2.0.1 (2016-09-12)
* Update dependencies and devDependencies
* express: ~4.13 to ~4.14
* pa11y-webservice: ~2.0 to ^2.0.1
* request: ^2 to ^2.74
* mocha: ^2 to ^3
* pa11y-webservice-client-node: ~1.2 to ^1.2.1
This fixes the following vulnerabilities:
* https://nodesecurity.io/advisories/45
* https://nodesecurity.io/advisories/63
* https://nodesecurity.io/advisories/65
* https://nodesecurity.io/advisories/106
* https://nodesecurity.io/advisories/121
* https://nodesecurity.io/advisories/130
## 2.0.0 (2016-06-05)
* Drop Node.js 0.10–0.12 support
* Update dependencies
* pa11y-webservice: ~1.11 to ~2.0
* See the [migration guide](https://github.com/pa11y/dashboard/blob/master/MIGRATION.md#migrating-from-10-to-20) for details
## 1.12.1 (2016-06-05)
* Update references/links after a repo rename
## 1.12.0 (2016-05-26)
* Update Node.js version support to 0.10–6.0
* Update dependencies
* body-parser: added at ~1.15
* chalk: ~0.2 to ~1.1
* compression: added at ~1.6
* express: ~3.4 to ~4.13
* express-hbs: ~0.2 to ~1.0
* moment: ~2.2 to ~2.13
* pa11y-webservice: ~1.10 to ~1.11
* pa11y-webservice-client-node: ~1.1 to ~1.2
* bower: ~1.2 to ~1.7
* cheerio: added at ~0.20
* jsdom: removed
* request: ~2.27 to ^2
* uglify-js: ~2.4 to ~2.6
## 1.11.0 (2016-05-23)
* Add the ability to configure task wait times
* Allow configuration by environment variables
* Update repository references to the new Pa11y organisation
* Add a changelog
## 1.10.0 (2016-05-18)
* Automatically focus on the filter input box when you select the filter
* Make a task URL clickable
* Tweak the documentation to make it more usable
* Add a resources section to the README
## 1.9.0 (2016-04-25)
* Show errors' context and selector on the results page
* Add context and selector to CSV output
* Fix lint errors
* Switch from Grunt to Make
* Add a `SIGINT` handler
* Update dependencies
* pa11y-webservice: ~1.6 to ~1.8
## 1.8.2 (2016-02-10)
* Update the license in the footer
## 1.8.1 (2016-02-10)
* Update repository references to springernature
## 1.8.0 (2016-02-04)
* Make the graph more accessible to color-blind users
* Fix lint errors
## 1.7.0 (2016-01-29)
* Hide the date list from individual result pages
* Make the date selector properly keyboard accessible
* Change the options button into a more accessible list
* Make the errors/warnings/notices lists keyboard accessible
## 1.6.1 (2016-01-26)
* Add keyboard access for filters
* Fix lint errors
## 1.6.0 (2015-08-20)
* Hide all graph data except for errors by default
## 1.5.0 (2015-07-06)
* Add the ability to use HTTP basic auth with task URLs
* Update dependencies
* pa11y-webservice: ~1.5 to ~1.6
## 1.4.0 (2015-07-02)
* Add the ability to set a per-task timeout
## 1.3.2 (2015-01-17)
* Update dependencies
* pa11y-webservice: ~1.3 to ~1.4
## 1.3.1 (2014-03-05)
* Fix the URL filter position when in demo mode
## 1.3.0 (2014-03-04)
* Add filtering of tasks on the home page
* Add the ability to ignore certain rules
* Add the ability to ignore a rule from the result page
* Tweak the display of task cards
## 1.2.3 (2014-01-13)
* Fix CSV export for the OS X version of Excel
## 1.2.2 (2014-01-09)
* Fix spacing issues when the graph is not visible
* Add notes on publishing a release
## 1.2.1 (2014-01-08)
* Fix dropdown positioning in Internet Explorer 7 and 8
## 1.2.0 (2013-12-12)
* Add HTML Codesniffer links on the results page
* Display the ignore rules for results on the results page
* Link the breadcrumbs on task sub-pages
* Fix an issue with saving empty ignore rules
* Cache-bust the CSS and JavaScript
* Add the ability to edit tasks
* Fix lint errors
* Tweaks to the display of the graphs
* Update dependencies
* pa11y-webservice: ~1.1 to ~1.2
* pa11y-webservice-client-node: ~1.0 to ~1.1
## 1.1.0 (2013-11-22)
* Add a functional test suite
* Allow the webservice to run automatically
* Documentation improvements
* Add a Travis config
* Fix lint errors
## 1.0.0 (2013-11-19)
* Initial stable release
* Add the ability to set a site-wide message
* Add a demo mode for demo/public-facing sites
* Disable search engine indexing by default
* Tweak the task header at smaller screen sizes
* Make checkboxes on the graph WCAG2AA compliant
* Make checkbox inputs and labels WCAG2AA compliant on new URL page
* Colour changes to ensure there are no contrast issues
* Make the copy more consistent
* Update screenshots
* Update dependencies
* pa11y-webservice-client-node: 1.0.0-beta.7 to ~1.0
## 1.0.0-beta.3 pre-release (2013-11-12)
* Fix lint errors
* Add descriptive labels to tasks
* Add a name field to "New URL" form
* Add a WCAG 2.0 link to the footer
* Tweak the layout at smaller screen sizes
* Notify users when there are no ignored rules
* Fix the expires headers for front end assets
* Move from Make to Grunt
* Compress static files
* Minify the site JavaScript
* Compile LESS files with grunt
* Add a watch task to recompile assets on change
* Commit compiled front-end code to the repo
* Add development instructions
* Update screenshots
* Update dependencies
* pa11y-webservice-client-node: 1.0.0-beta.4 to 1.0.0-beta.7
## 1.0.0-beta.2 pre-release (2013-10-04)
* Add screenshots to the README
* Fix margins
* Add bower package management
* Stop the graph from appearing if there's only one result
* Add the ability to run tasks ad-hoc
* Add more useful information to the footer
* General copy edits
* Update dependencies
* pa11y-webservice-client-node: 1.0.0-beta.3 to 1.0.0-beta.4
## 1.0.0-beta.1 pre-release (2013-09-27)
* Initial release
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing Guide
Thanks for getting involved :tada:
The Pa11y team loves to see new contributors, and we strive to provide a welcoming and inclusive environment. We ask that all contributors read and follow [our code of conduct][code-of-conduct] before joining. If you represent an organisation, then you might find our [guide for companies][companies] helpful.
Our website outlines the many ways that you can contribute to Pa11y:
- [Help us to talk to our users][communications]
- [Help us out with design][designers]
- [Help us with our code][developers]
[code-of-conduct]: https://pa11y.org/contributing/code-of-conduct/
[communications]: https://pa11y.org/contributing/communications/
[companies]: https://pa11y.org/contributing/companies/
[designers]: https://pa11y.org/contributing/designers/
[developers]: https://pa11y.org/contributing/developers/
================================================
FILE: Dockerfile.example
================================================
# Example Dockerfile for Pa11y Dashboard
#
# This is a starting point that you can adapt to your infrastructure. It is NOT
# intended to be used as-is.
#
# What this file provides:
#
# - Multi-stage build to keep the final image small
# - All Chromium system dependencies needed by Puppeteer
# - Puppeteer cache handled correctly across build stages
# - Non-root user for running the application and Chromium
#
# What you still need to provide:
#
# - A MongoDB instance (external; NOT included in this image)
# - Runtime configuration via environment variables (see README.md)
#
# Adapt this file to your needs. Common customisations include:
#
# - Adding corporate CA certificates (see commented-out example below)
# - Changing the Node.js or Debian version
# - Using `git clone` instead of `COPY` if your Dockerfile lives in a
# separate deployment repo (see commented-out alternative below)
# --- Build stage ---
FROM node:24-slim AS build
# Ensure the base image is fully up to date before installing dependencies
RUN apt -qq update && \
DEBIAN_FRONTEND=noninteractive apt -yqq full-upgrade && \
DEBIAN_FRONTEND=noninteractive apt -yqq autoremove && \
rm -rf /var/lib/apt/lists/*
# -- If your organisation uses a corporate proxy or TLS-intercepting CA
# (e.g. Zscaler), uncomment the following lines and place your CA
# certificate in the build context:
#
# COPY your-corporate-ca.pem /usr/local/share/ca-certificates/corporate-ca.crt
# RUN apt -qq update && \
# DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install \
# ca-certificates && \
# update-ca-certificates && \
# rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy application source into the build context.
# The .dockerignore file excludes dev files, tests, and config files.
COPY . .
# -- Alternative: if your Dockerfile lives in a separate deployment repo
# (not inside the pa11y-dashboard repo), replace the `COPY . .` above
# with a git clone. This is useful when your deployment repo only
# contains infrastructure files (Dockerfile, CI config, manifests).
#
# ARG PA11Y_DASHBOARD_VERSION=main
# RUN apt -qq update && \
# DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install \
# git ca-certificates && \
# rm -rf /var/lib/apt/lists/*
# RUN git clone --depth 1 --branch ${PA11Y_DASHBOARD_VERSION} \
# https://github.com/pa11y/pa11y-dashboard.git .
# Install system libraries required by Puppeteer's bundled Chromium binary.
# These must be present at `npm ci` time because Puppeteer downloads and
# validates Chrome during installation.
RUN apt -qq update && \
DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install \
fonts-liberation \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libgbm1 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libx11-xcb1 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
xdg-utils \
wget \
&& rm -rf /var/lib/apt/lists/*
# Puppeteer downloads Chromium to a cache directory during `npm ci`. By
# default this goes to ~/.cache, which is outside /app and would not survive
# the COPY --from=build in the runtime stage. Setting PUPPETEER_CACHE_DIR
# inside /app ensures the Chromium binary is included in the final image.
ENV PUPPETEER_CACHE_DIR=/app/.cache/puppeteer
RUN npm ci --omit=dev
# --- Runtime stage ---
FROM node:24-slim
# Install the same Chromium system libraries in the runtime stage.
# Only runtime dependencies are needed here (no wget, git, etc.).
RUN apt -qq update && \
DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install \
fonts-liberation \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libgbm1 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libx11-xcb1 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
xdg-utils \
&& rm -rf /var/lib/apt/lists/*
# -- If you added a corporate CA certificate in the build stage, repeat it
# here so that outbound HTTPS requests at runtime also work:
#
# RUN apt -qq update && \
# DEBIAN_FRONTEND=noninteractive apt -yqq --no-install-recommends install \
# ca-certificates && \
# rm -rf /var/lib/apt/lists/*
# COPY your-corporate-ca.pem /usr/local/share/ca-certificates/corporate-ca.crt
# RUN update-ca-certificates
# ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
# Run as a non-root user. Chromium will refuse to launch as root without
# --no-sandbox, and running as non-root is good practice regardless.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
&& mkdir -p /home/pptruser/Downloads \
&& chown -R pptruser:pptruser /home/pptruser
WORKDIR /app
COPY --from=build /app /app
RUN chown -R pptruser:pptruser /app
USER pptruser
ENV NODE_ENV=production
# Must match the PUPPETEER_CACHE_DIR used in the build stage
ENV PUPPETEER_CACHE_DIR=/app/.cache/puppeteer
EXPOSE 4000
CMD ["node", "index.js"]
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
================================================
FILE: MIGRATION.md
================================================
# Migration Guide
Pa11y Dashboard's API changes between major versions. This is a guide to help you make the switch when this happens.
## Table of contents
* [Table of contents](#table-of-contents)
* [Migrating from 4.0 to 5.0](#migrating-from-40-to-50)
* [Migrating from 3.0 to 4.0](#migrating-from-30-to-40)
* [Migrating from 2.0 to 3.0](#migrating-from-20-to-30)
* [PhantomJS to Headless Chrome](#phantomjs-to-headless-chrome)
* [Node.js Support](#nodejs-support)
* [Miscellaneous](#miscellaneous)
* [Migrating from 1.0 to 2.0](#migrating-from-10-to-20)
* [Node.js Support](#nodejs-support-1)
## Migrating from 4.0 to 5.0
Pa11y Dashboard 5 requires Node.js version 20 or greater.
## Migrating from 3.0 to 4.0
Pa11y Dashboard requires Node.js version 12 or greater. Versions 8 and 10 are not supported any more.
In addition, to use Pa11y Dashboard 4 with a version of Ubuntu above 20.04, a path to the Chrome executable must be defined in `chromeLaunchConfig`, as `chromeLaunchConfig.executablePath`. See the README's [Pa11y Dashboard and Linux/Ubuntu](README.md#pa11y-dashboard-and-linuxubuntu) section for details.
## Migrating from 2.0 to 3.0
### PhantomJS to Headless Chrome
Pa11y Dashboard 3 uses version 5 of Pa11y, which replaces PhantomJS with [Headless Chrome](https://developers.google.com/web/updates/2017/04/headless-chrome). This allows us to use more modern JavaScript APIs and make Pa11y testing more stable.
As a result of this change, [Pa11y Dashboard's requirements](../README.md#requirements) have changed, and you may need to install additional dependencies required by Chrome before being able to use this version.
### Node.js Support
Pa11y Dashboard 3 requires Node.js version 8 or greater. Versions 4 and 6 are not supported any more.
### Miscellaneous
The default viewport dimensions for Pa11y have been changed from `1024x768` to `1280x1024`. This could make pa11y report a different number of errors if different content appears on the page based on its width, so results obtained with v2 and v3 may not be comparable.
## Migrating from 1.0 to 2.0
### Node.js Support
The only breaking change in Pa11y Dashboard 2.0 is that Node.js 0.10 and 0.12 are no longer supported. We'll be using newer ES6 features in upcoming releases which will not work in these older Node.js versions.
================================================
FILE: Makefile
================================================
# Client-side asset tasks
# -----------------------
less:
@lessc -x ./public/less/main.less ./public/css/site.min.css
@$(TASK_DONE)
uglify:
@uglifyjs \
public/js/vendor/jquery/jquery.min.js \
public/js/vendor/bootstrap/js/alert.js \
public/js/vendor/bootstrap/js/dropdown.js \
public/js/vendor/bootstrap/js/tooltip.js \
public/js/vendor/bootstrap/js/transition.js \
public/js/vendor/bootstrap/js/collapse.js \
public/js/vendor/bootstrap/js/tab.js \
public/js/vendor/bootstrap/js/popover.js \
public/js/vendor/flot/jquery.flot.js \
public/js/vendor/flot/jquery.flot.dashes.js \
public/js/vendor/flot/jquery.flot.time.js \
public/js/vendor/flot/jquery.flot.selection.js \
public/js/vendor/flot/jquery.flot.resize.js \
public/js/vendor/helpers/html2canvas.min.js \
public/js/site.js \
-o ./public/js/site.min.js
@$(TASK_DONE)
================================================
FILE: README.md
================================================
# Pa11y Dashboard
Pa11y Dashboard is a web interface to the [Pa11y][pa11y] accessibility reporter, allowing you to focus on *fixing* issues rather than hunting them down.
![Version][shield-version]
[![Node.js version support][shield-node]][info-node]
[![Build status][shield-build]][info-build]
[![GPL-3.0 licensed][shield-license]][info-license]


---
## Running Pa11y Dashboard
### Requirements
- [Node.js][node]: Pa11y Dashboard 5 requires a stable (even-numbered) version of Node.js of 20 or above.
- [MongoDB][mongodb]: This project depends on Pa11y Webservice, which stores test results in a MongoDB database and expects one to be available and running.
#### Pa11y Dashboard and Linux/Ubuntu
Pa11y Dashboard uses Puppeteer, which bundles its own Chromium binary. On some Linux distributions (notably Ubuntu 20.04 and above), this bundled binary may fail to launch because required shared libraries are not installed by default.
There are two ways to resolve this:
1. **Install the missing system dependencies** so that the bundled Chromium works. The list of required packages varies by distribution. Refer to [Puppeteer's troubleshooting guide](https://pptr.dev/troubleshooting#chrome-doesnt-launch-on-linux) for the current list.
2. **Use a system-installed Chromium** instead of the bundled one. Install your distribution's Chromium package (e.g. `apt install chromium-browser`) and point Pa11y Dashboard to it via the `executablePath` option in [`chromeLaunchConfig`](#chromelaunchconfig), or the `CHROMIUM_EXECUTABLE` environment variable (e.g. `/usr/bin/chromium-browser`).
### Setting up Pa11y Dashboard
In order to run Pa11y Dashboard, we recommend cloning this repository locally:
```sh
git clone https://github.com/pa11y/pa11y-dashboard.git
```
Then installing the dependencies:
```sh
cd pa11y-dashboard
npm install
```
#### Installing MongoDB
Instructions for installing and running MongoDB are outside the scope of this document. When in doubt, please refer to the [MongoDB installation instructions](https://docs.mongodb.com/manual/installation/) for details of how to install and run MongoDB on your specific operating system. An example of the installation and configuration process for macOS follows.
Pa11y Dashboard uses [MongoDB Node.js Driver][mongodb-package] version 3, which [may not support some features][mongodb-package-compatibility] of MongoDB versions 6 and beyond. We do however test against MongoDB versions 2 to 7, plus the latest major version, which at the time of writing is `8`.
##### Example MongoDB installation for macOS
On recent versions of macOS (10.13 or later), you can use [Homebrew] to install MongoDB Community Edition.
Tap the MongoDB Homebrew Tap:
```sh
brew tap mongodb/brew
```
Install a supported Community version of MongoDB:
```sh
brew install mongodb-community@8.0
```
Start the MongoDB server:
```sh
brew services start mongodb/brew/mongodb-community@8.0
```
Check that the service has started properly:
```console
$ brew services list
Name Status User Plist
mongodb-community started pa11y /Users/pa11y/Library/LaunchAgents/homebrew.mxcl.mongodb-community.plist
```
#### Configuring Pa11y Dashboard
The last step before being able to run Pa11y Dashboard is to define a configuration for it. This can be done in two ways:
##### Option 1: Using environment variables
Each configuration can be set with an environment variable rather than a config file. For example to run the application on port `8080` you can use the following:
```sh
PORT=8080 node index.js
```
A more complete example using all available environment variables, as you might use in a Docker or cloud deployment:
```sh
PORT=8080 \
NOINDEX=true \
READONLY=false \
WEBSERVICE_DATABASE=mongodb://user:password@mongo-host:27017/pa11y \
WEBSERVICE_HOST=0.0.0.0 \
WEBSERVICE_PORT=3000 \
WEBSERVICE_CRON="0 30 0 * * *" \
CHROMIUM_FLAGS="--no-sandbox,--disable-setuid-sandbox" \
node index.js
```
The [available configurations](#configurations) are documented in the next section.
##### Option 2: Using config files
You can store the configuration for Pa11y Dashboard on a JSON file. You can use a different configuration file for each environment you're planning to run Pa11y Dashboard on. You can choose a specific environment to run the application from by setting the `NODE_ENV` environment variable:
```sh
NODE_ENV=development node index.js
```
Three example files are provided in this repository, you can copy and customise them to your liking:
```sh
cp config/development.sample.json config/development.json
```
```sh
cp config/test.sample.json config/test.json
```
```sh
cp config/production.sample.json config/production.json
```
The [production example](config/production.sample.json) uses all the existing configuration options as it would typically be used in a containerised environment:
```json
{
"port": 8080,
"noindex": true,
"readonly": false,
"webservice": {
"database": "mongodb://user:password@mongo-host:27017/pa11y",
"host": "0.0.0.0",
"port": 3000,
"cron": "0 30 0 * * *",
"chromeLaunchConfig": {
"args": [
"--no-sandbox",
"--disable-setuid-sandbox"
]
}
}
}
```
The [available configurations](#configurations) are documented in the next section.
If you run into problems, check the [troubleshooting guide](#troubleshooting).
### Running in Docker and other containerised environments
Pa11y Dashboard uses Puppeteer to launch a Chromium browser for accessibility testing. If you are running Pa11y Dashboard inside a Docker container, a Kubernetes pod, or any similar containerised environment, you will almost certainly need to pass the `--no-sandbox` and `--disable-setuid-sandbox` flags to Chromium.
This is necessary because Chromium relies on Linux user namespaces to sandbox its renderer processes. Disabling Chrome's sandbox with `--no-sandbox` is standard practice in containerised deployments and is safe provided the container runtime's own isolation is in place. The `--disable-setuid-sandbox` flag disables Chrome's older setuid-based sandbox fallback, which requires a setuid-root helper binary that is typically unavailable (and undesirable) in non-root container images.
Set these flags using the `CHROMIUM_FLAGS` environment variable or the `chromeLaunchConfig.args` config file option, as shown in the [configuration examples above](#configuring-pa11y-dashboard).
#### Cloud environment considerations
Pa11y Dashboard runs by default an embedded instance of [Pa11y Webservice][pa11y-webservice], which schedules accessibility tests using a cron expression. Each instance of the webservice runs its own independent cron scheduler with no distributed queue.
If you deploy multiple replicas (as is typically the default in most cloud environments) of Pa11y Dashboard with an embedded webservice, every replica will trigger the same scheduled tests independently. This will result in duplicated test runs and duplicated results in the database.
To avoid this, consider one of the following approaches:
- **Limit to a single replica.** If running the embedded webservice, ensure only one replica is active. This is the simplest option but sacrifices availability.
- **Run the webservice separately.** Deploy [Pa11y Webservice][pa11y-webservice] as a single-instance service and point the dashboard at it by setting [`webservice`](#webservice) to its URL. This way you can scale the dashboard replicas freely without duplicating scheduled tests.
#### Example Dockerfile
An example Dockerfile is provided at [`Dockerfile.example`](Dockerfile.example) to help you get started with containerised deployments. It is a starting point — **you are expected to review it and adapt it to your specific infrastructure before use**.
The example Dockerfile handles the non-obvious parts of containerising a Puppeteer-based application:
- **Multi-stage build** to keep the final image small (build tools and git are not included in the runtime image).
- **Chromium system dependencies** — Puppeteer bundles its own Chromium binary, but that binary depends on shared libraries that are not present in slim base images. The Dockerfile installs all required libraries in both the build and runtime stages.
- **Puppeteer cache directory** — Puppeteer downloads Chromium to a cache directory during `npm install`. By default this goes to `~/.cache`, which is outside the application directory and would not survive the `COPY --from=build` step in a multi-stage build. The Dockerfile sets `PUPPETEER_CACHE_DIR` inside the application directory so the Chromium binary is carried over to the final image.
- **Non-root user** — the application and Chromium run as a non-root user (`pptruser`).
The Dockerfile does **not** include MongoDB. You are expected to provision your database separately (as a managed service, a sidecar container, or however your organisation handles databases) and pass the connection string via the `WEBSERVICE_DATABASE` environment variable.
**Approach 1 — Dockerfile inside the pa11y-dashboard repo:**
If you are building directly from a clone of this repository then the default `COPY . .` instruction in the example Dockerfile will work. The included [`.dockerignore`](.dockerignore) excludes tests, development tooling, and config files from the build context. Copy the example and build:
```sh
cp Dockerfile.example Dockerfile
docker build -t pa11y-dashboard .
```
**Approach 2 — Dockerfile in a separate deployment repo:**
If you prefer to keep your deployment configuration (Dockerfile, CI/CD pipeline, manifests) in a separate repository, switch from `COPY . .` to the commented-out `git clone` alternative in the Dockerfile. This clones pa11y-dashboard at a pinned version during the build, keeping your deployment repo independent from the application source code. See the comments in `Dockerfile.example` for instructions.
**Running the image:**
Pass all configuration via environment variables at runtime. No config files need to be baked into the image. For example:
```sh
docker run -p 4000:4000 \
-e WEBSERVICE_DATABASE="mongodb://user:password@your-mongo-host:27017/pa11y" \
-e WEBSERVICE_HOST="0.0.0.0" \
-e WEBSERVICE_CRON="0 30 0 * * *" \
-e CHROMIUM_FLAGS="--no-sandbox,--disable-setuid-sandbox" \
pa11y-dashboard
```
### Configurations
The boot configurations for Pa11y Dashboard are as follows. Look at the sample JSON files in the repo for example usage.
#### `port`
*(number)* The port to run the application on. Set via a config file or the `PORT` environment variable.
#### `noindex`
*(boolean)* If set to `true` (default), the dashboard will not be indexed by search engines. Set to `false` to allow indexing. Set via a config file or the `NOINDEX` environment variable.
#### `readonly`
*(boolean)* If set to `true`, users will not be able to add, delete or run URLs (defaults to `false`). Set via a config file or the `READONLY` environment variable.
#### `siteMessage`
*(string)* A message to display prominently on the site home page. Defaults to `null`.
#### `webservice`
This can either be an object containing [Pa11y Webservice configurations][pa11y-webservice-config], or a string which is the base URL of a Pa11y Webservice instance you are running separately. If using environment variables, prefix the webservice vars with `WEBSERVICE_`.
#### `chromeLaunchConfig`
Configuration for the Chromium instance launched by Pa11y. When using a config file, this is an object nested under `webservice`:
```json
"webservice": {
"chromeLaunchConfig": {
"args": ["--no-sandbox", "--disable-setuid-sandbox"],
"executablePath": "/usr/bin/chromium"
}
}
```
When using environment variables, the following options are available:
- `CHROMIUM_FLAGS`: A comma-separated list of flags to pass to Chromium. For example, `--no-sandbox,--disable-setuid-sandbox`.
- `CHROMIUM_EXECUTABLE`: The path to a Chromium executable to use instead of Puppeteer's bundled binary. See [Pa11y Dashboard and Linux/Ubuntu](#pa11y-dashboard-and-linuxubuntu) for when this is needed.
## Contributing
There are many ways to contribute to Pa11y Dashboard, we cover these in the [contributing guide](CONTRIBUTING.md) for this repo.
If you're ready to contribute some code, you'll need to clone the repo and get set up as outlined in the [setup guide](#setting-up-pa11y-dashboard). You'll then need to start the application in test mode with:
```sh
NODE_ENV=test node index.js
```
You'll now be able to run the following commands:
```sh
npm run lint # Lint the code
npm test # Run all tests
```
To compile the client-side JavaScript and CSS, you'll need the following commands. Compiled code is committed to the repository.
```sh
make less # Compile the site CSS from LESS files
make uglify # Compile and uglify the client-side JavaScript
```
## Troubleshooting
### Common issues
- `500` errors or `Could not connect to pa11y-webservice` messages are often related to MongoDB. Ensure that you have the [appropriate version of MongoDB](#installing-mongodb) installed, and that it's running - it doesn't always start automatically.
- Error messages saying that pa11y-webservice isn't running may be due to dependency installation problems. Try deleting your `pa11y-dashboard/node_modules` directory and running `npm install` again.
### Create a new issue
Check the [issue tracker][issues] for similar issues before creating a new one. If the problem that you're experiencing is not covered by one of the existing issues, you can [create a new issue][issues-create]. Please include your node.js and MongoDB version numbers, and your operating system, as well as any information that may be useful in debugging the issue.
## Support and migration
> [!NOTE]
> We maintain a [migration guide](MIGRATION.md) to help you migrate between major versions.
When we release a new major version we will continue to support the previous major version for 6 months. This support will be limited to fixes for critical bugs and security issues. If you're opening an issue related to this project, please mention the specific version that the issue affects.
The following table lists the major versions available and, for each previous major version, its end-of-support date, and its final minor version released.
| Major version | Last minor release | Node.js support | Support end date |
| :------------ | :----------------- | :-------------------------- | :--------------- |
| `5` | | `20`, `22`, `24` | ✅ Current major version |
| `4` | `4.2` | `12`, `14`, `16`, `18`, `20`| May 2026 |
| `3` | `3.3` | `8`, `10` | May 2022 |
| `2` | `2.4` | `4`, `6` | January 2020 |
| `1` | `1.12` | `0.10`, `0.12`, `4`, `6` | December 2016 |
## License
Pa11y Dashboard is licensed under the [GNU General Public License 3.0][info-license].
Copyright © 2016-2025, Team Pa11y and contributors
[homebrew]: https://brew.sh/
[issues]: https://github.com/pa11y/pa11y-dashboard/issues?utf8=%E2%9C%93&q=is%3Aissue
[issues-create]: https://github.com/pa11y/pa11y-dashboard/issues/new
[mongodb]: http://www.mongodb.org/
[mongodb-package]: https://www.npmjs.com/package/mongodb
[mongodb-package-compatibility]: https://docs.mongodb.com/drivers/node/current/compatibility
[node]: http://nodejs.org/
[pa11y]: https://github.com/pa11y/pa11y
[pa11y-webservice-config]: https://github.com/pa11y/webservice#configurations
[info-node]: package.json
[info-build]: https://github.com/pa11y/pa11y-dashboard/actions/workflows/tests.yml
[info-license]: LICENSE
[shield-version]: https://img.shields.io/github/package-json/v/pa11y/pa11y-dashboard.svg
[shield-node]: https://img.shields.io/node/v/pa11y/pa11y-dashboard.svg
[shield-build]: https://github.com/pa11y/pa11y-dashboard/actions/workflows/tests.yml/badge.svg
[shield-license]: https://img.shields.io/badge/license-GPL%203.0-blue.svg
================================================
FILE: app.js
================================================
// This file is part of Pa11y Dashboard.
//
// Pa11y Dashboard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Pa11y Dashboard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
'use strict';
const bodyParser = require('body-parser');
const compression = require('compression');
const createClient = require('pa11y-webservice-client-node');
const {EventEmitter} = require('events');
const express = require('express');
const hbs = require('express-hbs');
const morgan = require('morgan');
const {nanoid} = require('nanoid');
const http = require('http');
const path = require('path');
const pkg = require('./package.json');
module.exports = initApp;
function initApp(config, callback) {
config = defaultConfig(config);
let webserviceUrl = config.webservice;
if (typeof webserviceUrl === 'object') {
webserviceUrl = `http://${webserviceUrl.host}:${webserviceUrl.port}/`;
}
const app = new EventEmitter();
app.express = express();
app.server = http.createServer(app.express);
app.webservice = createClient(webserviceUrl);
loadMiddleware(app);
// View engine
loadViewEngine(app, config);
// Load routes
loadRoutes(app, config);
// Error handling
loadErrorHandling(app, config, callback);
}
function defaultConfig(config) {
if (typeof config.noindex !== 'boolean') {
config.noindex = true;
}
if (typeof config.readonly !== 'boolean') {
config.readonly = false;
}
return config;
}
function loadMiddleware(app) {
app.express.use(compression());
// Adds an ID to every request, used later for logging
app.express.use(addRequestId);
// Logging middleware
morgan.token('id', request => {
return request.id;
});
// Log the start of all HTTP requests
const startLog = '[:date[iso] #:id] Started :method :url for :remote-addr';
// Immediate: true is required to log the request
// before the response happens
app.express.use(morgan(startLog, {immediate: true}));
// Log the end of all HTTP requests
const endLog = '[:date[iso] #:id] Completed :status :res[content-length] in :response-time ms';
app.express.use(morgan(endLog));
// Public files
app.express.use(express.static(path.join(__dirname, 'public'), {
maxAge: (process.env.NODE_ENV === 'production' ? 604800000 : 0)
}));
// General express config
app.express.disable('x-powered-by');
app.express.use(bodyParser.urlencoded({
extended: true
}));
}
function loadViewEngine(app, config) {
app.express.engine('html', hbs.express4({
extname: '.html',
contentHelperName: 'content',
layoutsDir: path.join(__dirname, 'view', 'layout'),
partialsDir: path.join(__dirname, 'view', 'partial'),
defaultLayout: path.join(__dirname, 'view', 'layout', 'default')
}));
app.express.set('views', path.join(__dirname, 'view'));
app.express.set('view engine', 'html');
// View helpers
require('./view/helper/date')(hbs);
require('./view/helper/string')(hbs);
require('./view/helper/url')(hbs);
require('./view/helper/conditionals')(hbs);
// Populate view locals
app.express.locals = {
lang: 'en',
year: (new Date()).getFullYear(),
version: pkg.version,
repo: pkg.homepage,
bugtracker: pkg.bugs,
noindex: config.noindex,
readonly: config.readonly,
siteMessage: config.siteMessage,
settings: {}
};
app.express.use((request, response, next) => {
response.locals.isHomePage = (request.path === '/');
response.locals.host = request.hostname;
next();
});
}
function loadRoutes(app, config) {
// Health check endpoint (must be registered before task routes
// to avoid the ID parameter matching '/health' as a task ID)
require('./route/health')(app);
// Because there's some overlap between the different routes,
// they have to be loaded in a specific order in order to avoid
// passing mongo the wrong id which would result in
// "ObjectID generation failed." errors (e.g. #277)
require('./route/index')(app);
require('./route/result/download')(app);
if (!config.readonly) {
require('./route/new')(app);
require('./route/task/delete')(app);
require('./route/task/run')(app);
require('./route/task/edit')(app);
require('./route/task/ignore')(app);
require('./route/task/unignore')(app);
}
// Needs to be loaded after `/route/new`
require('./route/task/index')(app);
// Needs to be loaded after `/route/task/edit`
require('./route/result/index')(app);
}
function loadErrorHandling(app, config, callback) {
app.express.get('*', (request, response) => {
response.status(404);
response.render('404');
});
app.express.use((error, request, response, next) => {
/* eslint no-unused-vars: 'off' */
if (error.code === 'ECONNREFUSED') {
error = new Error('Could not connect to Pa11y Webservice');
}
app.emit('route-error', error);
if (process.env.NODE_ENV !== 'production') {
response.locals.error = error;
}
response.status(500);
response.render('500');
});
app.server.listen(config.port, error => {
callback(error, app);
});
}
// Express middleware
function addRequestId(request, response, next) {
// Create a random request (nano)id, 10 characters long
// Nano ids are [0-9A-Za-z_-] so chance of collision is 1 in 64^10
// If a site has so much traffic that this chance is too high
// we probably have worse things to worry about
request.id = nanoid(10);
next();
}
================================================
FILE: bower.json
================================================
{
"name": "pa11y-dashboard",
"dependencies": {
"jquery": "~1.10",
"bootstrap": "~3.0",
"flot": "~0.8"
}
}
================================================
FILE: config/development.sample.json
================================================
{
"port": 4000,
"noindex": true,
"readonly": false,
"webservice": {
"database": "mongodb://localhost/pa11y-webservice-dev",
"host": "0.0.0.0",
"port": 3000,
"cron": "0 30 0 * * *"
}
}
================================================
FILE: config/production.sample.json
================================================
{
"port": 8080,
"noindex": true,
"readonly": false,
"webservice": {
"database": "mongodb://user:password@mongo-host:27017/pa11y",
"host": "0.0.0.0",
"port": 3000,
"cron": "0 30 0 * * *",
"chromeLaunchConfig": {
"args": [
"--no-sandbox",
"--disable-setuid-sandbox"
]
}
}
}
================================================
FILE: config/test.sample.json
================================================
{
"port": 4000,
"noindex": true,
"readonly": false,
"webservice": {
"database": "mongodb://127.0.0.1/pa11y-dashboard-integration-test",
"host": "127.0.0.1",
"port": 3000,
"cron": "0 30 0 * * *"
}
}
================================================
FILE: config.js
================================================
// This file is part of Pa11y Dashboard.
//
// Pa11y Dashboard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Pa11y Dashboard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
'use strict';
const fs = require('fs');
const environment = (process.env.NODE_ENV || 'development');
const jsonPath = `./config/${environment}.json`;
const jsPath = `./config/${environment}.js`;
if (fs.existsSync(jsonPath)) {
module.exports = require(jsonPath);
} else if (fs.existsSync(jsPath)) {
module.exports = require(jsPath);
} else {
const webserviceConfig = {
database: env('WEBSERVICE_DATABASE', 'mongodb://localhost/pa11y-webservice'),
host: env('WEBSERVICE_HOST', '0.0.0.0'),
port: Number(env('WEBSERVICE_PORT', '3000')),
cron: env('WEBSERVICE_CRON', false)
};
const chromiumFlags = env('CHROMIUM_FLAGS', undefined);
const chromiumExecutable = env('CHROMIUM_EXECUTABLE', undefined);
if (chromiumFlags || chromiumExecutable) {
webserviceConfig.chromeLaunchConfig = {};
if (chromiumFlags) {
webserviceConfig.chromeLaunchConfig.args = chromiumFlags.split(',');
}
if (chromiumExecutable) {
webserviceConfig.chromeLaunchConfig.executablePath = chromiumExecutable;
}
}
module.exports = {
port: Number(env('PORT', '4000')),
noindex: env('NOINDEX', 'true') === 'true',
readonly: env('READONLY', 'false') === 'true',
webservice: env('WEBSERVICE_URL', webserviceConfig)
};
}
function env(name, defaultValue) {
const value = process.env[name];
return typeof value === 'string' ? value : defaultValue;
}
================================================
FILE: data/standards.js
================================================
// This file is part of Pa11y Dashboard.
//
// Pa11y Dashboard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Pa11y Dashboard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
'use strict';
module.exports = function getStandards() {
return [
{
title: 'WCAG2A',
rules: [
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H30.2',
description: 'Img element is the only content of the link, but is missing alt text. The alt text should describe the purpose of the link.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H37',
description: 'Img element missing an alt attribute. Use the alt attribute to specify a short text alternative.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H67.1',
description: 'Img element with empty alt text must have absent or empty title attribute.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H67.2',
description: 'Img element is marked so that it is ignored by Assistive Technology.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.G94.Image',
description: 'Ensure that the img element\'s alt text serves the same purpose and presents the same information as the image.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H36',
description: 'Image submit button missing an alt attribute. Specify a text alternative that describes the button\'s function, using the alt attribute'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.G94.Button',
description: 'Ensure that the image submit button\'s alt text identifies the purpose of the button.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H24',
description: 'Area element in an image map missing an alt attribute. Each area element must have a text alternative that describes the function of the image map area.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H24.2',
description: 'Ensure that the area element\'s text alternative serves the same purpose as the part of image map image it references.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.G73,G74',
description: 'If this image cannot be fully described in a short text alternative, ensure a long text alternative is also available, such as in the body text or through a link.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H2.EG5',
description: 'Img element inside a link must not use alt text that duplicates the text content of the link.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H2.EG4',
description: 'Img element inside a link has empty or missing alt text when a link beside it contains link text. Consider combining the links.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H2.EG3',
description: 'Img element inside a link must not use alt text that duplicates the content of a text link beside it.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H53',
description: 'Object elements must contain a text alternative after all other alternatives are exhausted.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.G94,G92.Object',
description: 'Check that short (and if appropriate, long) text alternatives are available for non-text content that serve the same purpose and present the same information.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H35.3',
description: 'Applet elements must contain a text alternative in the element\'s body, for browsers without support for the applet element.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.H35.2',
description: 'Applet elements must contain an alt attribute, to provide a text alternative to browsers supporting the element but are unable to load the applet.'
},
{
name: 'WCAG2A.Principle1.Guideline1_1.1_1_1.G94,G92.Applet',
description: 'Check that short (and if appropriate, long) text alternatives are available for non-text content that serve the same purpose and present the same information.'
},
{
name: 'WCAG2A.Principle1.Guideline1_2.1_2_1.G158',
description: 'If this embedded object contains pre-recorded audio only, and is not provided as an alternative for text content, check that an alternative text version is available.'
},
{
name: 'WCAG2A.Principle1.Guideline1_2.1_2_1.G159,G166',
description: 'If this embedded object contains pre-recorded video only, and is not provided as an alternative for text content, check that an alternative text version is available, or an audio track is provided that presents equivalent information.'
},
{
name: 'WCAG2A.Principle1.Guideline1_2.1_2_2.G87,G93',
description: 'If this embedded object contains pre-recorded synchronised media and is not provided as an alternative for text content, check that captions are provided for audio content.'
},
{
name: 'WCAG2A.Principle1.Guideline1_2.1_2_3.G69,G78,G173,G8',
description: 'If this embedded object contains pre-recorded synchronised media and is not provided as an alternative for text content, check that an audio description of its video, and/or an alternative text version of the content is provided.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H42.2',
description: 'Heading tag found with no content. Text that is not intended as a heading should not be marked up with heading tags.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H93',
description: 'Multiple labels exist with the same "for" attribute. If these labels refer to different form controls, the controls should have unique "id" attributes.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.NonExistent',
description: 'This label\'s "for" attribute contains an ID that does not exist in the document.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.NonExistentFragment',
description: 'This label\'s "for" attribute contains an ID that does not exist in the document fragment.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.NotFormControl',
description: 'This label\'s "for" attribute contains an ID that points to an element that is not a form control.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.NoForAttr',
description: 'Label found without a "for" attribute, and therefore not explicitly associated with a form control.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.NoId',
description: 'Form control does not have an ID, therefore it cannot have an explicit label.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H65.3',
description: 'Form control without a label contains an empty title attribute. The title attribute should identify the purpose of the control.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H65',
description: 'Check that the title attribute identifies the purpose of the control, and that a label element is not appropriate.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.2',
description: 'Form control does not have an explicit label or title attribute, identifying the purpose of the control.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.NoLabelAllowed',
description: 'Label element should not be used for this type of form control.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.1.After',
description: 'The label element for this control should be placed after this element.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H44.1.Before',
description: 'The label element for this control should be placed before this element.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H49.[NodeName]',
description: 'Semantic markup should be used to mark emphasised or special text so that it can be programmatically determined.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H49.AlignAttr',
description: 'Semantic markup should be used to mark emphasised or special text so that it can be programmatically determined.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H42',
description: 'Heading markup should be used if this content is intended as a heading.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H63.3',
description: 'Table cell has an invalid scope attribute. Valid values are row, col, rowgroup, or colgroup.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H63.2',
description: 'Scope attributes on td elements that act as headers for other elements are obsolete in HTML5. Use a th element instead.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H43.ScopeAmbiguous',
description: 'Scope attributes on th elements are ambiguous in a table with multiple levels of headings. Use the headers attribute on td elements instead.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H43.IncorrectAttr',
description: 'Incorrect headers attribute on this td element. Expected "[expected headers]" but found "[actual headers]"'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H43.HeadersRequired',
description: 'The relationship between td elements and their associated th elements is not defined. As this table has multiple levels of th elements, you must use the headers attribute on td elements.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H43.MissingHeaderIds',
description: 'Not all th elements in this table contain an id attribute. These cells should contain ids so that they may be referenced by td elements headers attributes.\''
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H43.MissingHeadersAttrs',
description: 'Not all td elements in this table contain a headers attribute. Each headers attribute should list the ids of all th elements associated with that cell.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H43,H63',
description: 'The relationship between td elements and their associated th elements is not defined. Use either the scope attribute on th elements, or the headers attribute on td elements.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H63.1',
description: 'Not all th elements in this table have a scope attribute. These cells should contain a scope attribute to identify their association with td elements.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H39,H73.4',
description: 'If this table is a data table, and both a summary attribute and a caption element are present, the summary should not duplicate the caption.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H73.3.Check',
description: 'If this table is a data table, check that the summary attribute describes the tables organization or explains how to use the table.\''
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H73.3.NoSummary',
description: 'If this table is a data table, consider using the summary attribute of the table element to give an overview of this table.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H39.3.Check',
description: 'If this table is a data table, check that the caption element accurately describes this table.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H39.3.NoCaption',
description: 'If this table is a data table, consider using a caption element to the table element to identify this table.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H71.3',
description: 'Fieldset does not contain a legend element. All fieldsets should contain a legend element that describes a description of the field group.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H85.2',
description: 'If this selection list contains groups of related options, they should be grouped with optgroup.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H71.2',
description: 'Radio buttons or check boxes with the same name attribute must be contained within a fieldset element.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H48.1',
description: 'Content appears to have the visual appearance of a bulleted list. It may be appropriate to mark this content up using a ul element.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H48.2',
description: 'Content appears to have the visual appearance of a numbered list. It may be appropriate to mark this content up using an ol element.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.G141',
description: 'The heading structure is not logically nested. This [heading] element (should be a [correct heading] to be properly nested / appears to be the primary document heading, so should be an h1 element).'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_1.H48',
description: 'If this element contains a navigation section, it is recommended that it be marked up as a list.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_2.G57',
description: 'Check that the content is ordered in a meaningful sequence when linearised, such as when style sheets are disabled.'
},
{
name: 'WCAG2A.Principle1.Guideline1_3.1_3_3.G96',
description: 'Where instructions are provided for understanding the content, do not rely on sensory characteristics alone (such as shape, size or location) to describe objects.'
},
{
name: 'WCAG2A.Principle1.Guideline1_4.1_4_1.G14,G182',
description: 'Check that any information conveyed using colour alone is also available in text, or through other visual cues.'
},
{
name: 'WCAG2A.Principle1.Guideline1_4.1_4_2.F23',
description: 'If any audio plays automatically for longer than 3 seconds, check that there is the ability to pause, stop or mute the audio.'
},
{
name: 'WCAG2A.Principle1.Guideline1_4.1_4_3.F24.BGColour',
description: 'Check that this element has an inherited foreground colour to complement the corresponding inline background colour or image.'
},
{
name: 'WCAG2A.Principle1.Guideline1_4.1_4_3.F24.FGColour',
description: 'Check that this element has an inherited background colour or image to complement the corresponding inline foreground colour.'
},
{
name: 'WCAG2A.Principle2.Guideline2_1.2_1_1.SCR20.DblClick',
description: 'Ensure the functionality provided by double-clicking on this element is available through the keyboard.'
},
{
name: 'WCAG2A.Principle2.Guideline2_1.2_1_1.SCR20.MouseOver',
description: 'Ensure the functionality provided by mousing over this element is available through the keyboard; for instance, using the focus event.'
},
{
name: 'WCAG2A.Principle2.Guideline2_1.2_1_1.SCR20.MouseOut',
description: 'Ensure the functionality provided by mousing out of this element is available through the keyboard; for instance, using the blur event.'
},
{
name: 'WCAG2A.Principle2.Guideline2_1.2_1_1.SCR20.MouseMove',
description: 'Ensure the functionality provided by moving the mouse on this element is available through the keyboard.'
},
{
name: 'WCAG2A.Principle2.Guideline2_1.2_1_1.SCR20.MouseDown',
description: 'Ensure the functionality provided by mousing down on this element is available through the keyboard; for instance, using the keydown event.'
},
{
name: 'WCAG2A.Principle2.Guideline2_1.2_1_1.SCR20.MouseUp',
description: 'Ensure the functionality provided by mousing up on this element is available through the keyboard; for instance, using the keyup event.'
},
{
name: 'WCAG2A.Principle2.Guideline2_1.2_1_2.F10',
description: 'Check that this applet or plugin provides the ability to move the focus away from itself when using the keyboard.'
},
{
name: 'WCAG2A.1.Principle1.Guideline2_1.2_1_4.Check',
description: 'Check that if a keyboard shortcut is implemented in content using only letter (including upper- and lower-case letters), punctuation, number, or symbol characters, then at least one of the following is true: \nTurn off: A mechanism is available to turn the shortcut off;\nRemap: A mechanism is available to remap the shortcut to use one or more non- printable keyboard characters(e.g.Ctrl, Alt, etc);\nActive only on focus: The keyboard shortcut for a user interface component is only active when that component has focus.'
},
{
name: 'WCAG2A.Principle2.Guideline2_2.2_2_1.F40.2',
description: 'Meta refresh tag used to redirect to another page, with a time limit that is not zero. Users cannot control this time limit.'
},
{
name: 'WCAG2A.Principle2.Guideline2_2.2_2_1.F41.2',
description: 'Meta refresh tag used to refresh the current page. Users cannot control the time limit for this refresh.'
},
{
name: 'WCAG2A.Principle2.Guideline2_2.2_2_2.SCR33,SCR22,G187,G152,G186,G191',
description: 'If any part of the content moves, scrolls or blinks for more than 5 seconds, or auto-updates, check that there is a mechanism available to pause, stop, or hide the content.'
},
{
name: 'WCAG2A.Principle2.Guideline2_2.2_2_2.F4',
description: 'Ensure there is a mechanism available to stop this blinking element in less than five seconds.'
},
{
name: 'WCAG2A.Principle2.Guideline2_2.2_2_2.F47',
description: 'Blink elements cannot satisfy the requirement that blinking information can be stopped within five seconds.'
},
{
name: 'WCAG2A.Principle1.Guideline2_2.2_2_6.Check',
description: 'Check that users are warned of the duration of any user inactivity that could cause data loss, unless the data is preserved for more than 20 hours when the user does not take any actions.'
},
{
name: 'WCAG2A.Principle2.Guideline2_3.2_3_1.G19,G176',
description: 'Check that no component of the content flashes more than three times in any 1-second period, or that the size of any flashing area is sufficiently small.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_1.H64.1',
description: 'Iframe element requires a non-empty title attribute that identifies the frame.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_1.H64.2',
description: 'Check that the title attribute of this element contains text that identifies the frame.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_1.G1,G123,G124,H69',
description: 'Ensure that any common navigation elements can be bypassed; for instance, by use of skip links, header elements, or ARIA landmark roles.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_1.G1,G123,G124.NoSuchId',
description: 'This link points to a named anchor "[link target]" within the document, but no anchor exists with that name.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_1.G1,G123,G124.NoSuchIdFragment2.4.2',
description: 'This link points to a named anchor "[link target]" within the document, but no anchor exists with that name in the fragment tested.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_2.H25.1.NoTitleEl',
description: 'A title should be provided for the document, using a non-empty title element in the head section.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_2.H25.1.EmptyTitle',
description: 'The title element in the head section should be non-empty.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_2.H25.2',
description: 'Check that the title element describes the document.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_3.H4.2',
description: 'If tabindex is used, check that the tab order specified by the tabindex attributes follows relationships in the content.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_4.H77,H78,H79,H80,H81,H33',
description: 'Check that the link text combined with programmatically determined link context, or its title attribute, identifies the purpose of the link.'
},
{
name: 'WCAG2A.Principle2.Guideline2_4.2_4_4.H77,H78,H79,H80,H81',
description: 'Check that the link text combined with programmatically determined link context identifies the purpose of the link.'
},
{
name: 'WCAG2A.Principle1.Guideline2_5.2_5_1.Check',
description: 'Check that all functionality that uses multipoint or path-based gestures for operation can be operated with a single pointer without a path-based gesture, unless a multipoint or path-based gesture is essential.'
},
{
name: 'WCAG2A.Principle1.Guideline2_5.2_5_2.SinglePointer_Check',
description: 'Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2A.Principle1.Guideline2_5.2_5_2.Mousedown_Check',
description: 'This element has an mousedown event listener. Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2A.Principle1.Guideline2_5.2_5_2.Touchstart_Check',
description: 'This element has a touchstart event listener. Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2A.Principle1.Guideline2_5.2_5_3_F96.Check',
description: 'Check that for user interface components with labels that include text or images of text, the name contains the text that is presented visually.'
},
{
name: 'WCAG2A.Principle1.Guideline2_5.2_5_3_F96.AccessibleName',
description: 'Accessible name for this element does not contain the visible label text. Check that for user interface components with labels that include text or images of text, the name contains the text that is presented visually.'
},
{
name: 'WCAG2A.Principle1.Guideline2_5.2_5_4.Check',
description: 'Check that functionality that can be operated by device motion or user motion can also be operated by user interface components and responding to the motion can be disabled to prevent accidental actuation, except when: \nSupported Interface: The motion is used to operate functionality through an accessibility supported interface; \nEssential: The motion is essential for the function and doing so would invalidate the activity.'
},
{
name: 'WCAG2A.Principle1.Guideline2_5.2_5_4.Devicemotion',
description: 'This element has a devicemotion event listener. Check that functionality that can be operated by device motion or user motion can also be operated by user interface components and responding to the motion can be disabled to prevent accidental actuation, except when: \nSupported Interface: The motion is used to operate functionality through an accessibility supported interface; \nEssential: The motion is essential for the function and doing so would invalidate the activity.'
},
{
name: 'WCAG2A.Principle3.Guideline3_1.3_1_1.H57.2',
description: 'The html element should have a lang or xml:lang attribute which describes the language of the document.'
},
{
name: 'WCAG2A.Principle3.Guideline3_1.3_1_1.H57.3.Lang',
description: 'The language specified in the lang attribute of the document element does not appear to be well-formed.'
},
{
name: 'WCAG2A.Principle3.Guideline3_1.3_1_1.H57.3.XmlLang',
description: 'The language specified in the xml:lang attribute of the document element does not appear to be well-formed.'
},
{
name: 'WCAG2A.Principle3.Guideline3_2.3_2_1.G107',
description: 'Check that a change of context does not occur when any input field receives focus.'
},
{
name: 'WCAG2A.Principle3.Guideline3_2.3_2_2.H32.2',
description: 'Form does not contain a submit button (input type="submit", input type="image", or button type="submit").'
},
{
name: 'WCAG2A.Principle3.Guideline3_3.3_3_1.G83,G84,G85',
description: 'If an input error is automatically detected in this form, check that the item(s) in error are identified and the error(s) are described to the user in text.'
},
{
name: 'WCAG2A.Principle3.Guideline3_3.3_3_2.G131,G89,G184,H90',
description: 'Check that descriptive labels or instructions (including for required fields) are provided for user input in this form.'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_1.F77',
description: 'Duplicate id attribute value "[Element ID]" found on the web page.'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_2.H91.A.Empty',
description: 'Anchor element found with an ID but without a href or link text. Consider moving its ID to a parent or nearby element.'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_2.H91.A.EmptyWithName',
description: 'Anchor element found with a name attribute but without a href or link text. Consider moving the name attribute to become an ID of a parent or nearby element.'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_2.H91.A.EmptyNoId',
description: 'Anchor element found with no link content and no name and/or ID attribute.'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_2.H91.A.NoHref',
description: 'Anchor elements should not be used for defining in-page link targets. If not using the ID for other purposes (such as CSS or scripting), consider moving it to a parent element.'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_2.H91.A.Placeholder',
description: 'Anchor element found with link content, but no href and/or ID attribute has been supplied.'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_2.H91.A.NoContent',
description: 'Anchor element found with a valid href attribute, but no link content has been supplied.'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_2.H91.[NodeName].Name',
description: 'This /[element type/] does not have a name available to an accessibility API. Valid names are [valid names for this element].'
},
{
name: 'WCAG2A.Principle4.Guideline4_1.4_1_2.H91./[NodeName/].Value',
description: 'This /[element type/] does not have a value available to an accessibility API. Add one /[using a element-specific method/].'
}
]
},
{
title: 'WCAG2AA',
rules: [
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H30.2',
description: 'Img element is the only content of the link, but is missing alt text. The alt text should describe the purpose of the link.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H37',
description: 'Img element missing an alt attribute. Use the alt attribute to specify a short text alternative.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H67.1',
description: 'Img element with empty alt text must have absent or empty title attribute.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H67.2',
description: 'Img element is marked so that it is ignored by Assistive Technology.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.G94.Image',
description: 'Ensure that the img element\'s alt text serves the same purpose and presents the same information as the image.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H36',
description: 'Image submit button missing an alt attribute. Specify a text alternative that describes the button\'s function, using the alt attribute'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.G94.Button',
description: 'Ensure that the image submit button\'s alt text identifies the purpose of the button.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H24',
description: 'Area element in an image map missing an alt attribute. Each area element must have a text alternative that describes the function of the image map area.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H24.2',
description: 'Ensure that the area element\'s text alternative serves the same purpose as the part of image map image it references.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.G73,G74',
description: 'If this image cannot be fully described in a short text alternative, ensure a long text alternative is also available, such as in the body text or through a link.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H2.EG5',
description: 'Img element inside a link must not use alt text that duplicates the text content of the link.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H2.EG4',
description: 'Img element inside a link has empty or missing alt text when a link beside it contains link text. Consider combining the links.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H2.EG3',
description: 'Img element inside a link must not use alt text that duplicates the content of a text link beside it.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H53',
description: 'Object elements must contain a text alternative after all other alternatives are exhausted.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.G94,G92.Object',
description: 'Check that short (and if appropriate, long) text alternatives are available for non-text content that serve the same purpose and present the same information.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H35.3',
description: 'Applet elements must contain a text alternative in the element\'s body, for browsers without support for the applet element.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H35.2',
description: 'Applet elements must contain an alt attribute, to provide a text alternative to browsers supporting the element but are unable to load the applet.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.G94,G92.Applet',
description: 'Check that short (and if appropriate, long) text alternatives are available for non-text content that serve the same purpose and present the same information.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_2.1_2_1.G158',
description: 'If this embedded object contains pre-recorded audio only, and is not provided as an alternative for text content, check that an alternative text version is available.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_2.1_2_1.G159,G166',
description: 'If this embedded object contains pre-recorded video only, and is not provided as an alternative for text content, check that an alternative text version is available, or an audio track is provided that presents equivalent information.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_2.1_2_2.G87,G93',
description: 'If this embedded object contains pre-recorded synchronised media and is not provided as an alternative for text content, check that captions are provided for audio content.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_2.1_2_4.G9,G87,G93',
description: 'If this embedded object contains synchronised media, check that captions are provided for live audio content.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_2.1_2_5.G78,G173,G8',
description: 'If this embedded object contains pre-recorded synchronised media, check that an audio description is provided for its video content.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H42.2',
description: 'Heading tag found with no content. Text that is not intended as a heading should not be marked up with heading tags.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H93',
description: 'Multiple labels exist with the same "for" attribute. If these labels refer to different form controls, the controls should have unique "id" attributes.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.NonExistent',
description: 'This label\'s "for" attribute contains an ID that does not exist in the document.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.NonExistentFragment',
description: 'This label\'s "for" attribute contains an ID that does not exist in the document fragment.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.NotFormControl',
description: 'This label\'s "for" attribute contains an ID that points to an element that is not a form control.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.NoForAttr',
description: 'Label found without a "for" attribute, and therefore not explicitly associated with a form control.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.NoId',
description: 'Form control does not have an ID, therefore it cannot have an explicit label.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H65.3',
description: 'Form control without a label contains an empty title attribute. The title attribute should identify the purpose of the control.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H65',
description: 'Check that the title attribute identifies the purpose of the control, and that a label element is not appropriate.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.2',
description: 'Form control does not have an explicit label or title attribute, identifying the purpose of the control.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.NoLabelAllowed',
description: 'Label element should not be used for this type of form control.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.1.After',
description: 'The label element for this control should be placed after this element.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H44.1.Before',
description: 'The label element for this control should be placed before this element.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H49.[NodeName]',
description: 'Semantic markup should be used to mark emphasised or special text so that it can be programmatically determined.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H49.AlignAttr',
description: 'Semantic markup should be used to mark emphasised or special text so that it can be programmatically determined.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H42',
description: 'Heading markup should be used if this content is intended as a heading.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H63.3',
description: 'Table cell has an invalid scope attribute. Valid values are row, col, rowgroup, or colgroup.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H63.2',
description: 'Scope attributes on td elements that act as headers for other elements are obsolete in HTML5. Use a th element instead.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H43.ScopeAmbiguous',
description: 'Scope attributes on th elements are ambiguous in a table with multiple levels of headings. Use the headers attribute on td elements instead.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H43.IncorrectAttr',
description: 'Incorrect headers attribute on this td element. Expected "[expected headers]" but found "[actual headers]"'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H43.HeadersRequired',
description: 'The relationship between td elements and their associated th elements is not defined. As this table has multiple levels of th elements, you must use the headers attribute on td elements.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H43.MissingHeaderIds',
description: 'Not all th elements in this table contain an id attribute. These cells should contain ids so that they may be referenced by td elements headers attributes.\''
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H43.MissingHeadersAttrs',
description: 'Not all td elements in this table contain a headers attribute. Each headers attribute should list the ids of all th elements associated with that cell.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H43,H63',
description: 'The relationship between td elements and their associated th elements is not defined. Use either the scope attribute on th elements, or the headers attribute on td elements.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H63.1',
description: 'Not all th elements in this table have a scope attribute. These cells should contain a scope attribute to identify their association with td elements.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H39,H73.4',
description: 'If this table is a data table, and both a summary attribute and a caption element are present, the summary should not duplicate the caption.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H73.3.Check',
description: 'If this table is a data table, check that the summary attribute describes the tables organization or explains how to use the table.\''
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H73.3.NoSummary',
description: 'If this table is a data table, consider using the summary attribute of the table element to give an overview of this table.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H39.3.Check',
description: 'If this table is a data table, check that the caption element accurately describes this table.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H39.3.NoCaption',
description: 'If this table is a data table, consider using a caption element to the table element to identify this table.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H71.3',
description: 'Fieldset does not contain a legend element. All fieldsets should contain a legend element that describes a description of the field group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H85.2',
description: 'If this selection list contains groups of related options, they should be grouped with optgroup.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H71.2',
description: 'Radio buttons or check boxes with the same name attribute must be contained within a fieldset element.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H48.1',
description: 'Content appears to have the visual appearance of a bulleted list. It may be appropriate to mark this content up using a ul element.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H48.2',
description: 'Content appears to have the visual appearance of a numbered list. It may be appropriate to mark this content up using an ol element.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.G141',
description: 'The heading structure is not logically nested. This [heading] element (should be a [correct heading] to be properly nested / appears to be the primary document heading, so should be an h1 element).'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_1.H48',
description: 'If this element contains a navigation section, it is recommended that it be marked up as a list.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_2.G57',
description: 'Check that the content is ordered in a meaningful sequence when linearised, such as when style sheets are disabled.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_3.G96',
description: 'Where instructions are provided for understanding the content, do not rely on sensory characteristics alone (such as shape, size or location) to describe objects.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_4.RestrictView',
description: 'Check that content does not restrict its view and operation to a single display orientation, such as portrait or landscape, unless a specific display orientation is essential.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.FaultyValue',
description: 'This element contains a potentially faulty value in its autocomplete attribute.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Text',
description: 'Invalid autocomplete value. Element does not belong to Text control group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Multiline',
description: 'Invalid autocomplete value. Element does not belong to Multiline control group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Password',
description: 'Invalid autocomplete value. Element does not belong to Password control group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Url',
description: 'Invalid autocomplete value. Element does not belong to Url control group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Telephone',
description: 'Invalid autocomplete value. Element does not belong to Telephone control group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Numeric',
description: 'Invalid autocomplete value. Element does not belong to Numeric control group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Month',
description: 'Invalid autocomplete value. Element does not belong to Month control group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Date',
description: 'Invalid autocomplete value. Element does not belong to Date control group.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.Purpose',
description: 'Check that the input field serves a purpose identified in the Input Purposes for User Interface Components section; and that the content is implemented using technologies with support for identifying the expected meaning for form input data.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_3.1_3_5_H98.MissingAutocomplete',
description: 'This element does not have an autocomplete attribute. If this field collects information about the user, consider adding one to comply with this Success Criterion.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_1.G14,G182',
description: 'Check that any information conveyed using colour alone is also available in text, or through other visual cues.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_2.F23',
description: 'If any audio plays automatically for longer than 3 seconds, check that there is the ability to pause, stop or mute the audio.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail',
description: 'This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of /{value/}. Recommendation: /{colour recommendations/}.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_3.G145',
description: 'This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 3:1, but text in this element has a contrast ratio of /{value/}. Recommendation: /{colour recommendations/}.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_3.G18',
description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 4.5:1.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_3.G1451',
description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 3:1.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_3.F24.BGColour',
description: 'Check that this element has an inherited foreground colour to complement the corresponding inline background colour or image.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_3.F24.FGColour',
description: 'Check that this element has an inherited background colour or image to complement the corresponding inline foreground colour.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_4.G142',
description: 'Check that text can be resized without assistive technology up to 200 percent without loss of content or functionality.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_5.G140,C22,C30.AALevel',
description: 'If the technologies being used can achieve the visual presentation, check that text is used to convey information rather than images of text, except when the image of text is essential to the information being conveyed, or can be visually customised to the user\'s requirements.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_10_C32,C31,C33,C38,SCR34,G206.Check',
description: 'Check that content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions for: \nVertical scrolling content at a width equivalent to 320 CSS pixels;\\n Horizontal scrolling content at a height equivalent to 256 CSS pixels; \nExcept for parts of the content which require two-dimensional layout for usage or meaning.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_10_C32,C31,C33,C38,SCR34,G206.Fixed',
description: 'Principle1.Guideline1_4.1_4_10_C32,C31,C33,C38,SCR34,G206.Scrolling'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_10_C32,C31,C33,C38,SCR34,G206.Zoom',
description: 'Interfering with a user agents ability to zoom may be a failure of this Success Criterion.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_11_G195,G207,G18,G145,G174,F78.Check',
description: 'Check that the visual presentation of the following have a contrast ratio of at least 3:1 against adjacent color(s): \nUser Interface Components: Visual information required to identify user interface components and states, except for inactive components or where the appearance of the component is determined by the user agent and not modified by the author; \nGraphical Objects: Parts of graphics required to understand the content, except when a particular presentation of graphics is essential to the information being conveyed.'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_12_C36,C35.Check',
description: 'Check that no loss of content or functionality occurs by setting all of the following and by changing no other style property: \nLine height(line spacing) to at least 1.5 times the font size; \nSpacing following paragraphs to at least 2 times the font size; \nLetter spacing(tracking) to at least 0.12 times the font size; \nWord spacing to at least 0.16 times the font size'
},
{
name: 'WCAG2AA.Principle1.Guideline1_4.1_4_13_F95.Check',
description: 'Check that where receiving and then removing pointer hover or keyboard focus triggers additional content to become visible and then hidden, the following are true: \nDismissable: A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus, unless the additional content communicates an input error or does not obscure or replace other content; \nHoverable: If pointer hover can trigger the additional content, then the pointer can be moved over the additional content without the additional content disappearing; \nPersistent: The additional content remains visible until the hover or focus trigger is removed, the user dismisses it, or its information is no longer valid.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_1.2_1_1.SCR20.DblClick',
description: 'Ensure the functionality provided by double-clicking on this element is available through the keyboard.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_1.2_1_1.SCR20.MouseOver',
description: 'Ensure the functionality provided by mousing over this element is available through the keyboard; for instance, using the focus event.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_1.2_1_1.SCR20.MouseOut',
description: 'Ensure the functionality provided by mousing out of this element is available through the keyboard; for instance, using the blur event.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_1.2_1_1.SCR20.MouseMove',
description: 'Ensure the functionality provided by moving the mouse on this element is available through the keyboard.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_1.2_1_1.SCR20.MouseDown',
description: 'Ensure the functionality provided by mousing down on this element is available through the keyboard; for instance, using the keydown event.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_1.2_1_1.SCR20.MouseUp',
description: 'Ensure the functionality provided by mousing up on this element is available through the keyboard; for instance, using the keyup event.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_1.2_1_2.F10',
description: 'Check that this applet or plugin provides the ability to move the focus away from itself when using the keyboard.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_1.2_1_4.Check',
description: 'Check that if a keyboard shortcut is implemented in content using only letter (including upper- and lower-case letters), punctuation, number, or symbol characters, then at least one of the following is true: \nTurn off: A mechanism is available to turn the shortcut off; \nRemap: A mechanism is available to remap the shortcut to use one or more non- printable keyboard characters(e.g.Ctrl, Alt, etc); \nActive only on focus: The keyboard shortcut for a user interface component is only active when that component has focus.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_2.2_2_1.F40.2',
description: 'Meta refresh tag used to redirect to another page, with a time limit that is not zero. Users cannot control this time limit.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_2.2_2_1.F41.2',
description: 'Meta refresh tag used to refresh the current page. Users cannot control the time limit for this refresh.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_2.2_2_2.SCR33,SCR22,G187,G152,G186,G191',
description: 'If any part of the content moves, scrolls or blinks for more than 5 seconds, or auto-updates, check that there is a mechanism available to pause, stop, or hide the content.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_2.2_2_2.F4',
description: 'Ensure there is a mechanism available to stop this blinking element in less than five seconds.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_2.2_2_2.F47',
description: 'Blink elements cannot satisfy the requirement that blinking information can be stopped within five seconds.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_2.2_2_6.Check',
description: 'Check that users are warned of the duration of any user inactivity that could cause data loss, unless the data is preserved for more than 20 hours when the user does not take any actions.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_3.2_3_1.G19,G176',
description: 'Check that no component of the content flashes more than three times in any 1-second period, or that the size of any flashing area is sufficiently small.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_1.H64.1',
description: 'Iframe element requires a non-empty title attribute that identifies the frame.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_1.H64.2',
description: 'Check that the title attribute of this element contains text that identifies the frame.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_1.G1,G123,G124,H69',
description: 'Ensure that any common navigation elements can be bypassed; for instance, by use of skip links, header elements, or ARIA landmark roles.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_1.G1,G123,G124.NoSuchId',
description: 'This link points to a named anchor "[link target]" within the document, but no anchor exists with that name.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_1.G1,G123,G124.NoSuchIdFragment2.4.2',
description: 'This link points to a named anchor "[link target]" within the document, but no anchor exists with that name in the fragment tested.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_2.H25.1.NoTitleEl',
description: 'A title should be provided for the document, using a non-empty title element in the head section.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_2.H25.1.EmptyTitle',
description: 'The title element in the head section should be non-empty.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_2.H25.2',
description: 'Check that the title element describes the document.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_3.H4.2',
description: 'If tabindex is used, check that the tab order specified by the tabindex attributes follows relationships in the content.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_4.H77,H78,H79,H80,H81,H33',
description: 'Check that the link text combined with programmatically determined link context, or its title attribute, identifies the purpose of the link.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_4.H77,H78,H79,H80,H81',
description: 'Check that the link text combined with programmatically determined link context identifies the purpose of the link.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_5.G125,G64,G63,G161,G126,G185',
description: 'If this Web page is not part of a linear process, check that there is more than one way of locating this Web page within a set of Web pages.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_6.G130,G131',
description: 'Check that headings and labels describe topic or purpose.'
},
{
name: 'WCAG2AA.Principle2.Guideline2_4.2_4_7.G149,G165,G195,C15,SCR31',
description: 'Check that there is at least one mode of operation where the keyboard focus indicator can be visually located on user interface controls.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_5.2_5_1.Check',
description: 'Check that all functionality that uses multipoint or path-based gestures for operation can be operated with a single pointer without a path-based gesture, unless a multipoint or path-based gesture is essential.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_5.2_5_2.SinglePointer_Check',
description: 'Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_5.2_5_2.Mousedown_Check',
description: 'This element has an mousedown event listener. Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_5.2_5_2.Touchstart_Check',
description: 'This element has a touchstart event listener. Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_5.2_5_3_F96.Check',
description: 'Check that for user interface components with labels that include text or images of text, the name contains the text that is presented visually.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_5.2_5_3_F96.AccessibleName',
description: 'Accessible name for this element does not contain the visible label text. Check that for user interface components with labels that include text or images of text, the name contains the text that is presented visually.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_5.2_5_4.Check',
description: 'Check that functionality that can be operated by device motion or user motion can also be operated by user interface components and responding to the motion can be disabled to prevent accidental actuation, except when: \nSupported Interface: The motion is used to operate functionality through an accessibility supported interface; \nEssential: The motion is essential for the function and doing so would invalidate the activity.'
},
{
name: 'WCAG2AA.Principle1.Guideline2_5.2_5_4.Devicemotion',
description: 'WCAG2AA.This element has a devicemotion event listener. Check that functionality that can be operated by device motion or user motion can also be operated by user interface components and responding to the motion can be disabled to prevent accidental actuation, except when: \nSupported Interface: The motion is used to operate functionality through an accessibility supported interface; \nEssential: The motion is essential for the function and doing so would invalidate the activity.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_1.3_1_1.H57.2',
description: 'The html element should have a lang or xml:lang attribute which describes the language of the document.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_1.3_1_1.H57.3.Lang',
description: 'The language specified in the lang attribute of the document element does not appear to be well-formed.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_1.3_1_1.H57.3.XmlLang',
description: 'The language specified in the xml:lang attribute of the document element does not appear to be well-formed.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_1.3_1_2.H58',
description: 'Ensure that any change in language is marked using the lang and/or xml:lang attribute on an element, as appropriate.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_1.3_1_2.H58.1.Lang',
description: 'The language specified in the lang attribute of this element does not appear to be well-formed.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_1.3_1_2.H58.1.XmlLang',
description: 'The language specified in the xml:lang attribute of this element does not appear to be well-formed.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_2.3_2_1.G107',
description: 'Check that a change of context does not occur when any input field receives focus.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_2.3_2_2.H32.2',
description: 'Form does not contain a submit button (input type="submit", input type="image", or button type="submit").'
},
{
name: 'WCAG2AA.Principle3.Guideline3_2.3_2_3.G61',
description: 'Check that navigational mechanisms that are repeated on multiple Web pages occur in the same relative order each time they are repeated, unless a change is initiated by the user.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_2.3_2_4.G197',
description: 'Check that components that have the same functionality within this Web page are identified consistently in the set of Web pages to which it belongs.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_3.3_3_1.G83,G84,G85',
description: 'If an input error is automatically detected in this form, check that the item(s) in error are identified and the error(s) are described to the user in text.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_3.3_3_2.G131,G89,G184,H90',
description: 'Check that descriptive labels or instructions (including for required fields) are provided for user input in this form.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_3.3_3_3.G177',
description: 'Check that this form provides suggested corrections to errors in user input, unless it would jeopardize the security or purpose of the content.'
},
{
name: 'WCAG2AA.Principle3.Guideline3_3.3_3_4.G98,G99,G155,G164,G168.LegalForms',
description: 'If this form would bind a user to a financial or legal commitment, modify/delete user-controllable data, or submit test responses, ensure that submissions are either reversible, checked for input errors, and/or confirmed by the user.'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_1.F77',
description: 'Duplicate id attribute value "[Element ID]" found on the web page.'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.Empty',
description: 'Anchor element found with an ID but without a href or link text. Consider moving its ID to a parent or nearby element.'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.EmptyWithName',
description: 'Anchor element found with a name attribute but without a href or link text. Consider moving the name attribute to become an ID of a parent or nearby element.'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.EmptyNoId',
description: 'Anchor element found with no link content and no name and/or ID attribute.'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.NoHref',
description: 'Anchor elements should not be used for defining in-page link targets. If not using the ID for other purposes (such as CSS or scripting), consider moving it to a parent element.'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.Placeholder',
description: 'Anchor element found with link content, but no href and/or ID attribute has been supplied.'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.NoContent',
description: 'Anchor element found with a valid href attribute, but no link content has been supplied.'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.[NodeName].Name',
description: 'This [element type] does not have a name available to an accessibility API. Valid names are [valid names for this element].'
},
{
name: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.[NodeName].Value',
description: 'This [element type] does not have a value available to an accessibility API. Add one [using a element-specific method].'
},
{
name: 'WCAG2AA.Principle1.Guideline4_1.4_1_3_ARIA22,G199,ARIA19,G83,G84,G85,G139,G177,G194,ARIA23.Check',
description: 'Check that status messages can be programmatically determined through role or properties such that they can be presented to the user by assistive technologies without receiving focus.'
}
]
},
{
title: 'WCAG2AAA',
rules: [
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H30.2',
description: 'Img element is the only content of the link, but is missing alt text. The alt text should describe the purpose of the link.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H37',
description: 'Img element missing an alt attribute. Use the alt attribute to specify a short text alternative.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H67.1',
description: 'Img element with empty alt text must have absent or empty title attribute.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H67.2',
description: 'Img element is marked so that it is ignored by Assistive Technology.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.G94.Image',
description: 'Ensure that the img element\'s alt text serves the same purpose and presents the same information as the image.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H36',
description: 'Image submit button missing an alt attribute. Specify a text alternative that describes the button\'s function, using the alt attribute'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.G94.Button',
description: 'Ensure that the image submit button\'s alt text identifies the purpose of the button.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H24',
description: 'Area element in an image map missing an alt attribute. Each area element must have a text alternative that describes the function of the image map area.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H24.2',
description: 'Ensure that the area element\'s text alternative serves the same purpose as the part of image map image it references.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.G73,G74',
description: 'If this image cannot be fully described in a short text alternative, ensure a long text alternative is also available, such as in the body text or through a link.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H2.EG5',
description: 'Img element inside a link must not use alt text that duplicates the text content of the link.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H2.EG4',
description: 'Img element inside a link has empty or missing alt text when a link beside it contains link text. Consider combining the links.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H2.EG3',
description: 'Img element inside a link must not use alt text that duplicates the content of a text link beside it.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H53',
description: 'Object elements must contain a text alternative after all other alternatives are exhausted.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.G94,G92.Object',
description: 'Check that short (and if appropriate, long) text alternatives are available for non-text content that serve the same purpose and present the same information.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H35.3',
description: 'Applet elements must contain a text alternative in the element\'s body, for browsers without support for the applet element.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.H35.2',
description: 'Applet elements must contain an alt attribute, to provide a text alternative to browsers supporting the element but are unable to load the applet.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_1.1_1_1.G94,G92.Applet',
description: 'Check that short (and if appropriate, long) text alternatives are available for non-text content that serve the same purpose and present the same information.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_1.G158',
description: 'If this embedded object contains pre-recorded audio only, and is not provided as an alternative for text content, check that an alternative text version is available.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_1.G159,G166',
description: 'If this embedded object contains pre-recorded video only, and is not provided as an alternative for text content, check that an alternative text version is available, or an audio track is provided that presents equivalent information.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_2.G87,G93',
description: 'If this embedded object contains pre-recorded synchronised media and is not provided as an alternative for text content, check that captions are provided for audio content.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_4.G9,G87,G93',
description: 'If this embedded object contains synchronised media, check that captions are provided for live audio content.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_5.G78,G173,G8',
description: 'If this embedded object contains pre-recorded synchronised media, check that an audio description is provided for its video content.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_6.G54,G81',
description: 'If this embedded object contains pre-recorded synchronised media, check that a sign language interpretation is provided for its audio.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_7.G8',
description: 'If this embedded object contains synchronised media, and where pauses in foreground audio is not sufficient to allow audio descriptions to convey the sense of pre-recorded video, check that an extended audio description is provided, either through scripting or an alternate version.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_8.G69,G159',
description: 'If this embedded object contains pre-recorded synchronised media or video-only content, check that an alternative text version of the content is provided.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_2.1_2_9.G150,G151,G157',
description: 'If this embedded object contains live audio-only content, check that an alternative text version of the content is provided.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H42.2',
description: 'Heading tag found with no content. Text that is not intended as a heading should not be marked up with heading tags.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H93',
description: 'Multiple labels exist with the same "for" attribute. If these labels refer to different form controls, the controls should have unique "id" attributes.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.NonExistent',
description: 'This label\'s "for" attribute contains an ID that does not exist in the document.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.NonExistentFragment',
description: 'This label\'s "for" attribute contains an ID that does not exist in the document fragment.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.NotFormControl',
description: 'This label\'s "for" attribute contains an ID that points to an element that is not a form control.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.NoForAttr',
description: 'Label found without a "for" attribute, and therefore not explicitly associated with a form control.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.NoId',
description: 'Form control does not have an ID, therefore it cannot have an explicit label.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H65.3',
description: 'Form control without a label contains an empty title attribute. The title attribute should identify the purpose of the control.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H65',
description: 'Check that the title attribute identifies the purpose of the control, and that a label element is not appropriate.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.2',
description: 'Form control does not have an explicit label or title attribute, identifying the purpose of the control.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.NoLabelAllowed',
description: 'Label element should not be used for this type of form control.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.1.After',
description: 'The label element for this control should be placed after this element.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H44.1.Before',
description: 'The label element for this control should be placed before this element.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H49.[NodeName]',
description: 'Semantic markup should be used to mark emphasised or special text so that it can be programmatically determined.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H49.AlignAttr',
description: 'Semantic markup should be used to mark emphasised or special text so that it can be programmatically determined.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H42',
description: 'Heading markup should be used if this content is intended as a heading.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H63.3',
description: 'Table cell has an invalid scope attribute. Valid values are row, col, rowgroup, or colgroup.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H63.2',
description: 'Scope attributes on td elements that act as headers for other elements are obsolete in HTML5. Use a th element instead.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H43.ScopeAmbiguous',
description: 'Scope attributes on th elements are ambiguous in a table with multiple levels of headings. Use the headers attribute on td elements instead.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H43.IncorrectAttr',
description: 'Incorrect headers attribute on this td element. Expected "[expected headers]" but found "[actual headers]"'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H43.HeadersRequired',
description: 'The relationship between td elements and their associated th elements is not defined. As this table has multiple levels of th elements, you must use the headers attribute on td elements.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H43.MissingHeaderIds',
description: 'Not all th elements in this table contain an id attribute. These cells should contain ids so that they may be referenced by td elements headers attributes.\''
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H43.MissingHeadersAttrs',
description: 'Not all td elements in this table contain a headers attribute. Each headers attribute should list the ids of all th elements associated with that cell.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H43,H63',
description: 'The relationship between td elements and their associated th elements is not defined. Use either the scope attribute on th elements, or the headers attribute on td elements.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H63.1',
description: 'Not all th elements in this table have a scope attribute. These cells should contain a scope attribute to identify their association with td elements.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H39,H73.4',
description: 'If this table is a data table, and both a summary attribute and a caption element are present, the summary should not duplicate the caption.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H73.3.Check',
description: 'If this table is a data table, check that the summary attribute describes the tables organization or explains how to use the table.\''
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H73.3.NoSummary',
description: 'If this table is a data table, consider using the summary attribute of the table element to give an overview of this table.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H39.3.Check',
description: 'If this table is a data table, check that the caption element accurately describes this table.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H39.3.NoCaption',
description: 'If this table is a data table, consider using a caption element to the table element to identify this table.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H71.3',
description: 'Fieldset does not contain a legend element. All fieldsets should contain a legend element that describes a description of the field group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H85.2',
description: 'If this selection list contains groups of related options, they should be grouped with optgroup.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H71.2',
description: 'Radio buttons or check boxes with the same name attribute must be contained within a fieldset element.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H48.1',
description: 'Content appears to have the visual appearance of a bulleted list. It may be appropriate to mark this content up using a ul element.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H48.2',
description: 'Content appears to have the visual appearance of a numbered list. It may be appropriate to mark this content up using an ol element.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.G141',
description: 'The heading structure is not logically nested. This [heading] element (should be a [correct heading] to be properly nested / appears to be the primary document heading, so should be an h1 element).'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_1.H48',
description: 'If this element contains a navigation section, it is recommended that it be marked up as a list.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_2.G57',
description: 'Check that the content is ordered in a meaningful sequence when linearised, such as when style sheets are disabled.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_3.G96',
description: 'Where instructions are provided for understanding the content, do not rely on sensory characteristics alone (such as shape, size or location) to describe objects.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_4.RestrictView',
description: 'Check that content does not restrict its view and operation to a single display orientation, such as portrait or landscape, unless a specific display orientation is essential.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.FaultyValue',
description: 'This element contains a potentially faulty value in its autocomplete attribute.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Text',
description: 'Invalid autocomplete value. Element does not belong to Text control group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Multiline',
description: 'Invalid autocomplete value. Element does not belong to Multiline control group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Password',
description: 'Invalid autocomplete value. Element does not belong to Password control group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Url',
description: 'Invalid autocomplete value. Element does not belong to Url control group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Telephone',
description: 'Invalid autocomplete value. Element does not belong to Telephone control group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Numeric',
description: 'Invalid autocomplete value. Element does not belong to Numeric control group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Month',
description: 'Invalid autocomplete value. Element does not belong to Month control group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.InvalidAutocomplete_Date',
description: 'Invalid autocomplete value. Element does not belong to Date control group.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.Purpose',
description: 'Check that the input field serves a purpose identified in the Input Purposes for User Interface Components section; and that the content is implemented using technologies with support for identifying the expected meaning for form input data.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_5_H98.MissingAutocomplete',
description: 'This element does not have an autocomplete attribute. If this field collects information about the user, consider adding one to comply with this Success Criterion.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_3.1_3_6_ARIA11.Check',
description: 'Check that the purpose of User Interface Components, icons, and regions can be programmatically determined.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_1.G14,G182',
description: 'Check that any information conveyed using colour alone is also available in text, or through other visual cues.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_2.F23',
description: 'If any audio plays automatically for longer than 3 seconds, check that there is the ability to pause, stop or mute the audio.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_6.G17',
description: 'This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 7:1, but text in this element has a contrast ratio of /{value/}. Recommendation: /{colour recommendations/}.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_6.G18',
description: 'This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of /{value/}. Recommendation: /{colour recommendations/}.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_6.G17-1',
description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 7:1.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_6.G18-1',
description: 'This element\'s text is placed on a background image. Ensure the contrast ratio between the text and all covered parts of the image are at least 4.5:1.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_7.G56',
description: 'For pre-recorded audio-only content that is primarily speech (such as narration), any background sounds should be muteable, or be at least 20 dB (or about 4 times) quieter than the speech.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_8.G148,G156,G175',
description: 'Check that a mechanism is available for the user to select foreground and background colours for blocks of text, either through the Web page or the browser.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_8.H87,C20',
description: 'Check that a mechanism exists to reduce the width of a block of text to no more than 80 characters (or 40 in Chinese, Japanese or Korean script).'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_8.C19,G172,G169',
description: 'Check that blocks of text are not fully justified - that is, to both left and right edges - or a mechanism exists to remove full justification.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_8.G188,C21',
description: 'Check that line spacing in blocks of text are at least 150% in paragraphs, and paragraph spacing is at least 1.5 times the line spacing, or that a mechanism is available to achieve this.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_8.H87,G146,C26',
description: 'Check that text can be resized without assistive technology up to 200 percent without requiring the user to scroll horizontally on a full-screen window.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_9.G140,C22,C30.NoException',
description: 'Check that images of text are only used for pure decoration or where a particular presentation of text is essential to the information being conveyed.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_10_C32,C31,C33,C38,SCR34,G206.Check',
description: 'Check that content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions for: \nVertical scrolling content at a width equivalent to 320 CSS pixels;\\n Horizontal scrolling content at a height equivalent to 256 CSS pixels; \nExcept for parts of the content which require two-dimensional layout for usage or meaning.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_10_C32,C31,C33,C38,SCR34,G206.Fixed',
description: 'Principle1.Guideline1_4.1_4_10_C32,C31,C33,C38,SCR34,G206.Scrolling'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_10_C32,C31,C33,C38,SCR34,G206.Zoom',
description: 'Interfering with a user agents ability to zoom may be a failure of this Success Criterion.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_11_G195,G207,G18,G145,G174,F78.Check',
description: 'Check that the visual presentation of the following have a contrast ratio of at least 3:1 against adjacent color(s): \nUser Interface Components: Visual information required to identify user interface components and states, except for inactive components or where the appearance of the component is determined by the user agent and not modified by the author; \nGraphical Objects: Parts of graphics required to understand the content, except when a particular presentation of graphics is essential to the information being conveyed.'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_12_C36,C35.Check',
description: 'Check that no loss of content or functionality occurs by setting all of the following and by changing no other style property: \nLine height(line spacing) to at least 1.5 times the font size; \nSpacing following paragraphs to at least 2 times the font size; \nLetter spacing(tracking) to at least 0.12 times the font size; \nWord spacing to at least 0.16 times the font size'
},
{
name: 'WCAG2AAA.Principle1.Guideline1_4.1_4_13_F95.Check',
description: 'Check that where receiving and then removing pointer hover or keyboard focus triggers additional content to become visible and then hidden, the following are true: \nDismissable: A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus, unless the additional content communicates an input error or does not obscure or replace other content; \nHoverable: If pointer hover can trigger the additional content, then the pointer can be moved over the additional content without the additional content disappearing; \nPersistent: The additional content remains visible until the hover or focus trigger is removed, the user dismisses it, or its information is no longer valid.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_1.2_1_4.Check',
description: 'Check that if a keyboard shortcut is implemented in content using only letter (including upper- and lower-case letters), punctuation, number, or symbol characters, then at least one of the following is true: \nTurn off: A mechanism is available to turn the shortcut off; \nRemap: A mechanism is available to remap the shortcut to use one or more non- printable keyboard characters(e.g.Ctrl, Alt, etc); \nActive only on focus: The keyboard shortcut for a user interface component is only active when that component has focus.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_1.2_1_1.SCR20.DblClick',
description: 'Ensure the functionality provided by double-clicking on this element is available through the keyboard.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_1.2_1_1.SCR20.MouseOver',
description: 'Ensure the functionality provided by mousing over this element is available through the keyboard; for instance, using the focus event.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_1.2_1_1.SCR20.MouseOut',
description: 'Ensure the functionality provided by mousing out of this element is available through the keyboard; for instance, using the blur event.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_1.2_1_1.SCR20.MouseMove',
description: 'Ensure the functionality provided by moving the mouse on this element is available through the keyboard.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_1.2_1_1.SCR20.MouseDown',
description: 'Ensure the functionality provided by mousing down on this element is available through the keyboard; for instance, using the keydown event.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_1.2_1_1.SCR20.MouseUp',
description: 'Ensure the functionality provided by mousing up on this element is available through the keyboard; for instance, using the keyup event.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_1.2_1_2.F10',
description: 'Check that this applet or plugin provides the ability to move the focus away from itself when using the keyboard.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_2.2_2_1.F40.2',
description: 'Meta refresh tag used to redirect to another page, with a time limit that is not zero. Users cannot control this time limit.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_2.2_2_1.F41.2',
description: 'Meta refresh tag used to refresh the current page. Users cannot control the time limit for this refresh.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_2.2_2_2.SCR33,SCR22,G187,G152,G186,G191',
description: 'If any part of the content moves, scrolls or blinks for more than 5 seconds, or auto-updates, check that there is a mechanism available to pause, stop, or hide the content.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_2.2_2_2.F4',
description: 'Ensure there is a mechanism available to stop this blinking element in less than five seconds.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_2.2_2_2.F47',
description: 'Blink elements cannot satisfy the requirement that blinking information can be stopped within five seconds.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_2.2_2_3.G5',
description: 'Check that timing is not an essential part of the event or activity presented by the content, except for non-interactive synchronized media and real-time events.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_2.2_2_4.SCR14',
description: 'Check that all interruptions (including updates to content) can be postponed or suppressed by the user, except interruptions involving an emergency.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_2.2_2_5.G105,G181',
description: 'If this Web page is part of a set of Web pages with an inactivity time limit, check that an authenticated user can continue the activity without loss of data after re-authenticating.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_2.2_2_6.Check',
description: 'Check that users are warned of the duration of any user inactivity that could cause data loss, unless the data is preserved for more than 20 hours when the user does not take any actions.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_3.2_3_2.G19',
description: 'Check that no component of the content flashes more than three times in any 1-second period.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_3.2_3_3.Check',
description: 'Check that motion animation triggered by interaction can be disabled, unless the animation is essential to the functionality or the information being conveyed.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_1.Check',
description: 'Check that all functionality that uses multipoint or path-based gestures for operation can be operated with a single pointer without a path-based gesture, unless a multipoint or path-based gesture is essential.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_2.SinglePointer_Check',
description: 'Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_2.Mousedown_Check',
description: 'This element has an mousedown event listener. Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_2.Touchstart_Check',
description: 'This element has a touchstart event listener. Check that for functionality that can be operated using a single pointer, at least one of the following is true: \nNo Down- Event: The down - event of the pointer is not used to execute any part of the function; \nAbort or Undo: Completion of the function is on the up - event, and a mechanism is available to abort the function before completion or to undo the function after completion; \nUp Reversal: The up - event reverses any outcome of the preceding down - event; \nEssential: Completing the function on the down - event is essential.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_3_F96.Check',
description: 'Check that for user interface components with labels that include text or images of text, the name contains the text that is presented visually.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_3_F96.AccessibleName',
description: 'Accessible name for this element does not contain the visible label text. Check that for user interface components with labels that include text or images of text, the name contains the text that is presented visually.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_4.Check',
description: 'Check that functionality that can be operated by device motion or user motion can also be operated by user interface components and responding to the motion can be disabled to prevent accidental actuation, except when: \nSupported Interface: The motion is used to operate functionality through an accessibility supported interface; \nEssential: The motion is essential for the function and doing so would invalidate the activity.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_4.Devicemotion',
description: 'WCAG2AA.This element has a devicemotion event listener. Check that functionality that can be operated by device motion or user motion can also be operated by user interface components and responding to the motion can be disabled to prevent accidental actuation, except when: \nSupported Interface: The motion is used to operate functionality through an accessibility supported interface; \nEssential: The motion is essential for the function and doing so would invalidate the activity.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_5.Check',
description: 'Check that the size of the target for pointer inputs is at least 44 by 44 CSS pixels except when:\nEquivalent: The target is available through an equivalent link or control on the same page that is at least 44 by 44 CSS pixels;\nInline: The target is in a sentence or block of text;\nUser Agent Control: The size of the target is determined by the user agent and is not modified by the author;\nEssential: A particular presentation of the target is essential to the information being conveyed.'
},
{
name: 'WCAG2AAA.Principle1.Guideline2_5.2_5_6.Check',
description: 'Check that the content does not restrict use of input modalities available on a platform except where the restriction is essential, required to ensure the security of the content, or required to respect user settings.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_1.H64.1',
description: 'Iframe element requires a non-empty title attribute that identifies the frame.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_1.H64.2',
description: 'Check that the title attribute of this element contains text that identifies the frame.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_1.G1,G123,G124,H69',
description: 'Ensure that any common navigation elements can be bypassed; for instance, by use of skip links, header elements, or ARIA landmark roles.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_1.G1,G123,G124.NoSuchId',
description: 'This link points to a named anchor "[link target]" within the document, but no anchor exists with that name.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_1.G1,G123,G124.NoSuchIdFragment2.4.2',
description: 'This link points to a named anchor "[link target]" within the document, but no anchor exists with that name in the fragment tested.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_2.H25.1.NoTitleEl',
description: 'A title should be provided for the document, using a non-empty title element in the head section.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_2.H25.1.EmptyTitle',
description: 'The title element in the head section should be non-empty.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_2.H25.2',
description: 'Check that the title element describes the document.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_3.H4.2',
description: 'If tabindex is used, check that the tab order specified by the tabindex attributes follows relationships in the content.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_5.G125,G64,G63,G161,G126,G185',
description: 'If this Web page is not part of a linear process, check that there is more than one way of locating this Web page within a set of Web pages.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_6.G130,G131',
description: 'Check that headings and labels describe topic or purpose.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_7.G149,G165,G195,C15,SCR31',
description: 'Check that there is at least one mode of operation where the keyboard focus indicator can be visually located on user interface controls.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_8.H59.1',
description: 'Link elements can only be located in the head section of the document.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_8.H59.2a',
description: 'Link element is missing a non-empty rel attribute identifying the link type.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_8.H59.2b',
description: 'Link element is missing a non-empty href attribute pointing to the resource being linked.'
},
{
name: 'WCAG2AAA.Principle2.Guideline2_4.2_4_9.H30',
description: 'Check that text of the link describes the purpose of the link.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_1.H57.2',
description: 'The html element should have a lang or xml:lang attribute which describes the language of the document.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_1.H57.3.Lang',
description: 'The language specified in the lang attribute of the document element does not appear to be well-formed.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_1.H57.3.XmlLang',
description: 'The language specified in the xml:lang attribute of the document element does not appear to be well-formed.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_2.H58',
description: 'Ensure that any change in language is marked using the lang and/or xml:lang attribute on an element, as appropriate.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_2.H58.1.Lang',
description: 'The language specified in the lang attribute of this element does not appear to be well-formed.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_2.H58.1.XmlLang',
description: 'The language specified in the xml:lang attribute of this element does not appear to be well-formed.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_3.H40,H54,H60,G62,G70',
description: 'Check that there is a mechanism available for identifying specific definitions of words or phrases used in an unusual or restricted way, including idioms and jargon.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_4.G102,G55,G62,H28,G97',
description: 'Check that a mechanism for identifying the expanded form or meaning of abbreviations is available.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_5.G86,G103,G79,G153,G160',
description: 'Where the content requires reading ability more advanced than the lower secondary education level, supplemental content or an alternative version should be provided.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_6.H62.1.HTML5',
description: 'Ruby element does not contain an rt element containing pronunciation information for its body text.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_6.H62.1.XHTML11',
description: 'Ruby element does not contain an rt element containing pronunciation information for the text inside the rb element.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_1.3_1_6.H62.2',
description: 'Ruby element does not contain rp elements, which provide extra punctuation to browsers not supporting ruby text.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_2.3_2_1.G107',
description: 'Check that a change of context does not occur when any input field receives focus.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_2.3_2_2.H32.2',
description: 'Form does not contain a submit button (input type="submit", input type="image", or button type="submit").'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_2.3_2_3.G61',
description: 'Check that navigational mechanisms that are repeated on multiple Web pages occur in the same relative order each time they are repeated, unless a change is initiated by the user.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_2.3_2_4.G197',
description: 'Check that components that have the same functionality within this Web page are identified consistently in the set of Web pages to which it belongs.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_2.3_2_5.H83.3',
description: 'Check that this link\'s link text contains information indicating that the link will open in a new window.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_3.3_3_1.G83,G84,G85',
description: 'If an input error is automatically detected in this form, check that the item(s) in error are identified and the error(s) are described to the user in text.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_3.3_3_2.G131,G89,G184,H90',
description: 'Check that descriptive labels or instructions (including for required fields) are provided for user input in this form.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_3.3_3_3.G177',
description: 'Check that this form provides suggested corrections to errors in user input, unless it would jeopardize the security or purpose of the content.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_3.3_3_5.G71,G184,G193',
description: 'Check that context-sensitive help is available for this form, at a Web-page and/or control level.'
},
{
name: 'WCAG2AAA.Principle3.Guideline3_3.3_3_6.G98,G99,G155,G164,G168.AllForms',
description: 'Check that submissions to this form are either reversible, checked for input errors, and/or confirmed by the user.'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_1.F77',
description: 'Duplicate id attribute value "[Element ID]" found on the web page.'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.Empty',
description: 'Anchor element found with an ID but without a href or link text. Consider moving its ID to a parent or nearby element.'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.EmptyWithName',
description: 'Anchor element found with a name attribute but without a href or link text. Consider moving the name attribute to become an ID of a parent or nearby element.'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.EmptyNoId',
description: 'Anchor element found with no link content and no name and/or ID attribute.'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.NoHref',
description: 'Anchor elements should not be used for defining in-page link targets. If not using the ID for other purposes (such as CSS or scripting), consider moving it to a parent element.'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.Placeholder',
description: 'Anchor element found with link content, but no href and/or ID attribute has been supplied.'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.NoContent',
description: 'Anchor element found with a valid href attribute, but no link content has been supplied.'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.[NodeName].Name',
description: 'This [element type] does not have a name available to an accessibility API. Valid names are [valid names for this element].'
},
{
name: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.[NodeName].Value',
description: 'This [element type] does not have a value available to an accessibility API. Add one [using a element-specific method].'
},
{
name: 'WCAG2AAA.Principle1.Guideline4_1.4_1_3_ARIA22,G199,ARIA19,G83,G84,G85,G139,G177,G194,ARIA23.Check',
description: 'Check that status messages can be programmatically determined through role or properties such that they can be presented to the user by assistive technologies without receiving focus.'
}
]
}
];
};
================================================
FILE: data/techniques.js
================================================
// This file is part of Pa11y Dashboard.
//
// Pa11y Dashboard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Pa11y Dashboard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
'use strict';
module.exports = function getTechniques() {
return {
H30: {
title: 'H30: Providing link text that describes the purpose of a link for anchor elements',
url: 'http://www.w3.org/TR/WCAG20-TECHS/H30'
},
H37: {
title: 'H37: Using alt attributes on img elements',
url: 'http://www.w3.org/TR/WCAG20-TECHS/H37'
},
H67: {
title: 'H67: Using null alt text and no title attribute on img elements for images that AT should ignore',
url: 'http://www.w3.org/TR/WCAG20-TECHS/H67'
},
G94: {
title: 'G94: Providing short text alternative for non-text content that serves the same purpose and presents the same information as the non-text content',
url: 'http://www.w3.org/TR/WCAG20-TECHS/G94'
},
H36: {
title: 'H36: Using alt attributes on images used as submit buttons',
url: 'http://www.w3.org/TR/WCAG20-TECHS/H36'
},
H24: {
title: 'H24: Providing text alternatives for the area elements of image maps ',
url: 'http://www.w3.org/TR/WCAG20-TECHS/H24'
},
G73: {
title: 'G73: Providing a long description in another location with a link to it that is immediately adjacent to the non-text content',
url: 'http://www.w3.org/TR/WCAG20-TECHS/G73'
},
G74: {
title: 'G74: Providing a long description in text near the non-text content, with a reference to the location of the long description in the short description',
url: 'http://www.w3.org/TR/WCAG20-TECHS/G74'
},
H2: {
title: 'H2: Combining adjacent image and text links for the same resource',
url: 'http://www.w3.org/TR/WCAG20-TECHS/H2'
},
H53: {
title: 'H53: Using the body of the object element',
url: 'http://www.w3.org/TR/WCAG20-TECHS/H53'
},
G92: {
title: 'G92: Providing long description for non-text content that serves the same purpose and presents the same information',
url: 'http://www.w3.org/TR/WCAG20-TECHS/G92'
},
H35: {
title: 'H35: Providing text alternatives on applet elements ',
url: 'http://www.w3.org/TR/WCAG20-TECHS/H35'
},
G158: {
title: 'G158: Providing an alternative for time-based media for audio-only content',
url: 'http://www.w3.org/TR/WCAG20-TECHS/G158'
},
G159: {
title: 'G159: Providing an alternative for time-based media for video-only content',
url: 'http://www.w3.org/TR/WCAG20-TECHS/G159'
},
G166: {
title: 'G166: Providing audio that describes the important video content and describing it as such',
url: 'http://www.w3.org/TR/WCAG20-TECHS/G166'
},
G87: {
titl
gitextract_db6hdddw/
├── .bowerrc
├── .dockerignore
├── .editorconfig
├── .github/
│ ├── issue_template.md
│ └── workflows/
│ └── tests.yml
├── .gitignore
├── .npmrc
├── .nvmrc
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Dockerfile.example
├── LICENSE
├── MIGRATION.md
├── Makefile
├── README.md
├── app.js
├── bower.json
├── config/
│ ├── development.sample.json
│ ├── production.sample.json
│ └── test.sample.json
├── config.js
├── data/
│ ├── standards.js
│ └── techniques.js
├── eslint.config.js
├── index.js
├── package.json
├── public/
│ ├── js/
│ │ ├── site.js
│ │ └── vendor/
│ │ ├── bootstrap/
│ │ │ ├── .bower.json
│ │ │ ├── CNAME
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── DOCS-LICENSE
│ │ │ ├── Gruntfile.js
│ │ │ ├── LICENSE
│ │ │ ├── LICENSE-MIT
│ │ │ ├── README.md
│ │ │ ├── _config.yml
│ │ │ ├── _includes/
│ │ │ │ ├── ads.html
│ │ │ │ ├── footer.html
│ │ │ │ ├── header.html
│ │ │ │ ├── nav-about.html
│ │ │ │ ├── nav-components.html
│ │ │ │ ├── nav-css.html
│ │ │ │ ├── nav-customize.html
│ │ │ │ ├── nav-getting-started.html
│ │ │ │ ├── nav-javascript.html
│ │ │ │ ├── nav-main.html
│ │ │ │ ├── old-bs-docs.html
│ │ │ │ └── social-buttons.html
│ │ │ ├── _layouts/
│ │ │ │ ├── default.html
│ │ │ │ └── home.html
│ │ │ ├── about.html
│ │ │ ├── bower.json
│ │ │ ├── browserstack.json
│ │ │ ├── components.html
│ │ │ ├── composer.json
│ │ │ ├── css.html
│ │ │ ├── customize.html
│ │ │ ├── dist/
│ │ │ │ ├── css/
│ │ │ │ │ ├── bootstrap-theme.css
│ │ │ │ │ └── bootstrap.css
│ │ │ │ └── js/
│ │ │ │ └── bootstrap.js
│ │ │ ├── docs-assets/
│ │ │ │ ├── css/
│ │ │ │ │ ├── docs.css
│ │ │ │ │ └── pygments-manni.css
│ │ │ │ └── js/
│ │ │ │ ├── application.js
│ │ │ │ ├── customizer.js
│ │ │ │ ├── filesaver.js
│ │ │ │ ├── holder.js
│ │ │ │ ├── ie8-responsive-file-warning.js
│ │ │ │ ├── jszip.js
│ │ │ │ ├── less.js
│ │ │ │ ├── raw-files.js
│ │ │ │ └── uglify.js
│ │ │ ├── examples/
│ │ │ │ ├── carousel/
│ │ │ │ │ ├── carousel.css
│ │ │ │ │ └── index.html
│ │ │ │ ├── grid/
│ │ │ │ │ ├── grid.css
│ │ │ │ │ └── index.html
│ │ │ │ ├── jumbotron/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── jumbotron.css
│ │ │ │ ├── jumbotron-narrow/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── jumbotron-narrow.css
│ │ │ │ ├── justified-nav/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── justified-nav.css
│ │ │ │ ├── navbar/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar.css
│ │ │ │ ├── navbar-fixed-top/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar-fixed-top.css
│ │ │ │ ├── navbar-static-top/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── navbar-static-top.css
│ │ │ │ ├── non-responsive/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── non-responsive.css
│ │ │ │ ├── offcanvas/
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── offcanvas.css
│ │ │ │ │ └── offcanvas.js
│ │ │ │ ├── signin/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── signin.css
│ │ │ │ ├── starter-template/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── starter-template.css
│ │ │ │ ├── sticky-footer/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── sticky-footer.css
│ │ │ │ ├── sticky-footer-navbar/
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── sticky-footer-navbar.css
│ │ │ │ └── theme/
│ │ │ │ ├── index.html
│ │ │ │ └── theme.css
│ │ │ ├── getting-started.html
│ │ │ ├── index.html
│ │ │ ├── javascript.html
│ │ │ ├── js/
│ │ │ │ ├── affix.js
│ │ │ │ ├── alert.js
│ │ │ │ ├── button.js
│ │ │ │ ├── carousel.js
│ │ │ │ ├── collapse.js
│ │ │ │ ├── dropdown.js
│ │ │ │ ├── modal.js
│ │ │ │ ├── popover.js
│ │ │ │ ├── scrollspy.js
│ │ │ │ ├── tab.js
│ │ │ │ ├── tests/
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── unit/
│ │ │ │ │ │ ├── affix.js
│ │ │ │ │ │ ├── alert.js
│ │ │ │ │ │ ├── button.js
│ │ │ │ │ │ ├── carousel.js
│ │ │ │ │ │ ├── collapse.js
│ │ │ │ │ │ ├── dropdown.js
│ │ │ │ │ │ ├── modal.js
│ │ │ │ │ │ ├── phantom.js
│ │ │ │ │ │ ├── popover.js
│ │ │ │ │ │ ├── scrollspy.js
│ │ │ │ │ │ ├── tab.js
│ │ │ │ │ │ ├── tooltip.js
│ │ │ │ │ │ └── transition.js
│ │ │ │ │ └── vendor/
│ │ │ │ │ ├── jquery.js
│ │ │ │ │ ├── qunit.css
│ │ │ │ │ └── qunit.js
│ │ │ │ ├── tooltip.js
│ │ │ │ └── transition.js
│ │ │ ├── less/
│ │ │ │ ├── alerts.less
│ │ │ │ ├── badges.less
│ │ │ │ ├── bootstrap.less
│ │ │ │ ├── breadcrumbs.less
│ │ │ │ ├── button-groups.less
│ │ │ │ ├── buttons.less
│ │ │ │ ├── carousel.less
│ │ │ │ ├── close.less
│ │ │ │ ├── code.less
│ │ │ │ ├── component-animations.less
│ │ │ │ ├── dropdowns.less
│ │ │ │ ├── forms.less
│ │ │ │ ├── glyphicons.less
│ │ │ │ ├── grid.less
│ │ │ │ ├── input-groups.less
│ │ │ │ ├── jumbotron.less
│ │ │ │ ├── labels.less
│ │ │ │ ├── list-group.less
│ │ │ │ ├── media.less
│ │ │ │ ├── mixins.less
│ │ │ │ ├── modals.less
│ │ │ │ ├── navbar.less
│ │ │ │ ├── navs.less
│ │ │ │ ├── normalize.less
│ │ │ │ ├── pager.less
│ │ │ │ ├── pagination.less
│ │ │ │ ├── panels.less
│ │ │ │ ├── popovers.less
│ │ │ │ ├── print.less
│ │ │ │ ├── progress-bars.less
│ │ │ │ ├── responsive-utilities.less
│ │ │ │ ├── scaffolding.less
│ │ │ │ ├── tables.less
│ │ │ │ ├── theme.less
│ │ │ │ ├── thumbnails.less
│ │ │ │ ├── tooltip.less
│ │ │ │ ├── type.less
│ │ │ │ ├── utilities.less
│ │ │ │ ├── variables.less
│ │ │ │ └── wells.less
│ │ │ └── package.json
│ │ ├── flot/
│ │ │ ├── .bower.json
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── API.md
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── FAQ.md
│ │ │ ├── LICENSE.txt
│ │ │ ├── Makefile
│ │ │ ├── NEWS.md
│ │ │ ├── PLUGINS.md
│ │ │ ├── README.md
│ │ │ ├── component.json
│ │ │ ├── examples/
│ │ │ │ ├── ajax/
│ │ │ │ │ ├── data-eu-gdp-growth-1.json
│ │ │ │ │ ├── data-eu-gdp-growth-2.json
│ │ │ │ │ ├── data-eu-gdp-growth-3.json
│ │ │ │ │ ├── data-eu-gdp-growth-4.json
│ │ │ │ │ ├── data-eu-gdp-growth-5.json
│ │ │ │ │ ├── data-eu-gdp-growth.json
│ │ │ │ │ ├── data-japan-gdp-growth.json
│ │ │ │ │ ├── data-usa-gdp-growth.json
│ │ │ │ │ └── index.html
│ │ │ │ ├── annotating/
│ │ │ │ │ └── index.html
│ │ │ │ ├── axes-interacting/
│ │ │ │ │ └── index.html
│ │ │ │ ├── axes-multiple/
│ │ │ │ │ └── index.html
│ │ │ │ ├── axes-time/
│ │ │ │ │ └── index.html
│ │ │ │ ├── axes-time-zones/
│ │ │ │ │ ├── date.js
│ │ │ │ │ ├── index.html
│ │ │ │ │ └── tz/
│ │ │ │ │ ├── africa
│ │ │ │ │ ├── antarctica
│ │ │ │ │ ├── asia
│ │ │ │ │ ├── australasia
│ │ │ │ │ ├── backward
│ │ │ │ │ ├── etcetera
│ │ │ │ │ ├── europe
│ │ │ │ │ ├── factory
│ │ │ │ │ ├── iso3166.tab
│ │ │ │ │ ├── leapseconds
│ │ │ │ │ ├── northamerica
│ │ │ │ │ ├── pacificnew
│ │ │ │ │ ├── solar87
│ │ │ │ │ ├── solar88
│ │ │ │ │ ├── solar89
│ │ │ │ │ ├── southamerica
│ │ │ │ │ ├── systemv
│ │ │ │ │ ├── yearistype.sh
│ │ │ │ │ └── zone.tab
│ │ │ │ ├── basic-options/
│ │ │ │ │ └── index.html
│ │ │ │ ├── basic-usage/
│ │ │ │ │ └── index.html
│ │ │ │ ├── canvas/
│ │ │ │ │ └── index.html
│ │ │ │ ├── categories/
│ │ │ │ │ └── index.html
│ │ │ │ ├── examples.css
│ │ │ │ ├── image/
│ │ │ │ │ └── index.html
│ │ │ │ ├── index.html
│ │ │ │ ├── interacting/
│ │ │ │ │ └── index.html
│ │ │ │ ├── navigate/
│ │ │ │ │ └── index.html
│ │ │ │ ├── percentiles/
│ │ │ │ │ └── index.html
│ │ │ │ ├── realtime/
│ │ │ │ │ └── index.html
│ │ │ │ ├── resize/
│ │ │ │ │ └── index.html
│ │ │ │ ├── selection/
│ │ │ │ │ └── index.html
│ │ │ │ ├── series-errorbars/
│ │ │ │ │ └── index.html
│ │ │ │ ├── series-pie/
│ │ │ │ │ └── index.html
│ │ │ │ ├── series-toggle/
│ │ │ │ │ └── index.html
│ │ │ │ ├── series-types/
│ │ │ │ │ └── index.html
│ │ │ │ ├── stacking/
│ │ │ │ │ └── index.html
│ │ │ │ ├── symbols/
│ │ │ │ │ └── index.html
│ │ │ │ ├── threshold/
│ │ │ │ │ └── index.html
│ │ │ │ ├── tracking/
│ │ │ │ │ └── index.html
│ │ │ │ ├── visitors/
│ │ │ │ │ └── index.html
│ │ │ │ └── zooming/
│ │ │ │ └── index.html
│ │ │ ├── excanvas.js
│ │ │ ├── excanvas.min.js
│ │ │ ├── flot.jquery.json
│ │ │ ├── jquery.colorhelpers.js
│ │ │ ├── jquery.flot.canvas.js
│ │ │ ├── jquery.flot.categories.js
│ │ │ ├── jquery.flot.crosshair.js
│ │ │ ├── jquery.flot.dashes.js
│ │ │ ├── jquery.flot.errorbars.js
│ │ │ ├── jquery.flot.fillbetween.js
│ │ │ ├── jquery.flot.image.js
│ │ │ ├── jquery.flot.js
│ │ │ ├── jquery.flot.navigate.js
│ │ │ ├── jquery.flot.pie.js
│ │ │ ├── jquery.flot.resize.js
│ │ │ ├── jquery.flot.selection.js
│ │ │ ├── jquery.flot.stack.js
│ │ │ ├── jquery.flot.symbol.js
│ │ │ ├── jquery.flot.threshold.js
│ │ │ ├── jquery.flot.time.js
│ │ │ ├── jquery.js
│ │ │ └── package.json
│ │ └── jquery/
│ │ ├── .bower.json
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── bower.json
│ │ ├── component.json
│ │ ├── composer.json
│ │ ├── jquery-migrate.js
│ │ ├── jquery.js
│ │ └── package.json
│ └── less/
│ ├── alerts.less
│ ├── badges.less
│ ├── bootswatch.less
│ ├── breadcrumbs.less
│ ├── button-groups.less
│ ├── buttons.less
│ ├── carousel.less
│ ├── close.less
│ ├── code.less
│ ├── component-animations.less
│ ├── dropdowns.less
│ ├── forms.less
│ ├── glyphicons.less
│ ├── grid.less
│ ├── ie8and.less
│ ├── input-groups.less
│ ├── jumbotron.less
│ ├── labels.less
│ ├── list-group.less
│ ├── main.less
│ ├── media.less
│ ├── mixins.less
│ ├── modals.less
│ ├── navbar.less
│ ├── navs.less
│ ├── normalize.less
│ ├── pager.less
│ ├── pagination.less
│ ├── panels.less
│ ├── popovers.less
│ ├── print.less
│ ├── progress-bars.less
│ ├── responsive-utilities.less
│ ├── scaffolding.less
│ ├── site-ie8and.less
│ ├── site-nojavascript.less
│ ├── site-responsive.less
│ ├── site.less
│ ├── tables.less
│ ├── theme.less
│ ├── thumbnails.less
│ ├── tooltip.less
│ ├── type.less
│ ├── utilities.less
│ ├── variables-flatly.less
│ ├── variables.less
│ └── wells.less
├── route/
│ ├── health.js
│ ├── index.js
│ ├── new.js
│ ├── result/
│ │ ├── download.js
│ │ └── index.js
│ └── task/
│ ├── delete.js
│ ├── edit.js
│ ├── ignore.js
│ ├── index.js
│ ├── run.js
│ └── unignore.js
├── test/
│ └── integration/
│ ├── helper/
│ │ └── navigate.js
│ ├── route/
│ │ ├── health.js
│ │ ├── index.js
│ │ ├── new.js
│ │ ├── result/
│ │ │ ├── download.js
│ │ │ └── index.js
│ │ └── task/
│ │ ├── delete.js
│ │ ├── edit.js
│ │ ├── index.js
│ │ └── run.js
│ └── setup.js
└── view/
├── 404.html
├── 500.html
├── helper/
│ ├── conditionals.js
│ ├── date.js
│ ├── string.js
│ └── url.js
├── index.html
├── layout/
│ └── default.html
├── new.html
├── partial/
│ ├── breadcrumb.html
│ ├── graph.html
│ ├── page-footer.html
│ ├── page-header.html
│ ├── result-header.html
│ ├── result.html
│ ├── task-header.html
│ └── tasks.html
├── presenter/
│ ├── ignore.js
│ ├── result-list.js
│ ├── result.js
│ └── task.js
├── result/
│ └── index.html
└── task/
├── delete.html
├── edit.html
└── index.html
SYMBOL INDEX (510 symbols across 56 files)
FILE: app.js
function initApp (line 31) | function initApp(config, callback) {
function defaultConfig (line 57) | function defaultConfig(config) {
function loadMiddleware (line 67) | function loadMiddleware(app) {
function loadViewEngine (line 100) | function loadViewEngine(app, config) {
function loadRoutes (line 137) | function loadRoutes(app, config) {
function loadErrorHandling (line 164) | function loadErrorHandling(app, config, callback) {
function addRequestId (line 188) | function addRequestId(request, response, next) {
FILE: config.js
function env (line 55) | function env(name, defaultValue) {
FILE: index.js
function setupSignalHandlers (line 37) | function setupSignalHandlers(app) {
function logStartup (line 51) | function logStartup(app) {
function setupErrorLogging (line 65) | function setupErrorLogging(app) {
function startWebservice (line 76) | function startWebservice() {
FILE: public/js/site.js
function animateSection (line 140) | function animateSection (sectionName, offset){
function switchStandardsList (line 147) | function switchStandardsList(el){
function getGraphData (line 153) | function getGraphData() {
function getXAxisLabel (line 160) | function getXAxisLabel (el) {
function storeDatum (line 164) | function storeDatum (el, label) {
function plotGraphData (line 175) | function plotGraphData () {
function getData (line 180) | function getData() {
function toggleResetZoomButton (line 204) | function toggleResetZoomButton() {
function exportGraph (line 208) | function exportGraph() {
function downloadFile (line 227) | function downloadFile(dataurl, filename) {
function plotAccordingToChoices (line 284) | function plotAccordingToChoices() {
function showTooltip (line 310) | function showTooltip(x, y, contents) {
function initTaskFilter (line 340) | function initTaskFilter (container) {
function initTaskFilterTasks (line 345) | function initTaskFilterTasks (container) {
function initTaskFilterInput (line 350) | function initTaskFilterInput (container, tasks) {
function filterTasks (line 358) | function filterTasks (tasks, query) {
FILE: public/js/vendor/bootstrap/Gruntfile.js
function getFiles (line 210) | function getFiles(type) {
FILE: public/js/vendor/bootstrap/dist/js/bootstrap.js
function transitionEnd (line 36) | function transitionEnd() {
function removeElement (line 121) | function removeElement() {
function clearMenus (line 767) | function clearMenus() {
function getParent (line 778) | function getParent($this) {
function complete (line 1339) | function complete() {
function ScrollSpy (line 1607) | function ScrollSpy(element, options) {
function next (line 1808) | function next() {
FILE: public/js/vendor/bootstrap/docs-assets/js/customizer.js
function showError (line 12) | function showError(msg, err) {
function showCallout (line 23) | function showCallout(msg, showUpTop) {
function getQueryParam (line 36) | function getQueryParam(key) {
function createGist (line 42) | function createGist(configJson) {
function getCustomizerData (line 66) | function getCustomizerData() {
function parseUrl (line 85) | function parseUrl() {
function generateZip (line 118) | function generateZip(css, js, fonts, config, complete) {
function generateCustomCSS (line 153) | function generateCustomCSS(vars) {
function generateFonts (line 163) | function generateFonts() {
function bootstrapLessFilenames (line 172) | function bootstrapLessFilenames() {
function generateCSS (line 184) | function generateCSS() {
function generateJavascript (line 243) | function generateJavascript() {
FILE: public/js/vendor/bootstrap/docs-assets/js/holder.js
function contentLoaded (line 46) | function contentLoaded(n,t){var l="complete",s="readystatechange",u=!1,h...
function selector (line 49) | function selector(a){
function extend (line 55) | function extend(a,b){var c={};for(var d in a)c[d]=a[d];for(var e in b)c[...
function text_size (line 66) | function text_size(width, height, template) {
function draw (line 78) | function draw(ctx, dimensions, template, ratio, literal) {
function render (line 106) | function render(mode, el, holder, src) {
function fluid_update (line 163) | function fluid_update(element) {
function parse_flags (line 182) | function parse_flags(flags, options) {
FILE: public/js/vendor/bootstrap/docs-assets/js/jszip.js
function identity (line 1096) | function identity(input) {
function stringToArrayLike (line 1106) | function stringToArrayLike(str, array) {
function arrayLikeToString (line 1118) | function arrayLikeToString(array) {
function arrayLikeToArrayLike (line 1176) | function arrayLikeToArrayLike(arrayFrom, arrayTo) {
FILE: public/js/vendor/bootstrap/docs-assets/js/less.js
function n (line 8) | function n(t){return e.less[t.split("/")[1]]}
function f (line 8) | function f(){r.env==="development"?(r.optimization=0,r.watchTimer=setInt...
function m (line 8) | function m(){var e=document.getElementsByTagName("style");for(var t=0;t<...
function g (line 8) | function g(e,t){for(var n=0;n<r.sheets.length;n++)w(r.sheets[n],e,t,r.sh...
function y (line 8) | function y(e,t){var n=b(e),r=b(t),i,s,o,u,a="";if(n.hostPart!==r.hostPar...
function b (line 8) | function b(e,t){var n=/^((?:[a-z-]+:)?\/\/(?:[^\/\?#]*\/)|([\/\\]))?((?:...
function w (line 8) | function w(t,n,i,s){var o=t.contents||{},u=t.files||{},a=b(t.href,e.loca...
function E (line 8) | function E(e){return e.replace(/^[a-z]+:\/\/?[^\/]+/,"").replace(/^\//,"...
function S (line 8) | function S(e,t,n){var r,i=t.href||"",s="less:"+(t.title||E(i));if((r=doc...
function x (line 8) | function x(e,t,n,i){function a(t,n,r){t.status>=200&&t.status<300?n(t.re...
function T (line 8) | function T(){if(e.XMLHttpRequest)return new XMLHttpRequest;try{return ne...
function N (line 8) | function N(e){return e&&e.parentNode.removeChild(e)}
function C (line 8) | function C(e){r.env=="development"&&typeof console!="undefined"&&console...
function k (line 8) | function k(e,t){var n="less-error-message:"+E(t),i='<li><label>{line}</l...
function g (line 8) | function g(){a=c[u],f=o,h=o}
function y (line 8) | function y(){c[u]=a,o=f,h=o}
function b (line 8) | function b(){o>h&&(c[u]=c[u].slice(o-h),h=o)}
function w (line 8) | function w(e){var t=e.charCodeAt(0);return t===32||t===10||t===9}
function E (line 8) | function E(e){var t,n,r,i,a;if(e instanceof Function)return e.call(p.par...
function S (line 8) | function S(e){var t=o,n=u,r=o+c[u].length,i=o+=e;while(o<r){if(!w(s.char...
function x (line 8) | function x(e,t){var n=E(e);if(!!n)return n;T(t||(typeof e=="string"?"exp...
function T (line 8) | function T(e,t){var n=new Error(e);throw n.index=o,n.type=t||"Syntax",n}
function N (line 8) | function N(e){return typeof e=="string"?s.charAt(o)===e:e.test(c[u])?!0:!1}
function C (line 8) | function C(e,t){return e.filename&&t.filename&&e.filename!==t.filename?p...
function k (line 8) | function k(e,t){for(var n=e,r=-1;n>=0&&t.charAt(n)!=="\n";n--)r++;return...
function L (line 8) | function L(e){return r.mode==="browser"||r.mode==="rhino"?e.filename:n("...
function A (line 8) | function A(e,t,n){return{lineNumber:k(e,t).line+1,fileName:L(n)}}
function O (line 8) | function O(e,t){var n=C(e,t),r=k(e.index,n),i=r.line,s=r.column,o=n.spli...
function t (line 8) | function t(t){return e.functions.hsla(t.h,t.s,t.l,t.a)}
function n (line 8) | function n(t,n){return t instanceof e.Dimension&&t.unit=="%"?parseFloat(...
function r (line 8) | function r(t){if(t instanceof e.Dimension)return parseFloat(t.unit=="%"?...
function i (line 8) | function i(e){return Math.min(1,Math.max(0,e))}
function u (line 8) | function u(e){return e=e<0?e+1:e>1?e-1:e,e*6<1?o+(s-o)*e*6:e*2<1?s:e*3<2...
FILE: public/js/vendor/bootstrap/docs-assets/js/uglify.js
function g (line 14) | function g(a,b){if(a&&a.charAt(0)==="."&&b){b=b.split("/"),b=b.slice(0,b...
function h (line 14) | function h(a,d){return function(){return c.apply(null,b.call(arguments,0...
function i (line 14) | function i(a){return function(b){return g(b,a)}}
function j (line 14) | function j(b){return function(c){a[b]=c}}
function k (line 14) | function k(b,c){var d,e,f=b.indexOf("!");return f!==-1?(d=g(b.slice(0,f)...
function l (line 14) | function l(b,c,d,e){var f=[],g,i,l,m,n,o;e||(e=b);if(typeof d=="function...
function r (line 14) | function r(a){return q.letter.test(a)}
function s (line 14) | function s(a){return a=a.charCodeAt(0),a>=48&&a<=57}
function t (line 14) | function t(a){return s(a)||r(a)}
function u (line 14) | function u(a){return q.non_spacing_mark.test(a)||q.space_combining_mark....
function v (line 14) | function v(a){return q.connector_punctuation.test(a)}
function w (line 14) | function w(a){return a=="$"||a=="_"||r(a)}
function x (line 14) | function x(a){return w(a)||u(a)||s(a)||v(a)||a==""||a==""}
function y (line 14) | function y(a){if(i.test(a))return parseInt(a.substr(2),16);if(j.test(a))...
function z (line 14) | function z(a,b,c,d){this.message=a,this.line=b,this.col=c,this.pos=d,thi...
function A (line 14) | function A(a,b,c,d){throw new z(a,b,c,d)}
function B (line 14) | function B(a,b,c){return a.type==b&&(c==null||a.value==c)}
function D (line 14) | function D(a){function c(){return b.text.charAt(b.pos)}function e(a,c){v...
function K (line 14) | function K(a,b,c){this.name=a,this.start=b,this.end=c}
function L (line 14) | function L(a,b,c){function e(a,b){return B(d.token,a,b)}function f(){ret...
function M (line 14) | function M(a){var b=P(arguments,1);return function(){return a.apply(this...
function N (line 14) | function N(a){a instanceof Function&&(a=a());for(var b=1,c=arguments.len...
function O (line 14) | function O(a){var b={};for(var c=0;c<a.length;++c)b[a[c]]=!0;return b}
function P (line 14) | function P(a,b){return Array.prototype.slice.call(a,b||0)}
function Q (line 14) | function Q(a){return a.split("")}
function R (line 14) | function R(a,b){for(var c=b.length;--c>=0;)if(b[c]===a)return!0;return!1}
function S (line 14) | function S(a,b){return Object.prototype.hasOwnProperty.call(a,b)}
function i (line 14) | function i(){function a(a){return[this[0],K(a,function(a){var b=[a[0]];r...
function j (line 14) | function j(a){this.names={},this.mangled={},this.rev_mangled={},this.cna...
function l (line 14) | function l(a){function f(a){b=new j(b);var c=b.body=a();return c.scope=b...
function m (line 14) | function m(a,b){function g(a,c){return!b.toplevel&&!e.parent?a:b.except&...
function o (line 14) | function o(a,b){return E(a).length>E(b[0]=="stat"?b[1]:b).length?b:a}
function p (line 14) | function p(a){return a[0]=="block"&&a[1]&&a[1].length>0?a[1][a[1].length...
function q (line 14) | function q(a){if(a)switch(p(a)[0]){case"return":case"break":case"continu...
function r (line 14) | function r(a){return a[0]=="unary-prefix"&&f(a[1],["!","delete"])||a[0]=...
function s (line 14) | function s(a){return!a||a[0]=="block"&&(!a[1]||a[1].length==0)}
function t (line 14) | function t(a){return a[0]=="string"||a[0]=="unary-prefix"&&a[1]=="typeof...
function v (line 14) | function v(a){s(a)||n("Dropping unreachable code: "+E(a,!0))}
function w (line 14) | function w(a){function d(a){a=K(a,c);for(var b=0;b<a.length;++b){var e=a...
function x (line 14) | function x(a,b){function g(){throw e}function h(){throw f}function j(){r...
function y (line 14) | function y(a){function e(a,b){var e=d;d=b,a=K(a,c);var f={},g=K(b.names,...
function z (line 14) | function z(a,b){function h(a){var c=["unary-prefix","!",a];switch(a[0]){...
function B (line 14) | function B(a,b){var c=0,d=0;return a=a.replace(/[\\\b\f\n\r\t\x22\x27\u2...
function C (line 14) | function C(a){return a.replace(/[\u0080-\uffff]/g,function(a){var b=a.ch...
function E (line 14) | function E(a,b){function m(a){var c=B(a,b.ascii_only);return b.inline_sc...
function F (line 14) | function F(a,b){var c=[0];return d.parse(function(){function h(a){return...
function G (line 14) | function G(a,b){if(b>0){if(b==1)return a;var c=G(a,b>>1);return c+=c,b&1...
function H (line 14) | function H(a,b){var c={};a===!0&&(a={});for(var d in b)J(b,d)&&(c[d]=a&&...
function I (line 14) | function I(a){return/^[a-z_$][a-z0-9_$]*$/i.test(a)&&a!="this"&&!J(d.KEY...
function J (line 14) | function J(a,b){return Object.prototype.hasOwnProperty.call(a,b)}
function b (line 14) | function b(c){switch(c[0]){case"string":case"num":return c[1];case"name"...
function b (line 14) | function b(a){this.v=a}
function c (line 14) | function c(a){this.v=a}
function j (line 14) | function j(){var j=e.call(f,d[i],i);j instanceof b?(j=j.v,j instanceof c...
function d (line 14) | function d(a,b){b||(b={});var c=d.parser,e=d.uglify,f=c.parse(a,b.strict...
function l (line 14) | function l(a){function f(a,b){var c=d,e;return d=a,e=b(),d=c,e}function ...
FILE: public/js/vendor/bootstrap/js/alert.js
function removeElement (line 54) | function removeElement() {
FILE: public/js/vendor/bootstrap/js/dropdown.js
function clearMenus (line 93) | function clearMenus() {
function getParent (line 104) | function getParent($this) {
FILE: public/js/vendor/bootstrap/js/scrollspy.js
function ScrollSpy (line 26) | function ScrollSpy(element, options) {
FILE: public/js/vendor/bootstrap/js/tab.js
function next (line 68) | function next() {
FILE: public/js/vendor/bootstrap/js/tests/unit/phantom.js
function sendMessage (line 19) | function sendMessage() {
FILE: public/js/vendor/bootstrap/js/tests/vendor/jquery.js
function M (line 4) | function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.n...
function at (line 4) | function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)...
function st (line 4) | function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLeng...
function lt (line 4) | function lt(e){return e[b]=!0,e}
function ut (line 4) | function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){re...
function ct (line 4) | function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[...
function pt (line 4) | function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sou...
function ft (line 4) | function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"...
function dt (line 4) | function dt(e){return function(t){var n=t.nodeName.toLowerCase();return(...
function ht (line 4) | function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,...
function gt (line 4) | function gt(){}
function mt (line 4) | function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0)...
function yt (line 4) | function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}
function vt (line 4) | function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.firs...
function bt (line 4) | function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i-...
function xt (line 4) | function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)...
function wt (line 4) | function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)...
function Tt (line 4) | function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relat...
function Ct (line 4) | function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d)...
function Nt (line 4) | function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}
function kt (line 4) | function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0...
function F (line 4) | function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t...
function R (line 5) | function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType...
function W (line 5) | function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e...
function $ (line 5) | function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-...
function I (line 5) | function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&...
function it (line 5) | function it(){return!0}
function ot (line 5) | function ot(){return!1}
function at (line 5) | function at(){try{return a.activeElement}catch(e){}}
function pt (line 5) | function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}
function ft (line 5) | function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){retu...
function dt (line 5) | function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.cre...
function Lt (line 5) | function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType...
function Ht (line 5) | function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}
function qt (line 5) | function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttrib...
function _t (line 5) | function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval...
function Mt (line 5) | function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e)...
function Ot (line 5) | function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCas...
function Ft (line 5) | function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getEl...
function Bt (line 5) | function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}
function tn (line 6) | function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.sl...
function nn (line 6) | function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(...
function rn (line 6) | function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.sty...
function on (line 6) | function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[...
function an (line 6) | function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:...
function sn (line 6) | function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o...
function ln (line 6) | function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(...
function un (line 6) | function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[...
function gn (line 6) | function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn....
function Hn (line 6) | function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var ...
function qn (line 6) | function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!...
function _n (line 6) | function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i...
function k (line 6) | function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t...
function Mn (line 6) | function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[...
function On (line 6) | function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])fo...
function In (line 6) | function In(){try{return new e.XMLHttpRequest}catch(t){}}
function zn (line 6) | function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(...
function Kn (line 6) | function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}
function Zn (line 6) | function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;fo...
function er (line 6) | function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(functio...
function tr (line 6) | function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e...
function nr (line 6) | function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&n...
function rr (line 6) | function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}
function ir (line 6) | function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r...
function or (line 6) | function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.pa...
FILE: public/js/vendor/bootstrap/js/tests/vendor/qunit.js
function run (line 226) | function run() {
function done (line 759) | function done() {
function validTest (line 814) | function validTest( name ) {
function sourceFromStacktrace (line 840) | function sourceFromStacktrace() {
function escapeHtml (line 858) | function escapeHtml(s) {
function synchronize (line 875) | function synchronize( callback ) {
function process (line 883) | function process() {
function saveGlobal (line 899) | function saveGlobal() {
function checkPollution (line 909) | function checkPollution( name ) {
function diff (line 925) | function diff( a, b ) {
function fail (line 939) | function fail(message, exception, callback) {
function extend (line 950) | function extend(a, b) {
function addEvent (line 962) | function addEvent(elem, type, fn) {
function id (line 972) | function id(name) {
function bindCallbacks (line 988) | function bindCallbacks(o, callbacks, args) {
function useStrictEquality (line 1002) | function useStrictEquality(b, a) {
function quote (line 1165) | function quote( str ) {
function literal (line 1168) | function literal( o ) {
function join (line 1171) | function join( pre, arr, post ) {
function array (line 1181) | function array( arr, stack ) {
function getText (line 1339) | function getText( elems ) {
function inArray (line 1359) | function inArray( elem, array ) {
function diff (line 1388) | function diff(o, n) {
FILE: public/js/vendor/bootstrap/js/tooltip.js
function complete (line 263) | function complete() {
FILE: public/js/vendor/bootstrap/js/transition.js
function transitionEnd (line 26) | function transitionEnd() {
FILE: public/js/vendor/flot/examples/axes-time-zones/date.js
function invalidTZError (line 417) | function invalidTZError(t) { throw new Error('Timezone "' + t + '" is ei...
function builtInLoadZoneFile (line 418) | function builtInLoadZoneFile(fileName, opts) {
function getRegionForTimezone (line 436) | function getRegionForTimezone(tz) {
function parseTimeString (line 457) | function parseTimeString(str) {
function processZone (line 466) | function processZone(z) {
function getZone (line 479) | function getZone(dt, tz) {
function getBasicOffset (line 510) | function getBasicOffset(time) {
function getRule (line 519) | function getRule(dt, zone, isUTC) {
function getAdjustedOffset (line 702) | function getAdjustedOffset(off, rule) {
function getAbbreviation (line 705) | function getAbbreviation(zone, rule) {
FILE: public/js/vendor/flot/excanvas.js
function getContext (line 59) | function getContext() {
function bind (line 82) | function bind(f, obj, var_args) {
function encodeHtmlAttribute (line 89) | function encodeHtmlAttribute(s) {
function addNamespace (line 93) | function addNamespace(doc, prefix, urn) {
function addNamespacesAndStylesheet (line 99) | function addNamespacesAndStylesheet(doc) {
function onPropertyChange (line 178) | function onPropertyChange(e) {
function onResize (line 196) | function onResize(e) {
function createMatrixIdentity (line 214) | function createMatrixIdentity() {
function matrixMultiply (line 222) | function matrixMultiply(m1, m2) {
function copyState (line 239) | function copyState(o1, o2) {
function getRgbHslContent (line 394) | function getRgbHslContent(styleString) {
function percent (line 405) | function percent(s) {
function clamp (line 409) | function clamp(v, min, max) {
function hslToRgb (line 413) | function hslToRgb(parts){
function hueToRgb (line 435) | function hueToRgb(m1, m2, h) {
function processStyle (line 453) | function processStyle(styleString) {
function processFontStyle (line 496) | function processFontStyle(styleString) {
function getComputedStyle (line 518) | function getComputedStyle(style, element) {
function buildStyle (line 550) | function buildStyle(style) {
function processLineCap (line 560) | function processLineCap(lineCap) {
function CanvasRenderingContext2D_ (line 570) | function CanvasRenderingContext2D_(canvasElement) {
function bezierCurveTo (line 649) | function bezierCurveTo(self, cp1, cp2, p) {
function appendStroke (line 978) | function appendStroke(ctx, lineStr) {
function appendFill (line 1001) | function appendFill(ctx, lineStr, min, max) {
function getCoords (line 1112) | function getCoords(ctx, aX, aY) {
function matrixIsFinite (line 1135) | function matrixIsFinite(m) {
function setM (line 1141) | function setM(ctx, m, updateLineScale) {
function CanvasGradient_ (line 1344) | function CanvasGradient_(aType) {
function CanvasPattern_ (line 1362) | function CanvasPattern_(image, repetition) {
function throwException (line 1384) | function throwException(s) {
function assertImageIsValid (line 1388) | function assertImageIsValid(img) {
function DOMException_ (line 1397) | function DOMException_(s) {
FILE: public/js/vendor/flot/excanvas.min.js
function y (line 1) | function y(){return this.context_||(this.context_=new D(this))}
function g (line 1) | function g(j,m,p){var i=t.call(arguments,2);return function(){return j.a...
function af (line 1) | function af(i){return String(i).replace(/&/g,"&").replace(/"/g,"&quo...
function Y (line 1) | function Y(m,j,i){if(!m.namespaces[j]){m.namespaces.add(j,i,"#default#VM...
function R (line 1) | function R(j){Y(j,"g_vml_","urn:schemas-microsoft-com:vml");Y(j,"g_o_","...
function x (line 1) | function x(j){var i=j.srcElement;switch(j.propertyName){case"width":i.ge...
function W (line 1) | function W(j){var i=j.srcElement;if(i.firstChild){i.firstChild.style.wid...
function B (line 1) | function B(){return[[1,0,0],[0,1,0],[0,0,1]]}
function J (line 1) | function J(p,m){var j=B();for(var i=0;i<3;i++){for(var ah=0;ah<3;ah++){v...
function v (line 1) | function v(j,i){i.fillStyle=j.fillStyle;i.lineCap=j.lineCap;i.lineJoin=j...
function M (line 1) | function M(j){var p=j.indexOf("(",3);var i=j.indexOf(")",p+1);var m=j.su...
function c (line 1) | function c(i){return parseFloat(i)/100}
function r (line 1) | function r(j,m,i){return Math.min(i,Math.max(m,j))}
function I (line 1) | function I(ag){var i,ai,aj,ah,ak,Z;ah=parseFloat(ag[0])/360%360;if(ah<0)...
function a (line 1) | function a(j,i,m){if(m<0){m++}if(m>1){m--}if(6*m<1){return j+(i-j)*6*m}e...
function F (line 1) | function F(j){if(j in C){return C[j]}var ag,Z=1;j=String(j);if(j.charAt(...
function E (line 1) | function E(i){if(L[i]){return L[i]}var p=document.createElement("div");v...
function u (line 1) | function u(m,j){var i={};for(var ah in m){i[ah]=m[ah]}var ag=parseFloat(...
function ac (line 1) | function ac(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px ...
function S (line 1) | function S(i){return s[i]||"square"}
function D (line 1) | function D(i){this.m_=B();this.mStack_=[];this.aStack_=[];this.currentPa...
function K (line 1) | function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,c...
function w (line 1) | function w(m,ag){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.gl...
function G (line 1) | function G(aq,ai,aK,ar){var aj=aq.fillStyle;var aB=aq.arcScaleX_;var aA=...
function V (line 1) | function V(j,Z,p){var i=j.m_;return{x:d*(Z*i[0][0]+p*i[1][0]+i[2][0])-f,...
function h (line 1) | function h(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1]...
function aa (line 1) | function aa(j,i,p){if(!h(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i...
function U (line 1) | function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;t...
function T (line 1) | function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repeti...
function O (line 1) | function O(i){throw new P(i)}
function Q (line 1) | function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_E...
function P (line 1) | function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.c...
FILE: public/js/vendor/flot/jquery.colorhelpers.js
function clamp (line 55) | function clamp(min, value, max) {
FILE: public/js/vendor/flot/jquery.flot.canvas.js
function init (line 42) | function init(plot, classes) {
FILE: public/js/vendor/flot/jquery.flot.categories.js
function processRawData (line 56) | function processRawData(plot, series, data, datapoints) {
function getNextIndex (line 97) | function getNextIndex(categories) {
function categoriesTickGenerator (line 107) | function categoriesTickGenerator(axis) {
function setupCategoriesForAxis (line 120) | function setupCategoriesForAxis(series, axis, datapoints) {
function transformPointsOnAxis (line 146) | function transformPointsOnAxis(datapoints, axis, categories) {
function processDatapoints (line 174) | function processDatapoints(plot, series, datapoints) {
function init (line 179) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.crosshair.js
function init (line 70) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.dashes.js
function init (line 31) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.errorbars.js
function processRawData (line 76) | function processRawData(plot, series, data, datapoints){
function parseErrors (line 107) | function parseErrors(series, i){
function drawSeriesErrors (line 162) | function drawSeriesErrors(plot, ctx, s){
function drawError (line 275) | function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,of...
function drawPath (line 322) | function drawPath(ctx, pts){
function draw (line 330) | function draw(plot, ctx){
function init (line 342) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.fillbetween.js
function init (line 40) | function init( plot ) {
FILE: public/js/vendor/flot/jquery.flot.image.js
function drawSeries (line 118) | function drawSeries(plot, ctx, series) {
function processRawData (line 216) | function processRawData(plot, series, data, datapoints) {
function init (line 230) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.js
function H (line 32) | function H(J,K,I){return K<J?J:(K>I?I:K)}
function Canvas (line 51) | function Canvas(cls, container) {
function Plot (line 492) | function Plot(placeholder, data_, options_, plugins) {
function floorInBase (line 3057) | function floorInBase(n, base) {
FILE: public/js/vendor/flot/jquery.flot.navigate.js
function e (line 90) | function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,...
function f (line 90) | function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!...
function g (line 90) | function g(a){return Math.pow(a,2)}
function h (line 90) | function h(){return d.dragging===!1}
function i (line 90) | function i(a,b){a&&(a.unselectable=b?"off":"on",a.onselectstart=function...
function e (line 103) | function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0...
function init (line 126) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.pie.js
function init (line 68) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.resize.js
function m (line 23) | function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r...
function g (line 23) | function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width...
function init (line 28) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.selection.js
function init (line 82) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.stack.js
function init (line 43) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.symbol.js
function processRawData (line 17) | function processRawData(plot, series, datapoints) {
function init (line 62) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.threshold.js
function init (line 50) | function init(plot) {
FILE: public/js/vendor/flot/jquery.flot.time.js
function floorInBase (line 24) | function floorInBase(n, base) {
function formatDate (line 31) | function formatDate(d, fmt, monthNames, dayNames) {
function makeUtcWrapper (line 111) | function makeUtcWrapper(d) {
function dateGenerator (line 145) | function dateGenerator(ts, opts) {
function init (line 197) | function init(plot) {
FILE: public/js/vendor/flot/jquery.js
function createOptions (line 911) | function createOptions( options ) {
function dataAttr (line 1801) | function dataAttr( elem, key, data ) {
function isEmptyDataObject (line 1833) | function isEmptyDataObject( obj ) {
function returnFalse (line 3274) | function returnFalse() {
function returnTrue (line 3277) | function returnTrue() {
function Sizzle (line 3880) | function Sizzle( selector, context, results, seed ) {
function createInputPseudo (line 3949) | function createInputPseudo( type ) {
function createButtonPseudo (line 3957) | function createButtonPseudo( type ) {
function createPositionalPseudo (line 3965) | function createPositionalPseudo( fn ) {
function siblingCheck (line 4560) | function siblingCheck( a, b, ret ) {
function tokenize (line 4683) | function tokenize( selector, parseOnly ) {
function addCombinator (line 4746) | function addCombinator( matcher, combinator, base ) {
function elementMatcher (line 4798) | function elementMatcher( matchers ) {
function condense (line 4812) | function condense( unmatched, map, filter, context, xml ) {
function setMatcher (line 4833) | function setMatcher( preFilter, selector, matcher, postFilter, postFinde...
function matcherFromTokens (line 4926) | function matcherFromTokens( tokens ) {
function matcherFromGroupMatchers (line 4978) | function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
function multipleContexts (line 5102) | function multipleContexts( selector, contexts, results ) {
function select (line 5111) | function select( selector, context, results, seed, xml ) {
function setFilters (line 5338) | function setFilters() {}
function isDisconnected (line 5504) | function isDisconnected( node ) {
function sibling (line 5508) | function sibling( cur, dir ) {
function winnow (line 5616) | function winnow( elements, qualifier, keep ) {
function createSafeFragment (line 5649) | function createSafeFragment( document ) {
function findOrAppend (line 6033) | function findOrAppend( elem, tag ) {
function cloneCopyEvent (line 6037) | function cloneCopyEvent( src, dest ) {
function cloneFixAttributes (line 6065) | function cloneFixAttributes( src, dest ) {
function getAll (line 6208) | function getAll( elem ) {
function fixDefaultChecked (line 6221) | function fixDefaultChecked( elem ) {
function jQuerySub (line 6517) | function jQuerySub( selector, context ) {
function vendorPropName (line 6563) | function vendorPropName( style, name ) {
function isHidden (line 6585) | function isHidden( elem, el ) {
function showHide (line 6590) | function showHide( elements, show ) {
function setPositiveNumber (line 6900) | function setPositiveNumber( elem, value, subtract ) {
function augmentWidthOrHeight (line 6907) | function augmentWidthOrHeight( elem, name, extra, isBorderBox ) {
function getWidthOrHeight (line 6949) | function getWidthOrHeight( elem, name, extra ) {
function css_defaultDisplay (line 6992) | function css_defaultDisplay( nodeName ) {
function buildParams (line 7246) | function buildParams( prefix, obj, traditional, add ) {
function addToPrefiltersOrTransports (line 7335) | function addToPrefiltersOrTransports( structure ) {
function inspectPrefiltersOrTransports (line 7369) | function inspectPrefiltersOrTransports( structure, options, originalOpti...
function ajaxExtend (line 7411) | function ajaxExtend( target, src ) {
function done (line 7722) | function done( status, nativeStatusText, responses, headers ) {
function ajaxHandleResponses (line 8015) | function ajaxHandleResponses( s, jqXHR, responses ) {
function ajaxConvert (line 8077) | function ajaxConvert( s, response ) {
function createStandardXHR (line 8344) | function createStandardXHR() {
function createActiveXHR (line 8350) | function createActiveXHR() {
function createFxNow (line 8604) | function createFxNow() {
function createTweens (line 8611) | function createTweens( animation, props ) {
function Animation (line 8626) | function Animation( elem, properties, options ) {
function propFilter (line 8724) | function propFilter( props, specialEasing ) {
function defaultPrefilter (line 8791) | function defaultPrefilter( elem, props, opts ) {
function Tween (line 8915) | function Tween( elem, options, prop, end, easing ) {
function genFx (line 9099) | function genFx( type, includeWidth ) {
function getWindow (line 9405) | function getWindow( elem ) {
FILE: public/js/vendor/jquery/jquery-migrate.js
function migrateWarn (line 35) | function migrateWarn( msg) {
function migrateWarnProp (line 48) | function migrateWarnProp( obj, prop, value, msg ) {
function jQuerySub (line 268) | function jQuerySub( selector, context ) {
FILE: public/js/vendor/jquery/jquery.js
function isArraylike (line 983) | function isArraylike( obj ) {
function Sizzle (line 1183) | function Sizzle( selector, context, results, seed ) {
function createCache (line 1298) | function createCache() {
function markFunction (line 1316) | function markFunction( fn ) {
function assert (line 1325) | function assert( fn ) {
function addHandle (line 1347) | function addHandle( attrs, handler ) {
function siblingCheck (line 1362) | function siblingCheck( a, b ) {
function createInputPseudo (line 1389) | function createInputPseudo( type ) {
function createButtonPseudo (line 1400) | function createButtonPseudo( type ) {
function createPositionalPseudo (line 1411) | function createPositionalPseudo( fn ) {
function setFilters (line 2394) | function setFilters() {}
function tokenize (line 2398) | function tokenize( selector, parseOnly ) {
function toSelector (line 2465) | function toSelector( tokens ) {
function addCombinator (line 2475) | function addCombinator( matcher, combinator, base ) {
function elementMatcher (line 2525) | function elementMatcher( matchers ) {
function condense (line 2539) | function condense( unmatched, map, filter, context, xml ) {
function setMatcher (line 2560) | function setMatcher( preFilter, selector, matcher, postFilter, postFinde...
function matcherFromTokens (line 2653) | function matcherFromTokens( tokens ) {
function matcherFromGroupMatchers (line 2708) | function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
function multipleContexts (line 2836) | function multipleContexts( selector, contexts, results ) {
function select (line 2845) | function select( selector, context, results, seed ) {
function createOptions (line 2985) | function createOptions( options ) {
function internalData (line 3568) | function internalData( elem, name, data, pvt /* Internal Use Only */ ){
function internalRemoveData (line 3657) | function internalRemoveData( elem, name, pvt ) {
function dataAttr (line 3854) | function dataAttr( elem, key, data ) {
function isEmptyDataObject (line 3886) | function isEmptyDataObject( obj ) {
function returnTrue (line 4712) | function returnTrue() {
function returnFalse (line 4716) | function returnFalse() {
function safeActiveElement (line 4720) | function safeActiveElement() {
function sibling (line 5838) | function sibling( cur, dir ) {
function winnow (line 5956) | function winnow( elements, qualifier, not ) {
function createSafeFragment (line 5984) | function createSafeFragment( document ) {
function manipulationTarget (line 6298) | function manipulationTarget( elem, content ) {
function disableScript (line 6308) | function disableScript( elem ) {
function restoreScript (line 6312) | function restoreScript( elem ) {
function setGlobalEval (line 6323) | function setGlobalEval( elems, refElements ) {
function cloneCopyEvent (line 6331) | function cloneCopyEvent( src, dest ) {
function fixCloneNodeIssues (line 6359) | function fixCloneNodeIssues( src, dest ) {
function getAll (line 6452) | function getAll( context, tag ) {
function fixDefaultChecked (line 6475) | function fixDefaultChecked( elem ) {
function vendorPropName (line 6817) | function vendorPropName( style, name ) {
function isHidden (line 6839) | function isHidden( elem, el ) {
function showHide (line 6846) | function showHide( elements, show ) {
function setPositiveNumber (line 7175) | function setPositiveNumber( elem, value, subtract ) {
function augmentWidthOrHeight (line 7183) | function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
function getWidthOrHeight (line 7222) | function getWidthOrHeight( elem, name, extra ) {
function css_defaultDisplay (line 7266) | function css_defaultDisplay( nodeName ) {
function actualDisplay (line 7298) | function actualDisplay( name, doc ) {
function buildParams (line 7527) | function buildParams( prefix, obj, traditional, add ) {
function addToPrefiltersOrTransports (line 7642) | function addToPrefiltersOrTransports( structure ) {
function inspectPrefiltersOrTransports (line 7674) | function inspectPrefiltersOrTransports( structure, options, originalOpti...
function ajaxExtend (line 7701) | function ajaxExtend( target, src ) {
function done (line 8149) | function done( status, nativeStatusText, responses, headers ) {
function ajaxHandleResponses (line 8296) | function ajaxHandleResponses( s, jqXHR, responses ) {
function ajaxConvert (line 8351) | function ajaxConvert( s, response, jqXHR, isSuccess ) {
function createStandardXHR (line 8619) | function createStandardXHR() {
function createActiveXHR (line 8625) | function createActiveXHR() {
function createFxNow (line 8871) | function createFxNow() {
function createTween (line 8878) | function createTween( value, prop, animation ) {
function Animation (line 8892) | function Animation( elem, properties, options ) {
function propFilter (line 8996) | function propFilter( props, specialEasing ) {
function defaultPrefilter (line 9063) | function defaultPrefilter( elem, props, opts ) {
function Tween (line 9188) | function Tween( elem, options, prop, end, easing ) {
function genFx (line 9412) | function genFx( type, includeWidth ) {
function getWindow (line 9708) | function getWindow( elem ) {
FILE: route/new.js
function parseActions (line 70) | function parseActions(actions) {
function createNewTask (line 83) | function createNewTask({body}, actions, headers) {
FILE: route/result/download.js
function getTaskAndResult (line 20) | function getTaskAndResult(request, response, next) {
function getDownloadFileName (line 39) | function getDownloadFileName(task, result, extension) {
FILE: route/task/unignore.js
function route (line 5) | function route(app) {
FILE: test/integration/helper/navigate.js
function buildUrl (line 19) | function buildUrl(baseUrl, opts) {
function buildFormData (line 29) | function buildFormData(formData) {
function buildFetchOptions (line 42) | function buildFetchOptions(opts) {
function parseResponseBody (line 61) | function parseResponseBody(response) {
function saveRequest (line 69) | function saveRequest(store, response, body, opts) {
function resetSavedRequest (line 86) | function resetSavedRequest(store) {
function createNavigator (line 94) | function createNavigator(baseUrl, store) {
FILE: test/integration/setup.js
function assertDashboardIsAvailable (line 36) | async function assertDashboardIsAvailable(baseUrl) {
FILE: view/helper/conditionals.js
function helper (line 19) | function helper(hbs) {
FILE: view/helper/date.js
function helper (line 21) | function helper(hbs) {
FILE: view/helper/string.js
function helper (line 5) | function helper(hbs) {
FILE: view/helper/url.js
function helper (line 19) | function helper(hbs) {
FILE: view/presenter/ignore.js
function presentIgnoreRules (line 22) | function presentIgnoreRules(ignore) {
function createStandardDescriptionMap (line 31) | function createStandardDescriptionMap(standards) {
FILE: view/presenter/result-list.js
function presentResultList (line 23) | function presentResultList(results) {
FILE: view/presenter/result.js
function presentResult (line 24) | function presentResult(result) {
FILE: view/presenter/task.js
function presentTask (line 22) | function presentTask(task) {
Condensed preview — 369 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,747K chars).
[
{
"path": ".bowerrc",
"chars": 37,
"preview": "{\n\t\"directory\" : \"public/js/vendor\"\n}"
},
{
"path": ".dockerignore",
"chars": 478,
"preview": "# Version control\n.git\n.github\n\n# Dependencies (must be rebuilt inside the container)\nnode_modules\n\n# Tests\ntest\n\n# Buil"
},
{
"path": ".editorconfig",
"chars": 306,
"preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 4\nindent_style = tab\ninsert_final_newline = true\ntrim_tr"
},
{
"path": ".github/issue_template.md",
"chars": 622,
"preview": "**This repository's issues are reserved for feature requests, bug reports, and other issues with Pa11y Dashboard itself."
},
{
"path": ".github/workflows/tests.yml",
"chars": 1862,
"preview": "on:\n push:\n branches:\n - main\n pull_request:\n\njobs:\n lint:\n runs-on: ubuntu-latest\n steps:\n - uses"
},
{
"path": ".gitignore",
"chars": 1416,
"preview": "# Logs\nlogs/\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs"
},
{
"path": ".npmrc",
"chars": 19,
"preview": "lockfile-version=2\n"
},
{
"path": ".nvmrc",
"chars": 3,
"preview": "24\n"
},
{
"path": "CHANGELOG.md",
"chars": 10575,
"preview": "# Changelog\n\n## 5.2.0 (2026-03-25)\n\nAdditional containerisation-related improvements.\n\n* Add new /health health check en"
},
{
"path": "CONTRIBUTING.md",
"chars": 873,
"preview": "# Contributing Guide\n\nThanks for getting involved :tada:\n\nThe Pa11y team loves to see new contributors, and we strive to"
},
{
"path": "Dockerfile.example",
"chars": 5054,
"preview": "# Example Dockerfile for Pa11y Dashboard\n#\n# This is a starting point that you can adapt to your infrastructure. It is N"
},
{
"path": "LICENSE",
"chars": 35146,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "MIGRATION.md",
"chars": 2330,
"preview": "# Migration Guide\n\nPa11y Dashboard's API changes between major versions. This is a guide to help you make the switch whe"
},
{
"path": "Makefile",
"chars": 861,
"preview": "# Client-side asset tasks\n# -----------------------\n\nless:\n\t@lessc -x ./public/less/main.less ./public/css/site.min.css\n"
},
{
"path": "README.md",
"chars": 16323,
"preview": "# Pa11y Dashboard\n\nPa11y Dashboard is a web interface to the [Pa11y][pa11y] accessibility reporter, allowing you to focu"
},
{
"path": "app.js",
"chars": 5798,
"preview": "// This file is part of Pa11y Dashboard.\n//\n// Pa11y Dashboard is free software: you can redistribute it and/or modify\n/"
},
{
"path": "bower.json",
"chars": 124,
"preview": "{\n \"name\": \"pa11y-dashboard\",\n \"dependencies\": {\n \"jquery\": \"~1.10\",\n \"bootstrap\": \"~3.0\",\n \"flot\": \"~0.8\"\n "
},
{
"path": "config/development.sample.json",
"chars": 197,
"preview": "{\n\t\"port\": 4000,\n\t\"noindex\": true,\n\t\"readonly\": false,\n\t\"webservice\": {\n\t\t\"database\": \"mongodb://localhost/pa11y-webserv"
},
{
"path": "config/production.sample.json",
"chars": 303,
"preview": "{\n\t\"port\": 8080,\n\t\"noindex\": true,\n\t\"readonly\": false,\n\t\"webservice\": {\n\t\t\"database\": \"mongodb://user:password@mongo-hos"
},
{
"path": "config/test.sample.json",
"chars": 211,
"preview": "{\n\t\"port\": 4000,\n\t\"noindex\": true,\n\t\"readonly\": false,\n\t\"webservice\": {\n\t\t\"database\": \"mongodb://127.0.0.1/pa11y-dashboa"
},
{
"path": "config.js",
"chars": 2052,
"preview": "// This file is part of Pa11y Dashboard.\n//\n// Pa11y Dashboard is free software: you can redistribute it and/or modify\n/"
},
{
"path": "data/standards.js",
"chars": 109417,
"preview": "// This file is part of Pa11y Dashboard.\n//\n// Pa11y Dashboard is free software: you can redistribute it and/or modify\n/"
},
{
"path": "data/techniques.js",
"chars": 27986,
"preview": "// This file is part of Pa11y Dashboard.\n//\n// Pa11y Dashboard is free software: you can redistribute it and/or modify\n/"
},
{
"path": "eslint.config.js",
"chars": 488,
"preview": "'use strict';\n\nconst {defineConfig} = require('eslint/config');\n\nconst configPa11y = require('eslint-config-pa11y');\n\nmo"
},
{
"path": "index.js",
"chars": 3362,
"preview": "// This file is part of Pa11y Dashboard.\n//\n// Pa11y Dashboard is free software: you can redistribute it and/or modify\n/"
},
{
"path": "package.json",
"chars": 1757,
"preview": "{\n \"name\": \"pa11y-dashboard\",\n \"version\": \"5.2.0\",\n \"private\": true,\n \"description\": \"Pa11y Dashboard is a visual we"
},
{
"path": "public/js/site.js",
"chars": 13423,
"preview": "// This file is part of Pa11y Dashboard.\n//\n// Pa11y Dashboard is free software: you can redistribute it and/or modify\n/"
},
{
"path": "public/js/vendor/bootstrap/.bower.json",
"chars": 534,
"preview": "{\n \"name\": \"bootstrap\",\n \"version\": \"3.0.1\",\n \"main\": [\n \"./dist/js/bootstrap.js\",\n \"./dist/css/bootstrap.css\","
},
{
"path": "public/js/vendor/bootstrap/CNAME",
"chars": 17,
"preview": "getbootstrap.com\n"
},
{
"path": "public/js/vendor/bootstrap/CONTRIBUTING.md",
"chars": 3298,
"preview": "# Contributing to Bootstrap\n\nLooking to contribute something to Bootstrap? **Here's how you can help.**\n\n\n\n## Reporting "
},
{
"path": "public/js/vendor/bootstrap/DOCS-LICENSE",
"chars": 19466,
"preview": "Creative Commons Legal Code\n\nAttribution 3.0 Unported\n\n CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT P"
},
{
"path": "public/js/vendor/bootstrap/Gruntfile.js",
"chars": 5914,
"preview": "/* jshint node: true */\n\nmodule.exports = function(grunt) {\n \"use strict\";\n\n var btoa = require('btoa')\n // Project c"
},
{
"path": "public/js/vendor/bootstrap/LICENSE",
"chars": 10173,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "public/js/vendor/bootstrap/LICENSE-MIT",
"chars": 1079,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2013 Twitter, Inc\n\nPermission is hereby granted, free of charge, to any person obta"
},
{
"path": "public/js/vendor/bootstrap/README.md",
"chars": 7421,
"preview": "# [Bootstrap](http://getbootstrap.com) [](http://travis-"
},
{
"path": "public/js/vendor/bootstrap/_config.yml",
"chars": 968,
"preview": "# Dependencies\nmarkdown: rdiscount\npygments: true\n\n# Permalinks\npermalink: pretty\n\n# Server\ndesti"
},
{
"path": "public/js/vendor/bootstrap/_includes/ads.html",
"chars": 317,
"preview": "<div id=\"carbonads-container\"><div class=\"carbonad\"><div id=\"azcarbon\"></div><script>var z = document.createElement(\"scr"
},
{
"path": "public/js/vendor/bootstrap/_includes/footer.html",
"chars": 1398,
"preview": "<!-- Bootstrap core JavaScript\n================================================== -->\n<!-- Placed at the end of the docu"
},
{
"path": "public/js/vendor/bootstrap/_includes/header.html",
"chars": 1747,
"preview": "<meta charset=\"utf-8\">\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n<meta name=\"viewport\" content=\"width=device"
},
{
"path": "public/js/vendor/bootstrap/_includes/nav-about.html",
"chars": 189,
"preview": "<li>\n <a href=\"#history\">History</a>\n</li>\n<li>\n <a href=\"#team\">Core team</a>\n</li>\n<li>\n <a href=\"#community\">Commu"
},
{
"path": "public/js/vendor/bootstrap/_includes/nav-components.html",
"chars": 4978,
"preview": "<li>\n <a href=\"#glyphicons\">Glyphicons</a>\n <ul class=\"nav\">\n <li><a href=\"#glyphicons-glyphs\">Available glyphs</a>"
},
{
"path": "public/js/vendor/bootstrap/_includes/nav-css.html",
"chars": 4081,
"preview": "<li>\n <a href=\"#overview\">Overview</a>\n <ul class=\"nav\">\n <li><a href=\"#overview-doctype\">HTML5 doctype</a></li>\n "
},
{
"path": "public/js/vendor/bootstrap/_includes/nav-customize.html",
"chars": 1691,
"preview": "<li>\n <a href=\"#less\">LESS components</a>\n</li>\n<li>\n <a href=\"#plugins\">jQuery plugins</a>\n</li>\n<li>\n <a href=\"#les"
},
{
"path": "public/js/vendor/bootstrap/_includes/nav-getting-started.html",
"chars": 1129,
"preview": "<li>\n <a href=\"#download\">Download Bootstrap</a>\n <ul class=\"nav\">\n <li><a href=\"#download-compiled\">Compiled CSS, "
},
{
"path": "public/js/vendor/bootstrap/_includes/nav-javascript.html",
"chars": 2320,
"preview": "<li>\n <a href=\"#js-overview\">Overview</a>\n <ul class=\"nav\">\n <li><a href=\"#js-individual-compiled\">Individual or co"
},
{
"path": "public/js/vendor/bootstrap/_includes/nav-main.html",
"chars": 1613,
"preview": "<header class=\"navbar navbar-inverse navbar-fixed-top bs-docs-nav\" role=\"banner\">\n <div class=\"container\">\n <div cla"
},
{
"path": "public/js/vendor/bootstrap/_includes/old-bs-docs.html",
"chars": 319,
"preview": "<div class=\"bs-old-docs\">\n <div class=\"container\">\n <strong>\n <a href=\"{{ page.base_url }}2.3.2/\">Looking for B"
},
{
"path": "public/js/vendor/bootstrap/_includes/social-buttons.html",
"chars": 925,
"preview": "<div class=\"bs-social\">\n <ul class=\"bs-social-buttons\">\n <li>\n <iframe class=\"github-btn\" src=\"http://ghbtns.co"
},
{
"path": "public/js/vendor/bootstrap/_layouts/default.html",
"chars": 2812,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <!-- Meta, title, CSS, favicons, etc. -->\n {% include header.html %}\n "
},
{
"path": "public/js/vendor/bootstrap/_layouts/home.html",
"chars": 1497,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <!-- Meta, title, CSS, favicons, etc. -->\n {% include header.html %}\n "
},
{
"path": "public/js/vendor/bootstrap/about.html",
"chars": 5900,
"preview": "---\nlayout: default\ntitle: About\nslug: about\nlead: \"Learn about the history of Bootstrap, meet the core team, and check "
},
{
"path": "public/js/vendor/bootstrap/bower.json",
"chars": 215,
"preview": "{\n \"name\": \"bootstrap\",\n \"version\": \"3.0.1\",\n \"main\": [\"./dist/js/bootstrap.js\", \"./dist/css/bootstrap.css\", \"./dist/"
},
{
"path": "public/js/vendor/bootstrap/browserstack.json",
"chars": 752,
"preview": "{\n \"username\": \"--secure--\",\n \"key\": \"--secure--\",\n \"test_path\": \"js/tests/index.html\",\n \"browsers\": [\n {\n "
},
{
"path": "public/js/vendor/bootstrap/components.html",
"chars": 147895,
"preview": "---\nlayout: default\ntitle: Components\nslug: components\nlead: \"Over a dozen reusable components built to provide iconogra"
},
{
"path": "public/js/vendor/bootstrap/composer.json",
"chars": 547,
"preview": "{\n \"name\": \"twbs/bootstrap\"\n , \"description\": \"Sleek, intuitive, and powerful mobile first front-end framework for f"
},
{
"path": "public/js/vendor/bootstrap/css.html",
"chars": 102234,
"preview": "---\nlayout: default\ntitle: CSS\nslug: css\nlead: \"Global CSS settings, fundamental HTML elements styled and enhanced with "
},
{
"path": "public/js/vendor/bootstrap/customize.html",
"chars": 77717,
"preview": "---\nlayout: default\ntitle: Customize and download\nslug: customize\nlead: Customize Bootstrap's components, LESS variables"
},
{
"path": "public/js/vendor/bootstrap/dist/css/bootstrap-theme.css",
"chars": 19791,
"preview": "/*!\n * Bootstrap v3.0.1 by @fat and @mdo\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.org/license"
},
{
"path": "public/js/vendor/bootstrap/dist/css/bootstrap.css",
"chars": 125975,
"preview": "/*!\n * Bootstrap v3.0.1 by @fat and @mdo\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.org/license"
},
{
"path": "public/js/vendor/bootstrap/dist/js/bootstrap.js",
"chars": 58411,
"preview": "/*!\n * Bootstrap v3.0.1 by @fat and @mdo\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.org/license"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/css/docs.css",
"chars": 72735,
"preview": "/*!\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Creative Commons Attribution 3.0 Unported License. For\n * d"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/css/pygments-manni.css",
"chars": 3005,
"preview": ".hll { background-color: #ffffcc }\n /*{ background: #f0f3f3; }*/\n.c { color: #999; } /* Comment */\n.err { color: #AA0000"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/application.js",
"chars": 2468,
"preview": "// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT\n// IT'S ALL JUST JUNK FOR OUR DOCS!\n// +++++++++++++++++++++++++++++++++++"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/customizer.js",
"chars": 10315,
"preview": "/*!\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Creative Commons Attribution 3.0 Unported License. For\n * d"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/filesaver.js",
"chars": 8033,
"preview": "/* Blob.js\n * A Blob implementation.\n * 2013-06-20\n *\n * By Eli Grey, http://eligrey.com\n * By Devin Samarin, https://gi"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/holder.js",
"chars": 12638,
"preview": "/*\n\nHolder - 2.1 - client side image placeholders\n(c) 2012-2013 Ivan Malopinsky / http://imsky.co\n\nProvided under the MI"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/ie8-responsive-file-warning.js",
"chars": 581,
"preview": "// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT\n// IT'S JUST JUNK FOR OUR DOCS!\n// +++++++++++++++++++++++++++++++++++++++"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/jszip.js",
"chars": 50712,
"preview": "/**\n\nJSZip - A Javascript class for generating and reading zip files\n<http://stuartk.com/jszip>\n\n(c) 2009-2012 Stuart Kn"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/less.js",
"chars": 58184,
"preview": "//\n// LESS - Leaner CSS v1.3.3\n// http://lesscss.org\n//\n// Copyright (c) 2009-2013, Alexis Sellier\n// Licensed under the"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/raw-files.js",
"chars": 440570,
"preview": "var __js = {\"affix.js\":\"/* ========================================================================\\n * Bootstrap: affix"
},
{
"path": "public/js/vendor/bootstrap/docs-assets/js/uglify.js",
"chars": 50609,
"preview": "/** @license uglifyweb Copyright (c) 2011, The Dojo Foundation All Rights Reserved.\n * The parts that are unique to this"
},
{
"path": "public/js/vendor/bootstrap/examples/carousel/carousel.css",
"chars": 2709,
"preview": "/* GLOBAL STYLES\n-------------------------------------------------- */\n/* Padding below the footer and lighter body text"
},
{
"path": "public/js/vendor/bootstrap/examples/carousel/index.html",
"chars": 9941,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/grid/grid.css",
"chars": 422,
"preview": ".container {\n padding-left: 15px;\n padding-right: 15px;\n}\n\nh4 {\n margin-top: 25px;\n}\n.row {\n margin-bottom: 20px;\n}\n"
},
{
"path": "public/js/vendor/bootstrap/examples/grid/index.html",
"chars": 6167,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/jumbotron/index.html",
"chars": 4378,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/jumbotron/jumbotron.css",
"chars": 127,
"preview": "/* Move down content because we have a fixed navbar that is 50px tall */\nbody {\n padding-top: 50px;\n padding-bottom: 2"
},
{
"path": "public/js/vendor/bootstrap/examples/jumbotron-narrow/index.html",
"chars": 3049,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/jumbotron-narrow/jumbotron-narrow.css",
"chars": 1411,
"preview": "/* Space out content a bit */\nbody {\n padding-top: 20px;\n padding-bottom: 20px;\n}\n\n/* Everything but the jumbotron get"
},
{
"path": "public/js/vendor/bootstrap/examples/justified-nav/index.html",
"chars": 3582,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/justified-nav/justified-nav.css",
"chars": 2361,
"preview": "body {\n padding-top: 20px;\n}\n\n.footer {\n border-top: 1px solid #eee;\n margin-top: 40px;\n padding-top: 40px;\n paddin"
},
{
"path": "public/js/vendor/bootstrap/examples/navbar/index.html",
"chars": 3591,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/navbar/navbar.css",
"chars": 90,
"preview": "body {\n padding-top: 20px;\n padding-bottom: 20px;\n}\n\n.navbar {\n margin-bottom: 20px;\n}\n"
},
{
"path": "public/js/vendor/bootstrap/examples/navbar-fixed-top/index.html",
"chars": 3750,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/navbar-fixed-top/navbar-fixed-top.css",
"chars": 52,
"preview": "body {\n min-height: 2000px;\n padding-top: 70px;\n}\n"
},
{
"path": "public/js/vendor/bootstrap/examples/navbar-static-top/index.html",
"chars": 3754,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/navbar-static-top/navbar-static-top.css",
"chars": 77,
"preview": "body {\n min-height: 2000px;\n}\n\n.navbar-static-top {\n margin-bottom: 19px;\n}"
},
{
"path": "public/js/vendor/bootstrap/examples/non-responsive/index.html",
"chars": 4190,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/non-responsive/non-responsive.css",
"chars": 2424,
"preview": "/* Template-specific stuff\n *\n * Customizations just for the template; these are not necessary for anything\n * with disa"
},
{
"path": "public/js/vendor/bootstrap/examples/offcanvas/index.html",
"chars": 6584,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/offcanvas/offcanvas.css",
"chars": 890,
"preview": "/*\n * Style tweaks\n * --------------------------------------------------\n */\nhtml {\n overflow-x: hidden; /* Prevent scr"
},
{
"path": "public/js/vendor/bootstrap/examples/offcanvas/offcanvas.js",
"chars": 137,
"preview": "$(document).ready(function() {\n $('[data-toggle=offcanvas]').click(function() {\n $('.row-offcanvas').toggleClass('ac"
},
{
"path": "public/js/vendor/bootstrap/examples/signin/index.html",
"chars": 1837,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/signin/signin.css",
"chars": 791,
"preview": "body {\n padding-top: 40px;\n padding-bottom: 40px;\n background-color: #eee;\n}\n\n.form-signin {\n max-width: 330px;\n pa"
},
{
"path": "public/js/vendor/bootstrap/examples/starter-template/index.html",
"chars": 2514,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/starter-template/starter-template.css",
"chars": 96,
"preview": "body {\n padding-top: 50px;\n}\n.starter-template {\n padding: 40px 15px;\n text-align: center;\n}\n"
},
{
"path": "public/js/vendor/bootstrap/examples/sticky-footer/index.html",
"chars": 2025,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/sticky-footer/sticky-footer.css",
"chars": 751,
"preview": "/* Sticky footer styles\n-------------------------------------------------- */\n\nhtml,\nbody {\n height: 100%;\n /* The htm"
},
{
"path": "public/js/vendor/bootstrap/examples/sticky-footer-navbar/index.html",
"chars": 3775,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/sticky-footer-navbar/sticky-footer-navbar.css",
"chars": 828,
"preview": "/* Sticky footer styles\n-------------------------------------------------- */\n\nhtml,\nbody {\n height: 100%;\n /* The htm"
},
{
"path": "public/js/vendor/bootstrap/examples/theme/index.html",
"chars": 16670,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "public/js/vendor/bootstrap/examples/theme/theme.css",
"chars": 199,
"preview": "body {\n padding-top: 70px;\n padding-bottom: 30px;\n}\n\n.theme-dropdown .dropdown-menu {\n display: block;\n position: st"
},
{
"path": "public/js/vendor/bootstrap/getting-started.html",
"chars": 49322,
"preview": "---\nlayout: default\ntitle: Getting started\nslug: getting-started\nlead: \"An overview of Bootstrap, how to download and us"
},
{
"path": "public/js/vendor/bootstrap/index.html",
"chars": 748,
"preview": "---\nlayout: home\ntitle: Bootstrap\nbase_url: \"./\"\n---\n\n<main class=\"bs-masthead\" id=\"content\" role=\"main\">\n <div class=\""
},
{
"path": "public/js/vendor/bootstrap/javascript.html",
"chars": 94248,
"preview": "---\nlayout: default\ntitle: JavaScript\nslug: js\nlead: \"Bring Bootstrap's components to life with over a dozen custom jQue"
},
{
"path": "public/js/vendor/bootstrap/js/affix.js",
"chars": 3868,
"preview": "/* ========================================================================\n * Bootstrap: affix.js v3.0.0\n * http://getb"
},
{
"path": "public/js/vendor/bootstrap/js/alert.js",
"chars": 2589,
"preview": "/* ========================================================================\n * Bootstrap: alert.js v3.0.0\n * http://getb"
},
{
"path": "public/js/vendor/bootstrap/js/button.js",
"chars": 3055,
"preview": "/* ========================================================================\n * Bootstrap: button.js v3.0.0\n * http://get"
},
{
"path": "public/js/vendor/bootstrap/js/carousel.js",
"chars": 6452,
"preview": "/* ========================================================================\n * Bootstrap: carousel.js v3.0.0\n * http://g"
},
{
"path": "public/js/vendor/bootstrap/js/collapse.js",
"chars": 5235,
"preview": "/* ========================================================================\n * Bootstrap: collapse.js v3.0.0\n * http://g"
},
{
"path": "public/js/vendor/bootstrap/js/dropdown.js",
"chars": 4491,
"preview": "/* ========================================================================\n * Bootstrap: dropdown.js v3.0.0\n * http://g"
},
{
"path": "public/js/vendor/bootstrap/js/modal.js",
"chars": 6982,
"preview": "/* ========================================================================\n * Bootstrap: modal.js v3.0.0\n * http://getb"
},
{
"path": "public/js/vendor/bootstrap/js/popover.js",
"chars": 3495,
"preview": "/* ========================================================================\n * Bootstrap: popover.js v3.0.0\n * http://ge"
},
{
"path": "public/js/vendor/bootstrap/js/scrollspy.js",
"chars": 4629,
"preview": "/* ========================================================================\n * Bootstrap: scrollspy.js v3.0.0\n * http://"
},
{
"path": "public/js/vendor/bootstrap/js/tab.js",
"chars": 3500,
"preview": "/* ========================================================================\n * Bootstrap: tab.js v3.0.0\n * http://getboo"
},
{
"path": "public/js/vendor/bootstrap/js/tests/index.html",
"chars": 1678,
"preview": "<!DOCTYPE HTML>\n<html>\n<head>\n <title>Bootstrap Plugin Test Suite</title>\n\n <!-- jquery -->\n <!--<script src=\"http://"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/affix.js",
"chars": 791,
"preview": "$(function () {\n\n module(\"affix\")\n\n test(\"should provide no conflict\", function () {\n var affix = $.fn.af"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/alert.js",
"chars": 2120,
"preview": "$(function () {\n\n module(\"alert\")\n\n test(\"should provide no conflict\", function () {\n var alert = $.fn.al"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/button.js",
"chars": 4440,
"preview": "$(function () {\n\n module(\"button\")\n\n test(\"should provide no conflict\", function () {\n var button = $.fn."
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/carousel.js",
"chars": 6381,
"preview": "$(function () {\n\n module(\"carousel\")\n\n test(\"should provide no conflict\", function () {\n var carousel = $"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/collapse.js",
"chars": 5903,
"preview": "$(function () {\n\n module(\"collapse\")\n\n test(\"should provide no conflict\", function () {\n var collapse = $"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/dropdown.js",
"chars": 8414,
"preview": "$(function () {\n\n module(\"dropdowns\")\n\n test(\"should provide no conflict\", function () {\n var dropdown = "
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/modal.js",
"chars": 6132,
"preview": "$(function () {\n\n module(\"modal\")\n\n test(\"should provide no conflict\", function () {\n var modal = $.fn.modal.no"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/phantom.js",
"chars": 2137,
"preview": "/*\n * grunt-contrib-qunit\n * http://gruntjs.com/\n *\n * Copyright (c) 2013 \"Cowboy\" Ben Alman, contributors\n * Licensed u"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/popover.js",
"chars": 5286,
"preview": "$(function () {\n\n module(\"popover\")\n\n test(\"should provide no conflict\", function () {\n var popover = $.f"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/scrollspy.js",
"chars": 1194,
"preview": "$(function () {\n\n module(\"scrollspy\")\n\n test(\"should provide no conflict\", function () {\n var scrollspy ="
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/tab.js",
"chars": 2843,
"preview": "$(function () {\n\n module(\"tabs\")\n\n test(\"should provide no conflict\", function () {\n var tab = $.fn.tab.n"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/tooltip.js",
"chars": 17062,
"preview": "$(function () {\n\n module(\"tooltip\")\n\n test(\"should provide no conflict\", function () {\n var tooltip = $.f"
},
{
"path": "public/js/vendor/bootstrap/js/tests/unit/transition.js",
"chars": 365,
"preview": "$(function () {\n\n module(\"transition\")\n\n test(\"should be defined on jquery support object\", function () {\n "
},
{
"path": "public/js/vendor/bootstrap/js/tests/vendor/jquery.js",
"chars": 93106,
"preview": "/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license\n//@ sourceMappingURL=jquery-1.10.2.min."
},
{
"path": "public/js/vendor/bootstrap/js/tests/vendor/qunit.css",
"chars": 4560,
"preview": "/**\n * QUnit - A JavaScript Unit Testing Framework\n *\n * http://docs.jquery.com/QUnit\n *\n * Copyright (c) 2012 John Resi"
},
{
"path": "public/js/vendor/bootstrap/js/tests/vendor/qunit.js",
"chars": 38065,
"preview": "/**\n * QUnit - A JavaScript Unit Testing Framework\n *\n * http://docs.jquery.com/QUnit\n *\n * Copyright (c) 2012 John Resi"
},
{
"path": "public/js/vendor/bootstrap/js/tooltip.js",
"chars": 11915,
"preview": "/* ========================================================================\n * Bootstrap: tooltip.js v3.0.0\n * http://ge"
},
{
"path": "public/js/vendor/bootstrap/js/transition.js",
"chars": 1971,
"preview": "/* ========================================================================\n * Bootstrap: transition.js v3.0.0\n * http:/"
},
{
"path": "public/js/vendor/bootstrap/less/alerts.less",
"chars": 1430,
"preview": "//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert"
},
{
"path": "public/js/vendor/bootstrap/less/badges.less",
"chars": 1007,
"preview": "//\n// Badges\n// --------------------------------------------------\n\n\n// Base classes\n.badge {\n display: inline-block;\n "
},
{
"path": "public/js/vendor/bootstrap/less/bootstrap.less",
"chars": 1071,
"preview": "// Core variables and mixins\n@import \"variables.less\";\n@import \"mixins.less\";\n\n// Reset\n@import \"normalize.less\";\n@impor"
},
{
"path": "public/js/vendor/bootstrap/less/breadcrumbs.less",
"chars": 540,
"preview": "//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: 8px 15px;\n margin-bo"
},
{
"path": "public/js/vendor/bootstrap/less/button-groups.less",
"chars": 5349,
"preview": "//\n// Button groups\n// --------------------------------------------------\n\n// Button carets\n//\n// Match the button text "
},
{
"path": "public/js/vendor/bootstrap/less/buttons.less",
"chars": 3422,
"preview": "//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------"
},
{
"path": "public/js/vendor/bootstrap/less/carousel.less",
"chars": 4573,
"preview": "//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators"
},
{
"path": "public/js/vendor/bootstrap/less/close.less",
"chars": 683,
"preview": "//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-s"
},
{
"path": "public/js/vendor/bootstrap/less/code.less",
"chars": 1102,
"preview": "//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\nco"
},
{
"path": "public/js/vendor/bootstrap/less/component-animations.less",
"chars": 509,
"preview": "//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `."
},
{
"path": "public/js/vendor/bootstrap/less/dropdowns.less",
"chars": 4146,
"preview": "//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display:"
},
{
"path": "public/js/vendor/bootstrap/less/forms.less",
"chars": 8855,
"preview": "//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline"
},
{
"path": "public/js/vendor/bootstrap/less/glyphicons.less",
"chars": 14903,
"preview": "//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus a"
},
{
"path": "public/js/vendor/bootstrap/less/grid.less",
"chars": 2201,
"preview": "//\n// Grid system\n// --------------------------------------------------\n\n// Set the container width, and override it for"
},
{
"path": "public/js/vendor/bootstrap/less/input-groups.less",
"chars": 3270,
"preview": "//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.i"
},
{
"path": "public/js/vendor/bootstrap/less/jumbotron.less",
"chars": 879,
"preview": "//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding: @jumbotron-padding;\n ma"
},
{
"path": "public/js/vendor/bootstrap/less/labels.less",
"chars": 992,
"preview": "//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3e"
},
{
"path": "public/js/vendor/bootstrap/less/list-group.less",
"chars": 1914,
"preview": "//\n// List groups\n// --------------------------------------------------\n\n// Base class\n//\n// Easily usable on <ul>, <ol>"
},
{
"path": "public/js/vendor/bootstrap/less/media.less",
"chars": 848,
"preview": "// Media objects\n// Source: http://stubbornella.org/content/?p=497\n// --------------------------------------------------"
},
{
"path": "public/js/vendor/bootstrap/less/mixins.less",
"chars": 26014,
"preview": "//\n// Mixins\n// --------------------------------------------------\n\n\n// Utilities\n// -------------------------\n\n// Clear"
},
{
"path": "public/js/vendor/bootstrap/less/modals.less",
"chars": 3148,
"preview": "//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scr"
},
{
"path": "public/js/vendor/bootstrap/less/navbar.less",
"chars": 14214,
"preview": "//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static n"
},
{
"path": "public/js/vendor/bootstrap/less/navs.less",
"chars": 5429,
"preview": "//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// ------------------------------------"
},
{
"path": "public/js/vendor/bootstrap/less/normalize.less",
"chars": 7275,
"preview": "/*! normalize.css v2.1.3 | MIT License | git.io/normalize */\n\n// ======================================================="
},
{
"path": "public/js/vendor/bootstrap/less/pager.less",
"chars": 865,
"preview": "//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @li"
},
{
"path": "public/js/vendor/bootstrap/less/pagination.less",
"chars": 1858,
"preview": "//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-"
},
{
"path": "public/js/vendor/bootstrap/less/panels.less",
"chars": 3843,
"preview": "//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-heigh"
},
{
"path": "public/js/vendor/bootstrap/less/popovers.less",
"chars": 3282,
"preview": "//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left"
},
{
"path": "public/js/vendor/bootstrap/less/print.less",
"chars": 1650,
"preview": "//\n// Basic print styles\n// --------------------------------------------------\n// Source: https://github.com/h5bp/html5-"
},
{
"path": "public/js/vendor/bootstrap/less/progress-bars.less",
"chars": 1849,
"preview": "//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -----------------------"
},
{
"path": "public/js/vendor/bootstrap/less/responsive-utilities.less",
"chars": 4880,
"preview": "//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n/"
},
{
"path": "public/js/vendor/bootstrap/less/scaffolding.less",
"chars": 1867,
"preview": "//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n\n*,\n*:before,\n*:after "
},
{
"path": "public/js/vendor/bootstrap/less/tables.less",
"chars": 4351,
"preview": "//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n max-width: 100%;\n background-color: @tab"
},
{
"path": "public/js/vendor/bootstrap/less/theme.less",
"chars": 6854,
"preview": "\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@"
},
{
"path": "public/js/vendor/bootstrap/less/thumbnails.less",
"chars": 601,
"preview": "//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.th"
},
{
"path": "public/js/vendor/bootstrap/less/tooltip.less",
"chars": 2576,
"preview": "//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n "
},
{
"path": "public/js/vendor/bootstrap/less/type.less",
"chars": 5130,
"preview": "//\n// Typography\n// --------------------------------------------------\n\n\n// Body text\n// -------------------------\n\np {\n"
},
{
"path": "public/js/vendor/bootstrap/less/utilities.less",
"chars": 780,
"preview": "//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.c"
},
{
"path": "public/js/vendor/bootstrap/less/variables.less",
"chars": 19647,
"preview": "//\n// Variables\n// --------------------------------------------------\n\n\n// Global values\n// ----------------------------"
},
{
"path": "public/js/vendor/bootstrap/less/wells.less",
"chars": 535,
"preview": "//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding:"
},
{
"path": "public/js/vendor/bootstrap/package.json",
"chars": 1130,
"preview": "{\n \"name\": \"bootstrap\"\n , \"description\": \"Sleek, intuitive, and powerful front-end framework for faster and easier w"
},
{
"path": "public/js/vendor/flot/.bower.json",
"chars": 410,
"preview": "{\n \"name\": \"Flot\",\n \"version\": \"0.8.1\",\n \"main\": \"jquery.flot.js\",\n \"dependencies\": {\n \"jquery\": \">= 1.2.6\"\n },\n"
},
{
"path": "public/js/vendor/flot/.gitignore",
"chars": 40,
"preview": "*.min.js\n!excanvas.min.js\nnode_modules/\n"
},
{
"path": "public/js/vendor/flot/.travis.yml",
"chars": 35,
"preview": "language: node_js\nnode_js:\n - 0.8\n"
},
{
"path": "public/js/vendor/flot/API.md",
"chars": 52422,
"preview": "# Flot Reference #\n\nConsider a call to the plot function:\n\n```js\nvar plot = $.plot(placeholder, data, options)\n```\n\nThe "
},
{
"path": "public/js/vendor/flot/CONTRIBUTING.md",
"chars": 3052,
"preview": "## Contributing to Flot ##\n\nWe welcome all contributions, but following these guidelines results in less\nwork for us, an"
},
{
"path": "public/js/vendor/flot/FAQ.md",
"chars": 3237,
"preview": "## Frequently asked questions ##\n\n#### How much data can Flot cope with? ####\n\nFlot will happily draw everything you sen"
},
{
"path": "public/js/vendor/flot/LICENSE.txt",
"chars": 1069,
"preview": "Copyright (c) 2007-2013 IOLA and Ole Laursen\n\nPermission is hereby granted, free of charge, to any person\nobtaining a co"
},
{
"path": "public/js/vendor/flot/Makefile",
"chars": 285,
"preview": "# Makefile for generating minified files\n\n.PHONY: all\n\n# we cheat and process all .js files instead of an exhaustive lis"
},
{
"path": "public/js/vendor/flot/NEWS.md",
"chars": 34653,
"preview": "## Flot 0.8.1 ##\n\n### Bug fixes ###\n\n - Fixed a regression in the time plugin, introduced in 0.8, that caused dates\n t"
},
{
"path": "public/js/vendor/flot/PLUGINS.md",
"chars": 4340,
"preview": "## Writing plugins ##\n\nAll you need to do to make a new plugin is creating an init function\nand a set of options (if nee"
},
{
"path": "public/js/vendor/flot/README.md",
"chars": 3774,
"preview": "# Flot [](https://travis-ci.org/flot/flot)\n\n## About ##\n\nFlot is a J"
},
{
"path": "public/js/vendor/flot/component.json",
"chars": 114,
"preview": "{\n\t\"name\": \"Flot\",\n\t\"version\": \"0.8.1\",\n\t\"main\": \"jquery.flot.js\",\n\t\"dependencies\": {\n\t\t\"jquery\": \">= 1.2.6\"\n\t}\n}\n"
},
{
"path": "public/js/vendor/flot/examples/ajax/data-eu-gdp-growth-1.json",
"chars": 73,
"preview": "{\n \"label\": \"Europe (EU27)\",\n \"data\": [[1999, 3.0], [2000, 3.9]]\n}\n"
},
{
"path": "public/js/vendor/flot/examples/ajax/data-eu-gdp-growth-2.json",
"chars": 99,
"preview": "{\n \"label\": \"Europe (EU27)\",\n \"data\": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2]]\n}\n"
},
{
"path": "public/js/vendor/flot/examples/ajax/data-eu-gdp-growth-3.json",
"chars": 125,
"preview": "{\n \"label\": \"Europe (EU27)\",\n \"data\": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5"
},
{
"path": "public/js/vendor/flot/examples/ajax/data-eu-gdp-growth-4.json",
"chars": 151,
"preview": "{\n \"label\": \"Europe (EU27)\",\n \"data\": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5"
},
{
"path": "public/js/vendor/flot/examples/ajax/data-eu-gdp-growth-5.json",
"chars": 177,
"preview": "{\n \"label\": \"Europe (EU27)\",\n \"data\": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5"
},
{
"path": "public/js/vendor/flot/examples/ajax/data-eu-gdp-growth.json",
"chars": 177,
"preview": "{\n \"label\": \"Europe (EU27)\",\n \"data\": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5"
},
{
"path": "public/js/vendor/flot/examples/ajax/data-japan-gdp-growth.json",
"chars": 171,
"preview": "{\n \"label\": \"Japan\",\n \"data\": [[1999, -0.1], [2000, 2.9], [2001, 0.2], [2002, 0.3], [2003, 1.4], [2004, 2.7], [200"
},
{
"path": "public/js/vendor/flot/examples/ajax/data-usa-gdp-growth.json",
"chars": 167,
"preview": "{\n \"label\": \"USA\",\n \"data\": [[1999, 4.4], [2000, 3.7], [2001, 0.8], [2002, 1.6], [2003, 2.5], [2004, 3.6], [2005, "
},
{
"path": "public/js/vendor/flot/examples/ajax/index.html",
"chars": 4333,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n<head>\n\t<meta http-equ"
},
{
"path": "public/js/vendor/flot/examples/annotating/index.html",
"chars": 2808,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n<head>\n\t<meta http-equ"
},
{
"path": "public/js/vendor/flot/examples/axes-interacting/index.html",
"chars": 2836,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n<head>\n\t<meta http-equ"
},
{
"path": "public/js/vendor/flot/examples/axes-multiple/index.html",
"chars": 25422,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n<head>\n\t<meta http-equ"
},
{
"path": "public/js/vendor/flot/examples/axes-time/index.html",
"chars": 18332,
"preview": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n<head>\n\t<meta http-equ"
}
]
// ... and 169 more files (download for full content)
About this extraction
This page contains the full source code of the nature/pa11y-dashboard GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 369 files (4.2 MB), approximately 1.1M tokens, and a symbol index with 510 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.