├── .gitignore
├── .vscode
└── settings.json
├── LICENSE
├── Readme.md
├── docs
├── Resources.md
└── UnitTests.md
├── index.js
├── package-lock.json
├── package.json
└── test
├── browser
├── sample.test.js
└── testRunner.html
├── node
├── detectBrowserUnsupportedFeatures.test.js
└── polyfillLoader.test.js
└── utils
├── IE11.Config.js
└── base.Config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
2 | .grunt
3 |
4 | # Dependency directories
5 | node_modules
6 |
7 | # Optional npm cache directory
8 | .npm
9 | npm-debug.log*
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 José Quinto
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Polyfill.io Features Detection in the browser
2 | Feature detection in the browser before loading polyfill using services like polyfill.io
3 |
4 | [](https://badge.fury.io/js/polyfill-io-feature-detection)
5 | [](https://nodesecurity.io/orgs/jquinto/projects/97ba8357-aca4-44b2-b17a-62e69e9d0bd2)
6 | [](https://codeclimate.com/github/jquintozamora/polyfill-io-feature-detection)
7 | [](https://raw.githubusercontent.com/jquintozamora/polyfill-io-feature-detection/master/LICENSE)
8 | [](Readme.md#want-to-contribute)
9 |
10 | [](https://nodei.co/npm/polyfill-io-feature-detection/)
11 |
12 |
13 |
14 | ## When should I use polyfill-io-feature-detection?
15 | + You want to isolate your app code from the browser supported features (applying polyfills)
16 | + You have to add polyfills to yout web application because requires support to different browsers and devices
17 | + You want to use polyfill service like [polyfill.io](https://polyfill.io/v2/docs) instead of including the polyfills in your bundle
18 | + You want (should) to [load polyfills only when needed](https://philipwalton.com/articles/loading-polyfills-only-when-needed)
19 | + You want to optimize the experience for users on modern browser
20 | + You want to save the polyfill service call when possible (using this polyfillLoader)
21 |
22 | If you meet all these requirements, you probably will love this package. Because it allows you to load polyfills dynamically only when your browser really need it.
23 |
24 |
25 | ## Usage
26 | ```js
27 | function App () {
28 | // your app code here
29 | }
30 |
31 | import { polyfillLoader } from 'polyfill-io-feature-detection';
32 | polyfillLoader({
33 | "features": "Promise",
34 | "onCompleted": App
35 | });
36 | ```
37 |
38 | ## Usage with React
39 | ```js
40 | // index.jsx
41 | import React from 'react';
42 | import {render} from 'react-dom';
43 | import App from './containers/App.jsx';
44 |
45 | import { polyfillLoader } from 'polyfill-io-feature-detection';
46 | // This function load polyfills only if needed. By default it uses polyfill.io
47 | polyfillLoader({
48 | "features": "Promise,fetch",
49 | "onCompleted": main
50 | });
51 |
52 | // That function will be called after loading polyfills
53 | function main() {
54 | render(
55 |
56 | , document.getElementById('starter')
57 | );
58 | }
59 | ```
60 | More information: [Getting React to Load polyfills only when needed](https://blog.josequinto.com/2017/01/20/getting-react-to-load-polyfills-only-when-needed)
61 |
62 | ## Want to contribute?
63 | Anyone can help make this project better
64 |
65 | ## License
66 | (The MIT License)
67 | Copyright (c) 2017 Jose Quinto (https://blog.josequinto.com)
68 |
69 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
70 |
71 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
72 |
73 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
74 |
--------------------------------------------------------------------------------
/docs/Resources.md:
--------------------------------------------------------------------------------
1 | # Resources
2 | - [Load polyfills only when needed](https://philipwalton.com/articles/loading-polyfills-only-when-needed)
3 | - Feature Detection:
4 | - [Writing Polyfills](https://addyosmani.com/blog/writing-polyfills)
5 | - [An easier way of using polyfills](https://hacks.mozilla.org/2014/11/an-easier-way-of-using-polyfills)
6 | - [Polyfill.io feature detectin](https://polyfill.io/v2/docs/examples#feature-detection)
7 | - [Utility to convert between polyfill list and a query string representation](https://github.com/Financial-Times/polyfill-service/blob/master/service/PolyfillSet.js)
8 | - [Testing with Mocha and Proclaim](https://github.com/Financial-Times/polyfill-service/blob/master/test/node/lib/test_aliases.js)
9 | - [Using console.log asserts with Mocha and Chai without Stubbs](https://github.com/mochajs/mocha/wiki/Mess-with-globals)
10 |
--------------------------------------------------------------------------------
/docs/UnitTests.md:
--------------------------------------------------------------------------------
1 | ## Unit Tests
2 | Testing Platform: Mocha
3 | Assert Library: Chai
4 | Testing folder structure:
5 | ```
6 | test
7 | browser --> just a sample test folder, not used in the project
8 | node
9 | JS Unit test files
10 | utils
11 | IE11.Config.js --> specific IE11 window configuration for Testing
12 | ```
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | if (!Array.prototype.filter) {
4 | Array.prototype.filter = function (func, thisArg) {
5 | 'use strict';
6 | if (!((typeof func === 'Function' || typeof func === 'function') && this))
7 | throw new TypeError();
8 |
9 | var len = this.length >>> 0,
10 | res = new Array(len), // preallocate array
11 | t = this, c = 0, i = -1;
12 | if (thisArg === undefined) {
13 | while (++i !== len) {
14 | // checks to see if the key was set
15 | if (i in this) {
16 | if (func(t[i], i, t)) {
17 | res[c++] = t[i];
18 | }
19 | }
20 | }
21 | }
22 | else {
23 | while (++i !== len) {
24 | // checks to see if the key was set
25 | if (i in this) {
26 | if (func.call(thisArg, t[i], i, t)) {
27 | res[c++] = t[i];
28 | }
29 | }
30 | }
31 | }
32 |
33 | res.length = c; // shrink down array to proper size
34 | return res;
35 | };
36 | }
37 |
38 | // Production steps of ECMA-262, Edition 5, 15.4.4.19
39 | // Reference: http://es5.github.io/#x15.4.4.19
40 | if (!Array.prototype.map) {
41 | Array.prototype.map = function (callback/*, thisArg*/) {
42 |
43 | var T, A, k;
44 |
45 | if (this == null) {
46 | throw new TypeError('this is null or not defined');
47 | }
48 |
49 | // 1. Let O be the result of calling ToObject passing the |this|
50 | // value as the argument.
51 | var O = Object(this);
52 |
53 | // 2. Let lenValue be the result of calling the Get internal
54 | // method of O with the argument "length".
55 | // 3. Let len be ToUint32(lenValue).
56 | var len = O.length >>> 0;
57 |
58 | // 4. If IsCallable(callback) is false, throw a TypeError exception.
59 | // See: http://es5.github.com/#x9.11
60 | if (typeof callback !== 'function') {
61 | throw new TypeError(callback + ' is not a function');
62 | }
63 |
64 | // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
65 | if (arguments.length > 1) {
66 | T = arguments[1];
67 | }
68 |
69 | // 6. Let A be a new array created as if by the expression new Array(len)
70 | // where Array is the standard built-in constructor with that name and
71 | // len is the value of len.
72 | A = new Array(len);
73 |
74 | // 7. Let k be 0
75 | k = 0;
76 |
77 | // 8. Repeat, while k < len
78 | while (k < len) {
79 |
80 | var kValue, mappedValue;
81 |
82 | // a. Let Pk be ToString(k).
83 | // This is implicit for LHS operands of the in operator
84 | // b. Let kPresent be the result of calling the HasProperty internal
85 | // method of O with argument Pk.
86 | // This step can be combined with c
87 | // c. If kPresent is true, then
88 | if (k in O) {
89 |
90 | // i. Let kValue be the result of calling the Get internal
91 | // method of O with argument Pk.
92 | kValue = O[k];
93 |
94 | // ii. Let mappedValue be the result of calling the Call internal
95 | // method of callback with T as the this value and argument
96 | // list containing kValue, k, and O.
97 | mappedValue = callback.call(T, kValue, k, O);
98 |
99 | // For best browser support, use the following:
100 | A[k] = mappedValue;
101 | }
102 | // d. Increase k by 1.
103 | k++;
104 | }
105 |
106 | // 9. return A
107 | return A;
108 | };
109 | }
110 |
111 | // Check each feature in the featureString parameter (comma separated)
112 | // and returns an array with all unsupported features for the current browser
113 | var detectBrowserUnsupportedFeatures = function (featureStringCommaSeparated) {
114 | var arrayFeatures = featureStringCommaSeparated
115 | .split(',')
116 | .filter(function (x) { return x.length })
117 | .map(function (x) { return x.replace(/[\*\/]/g, '') }); // Eliminate XSS vuln
118 | var arrayUnsupportedFeatures = [];
119 | for (var i = 0; i < arrayFeatures.length; i++) {
120 | var supportedFeature = true;
121 | var fullFeature = arrayFeatures[i];
122 | if (contains(fullFeature, "~")) {
123 | if (contains(fullFeature, "Intl.~locale")) {
124 | supportedFeature = checkIntlLocale(window, fullFeature);
125 | } else {
126 | console.warn('Feature ' + fullFeature + ' can not be detected because it has not JavaScript API.');
127 | }
128 | } else {
129 | // Get the feature and the container Object
130 | var featureString = fullFeature.substring(fullFeature.lastIndexOf('.') + 1);
131 | if (contains(featureString, "@@")) {
132 | console.warn('Feature ' + featureString + ' can not be detected because it depends on Symbol.');
133 | } else {
134 | var objectString = fullFeature.substring(0, fullFeature.lastIndexOf('.'));
135 | var object = getDescendantProp(window, objectString);
136 | if (object !== undefined) {
137 | //if ((object.hasOwnProperty(featureString)) === false) {
138 | if ((featureString in object) === false) {
139 | supportedFeature = false;
140 | }
141 | } else {
142 | supportedFeature = false;
143 | }
144 | }
145 | }
146 | // If the feature is not supported by the browser, then add it to polyfill it
147 | if (supportedFeature === false) {
148 | arrayUnsupportedFeatures.push(fullFeature);
149 | }
150 | }
151 | return arrayUnsupportedFeatures;
152 | }
153 |
154 | function checkIntlLocale(obj, feature) {
155 | var localeArray = feature.split("Intl.~locale");
156 | var locale = "";
157 | if (localeArray.length === 2) {
158 | var tempLocale = localeArray[1];
159 | if (tempLocale && tempLocale !== "") {
160 | locale = tempLocale.replace(".", "");
161 |
162 | if (!("Intl" in obj &&
163 | "Collator" in obj.Intl &&
164 | "supportedLocalesOf" in obj.Intl.Collator &&
165 | obj.Intl.Collator.supportedLocalesOf(locale).length === 1 &&
166 | "DateTimeFormat" in obj.Intl &&
167 | "supportedLocalesOf" in obj.Intl.DateTimeFormat &&
168 | obj.Intl.DateTimeFormat.supportedLocalesOf(locale).length === 1 &&
169 | "NumberFormat" in obj.Intl &&
170 | "supportedLocalesOf" in obj.Intl.NumberFormat &&
171 | obj.Intl.NumberFormat.supportedLocalesOf(locale).length === 1)) {
172 | return false;
173 | } else {
174 | return true;
175 | }
176 | } else {
177 | console.warn('Feature ' + feature + ' has wrong Intl.~locale.XX format. For example Intl.~locale.en-US');
178 | }
179 | } else {
180 | console.warn('Feature ' + feature + ' has wrong Intl.~locale format. For example Intl.~locale.en-US');
181 | }
182 | // if any error, returns false
183 | return false;
184 | }
185 |
186 | // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/includes
187 | function contains(origin, search, start) {
188 | 'use strict';
189 | if (typeof start !== 'number') {
190 | start = 0;
191 | }
192 | if (start + search.length > origin.length) {
193 | return false;
194 | } else {
195 | return origin.indexOf(search, start) !== -1;
196 | }
197 | }
198 |
199 | function getDescendantProp(obj, desc) {
200 | var arr = desc.split(".");
201 | if (arr.length > 0 && arr[0] !== "") {
202 | while (arr.length) {
203 | var name = arr.shift();
204 | if (name in obj) {
205 | obj = obj[name];
206 | } else {
207 | console.warn('[getDescendantProp] - ' + name + ' property does not exists.');
208 | return undefined;
209 | }
210 | }
211 | }
212 | return obj;
213 | }
214 |
215 | function loadScript(src, done) {
216 | var finished = false
217 |
218 | function handleLoad() {
219 | if (!finished) {
220 | finished = true
221 | done(src)
222 | }
223 | }
224 |
225 | function handleReadyStateChange() {
226 | if (!finished) {
227 | if (script.readyState === 'complete') {
228 | handleLoad()
229 | }
230 | }
231 | }
232 |
233 | function handleError() {
234 | if (!finished) {
235 | finished = true
236 | done(new Error('Failed to load script ' + src))
237 | }
238 | }
239 | var script = document.createElement('script')
240 | script.onload = handleLoad
241 | script.type = 'text/javascript'
242 | script.onreadystatechange = handleReadyStateChange
243 | script.onerror = handleError
244 | script.src = src
245 | document.head.appendChild(script)
246 | }
247 |
248 | var polyfillLoader = function (options) {
249 | var onCompleted = options.onCompleted;
250 | if (onCompleted === undefined) {
251 | return new Error("options.onCompleted function is required.");
252 | }
253 | var featureString = options.features || '';
254 | var features = detectBrowserUnsupportedFeatures(featureString);
255 | if (features.length === 0) {
256 | onCompleted();
257 | } else {
258 | var polyfillService = options.polyfillService || 'https://cdn.polyfill.io/v2/polyfill.min.js';
259 | // https://polyfill.io/v2/docs/examples#feature-detection
260 | var polyfillServiceUrl = polyfillService + '?features=' + features.join(',') + '&flags=gated,always';
261 | loadScript(polyfillServiceUrl, onCompleted);
262 | }
263 | }
264 |
265 | module.exports = {
266 | polyfillLoader: polyfillLoader,
267 | detectBrowserUnsupportedFeatures: detectBrowserUnsupportedFeatures
268 | };
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "polyfill-io-feature-detection",
3 | "version": "1.1.14",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "ajv": {
8 | "version": "5.5.2",
9 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
10 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
11 | "dev": true,
12 | "requires": {
13 | "co": "^4.6.0",
14 | "fast-deep-equal": "^1.0.0",
15 | "fast-json-stable-stringify": "^2.0.0",
16 | "json-schema-traverse": "^0.3.0"
17 | }
18 | },
19 | "asn1": {
20 | "version": "0.2.3",
21 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
22 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
23 | "dev": true
24 | },
25 | "assert-plus": {
26 | "version": "1.0.0",
27 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
28 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
29 | "dev": true
30 | },
31 | "assertion-error": {
32 | "version": "1.1.0",
33 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
34 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
35 | "dev": true
36 | },
37 | "asynckit": {
38 | "version": "0.4.0",
39 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
40 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
41 | "dev": true
42 | },
43 | "aws-sign2": {
44 | "version": "0.7.0",
45 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
46 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
47 | "dev": true
48 | },
49 | "aws4": {
50 | "version": "1.7.0",
51 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
52 | "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==",
53 | "dev": true
54 | },
55 | "balanced-match": {
56 | "version": "1.0.0",
57 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
58 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
59 | "dev": true
60 | },
61 | "bcrypt-pbkdf": {
62 | "version": "1.0.2",
63 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
64 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
65 | "dev": true,
66 | "optional": true,
67 | "requires": {
68 | "tweetnacl": "^0.14.3"
69 | }
70 | },
71 | "brace-expansion": {
72 | "version": "1.1.11",
73 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
74 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
75 | "dev": true,
76 | "requires": {
77 | "balanced-match": "^1.0.0",
78 | "concat-map": "0.0.1"
79 | }
80 | },
81 | "browser-stdout": {
82 | "version": "1.3.1",
83 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
84 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
85 | "dev": true
86 | },
87 | "caseless": {
88 | "version": "0.12.0",
89 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
90 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
91 | "dev": true
92 | },
93 | "chai": {
94 | "version": "4.1.2",
95 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
96 | "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
97 | "dev": true,
98 | "requires": {
99 | "assertion-error": "^1.0.1",
100 | "check-error": "^1.0.1",
101 | "deep-eql": "^3.0.0",
102 | "get-func-name": "^2.0.0",
103 | "pathval": "^1.0.0",
104 | "type-detect": "^4.0.0"
105 | }
106 | },
107 | "chai-as-promised": {
108 | "version": "5.3.0",
109 | "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-5.3.0.tgz",
110 | "integrity": "sha1-CdekApCKpw39vq1T5YU/x50+8hw=",
111 | "dev": true
112 | },
113 | "chai-subset": {
114 | "version": "1.6.0",
115 | "resolved": "https://registry.npmjs.org/chai-subset/-/chai-subset-1.6.0.tgz",
116 | "integrity": "sha1-pdDKFOMpp5WW7XAFi2ZGvWmIz+k=",
117 | "dev": true
118 | },
119 | "chakram": {
120 | "version": "1.5.0",
121 | "resolved": "https://registry.npmjs.org/chakram/-/chakram-1.5.0.tgz",
122 | "integrity": "sha1-PYsKiPdo3WraWSpSRmPMDcFKwc8=",
123 | "dev": true,
124 | "requires": {
125 | "chai": "3.x.x",
126 | "chai-as-promised": "5.x.x",
127 | "chai-subset": "1.x.x",
128 | "extend-object": "1.x.x",
129 | "q": "1.x.x",
130 | "request": "2.x.x",
131 | "request-debug": "0.x.x",
132 | "tv4": "1.x.x"
133 | },
134 | "dependencies": {
135 | "chai": {
136 | "version": "3.5.0",
137 | "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz",
138 | "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
139 | "dev": true,
140 | "requires": {
141 | "assertion-error": "^1.0.1",
142 | "deep-eql": "^0.1.3",
143 | "type-detect": "^1.0.0"
144 | }
145 | },
146 | "deep-eql": {
147 | "version": "0.1.3",
148 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
149 | "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
150 | "dev": true,
151 | "requires": {
152 | "type-detect": "0.1.1"
153 | },
154 | "dependencies": {
155 | "type-detect": {
156 | "version": "0.1.1",
157 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz",
158 | "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=",
159 | "dev": true
160 | }
161 | }
162 | },
163 | "type-detect": {
164 | "version": "1.0.0",
165 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz",
166 | "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=",
167 | "dev": true
168 | }
169 | }
170 | },
171 | "check-error": {
172 | "version": "1.0.2",
173 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
174 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
175 | "dev": true
176 | },
177 | "co": {
178 | "version": "4.6.0",
179 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
180 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
181 | "dev": true
182 | },
183 | "combined-stream": {
184 | "version": "1.0.6",
185 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
186 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
187 | "dev": true,
188 | "requires": {
189 | "delayed-stream": "~1.0.0"
190 | }
191 | },
192 | "commander": {
193 | "version": "2.15.1",
194 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
195 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
196 | "dev": true
197 | },
198 | "concat-map": {
199 | "version": "0.0.1",
200 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
201 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
202 | "dev": true
203 | },
204 | "core-util-is": {
205 | "version": "1.0.2",
206 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
207 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
208 | "dev": true
209 | },
210 | "dashdash": {
211 | "version": "1.14.1",
212 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
213 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
214 | "dev": true,
215 | "requires": {
216 | "assert-plus": "^1.0.0"
217 | }
218 | },
219 | "debug": {
220 | "version": "3.1.0",
221 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
222 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
223 | "dev": true,
224 | "requires": {
225 | "ms": "2.0.0"
226 | }
227 | },
228 | "deep-eql": {
229 | "version": "3.0.1",
230 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
231 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
232 | "dev": true,
233 | "requires": {
234 | "type-detect": "^4.0.0"
235 | }
236 | },
237 | "delayed-stream": {
238 | "version": "1.0.0",
239 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
240 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
241 | "dev": true
242 | },
243 | "diff": {
244 | "version": "3.5.0",
245 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
246 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
247 | "dev": true
248 | },
249 | "ecc-jsbn": {
250 | "version": "0.1.1",
251 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
252 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
253 | "dev": true,
254 | "optional": true,
255 | "requires": {
256 | "jsbn": "~0.1.0"
257 | }
258 | },
259 | "escape-string-regexp": {
260 | "version": "1.0.5",
261 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
262 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
263 | "dev": true
264 | },
265 | "extend": {
266 | "version": "3.0.2",
267 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
268 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
269 | "dev": true
270 | },
271 | "extend-object": {
272 | "version": "1.0.0",
273 | "resolved": "https://registry.npmjs.org/extend-object/-/extend-object-1.0.0.tgz",
274 | "integrity": "sha1-QlFPhAFdE1bK9Rh5ad+yvBvaCCM=",
275 | "dev": true
276 | },
277 | "extsprintf": {
278 | "version": "1.3.0",
279 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
280 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
281 | "dev": true
282 | },
283 | "fast-deep-equal": {
284 | "version": "1.1.0",
285 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
286 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
287 | "dev": true
288 | },
289 | "fast-json-stable-stringify": {
290 | "version": "2.0.0",
291 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
292 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
293 | "dev": true
294 | },
295 | "forever-agent": {
296 | "version": "0.6.1",
297 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
298 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
299 | "dev": true
300 | },
301 | "form-data": {
302 | "version": "2.3.2",
303 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
304 | "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
305 | "dev": true,
306 | "requires": {
307 | "asynckit": "^0.4.0",
308 | "combined-stream": "1.0.6",
309 | "mime-types": "^2.1.12"
310 | }
311 | },
312 | "fs.realpath": {
313 | "version": "1.0.0",
314 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
315 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
316 | "dev": true
317 | },
318 | "get-func-name": {
319 | "version": "2.0.0",
320 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
321 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
322 | "dev": true
323 | },
324 | "getpass": {
325 | "version": "0.1.7",
326 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
327 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
328 | "dev": true,
329 | "requires": {
330 | "assert-plus": "^1.0.0"
331 | }
332 | },
333 | "glob": {
334 | "version": "7.1.2",
335 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
336 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
337 | "dev": true,
338 | "requires": {
339 | "fs.realpath": "^1.0.0",
340 | "inflight": "^1.0.4",
341 | "inherits": "2",
342 | "minimatch": "^3.0.4",
343 | "once": "^1.3.0",
344 | "path-is-absolute": "^1.0.0"
345 | }
346 | },
347 | "growl": {
348 | "version": "1.10.5",
349 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
350 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
351 | "dev": true
352 | },
353 | "har-schema": {
354 | "version": "2.0.0",
355 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
356 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
357 | "dev": true
358 | },
359 | "har-validator": {
360 | "version": "5.0.3",
361 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
362 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
363 | "dev": true,
364 | "requires": {
365 | "ajv": "^5.1.0",
366 | "har-schema": "^2.0.0"
367 | }
368 | },
369 | "has-flag": {
370 | "version": "3.0.0",
371 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
372 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
373 | "dev": true
374 | },
375 | "he": {
376 | "version": "1.1.1",
377 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
378 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
379 | "dev": true
380 | },
381 | "http-signature": {
382 | "version": "1.2.0",
383 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
384 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
385 | "dev": true,
386 | "requires": {
387 | "assert-plus": "^1.0.0",
388 | "jsprim": "^1.2.2",
389 | "sshpk": "^1.7.0"
390 | }
391 | },
392 | "inflight": {
393 | "version": "1.0.6",
394 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
395 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
396 | "dev": true,
397 | "requires": {
398 | "once": "^1.3.0",
399 | "wrappy": "1"
400 | }
401 | },
402 | "inherits": {
403 | "version": "2.0.3",
404 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
405 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
406 | "dev": true
407 | },
408 | "is-typedarray": {
409 | "version": "1.0.0",
410 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
411 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
412 | "dev": true
413 | },
414 | "isstream": {
415 | "version": "0.1.2",
416 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
417 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
418 | "dev": true
419 | },
420 | "jsbn": {
421 | "version": "0.1.1",
422 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
423 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
424 | "dev": true,
425 | "optional": true
426 | },
427 | "json-schema": {
428 | "version": "0.2.3",
429 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
430 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
431 | "dev": true
432 | },
433 | "json-schema-traverse": {
434 | "version": "0.3.1",
435 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
436 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
437 | "dev": true
438 | },
439 | "json-stringify-safe": {
440 | "version": "5.0.1",
441 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
442 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
443 | "dev": true
444 | },
445 | "jsprim": {
446 | "version": "1.4.1",
447 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
448 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
449 | "dev": true,
450 | "requires": {
451 | "assert-plus": "1.0.0",
452 | "extsprintf": "1.3.0",
453 | "json-schema": "0.2.3",
454 | "verror": "1.10.0"
455 | }
456 | },
457 | "mime-db": {
458 | "version": "1.35.0",
459 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz",
460 | "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==",
461 | "dev": true
462 | },
463 | "mime-types": {
464 | "version": "2.1.19",
465 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz",
466 | "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==",
467 | "dev": true,
468 | "requires": {
469 | "mime-db": "~1.35.0"
470 | }
471 | },
472 | "minimatch": {
473 | "version": "3.0.4",
474 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
475 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
476 | "dev": true,
477 | "requires": {
478 | "brace-expansion": "^1.1.7"
479 | }
480 | },
481 | "minimist": {
482 | "version": "0.0.8",
483 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
484 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
485 | "dev": true
486 | },
487 | "mkdirp": {
488 | "version": "0.5.1",
489 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
490 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
491 | "dev": true,
492 | "requires": {
493 | "minimist": "0.0.8"
494 | }
495 | },
496 | "mocha": {
497 | "version": "5.2.0",
498 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
499 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
500 | "dev": true,
501 | "requires": {
502 | "browser-stdout": "1.3.1",
503 | "commander": "2.15.1",
504 | "debug": "3.1.0",
505 | "diff": "3.5.0",
506 | "escape-string-regexp": "1.0.5",
507 | "glob": "7.1.2",
508 | "growl": "1.10.5",
509 | "he": "1.1.1",
510 | "minimatch": "3.0.4",
511 | "mkdirp": "0.5.1",
512 | "supports-color": "5.4.0"
513 | }
514 | },
515 | "ms": {
516 | "version": "2.0.0",
517 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
518 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
519 | "dev": true
520 | },
521 | "oauth-sign": {
522 | "version": "0.8.2",
523 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
524 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
525 | "dev": true
526 | },
527 | "once": {
528 | "version": "1.4.0",
529 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
530 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
531 | "dev": true,
532 | "requires": {
533 | "wrappy": "1"
534 | }
535 | },
536 | "path-is-absolute": {
537 | "version": "1.0.1",
538 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
539 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
540 | "dev": true
541 | },
542 | "pathval": {
543 | "version": "1.1.0",
544 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
545 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
546 | "dev": true
547 | },
548 | "performance-now": {
549 | "version": "2.1.0",
550 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
551 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
552 | "dev": true
553 | },
554 | "punycode": {
555 | "version": "1.4.1",
556 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
557 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
558 | "dev": true
559 | },
560 | "q": {
561 | "version": "1.5.1",
562 | "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
563 | "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
564 | "dev": true
565 | },
566 | "qs": {
567 | "version": "6.5.2",
568 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
569 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
570 | "dev": true
571 | },
572 | "request": {
573 | "version": "2.87.0",
574 | "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
575 | "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
576 | "dev": true,
577 | "requires": {
578 | "aws-sign2": "~0.7.0",
579 | "aws4": "^1.6.0",
580 | "caseless": "~0.12.0",
581 | "combined-stream": "~1.0.5",
582 | "extend": "~3.0.1",
583 | "forever-agent": "~0.6.1",
584 | "form-data": "~2.3.1",
585 | "har-validator": "~5.0.3",
586 | "http-signature": "~1.2.0",
587 | "is-typedarray": "~1.0.0",
588 | "isstream": "~0.1.2",
589 | "json-stringify-safe": "~5.0.1",
590 | "mime-types": "~2.1.17",
591 | "oauth-sign": "~0.8.2",
592 | "performance-now": "^2.1.0",
593 | "qs": "~6.5.1",
594 | "safe-buffer": "^5.1.1",
595 | "tough-cookie": "~2.3.3",
596 | "tunnel-agent": "^0.6.0",
597 | "uuid": "^3.1.0"
598 | }
599 | },
600 | "request-debug": {
601 | "version": "0.2.0",
602 | "resolved": "https://registry.npmjs.org/request-debug/-/request-debug-0.2.0.tgz",
603 | "integrity": "sha1-/AVOyBcYGwTKQaBSwTb2HEirr3g=",
604 | "dev": true,
605 | "requires": {
606 | "stringify-clone": "^1.0.0"
607 | }
608 | },
609 | "safe-buffer": {
610 | "version": "5.1.2",
611 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
612 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
613 | "dev": true
614 | },
615 | "safer-buffer": {
616 | "version": "2.1.2",
617 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
618 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
619 | "dev": true
620 | },
621 | "sshpk": {
622 | "version": "1.14.2",
623 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
624 | "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
625 | "dev": true,
626 | "requires": {
627 | "asn1": "~0.2.3",
628 | "assert-plus": "^1.0.0",
629 | "bcrypt-pbkdf": "^1.0.0",
630 | "dashdash": "^1.12.0",
631 | "ecc-jsbn": "~0.1.1",
632 | "getpass": "^0.1.1",
633 | "jsbn": "~0.1.0",
634 | "safer-buffer": "^2.0.2",
635 | "tweetnacl": "~0.14.0"
636 | }
637 | },
638 | "stringify-clone": {
639 | "version": "1.1.1",
640 | "resolved": "https://registry.npmjs.org/stringify-clone/-/stringify-clone-1.1.1.tgz",
641 | "integrity": "sha1-MJojX7Ts/M19OI2+GLqQT6yvQzs=",
642 | "dev": true
643 | },
644 | "supports-color": {
645 | "version": "5.4.0",
646 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
647 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
648 | "dev": true,
649 | "requires": {
650 | "has-flag": "^3.0.0"
651 | }
652 | },
653 | "tough-cookie": {
654 | "version": "2.3.4",
655 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
656 | "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
657 | "dev": true,
658 | "requires": {
659 | "punycode": "^1.4.1"
660 | }
661 | },
662 | "tunnel-agent": {
663 | "version": "0.6.0",
664 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
665 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
666 | "dev": true,
667 | "requires": {
668 | "safe-buffer": "^5.0.1"
669 | }
670 | },
671 | "tv4": {
672 | "version": "1.3.0",
673 | "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz",
674 | "integrity": "sha1-0CDIRvrdUMhVq7JeuuzGj8EPeWM=",
675 | "dev": true
676 | },
677 | "tweetnacl": {
678 | "version": "0.14.5",
679 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
680 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
681 | "dev": true,
682 | "optional": true
683 | },
684 | "type-detect": {
685 | "version": "4.0.8",
686 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
687 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
688 | "dev": true
689 | },
690 | "uuid": {
691 | "version": "3.3.2",
692 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
693 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
694 | "dev": true
695 | },
696 | "verror": {
697 | "version": "1.10.0",
698 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
699 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
700 | "dev": true,
701 | "requires": {
702 | "assert-plus": "^1.0.0",
703 | "core-util-is": "1.0.2",
704 | "extsprintf": "^1.2.0"
705 | }
706 | },
707 | "wrappy": {
708 | "version": "1.0.2",
709 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
710 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
711 | "dev": true
712 | }
713 | }
714 | }
715 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "polyfill-io-feature-detection",
3 | "version": "1.1.14",
4 | "description": "Feature detection in the browser before loading polyfill using services like polyfill.io",
5 | "license": "MIT",
6 | "main": "index.js",
7 | "author": "Jose Quinto (https://blog.josequinto.com)",
8 | "scripts": {
9 | "pretest": "npm install",
10 | "test": "mocha test/node/detectBrowserUnsupportedFeatures.test.js",
11 | "pretestLoaders": "npm install",
12 | "testLoader": "mocha test/node/polyfillLoader.test.js"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/jquintozamora/polyfill-io-feature-detection"
17 | },
18 | "keywords": [
19 | "polyfill.io",
20 | "feature",
21 | "detection",
22 | "polyfill",
23 | "detect",
24 | "pre-detect",
25 | "supported",
26 | "browser"
27 | ],
28 | "devDependencies": {
29 | "chai": "4.1.2",
30 | "chakram": "1.5.0",
31 | "mocha": "5.2.0"
32 | },
33 | "dependencies": {}
34 | }
35 |
--------------------------------------------------------------------------------
/test/browser/sample.test.js:
--------------------------------------------------------------------------------
1 |
2 | var assert = chai.assert;
3 |
4 | describe('Array', function() {
5 | it('should start empty', function() {
6 | var arr = [];
7 |
8 | assert.equal(arr.length, 0);
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/test/browser/testRunner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mocha Tests
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
--------------------------------------------------------------------------------
/test/node/detectBrowserUnsupportedFeatures.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | Unit Tests for detectBrowserUnsupportedFeatures function
3 | */
4 |
5 | 'use strict';
6 | var expect = require('chai').expect;
7 | var polyfillLoader = require('./../../index.js');
8 |
9 | describe('Browser Feature detection Tests for IE 11', function () {
10 | var warn, warnOutput = '';
11 |
12 | before(function () {
13 | // runs before all tests in this block
14 | // Import IE11 window configs.
15 | window = require('./../utils/IE11.Config').configs();
16 | });
17 |
18 | // mocking or stubbing console is not needed, we could use this: https://github.com/mochajs/mocha/wiki/Mess-with-globals
19 | // restore console.warn
20 | var cleanup = function () {
21 | console.warn = warn;
22 | warnOutput = "";
23 | };
24 | beforeEach(function () {
25 | // store these functions to restore later because we are messing with them
26 | warn = console.warn;
27 | // our stub will concatenate any output to a string
28 | console.warn = function (s) {
29 | warnOutput += s;
30 | };
31 | });
32 | // restore after each test
33 | afterEach(cleanup);
34 |
35 | it('should detect Promise as unsupported feature', function () {
36 | var features = "Promise";
37 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq(["Promise"]);
38 | });
39 |
40 | it('should detect Array.isArray as supported feature', function () {
41 | var features = "Array.isArray";
42 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq([]);
43 | });
44 |
45 | it('should strip out more than one supported features', function () {
46 | var features = "Array.isArray,Date.now,Element.prototype.dataset,Object.defineProperties";
47 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq([]);
48 | });
49 |
50 | it('should return more than one unsupported features', function () {
51 | var features = "Array.from,Array.prototype.fill,AudioContext,Promise,Element.prototype.append,Math.trunc,Object.is,Symbol.iterator";
52 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq(["Array.from",
53 | "Array.prototype.fill",
54 | "AudioContext",
55 | "Promise",
56 | "Element.prototype.append",
57 | "Math.trunc",
58 | "Object.is",
59 | "Symbol.iterator"]);
60 | try {
61 | expect(warnOutput).to.equal('[getDescendantProp] - Symbol property does not exists.');
62 | }
63 | catch (e) {
64 | cleanup();
65 | throw e;
66 | }
67 | });
68 |
69 | it('should warn when not object exists getting the descendants of a complex object', function () {
70 | var features = "Symbol.iterator";
71 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq(["Symbol.iterator"]);
72 | try {
73 | expect(warnOutput).to.equal('[getDescendantProp] - Symbol property does not exists.');
74 | }
75 | catch (e) {
76 | cleanup();
77 | throw e;
78 | }
79 | });
80 |
81 |
82 | it('should warn when a feature can not be detected because has not JavaScript API', function () {
83 | var features = "~html5-elements";
84 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq([]);
85 | try {
86 | expect(warnOutput).to.equal('Feature ~html5-elements can not be detected because it has not JavaScript API.');
87 | }
88 | catch (e) {
89 | cleanup();
90 | throw e;
91 | }
92 | });
93 |
94 |
95 | it('should warn when a feature can not be detected because has not JavaScript API, but still detect other unsupported features', function () {
96 | var features = "Promise,~html5-elements";
97 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq(["Promise"]);
98 | try {
99 | expect(warnOutput).to.equal('Feature ~html5-elements can not be detected because it has not JavaScript API.');
100 | }
101 | catch (e) {
102 | cleanup();
103 | throw e;
104 | }
105 | });
106 |
107 |
108 | it('should warn when a feature can not be detected because it depends on Symbol', function () {
109 | var features = "Array.prototype.@@iterator";
110 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq([]);
111 | try {
112 | expect(warnOutput).to.equal('Feature @@iterator can not be detected because it depends on Symbol.');
113 | }
114 | catch (e) {
115 | cleanup();
116 | throw e;
117 | }
118 | });
119 |
120 |
121 | it('should warn when a feature can not be detected because it depends on Symbol, but still detect other unsupported features', function () {
122 | var features = "Promise,Array.prototype.@@iterator";
123 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq(["Promise"]);
124 | try {
125 | expect(warnOutput).to.equal('Feature @@iterator can not be detected because it depends on Symbol.');
126 | }
127 | catch (e) {
128 | cleanup();
129 | throw e;
130 | }
131 | });
132 |
133 |
134 | it('should add any random string as a unsupported feature. TODO: To check features in the list of available polyfills.', function () {
135 | // Available polyfills: https://github.com/Financial-Times/polyfill-service/blob/master/docs/assets/compat.json
136 | var features = "ramdom-String=+£$";
137 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq(["ramdom-String=+£$"]);
138 | // Note that polyfill.io service will bring empty file when request the feature ramdom-String=+£$
139 | });
140 |
141 | it('should detect Intl.~locale.en-US as unsupported feature.', function () {
142 | // Available polyfills: https://github.com/Financial-Times/polyfill-service/blob/master/docs/assets/compat.json
143 | var features = "Intl.~locale.en-US";
144 | expect(polyfillLoader.detectBrowserUnsupportedFeatures(features)).to.be.deep.eq(["Intl.~locale.en-US"]);
145 | });
146 |
147 |
148 |
149 | });
150 |
--------------------------------------------------------------------------------
/test/node/polyfillLoader.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | Unit Tests for polyfillLoader function
3 | */
4 |
5 | 'use strict';
6 | var expect = require('chai').expect;
7 | var pf = require('./../../index.js');
8 | var chakram = require('chakram');
9 |
10 | describe('Polyfill Loader Tests for IE 11', function () {
11 |
12 | before(function () {
13 | // runs before all tests in this block
14 | // Import IE11 window configs.
15 | window = require('./../utils/IE11.Config').configs();
16 |
17 | global.document = {};
18 | document.createElement = function (tag) { return { src: "", onload: function () { }, onerror: function () { } }; };
19 | document.head = {};
20 | document.head.appendChild = function (obj) {
21 | setTimeout(function () {
22 | if (obj.src.indexOf("https://error") > -1) {
23 | obj.onerror();
24 | } else {
25 | if (obj.onload) {
26 | obj.onload();
27 | } else {
28 | obj.onerror();
29 | }
30 | }
31 | }, 500);
32 | };
33 | });
34 |
35 |
36 | it('should call main with the polyfill url as a parameter', function (done) {
37 | var features = "Promise,fetch,Object.is";
38 | function main(data) {
39 | expect(data).to.eq("https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise,fetch,Object.is&flags=gated,always");
40 | // this test is done, go to the next one
41 | done();
42 | }
43 | pf.polyfillLoader({
44 | "onCompleted": main,
45 | "features": features
46 | });
47 | });
48 |
49 |
50 | it('should call main with the polyfill url as a parameter filtered by only not supported features', function (done) {
51 | var features = "Promise,Date.now";
52 | function main(data) {
53 | expect(data).to.eq("https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise&flags=gated,always");
54 | // this test is done, go to the next one
55 | done();
56 | }
57 | pf.polyfillLoader({
58 | "onCompleted": main,
59 | "features": features
60 | });
61 | });
62 |
63 | it('should call main with no parameters as all the features are supported by the browser', function (done) {
64 | var features = "Array.prototype.filter,Date.now";
65 | function main(data) {
66 | expect(data).to.eq(undefined);
67 | // this test is done, go to the next one
68 | done();
69 | }
70 | pf.polyfillLoader({
71 | "onCompleted": main,
72 | "features": features
73 | });
74 | });
75 |
76 | it('should call my custom service if configured as parameter polyfillService', function (done) {
77 | var features = "Promise";
78 | function main(data) {
79 | expect(data).to.eq('https://myservice?features=Promise&flags=gated,always');
80 | // this test is done, go to the next one
81 | done();
82 | }
83 | pf.polyfillLoader({
84 | "onCompleted": main,
85 | "features": features,
86 | "polyfillService": "https://myservice"
87 | });
88 | });
89 |
90 | it('should call main with error parameter when failed to load the script', function (done) {
91 | var features = "Promise";
92 | function main(data) {
93 | expect(data.toString()).to.eq((new Error('Failed to load script https://error?features=Promise&flags=gated,always')).toString());
94 | // this test is done, go to the next one
95 | done();
96 | }
97 | pf.polyfillLoader({
98 | "onCompleted": main,
99 | "features": features,
100 | "polyfillService": "https://error"
101 | });
102 | });
103 |
104 |
105 | it("should have polyfill.io service enable on default and returning 200 status", function (done) {
106 | // this.timeout(5000);
107 | var features = "Promise,Date.now";
108 | function main(data) {
109 | expect(data).to.eq("https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise&flags=gated,always");
110 | var Ie11UA = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko";
111 | return chakram.get(data + "&ua=" + encodeURIComponent(Ie11UA))
112 | .then(function (response) {
113 | chakram.expect(response).to.have.status(200);
114 | done();
115 | });
116 | }
117 | pf.polyfillLoader({
118 | "onCompleted": main,
119 | "features": features
120 | });
121 | });
122 |
123 | });
124 |
--------------------------------------------------------------------------------
/test/utils/IE11.Config.js:
--------------------------------------------------------------------------------
1 | // Testing Configuration for IE 11
2 | // Source: https://polyfill.io/v2/docs/features/#feature-list
3 | // TODO: Add support to iterators
4 |
5 | exports.configs = function () {
6 | window = {};
7 | window.Array = {};
8 | //window.Array.from = function () { };
9 | window.Array.isArray = function () { };
10 | //window.Array.of = function () { };
11 | //window.Array.prototype.@@iterator = function() {}; // no
12 | window.Array.prototype = {};
13 | //window.Array.prototype.contains = function () { };
14 | //window.Array.prototype.entries = function () { };
15 | window.Array.prototype.every = function () { };
16 | //window.Array.prototype.fill = function () { };
17 | window.Array.prototype.filter = function () { };
18 | //window.Array.prototype.find = function () { };
19 | //window.Array.prototype.findIndex = function () { };
20 | window.Array.prototype.forEach = function () { };
21 | //window.Array.prototype.includes = function () { };
22 | window.Array.prototype.indexOf = function () { };
23 | //window.Array.prototype.keys = function () { };
24 | window.Array.prototype.lastIndexOf = function () { };
25 | window.Array.prototype.map = function () { };
26 | window.Array.prototype.reduce = function () { };
27 | window.Array.prototype.reduceRight = function () { };
28 | window.Array.prototype.some = function () { };
29 | //window.Array.prototype.values = function () { };
30 | //window.AudioContext = function () { };
31 | //window.CustomEvent = function () { };
32 | //window.DOMTokenList = function () { };
33 | //window.DOMTokenList.prototype.@@iterator = function() {};
34 | window.Date = {};
35 | window.Date.now = function () { };
36 | window.Date.prototype = {};
37 | window.Date.prototype.toISOString = function () { };
38 | window.Document = function () { };
39 | window.Element = function () { };
40 | //window.Element.prototype.after = function () { };
41 | //window.Element.prototype.append = function () { };
42 | //window.Element.prototype.before = function () { };
43 | //window.Element.prototype.classList = function () { };
44 | //window.Element.prototype.cloneNode = function () { };
45 | //window.Element.prototype.closest = function () { };
46 | window.Element.prototype.dataset = function () { };
47 | //window.Element.prototype.matches = function () { };
48 | window.Element.prototype.placeholder = function () { };
49 | //window.Element.prototype.prepend = function () { };
50 | //window.Element.prototype.remove = function () { };
51 | //window.Element.prototype.replaceWith = function () { };
52 | window.Event = function () { };
53 | window.Event.focusin = function () { };
54 | window.Event.hashchange = function () { };
55 | window.Function = {};
56 | //window.Function.name = function () { };
57 | window.Function.prototype = {};
58 | window.Function.prototype.bind = function () { };
59 | //window.HTMLCanvasElement = {};
60 | //window.HTMLCanvasElement.protoype = {};
61 | //window.HTMLCanvasElement.protoype.toBlob = function () { };
62 | window.HTMLDocument = function () { };
63 | //window.HTMLPictureElement = function () { };
64 | //window.IntersectionObserver = function () { };
65 | window.Intl = function () { };
66 | window.Intl.Collator = function () { };
67 | window.Intl.DateTimeFormat = function () { };
68 | window.Intl.NumberFormat = function () { };
69 | window.Intl.Collator.supportedLocalesOf = function (a) { return [] };
70 | window.Intl.DateTimeFormat.supportedLocalesOf = function (a) { return []; };
71 | window.Intl.NumberFormat.supportedLocalesOf = function (a) { return []; };
72 |
73 | window.JSON = function () { };
74 | //window.Map = function () { };
75 | window.Math = {};
76 | //window.Math.acosh = function () { };
77 | //window.Math.asinh = function () { };
78 | //window.Math.atanh = function () { };
79 | //window.Math.cbrt = function () { };
80 | //window.Math.clz32 = function () { };
81 | //window.Math.cosh = function () { };
82 | //window.Math.expm1 = function () { };
83 | //window.Math.hypot = function () { };
84 | //window.Math.imul = function () { };
85 | //window.Math.log10 = function () { };
86 | //window.Math.log1p = function () { };
87 | //window.Math.log2 = function () { };
88 | //window.Math.sign = function () { };
89 | //window.Math.sinh = function () { };
90 | //window.Math.tanh = function () { };
91 | //window.Math.trunc = function () { };
92 | window.Node = {};
93 | window.Node.prototype = {};
94 | //window.Node.prototype.contains = function () { };
95 | //window.NodeList.prototype.@@iterator = function() {}; // no
96 | //window.Number = {};
97 | //window.Number.MAX_SAFE_INTEGER = function () { };
98 | //window.Number.MIN_SAFE_INTEGER = function () { };
99 | //window.Number.isFinite = function () { };
100 | //window.Number.isInteger = function () { };
101 | //window.Number.isNaN = function () { };
102 | window.Object = {};
103 | //window.Object.assign = function () { };
104 | window.Object.create = function () { };
105 | window.Object.defineProperties = function () { };
106 | window.Object.defineProperty = function () { };
107 | window.Object.getOwnPropertyDescriptor = function () { };
108 | window.Object.getOwnPropertyNames = function () { };
109 | window.Object.getPrototypeOf = function () { };
110 | //window.Object.is = function () { };
111 | window.Object.keys = function () { };
112 | window.Object.setPrototypeOf = function () { };
113 | //window.Promise = function () { };
114 | //window.Set = function () { };
115 | window.String = {};
116 | window.String.prototype = {};
117 | //window.String.prototype.contains = function () { };
118 | //window.String.prototype.endsWith = function () { };
119 | //window.String.prototype.includes = function () { };
120 | //window.String.prototype.repeat = function () { };
121 | //window.String.prototype.startsWith = function () { };
122 | window.String.prototype.trim = function () { };
123 | // window.Symbol = function () { };
124 | // window.Symbol.hasInstance = function () { };
125 | // window.Symbol.isConcatSpreadable = function () { };
126 | // window.Symbol.iterator = function () { };
127 | // window.Symbol.match = function () { };
128 | // window.Symbol.replace = function () { };
129 | // window.Symbol.search = function () { };
130 | // window.Symbol.species = function () { };
131 | // window.Symbol.split = function () { };
132 | // window.Symbol.toPrimitive = function () { };
133 | // window.Symbol.toStringTag = function () { };
134 | // window.Symbol.unscopables = function () { };
135 | //window.URL = function () { };
136 | //window.UserTiming = function () { };
137 | //window.WeakMap = function () { };
138 | //window.WeakSet = function () { };
139 | window.XMLHttpRequest = function () { };
140 | window.atob = function () { };
141 | window.console = function () { };
142 | window.console.assert = function () { };
143 | window.console.clear = function () { };
144 | window.console.count = function () { };
145 | window.console.debug = function () { };
146 | window.console.dir = function () { };
147 | window.console.dirxml = function () { };
148 | window.console.error = function () { };
149 | //window.console.exception = function () { };
150 | window.console.group = function () { };
151 | window.console.groupCollapsed = function () { };
152 | window.console.groupEnd = function () { };
153 | window.console.info = function () { };
154 | window.console.log = function () { };
155 | //window.console.markTimeline = function () { };
156 | //window.console.table = function () { };
157 | window.console.time = function () { };
158 | window.console.timeEnd = function () { };
159 | //window.console.timeStamp = function () { };
160 | //window.console.timeline = function () { };
161 | //window.console.timelineEnd = function () { };
162 | window.console.trace = function () { };
163 | window.console.warn = function () { };
164 | window.devicePixelRatio = function () { };
165 | window.document = {};
166 | //window.document.currentScript = function () { };
167 | window.document.getElementsByClassName = function () { };
168 | window.document.head = function () { };
169 | window.document.querySelector = function () { };
170 | window.document.visibilityState = function () { };
171 | //window.fetch = function () { };
172 | window.getComputedStyle = function () { };
173 | window.localStorage = function () { };
174 | window.location = {};
175 | window.location.origin = function () { };
176 | window.matchMedia = function () { };
177 | window.navigator = {};
178 | window.navigator.geolocation = function () { };
179 | //window.navigator.sendBeacon = function () { };
180 | window.performance = {};
181 | window.performance.now = function () { };
182 | window.requestAnimationFrame = function () { };
183 | window.screen = {};
184 | //window.screen.orientation = function () { };
185 | window.setImmediate = function () { };
186 | //window.~html5-elements = function() {}; // yes
187 | //window.~viewport = function() {}; // no
188 |
189 | return window;
190 | }
--------------------------------------------------------------------------------
/test/utils/base.Config.js:
--------------------------------------------------------------------------------
1 | // Testing Configuration Template
2 | // Source: https://polyfill.io/v2/docs/features/#feature-list
3 | // TODO: Add support to iterators
4 |
5 | exports.configs = function () {
6 | window = {};
7 | window.Array = {};
8 | window.Array.from = function () { };
9 | window.Array.isArray = function () { };
10 | window.Array.of = function () { };
11 | //window.Array.prototype.@@iterator = function() {};
12 | window.Array.prototype = {};
13 | window.Array.prototype.contains = function () { };
14 | window.Array.prototype.entries = function () { };
15 | window.Array.prototype.every = function () { };
16 | window.Array.prototype.fill = function () { };
17 | window.Array.prototype.filter = function () { };
18 | window.Array.prototype.find = function () { };
19 | window.Array.prototype.findIndex = function () { };
20 | window.Array.prototype.forEach = function () { };
21 | window.Array.prototype.includes = function () { };
22 | window.Array.prototype.indexOf = function () { };
23 | window.Array.prototype.keys = function () { };
24 | window.Array.prototype.lastIndexOf = function () { };
25 | window.Array.prototype.map = function () { };
26 | window.Array.prototype.reduce = function () { };
27 | window.Array.prototype.reduceRight = function () { };
28 | window.Array.prototype.some = function () { };
29 | window.Array.prototype.values = function () { };
30 | window.AudioContext = function () { };
31 | window.CustomEvent = function () { };
32 | window.DOMTokenList = function () { };
33 | //window.DOMTokenList.prototype.@@iterator = function() {};
34 | window.Date = {};
35 | window.Date.now = function () { };
36 | window.Date.prototype = {};
37 | window.Date.prototype.toISOString = function () { };
38 | window.Document = function () { };
39 | window.Element = function () { };
40 | window.Element.prototype.after = function () { };
41 | window.Element.prototype.append = function () { };
42 | window.Element.prototype.before = function () { };
43 | window.Element.prototype.classList = function () { };
44 | window.Element.prototype.cloneNode = function () { };
45 | window.Element.prototype.closest = function () { };
46 | window.Element.prototype.dataset = function () { };
47 | window.Element.prototype.matches = function () { };
48 | window.Element.prototype.placeholder = function () { };
49 | window.Element.prototype.prepend = function () { };
50 | window.Element.prototype.remove = function () { };
51 | window.Element.prototype.replaceWith = function () { };
52 | window.Event = function () { };
53 | window.Event.focusin = function () { };
54 | window.Event.hashchange = function () { };
55 | window.Function = {};
56 | window.Function.name = function () { };
57 | window.Function.prototype = {};
58 | window.Function.prototype.bind = function () { };
59 | window.HTMLCanvasElement = {};
60 | window.HTMLCanvasElement.protoype = {};
61 | window.HTMLCanvasElement.protoype.toBlob = function () { };
62 | window.HTMLDocument = function () { };
63 | window.HTMLPictureElement = function () { };
64 | window.IntersectionObserver = function () { };
65 | window.Intl = function () { };
66 | window.Intl.Collator = function () { };
67 | window.Intl.DateTimeFormat = function () { };
68 | window.Intl.NumberFormat = function () { };
69 | window.Intl.Collator.supportedLocalesOf = function (a) { return [] };
70 | window.Intl.DateTimeFormat.supportedLocalesOf = function (a) { return []; };
71 | window.Intl.NumberFormat.supportedLocalesOf = function (a) { return []; };
72 | window.JSON = function () { };
73 | window.Map = function () { };
74 | window.Math = {};
75 | window.Math.acosh = function () { };
76 | window.Math.asinh = function () { };
77 | window.Math.atanh = function () { };
78 | window.Math.cbrt = function () { };
79 | window.Math.clz32 = function () { };
80 | window.Math.cosh = function () { };
81 | window.Math.expm1 = function () { };
82 | window.Math.hypot = function () { };
83 | window.Math.imul = function () { };
84 | window.Math.log10 = function () { };
85 | window.Math.log1p = function () { };
86 | window.Math.log2 = function () { };
87 | window.Math.sign = function () { };
88 | window.Math.sinh = function () { };
89 | window.Math.tanh = function () { };
90 | window.Math.trunc = function () { };
91 | window.Node = {};
92 | window.Node.prototype = {};
93 | window.Node.prototype.contains = function () { };
94 | //window.NodeList.prototype.@@iterator = function() {};
95 | window.Number = {};
96 | window.Number.MAX_SAFE_INTEGER = function () { };
97 | window.Number.MIN_SAFE_INTEGER = function () { };
98 | window.Number.isFinite = function () { };
99 | window.Number.isInteger = function () { };
100 | window.Number.isNaN = function () { };
101 | window.Object = {};
102 | window.Object.assign = function () { };
103 | window.Object.create = function () { };
104 | window.Object.defineProperties = function () { };
105 | window.Object.defineProperty = function () { };
106 | window.Object.getOwnPropertyDescriptor = function () { };
107 | window.Object.getOwnPropertyNames = function () { };
108 | window.Object.getPrototypeOf = function () { };
109 | window.Object.is = function () { };
110 | window.Object.keys = function () { };
111 | window.Object.setPrototypeOf = function () { };
112 | window.Promise = function () { };
113 | window.Set = function () { };
114 | window.String = {};
115 | window.String.prototype = {};
116 | window.String.prototype.contains = function () { };
117 | window.String.prototype.endsWith = function () { };
118 | window.String.prototype.includes = function () { };
119 | window.String.prototype.repeat = function () { };
120 | window.String.prototype.startsWith = function () { };
121 | window.String.prototype.trim = function () { };
122 | window.Symbol = function () { };
123 | window.Symbol.hasInstance = function () { };
124 | window.Symbol.isConcatSpreadable = function () { };
125 | window.Symbol.iterator = function () { };
126 | window.Symbol.match = function () { };
127 | window.Symbol.replace = function () { };
128 | window.Symbol.search = function () { };
129 | window.Symbol.species = function () { };
130 | window.Symbol.split = function () { };
131 | window.Symbol.toPrimitive = function () { };
132 | window.Symbol.toStringTag = function () { };
133 | window.Symbol.unscopables = function () { };
134 | window.URL = function () { };
135 | window.UserTiming = function () { };
136 | window.WeakMap = function () { };
137 | window.WeakSet = function () { };
138 | window.XMLHttpRequest = function () { };
139 | window.atob = function () { };
140 | window.console = function () { };
141 | window.console.assert = function () { };
142 | window.console.clear = function () { };
143 | window.console.count = function () { };
144 | window.console.debug = function () { };
145 | window.console.dir = function () { };
146 | window.console.dirxml = function () { };
147 | window.console.error = function () { };
148 | window.console.exception = function () { };
149 | window.console.group = function () { };
150 | window.console.groupCollapsed = function () { };
151 | window.console.groupEnd = function () { };
152 | window.console.info = function () { };
153 | window.console.log = function () { };
154 | window.console.markTimeline = function () { };
155 | window.console.table = function () { };
156 | window.console.time = function () { };
157 | window.console.timeEnd = function () { };
158 | window.console.timeStamp = function () { };
159 | window.console.timeline = function () { };
160 | window.console.timelineEnd = function () { };
161 | window.console.trace = function () { };
162 | window.console.warn = function () { };
163 | window.devicePixelRatio = function () { };
164 | window.document = {};
165 | window.document.currentScript = function () { };
166 | window.document.getElementsByClassName = function () { };
167 | window.document.head = function () { };
168 | window.document.querySelector = function () { };
169 | window.document.visibilityState = function () { };
170 | window.fetch = function () { };
171 | window.getComputedStyle = function () { };
172 | window.localStorage = function () { };
173 | window.location = {};
174 | window.location.origin = function () { };
175 | window.matchMedia = function () { };
176 | window.navigator = {};
177 | window.navigator.geolocation = function () { };
178 | window.navigator.sendBeacon = function () { };
179 | window.performance = {};
180 | window.performance.now = function () { };
181 | window.requestAnimationFrame = function () { };
182 | window.screen = {};
183 | window.screen.orientation = function () { };
184 | window.setImmediate = function () { };
185 | //window.~html5-elements = function() {};
186 | //window.~viewport = function() {};
187 |
188 | return window;
189 | }
--------------------------------------------------------------------------------