site-inspector 1.0.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +8 -0
  3. data/.rubocop.yml +42 -0
  4. data/.rubocop_todo.yml +139 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +9 -0
  7. data/Gemfile +7 -0
  8. data/Guardfile +10 -0
  9. data/README.md +189 -0
  10. data/Rakefile +10 -0
  11. data/bin/site-inspector +50 -22
  12. data/lib/cliver/dependency_ext.rb +24 -0
  13. data/lib/site-inspector.rb +62 -615
  14. data/lib/site-inspector/cache.rb +10 -51
  15. data/lib/site-inspector/checks/accessibility.rb +135 -0
  16. data/lib/site-inspector/checks/check.rb +54 -0
  17. data/lib/site-inspector/checks/content.rb +85 -0
  18. data/lib/site-inspector/checks/cookies.rb +45 -0
  19. data/lib/site-inspector/checks/dns.rb +138 -0
  20. data/lib/site-inspector/checks/headers.rb +68 -0
  21. data/lib/site-inspector/checks/hsts.rb +81 -0
  22. data/lib/site-inspector/checks/https.rb +40 -0
  23. data/lib/site-inspector/checks/sniffer.rb +67 -0
  24. data/lib/site-inspector/checks/wappalyzer.rb +62 -0
  25. data/lib/site-inspector/checks/whois.rb +36 -0
  26. data/lib/site-inspector/disk_cache.rb +42 -0
  27. data/lib/site-inspector/domain.rb +271 -0
  28. data/lib/site-inspector/endpoint.rb +217 -0
  29. data/lib/site-inspector/rails_cache.rb +13 -0
  30. data/lib/site-inspector/version.rb +5 -0
  31. data/package-lock.json +505 -0
  32. data/package.json +23 -0
  33. data/script/bootstrap +2 -0
  34. data/script/cibuild +11 -0
  35. data/script/console +3 -0
  36. data/script/pa11y-version +10 -0
  37. data/script/release +38 -0
  38. data/site-inspector.gemspec +42 -0
  39. data/spec/checks/site_inspector_endpoint_accessibility_spec.rb +84 -0
  40. data/spec/checks/site_inspector_endpoint_check_spec.rb +42 -0
  41. data/spec/checks/site_inspector_endpoint_content_spec.rb +117 -0
  42. data/spec/checks/site_inspector_endpoint_cookies_spec.rb +73 -0
  43. data/spec/checks/site_inspector_endpoint_dns_spec.rb +184 -0
  44. data/spec/checks/site_inspector_endpoint_headers_spec.rb +65 -0
  45. data/spec/checks/site_inspector_endpoint_hsts_spec.rb +92 -0
  46. data/spec/checks/site_inspector_endpoint_https_spec.rb +49 -0
  47. data/spec/checks/site_inspector_endpoint_sniffer_spec.rb +150 -0
  48. data/spec/checks/site_inspector_endpoint_wappalyzer_spec.rb +34 -0
  49. data/spec/checks/site_inspector_endpoint_whois_spec.rb +26 -0
  50. data/spec/fixtures/wappalyzer.json +125 -0
  51. data/spec/site_inspector_cache_spec.rb +15 -0
  52. data/spec/site_inspector_disk_cache_spec.rb +39 -0
  53. data/spec/site_inspector_domain_spec.rb +271 -0
  54. data/spec/site_inspector_endpoint_spec.rb +252 -0
  55. data/spec/site_inspector_spec.rb +48 -0
  56. data/spec/spec_helper.rb +19 -0
  57. metadata +204 -63
  58. data/lib/site-inspector/compliance.rb +0 -19
  59. data/lib/site-inspector/dns.rb +0 -92
  60. data/lib/site-inspector/headers.rb +0 -59
  61. data/lib/site-inspector/sniffer.rb +0 -26
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SiteInspector
4
+ # Every domain has four possible "endpoints" to evaluate
5
+ #
6
+ # For example, if you had `example.com` you'd have:
7
+ # 1. `http://example.com`
8
+ # 2. `http://www.example.com`
9
+ # 3. `https://example.com`
10
+ # 4. `https://www.example.com`
11
+ #
12
+ # Because each of the four endpoints could potentially respond differently
13
+ # We must evaluate all four to make certain determination
14
+ class Endpoint
15
+ attr_accessor :host, :uri, :domain
16
+
17
+ # Initatiate a new Endpoint object
18
+ #
19
+ # endpoint - (string) the endpoint to query (e.g., `https://example.com`)
20
+ # options - A hash of options
21
+ # domain - the parent domain object, if passed, facilitates caching of redirects
22
+ def initialize(host, options = {})
23
+ @uri = Addressable::URI.parse(host.downcase)
24
+ # The root URL always has an implict path of "/", even if not requested
25
+ # Make it explicit to facilitate caching and prevent a potential redirect
26
+ @uri.path = '/'
27
+ @host = uri.host.sub(/^www\./, '')
28
+ @checks = {}
29
+ @domain = options[:domain]
30
+ end
31
+
32
+ def www?
33
+ !!(uri.host =~ /^www\./)
34
+ end
35
+
36
+ def root?
37
+ !www?
38
+ end
39
+
40
+ def https?
41
+ https.scheme?
42
+ end
43
+
44
+ def http?
45
+ !https?
46
+ end
47
+
48
+ def scheme
49
+ @uri.scheme
50
+ end
51
+
52
+ def request(options = {})
53
+ target = options[:path] ? URI.join(uri, options.delete(:path)) : uri
54
+ request = Typhoeus::Request.new(target, SiteInspector.typhoeus_defaults.merge(options))
55
+ hydra.queue(request)
56
+ hydra.run
57
+ request.response
58
+ end
59
+
60
+ # Makes a GET request of the given host
61
+ #
62
+ # Retutns the Typhoeus::Response object
63
+ def response
64
+ @response ||= request
65
+ end
66
+
67
+ def response_code
68
+ response.response_code.to_s if response
69
+ end
70
+
71
+ def timed_out?
72
+ response&.timed_out?
73
+ end
74
+
75
+ # Does the endpoint return a 2xx or 3xx response code?
76
+ def up?
77
+ response && response_code.start_with?('2') || response_code.start_with?('3')
78
+ end
79
+
80
+ # Does the server respond at all?
81
+ def responds?
82
+ response.code != 0 && !timed_out?
83
+ end
84
+
85
+ # If the domain is a redirect, what's the first endpoint we're redirected to?
86
+ def redirect
87
+ return unless response && response_code.start_with?('3')
88
+
89
+ @redirect ||= begin
90
+ redirect = Addressable::URI.parse(headers['location'])
91
+
92
+ # This is a relative redirect, but we still need the absolute URI
93
+ if redirect.relative?
94
+ redirect.path = "/#{redirect.path}" unless redirect.path[0] == '/'
95
+ redirect.host = host
96
+ redirect.scheme = scheme
97
+ end
98
+
99
+ # This was a redirect to a subpath or back to itself, which we don't care about
100
+ return if redirect.host == host && redirect.scheme == scheme
101
+
102
+ # Init a new endpoint representing the redirect
103
+ find_or_create_by_uri(redirect.to_s)
104
+ end
105
+ end
106
+
107
+ # Does this endpoint return a redirect?
108
+ def redirect?
109
+ !!redirect
110
+ end
111
+
112
+ # What's the effective URL of a request to this domain?
113
+ def resolves_to
114
+ return self unless redirect?
115
+
116
+ # If the redirect doesn't return a 30x response code, return the redirected endpoint
117
+ # Otherwise, we'll need to go down the rabbit hole and see how deep it goes
118
+ return redirect unless redirect.redirect?
119
+
120
+ @resolves_to ||= begin
121
+ response = request(followlocation: true)
122
+
123
+ # Workaround for Webmock not playing nicely with Typhoeus redirects
124
+ url = if response.mock?
125
+ response.headers['Location'] || response.request.url
126
+ else
127
+ response.effective_url
128
+ end
129
+
130
+ find_or_create_by_uri(url)
131
+ end
132
+ end
133
+
134
+ def external_redirect?
135
+ host != resolves_to.host
136
+ end
137
+
138
+ def to_s
139
+ uri.to_s
140
+ end
141
+
142
+ def inspect
143
+ "#<SiteInspector::Endpoint uri=\"#{uri}\">"
144
+ end
145
+
146
+ # Returns information about the endpoint
147
+ #
148
+ # By default, all checks are run. If one or more check names are passed
149
+ # in the options hash, only those checks will be run.
150
+ #
151
+ # options:
152
+ # a hash of check symbols and bools representing which checks should be run
153
+ #
154
+ # Returns the hash representing the endpoint and its checks
155
+ def to_h(options = {})
156
+ hash = {
157
+ uri: uri.to_s,
158
+ host: host,
159
+ www: www?,
160
+ https: https?,
161
+ scheme: scheme,
162
+ up: up?,
163
+ responds: responds?,
164
+ timed_out: timed_out?,
165
+ redirect: redirect?,
166
+ external_redirect: external_redirect?
167
+ }
168
+
169
+ # Either they've specifically asked for a check, or we throw everything at them
170
+ checks = SiteInspector::Endpoint.checks.select { |c| options.key?(c.name) }
171
+ checks = SiteInspector::Endpoint.checks if checks.empty?
172
+
173
+ Parallel.each(checks, in_threads: 4) do |check|
174
+ hash[check.name] = send(check.name).to_h
175
+ end
176
+
177
+ hash
178
+ end
179
+
180
+ def self.checks
181
+ return @checks if defined? @checks
182
+
183
+ @checks = ObjectSpace.each_object(Class).select { |klass| klass < Check }.select(&:enabled?).sort_by(&:name)
184
+ end
185
+
186
+ def method_missing(method_sym, *arguments, &block)
187
+ check = SiteInspector::Endpoint.checks.find { |c| c.name == method_sym }
188
+ if check
189
+ @checks[method_sym] ||= check.new(self)
190
+ else
191
+ super
192
+ end
193
+ end
194
+
195
+ def respond_to_missing?(method_sym, include_private = false)
196
+ if checks.key?(method_sym)
197
+ true
198
+ else
199
+ super
200
+ end
201
+ end
202
+
203
+ private
204
+
205
+ def hydra
206
+ SiteInspector.hydra
207
+ end
208
+
209
+ # In the event that a redirect is to one of the domain's four endpoints,
210
+ # Try to return the existing endpoint, rather than create a new one
211
+ def find_or_create_by_uri(uri)
212
+ uri = Addressable::URI.parse(uri.downcase)
213
+ cached_endpoint = domain.endpoints.find { |e| e.uri.to_s == uri.to_s } if domain
214
+ cached_endpoint || Endpoint.new(uri.to_s)
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SiteInspector
4
+ class RailsCache
5
+ def get(request)
6
+ Rails.cache.read(request)
7
+ end
8
+
9
+ def set(request, response)
10
+ Rails.cache.write(request, response)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SiteInspector
4
+ VERSION = '3.2.0'
5
+ end
@@ -0,0 +1,505 @@
1
+ {
2
+ "name": "site-inspector",
3
+ "version": "2.0.0",
4
+ "lockfileVersion": 1,
5
+ "requires": true,
6
+ "dependencies": {
7
+ "agent-base": {
8
+ "version": "4.3.0",
9
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
10
+ "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
11
+ "requires": {
12
+ "es6-promisify": "^5.0.0"
13
+ }
14
+ },
15
+ "ansi-styles": {
16
+ "version": "3.2.1",
17
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
18
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
19
+ "requires": {
20
+ "color-convert": "^1.9.0"
21
+ }
22
+ },
23
+ "async-limiter": {
24
+ "version": "1.0.1",
25
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
26
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
27
+ },
28
+ "axe-core": {
29
+ "version": "3.4.2",
30
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.4.2.tgz",
31
+ "integrity": "sha512-aPpM84KPiRfeaK3LhA9ag4OmjLUZkNKMH0sZuK+YRBS+QJcegjveidCyvWSBlBr/iIMQdn/1hU00e3YBiuTEdw=="
32
+ },
33
+ "balanced-match": {
34
+ "version": "1.0.0",
35
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
36
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
37
+ },
38
+ "bfj": {
39
+ "version": "4.2.4",
40
+ "resolved": "https://registry.npmjs.org/bfj/-/bfj-4.2.4.tgz",
41
+ "integrity": "sha1-hfeyNoPCr9wVhgOEotHD+sgO0zo=",
42
+ "requires": {
43
+ "check-types": "^7.3.0",
44
+ "hoopy": "^0.1.2",
45
+ "tryer": "^1.0.0"
46
+ }
47
+ },
48
+ "brace-expansion": {
49
+ "version": "1.1.11",
50
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
51
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
52
+ "requires": {
53
+ "balanced-match": "^1.0.0",
54
+ "concat-map": "0.0.1"
55
+ }
56
+ },
57
+ "buffer-from": {
58
+ "version": "1.1.1",
59
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
60
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
61
+ },
62
+ "chalk": {
63
+ "version": "2.4.2",
64
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
65
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
66
+ "requires": {
67
+ "ansi-styles": "^3.2.1",
68
+ "escape-string-regexp": "^1.0.5",
69
+ "supports-color": "^5.3.0"
70
+ }
71
+ },
72
+ "check-types": {
73
+ "version": "7.4.0",
74
+ "resolved": "https://registry.npmjs.org/check-types/-/check-types-7.4.0.tgz",
75
+ "integrity": "sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg=="
76
+ },
77
+ "color-convert": {
78
+ "version": "1.9.3",
79
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
80
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
81
+ "requires": {
82
+ "color-name": "1.1.3"
83
+ }
84
+ },
85
+ "color-name": {
86
+ "version": "1.1.3",
87
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
88
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
89
+ },
90
+ "commander": {
91
+ "version": "3.0.2",
92
+ "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
93
+ "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow=="
94
+ },
95
+ "concat-map": {
96
+ "version": "0.0.1",
97
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
98
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
99
+ },
100
+ "concat-stream": {
101
+ "version": "1.6.2",
102
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
103
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
104
+ "requires": {
105
+ "buffer-from": "^1.0.0",
106
+ "inherits": "^2.0.3",
107
+ "readable-stream": "^2.2.2",
108
+ "typedarray": "^0.0.6"
109
+ }
110
+ },
111
+ "core-util-is": {
112
+ "version": "1.0.2",
113
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
114
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
115
+ },
116
+ "debug": {
117
+ "version": "4.1.1",
118
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
119
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
120
+ "requires": {
121
+ "ms": "^2.1.1"
122
+ }
123
+ },
124
+ "es6-promise": {
125
+ "version": "4.2.8",
126
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
127
+ "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
128
+ },
129
+ "es6-promisify": {
130
+ "version": "5.0.0",
131
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
132
+ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
133
+ "requires": {
134
+ "es6-promise": "^4.0.3"
135
+ }
136
+ },
137
+ "escape-string-regexp": {
138
+ "version": "1.0.5",
139
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
140
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
141
+ },
142
+ "extract-zip": {
143
+ "version": "1.6.7",
144
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
145
+ "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
146
+ "requires": {
147
+ "concat-stream": "1.6.2",
148
+ "debug": "2.6.9",
149
+ "mkdirp": "0.5.1",
150
+ "yauzl": "2.4.1"
151
+ },
152
+ "dependencies": {
153
+ "debug": {
154
+ "version": "2.6.9",
155
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
156
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
157
+ "requires": {
158
+ "ms": "2.0.0"
159
+ }
160
+ },
161
+ "ms": {
162
+ "version": "2.0.0",
163
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
164
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
165
+ }
166
+ }
167
+ },
168
+ "fd-slicer": {
169
+ "version": "1.0.1",
170
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
171
+ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
172
+ "requires": {
173
+ "pend": "~1.2.0"
174
+ }
175
+ },
176
+ "fs.realpath": {
177
+ "version": "1.0.0",
178
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
179
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
180
+ },
181
+ "function-bind": {
182
+ "version": "1.1.1",
183
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
184
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
185
+ },
186
+ "glob": {
187
+ "version": "7.1.6",
188
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
189
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
190
+ "requires": {
191
+ "fs.realpath": "^1.0.0",
192
+ "inflight": "^1.0.4",
193
+ "inherits": "2",
194
+ "minimatch": "^3.0.4",
195
+ "once": "^1.3.0",
196
+ "path-is-absolute": "^1.0.0"
197
+ }
198
+ },
199
+ "has": {
200
+ "version": "1.0.3",
201
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
202
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
203
+ "requires": {
204
+ "function-bind": "^1.1.1"
205
+ }
206
+ },
207
+ "has-flag": {
208
+ "version": "3.0.0",
209
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
210
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
211
+ },
212
+ "hoopy": {
213
+ "version": "0.1.4",
214
+ "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
215
+ "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ=="
216
+ },
217
+ "html_codesniffer": {
218
+ "version": "2.4.1",
219
+ "resolved": "https://registry.npmjs.org/html_codesniffer/-/html_codesniffer-2.4.1.tgz",
220
+ "integrity": "sha512-7g4Z8+7agJFi7XJGu2r0onIqA7ig9b26vFEvUE6DgtFJlJzy1ELYEKzzd5Xwam4xjHiHQ/w8yHO7KTGNcXnwzg=="
221
+ },
222
+ "https-proxy-agent": {
223
+ "version": "2.2.4",
224
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
225
+ "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
226
+ "requires": {
227
+ "agent-base": "^4.3.0",
228
+ "debug": "^3.1.0"
229
+ },
230
+ "dependencies": {
231
+ "debug": {
232
+ "version": "3.2.6",
233
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
234
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
235
+ "requires": {
236
+ "ms": "^2.1.1"
237
+ }
238
+ }
239
+ }
240
+ },
241
+ "inflight": {
242
+ "version": "1.0.6",
243
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
244
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
245
+ "requires": {
246
+ "once": "^1.3.0",
247
+ "wrappy": "1"
248
+ }
249
+ },
250
+ "inherits": {
251
+ "version": "2.0.4",
252
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
253
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
254
+ },
255
+ "is": {
256
+ "version": "3.3.0",
257
+ "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz",
258
+ "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg=="
259
+ },
260
+ "isarray": {
261
+ "version": "1.0.0",
262
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
263
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
264
+ },
265
+ "mime": {
266
+ "version": "2.4.4",
267
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
268
+ "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
269
+ },
270
+ "minimatch": {
271
+ "version": "3.0.4",
272
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
273
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
274
+ "requires": {
275
+ "brace-expansion": "^1.1.7"
276
+ }
277
+ },
278
+ "minimist": {
279
+ "version": "0.0.8",
280
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
281
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
282
+ },
283
+ "mkdirp": {
284
+ "version": "0.5.1",
285
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
286
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
287
+ "requires": {
288
+ "minimist": "0.0.8"
289
+ }
290
+ },
291
+ "ms": {
292
+ "version": "2.1.2",
293
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
294
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
295
+ },
296
+ "node.extend": {
297
+ "version": "2.0.2",
298
+ "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-2.0.2.tgz",
299
+ "integrity": "sha512-pDT4Dchl94/+kkgdwyS2PauDFjZG0Hk0IcHIB+LkW27HLDtdoeMxHTxZh39DYbPP8UflWXWj9JcdDozF+YDOpQ==",
300
+ "requires": {
301
+ "has": "^1.0.3",
302
+ "is": "^3.2.1"
303
+ }
304
+ },
305
+ "once": {
306
+ "version": "1.4.0",
307
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
308
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
309
+ "requires": {
310
+ "wrappy": "1"
311
+ }
312
+ },
313
+ "p-finally": {
314
+ "version": "1.0.0",
315
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
316
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
317
+ },
318
+ "p-timeout": {
319
+ "version": "2.0.1",
320
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
321
+ "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
322
+ "requires": {
323
+ "p-finally": "^1.0.0"
324
+ }
325
+ },
326
+ "pa11y": {
327
+ "version": "5.3.0",
328
+ "resolved": "https://registry.npmjs.org/pa11y/-/pa11y-5.3.0.tgz",
329
+ "integrity": "sha512-g1cVpmRQQXClTZYbx4JC+FqCu6AfM9K3px2TPb2NY9JrorxYiInOKQCa9eF6URjY//bDkQmkn65rTWmbwTC07A==",
330
+ "requires": {
331
+ "commander": "^3.0.2",
332
+ "node.extend": "^2.0.2",
333
+ "p-timeout": "^2.0.1",
334
+ "pa11y-reporter-cli": "^1.0.1",
335
+ "pa11y-reporter-csv": "^1.0.0",
336
+ "pa11y-reporter-json": "^1.0.0",
337
+ "pa11y-runner-axe": "^1.0.1",
338
+ "pa11y-runner-htmlcs": "^1.2.0",
339
+ "puppeteer": "^1.13.0",
340
+ "semver": "^5.6.0"
341
+ }
342
+ },
343
+ "pa11y-reporter-cli": {
344
+ "version": "1.0.1",
345
+ "resolved": "https://registry.npmjs.org/pa11y-reporter-cli/-/pa11y-reporter-cli-1.0.1.tgz",
346
+ "integrity": "sha512-k+XPl5pBU2R1J6iagGv/GpN/dP7z2cX9WXqO0ALpBwHlHN3ZSukcHCOhuLMmkOZNvufwsvobaF5mnaZxT70YyA==",
347
+ "requires": {
348
+ "chalk": "^2.1.0"
349
+ }
350
+ },
351
+ "pa11y-reporter-csv": {
352
+ "version": "1.0.0",
353
+ "resolved": "https://registry.npmjs.org/pa11y-reporter-csv/-/pa11y-reporter-csv-1.0.0.tgz",
354
+ "integrity": "sha512-S2gFgbAvONBzAVsVbF8zsYabszrzj7SKhQxrEbw19zF0OFI8wCWn8dFywujYYkg674rmyjweSxSdD+kHTcx4qA=="
355
+ },
356
+ "pa11y-reporter-json": {
357
+ "version": "1.0.0",
358
+ "resolved": "https://registry.npmjs.org/pa11y-reporter-json/-/pa11y-reporter-json-1.0.0.tgz",
359
+ "integrity": "sha512-EdLrzh1hyZ8DudCSSrcakgtsHDiSsYNsWLSoEAo1JnFTIK8hYpD7vL+xgd0u+LXDxz9wLLFnckdubpklaRpl/w==",
360
+ "requires": {
361
+ "bfj": "^4.2.3"
362
+ }
363
+ },
364
+ "pa11y-runner-axe": {
365
+ "version": "1.0.1",
366
+ "resolved": "https://registry.npmjs.org/pa11y-runner-axe/-/pa11y-runner-axe-1.0.1.tgz",
367
+ "integrity": "sha512-TZls/tSpiQfCbgRg7t+5O0R6/PrOHBCZXX+/dT4QemarTef0TzQqHz8az8sbC9IpDFAY+X2pGJW5becaXiIuWw==",
368
+ "requires": {
369
+ "axe-core": "^3.1.2"
370
+ }
371
+ },
372
+ "pa11y-runner-htmlcs": {
373
+ "version": "1.2.0",
374
+ "resolved": "https://registry.npmjs.org/pa11y-runner-htmlcs/-/pa11y-runner-htmlcs-1.2.0.tgz",
375
+ "integrity": "sha512-uf0wEsoeRfyALXVcZeDadV7ot7pE6JZ3EZwbspwmyXW30ahjCClAfE/FtaNo1y2Mlxx5J9ui1sW2YzhHXocV5g==",
376
+ "requires": {
377
+ "html_codesniffer": "^2.4.1"
378
+ }
379
+ },
380
+ "path-is-absolute": {
381
+ "version": "1.0.1",
382
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
383
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
384
+ },
385
+ "pend": {
386
+ "version": "1.2.0",
387
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
388
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
389
+ },
390
+ "process-nextick-args": {
391
+ "version": "2.0.1",
392
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
393
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
394
+ },
395
+ "progress": {
396
+ "version": "2.0.3",
397
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
398
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
399
+ },
400
+ "proxy-from-env": {
401
+ "version": "1.0.0",
402
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
403
+ "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4="
404
+ },
405
+ "puppeteer": {
406
+ "version": "1.20.0",
407
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz",
408
+ "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==",
409
+ "requires": {
410
+ "debug": "^4.1.0",
411
+ "extract-zip": "^1.6.6",
412
+ "https-proxy-agent": "^2.2.1",
413
+ "mime": "^2.0.3",
414
+ "progress": "^2.0.1",
415
+ "proxy-from-env": "^1.0.0",
416
+ "rimraf": "^2.6.1",
417
+ "ws": "^6.1.0"
418
+ }
419
+ },
420
+ "readable-stream": {
421
+ "version": "2.3.7",
422
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
423
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
424
+ "requires": {
425
+ "core-util-is": "~1.0.0",
426
+ "inherits": "~2.0.3",
427
+ "isarray": "~1.0.0",
428
+ "process-nextick-args": "~2.0.0",
429
+ "safe-buffer": "~5.1.1",
430
+ "string_decoder": "~1.1.1",
431
+ "util-deprecate": "~1.0.1"
432
+ }
433
+ },
434
+ "rimraf": {
435
+ "version": "2.7.1",
436
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
437
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
438
+ "requires": {
439
+ "glob": "^7.1.3"
440
+ }
441
+ },
442
+ "safe-buffer": {
443
+ "version": "5.1.2",
444
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
445
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
446
+ },
447
+ "semver": {
448
+ "version": "5.7.1",
449
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
450
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
451
+ },
452
+ "string_decoder": {
453
+ "version": "1.1.1",
454
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
455
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
456
+ "requires": {
457
+ "safe-buffer": "~5.1.0"
458
+ }
459
+ },
460
+ "supports-color": {
461
+ "version": "5.5.0",
462
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
463
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
464
+ "requires": {
465
+ "has-flag": "^3.0.0"
466
+ }
467
+ },
468
+ "tryer": {
469
+ "version": "1.0.1",
470
+ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz",
471
+ "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA=="
472
+ },
473
+ "typedarray": {
474
+ "version": "0.0.6",
475
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
476
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
477
+ },
478
+ "util-deprecate": {
479
+ "version": "1.0.2",
480
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
481
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
482
+ },
483
+ "wrappy": {
484
+ "version": "1.0.2",
485
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
486
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
487
+ },
488
+ "ws": {
489
+ "version": "6.2.1",
490
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
491
+ "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
492
+ "requires": {
493
+ "async-limiter": "~1.0.0"
494
+ }
495
+ },
496
+ "yauzl": {
497
+ "version": "2.4.1",
498
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
499
+ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
500
+ "requires": {
501
+ "fd-slicer": "~1.0.1"
502
+ }
503
+ }
504
+ }
505
+ }