pax_global_header00006660000000000000000000000064145746237340014531gustar00rootroot0000000000000052 comment=35a517c5861d79dc8bff7db8626013d20b711b06 follow-redirects-1.15.6/000077500000000000000000000000001457462373400151075ustar00rootroot00000000000000follow-redirects-1.15.6/.editorconfig000066400000000000000000000001431457462373400175620ustar00rootroot00000000000000root = true [*] indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true follow-redirects-1.15.6/.eslintrc000066400000000000000000000134531457462373400167410ustar00rootroot00000000000000{ extends: "eslint:recommended", env: { node: true, es6: true }, rules: { // Best Practices accessor-pairs: "error", array-callback-return: "error", block-scoped-var: "error", class-methods-use-this: "error", complexity: "off", consistent-return: "error", curly: "error", default-case: "error", dot-location: ["error", "property"], dot-notation: "error", eqeqeq: "error", guard-for-in: "error", no-alert: "error", no-caller: "error", no-case-declarations: "error", no-div-regex: "error", no-else-return: "error", no-empty-function: "error", no-empty-pattern: "error", no-eq-null: "error", no-eval: "error", no-extend-native: "error", no-extra-bind: "error", no-extra-label: "error", no-fallthrough: "error", no-floating-decimal: "error", no-global-assign: "error", no-implicit-coercion: "error", no-implicit-globals: "error", no-implied-eval: "error", no-invalid-this: "error", no-iterator: "error", no-labels: "error", no-lone-blocks: "error", no-loop-func: "error", no-magic-numbers: "off", no-multi-spaces: "error", no-multi-str: "error", no-new: "error", no-new-func: "error", no-new-wrappers: "error", no-octal: "error", no-octal-escape: "error", no-param-reassign: "off", no-proto: "error", no-redeclare: "error", no-restricted-properties: "error", no-return-assign: "error", no-return-await: "error", no-script-url: "error", no-self-assign: "error", no-self-compare: "error", no-sequences: "error", no-throw-literal: "error", no-unmodified-loop-condition: "error", no-unused-expressions: "error", no-unused-labels: "error", no-useless-call: "error", no-useless-concat: "error", no-useless-escape: "error", no-useless-return: "error", no-void: "error", no-warning-comments: "error", no-with: "error", prefer-promise-reject-errors: "error", radix: "error", require-await: "error", vars-on-top: "off", wrap-iife: "error", // Strict Mode strict: ["error", "never"], // Variables init-declarations: "off", no-catch-shadow: "error", no-delete-var: "error", no-label-var: "error", no-restricted-globals: "error", no-shadow: "error", no-shadow-restricted-names: "error", no-undef: "error", no-undef-init: "error", no-undefined: "off", no-unused-vars: "error", no-use-before-define: ["error", { "functions": false }], // Node.js callback-return: "off", global-require: "error", handle-callback-err: "error", no-buffer-constructor: "error", no-mixed-requires: "error", no-new-require: "error", no-path-concat: "error", no-process-env: "error", no-process-exit: "error", no-restricted-modules: "error", no-sync: "error", // Stylistic Issues array-bracket-newline: "error", array-bracket-spacing: "error", array-element-newline: "off", block-spacing: "error", brace-style: ["error", "stroustrup", { allowSingleLine: true }], camelcase: "error", capitalized-comments: "off", comma-dangle: ["error", "always-multiline"], comma-spacing: "error", comma-style: "error", computed-property-spacing: "error", consistent-this: ["error", "self"], eol-last: "error", func-call-spacing: "error", func-name-matching: "error", func-names: "off", func-style: ["error", "declaration"], function-paren-newline: "error", id-blacklist: "error", id-length: "off", id-match: "error", implicit-arrow-linebreak: "error", indent: ["error", 2], jsx-quotes: "error", key-spacing: "error", keyword-spacing: "error", line-comment-position: "off", linebreak-style: "error", lines-around-comment: "error", lines-between-class-members: "error", max-depth: "error", max-len: "off", max-lines: "off", max-nested-callbacks: "error", max-params: "error", max-statements: "off", max-statements-per-line: "error", multiline-comment-style: ["error", "separate-lines"], multiline-ternary: "off", new-cap: "error", new-parens: "error", newline-per-chained-call: "off", no-array-constructor: "error", no-bitwise: "error", no-continue: "error", no-inline-comments: "off", no-lonely-if: "error", no-mixed-operators: "off", no-mixed-spaces-and-tabs: "error", no-multi-assign: "off", no-multiple-empty-lines: "error", no-negated-condition: "off", no-nested-ternary: "error", no-new-object: "error", no-plusplus: "off", no-restricted-syntax: "error", no-tabs: "error", no-ternary: "off", no-trailing-spaces: "error", no-underscore-dangle: "off", no-unneeded-ternary: "error", no-whitespace-before-property: "error", nonblock-statement-body-position: "error", object-curly-newline: "off", object-curly-spacing: ["error", "always"], object-property-newline: "off", one-var: "off", one-var-declaration-per-line: "error", operator-assignment: "error", operator-linebreak: ["error", "after", { overrides: { ":": "after" } }], padded-blocks: ["error", "never"], padding-line-between-statements: "error", quote-props: ["error", "consistent-as-needed"], quotes: "error", require-jsdoc: "off", semi: "error", semi-spacing: "error", semi-style: "error", sort-keys: "off", sort-vars: "error", space-before-blocks: "error", space-before-function-paren: ["error", {"anonymous": "always", "named": "never"}], space-in-parens: "error", space-infix-ops: "error", space-unary-ops: "error", spaced-comment: "error", switch-colon-spacing: "error", template-tag-spacing: "error", unicode-bom: "error", wrap-regex: "off", }, } follow-redirects-1.15.6/.github/000077500000000000000000000000001457462373400164475ustar00rootroot00000000000000follow-redirects-1.15.6/.github/FUNDING.yml000066400000000000000000000000261457462373400202620ustar00rootroot00000000000000github: RubenVerborgh follow-redirects-1.15.6/.github/workflows/000077500000000000000000000000001457462373400205045ustar00rootroot00000000000000follow-redirects-1.15.6/.github/workflows/ci.yml000066400000000000000000000030421457462373400216210ustar00rootroot00000000000000name: CI on: push: branches: - main pull_request: branches: - main permissions: contents: read jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/setup-node@v3 with: node-version: '18.0' - uses: actions/checkout@v4 - run: npm ci - run: npm run lint test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: node-version: - '4.x' - '6.x' - '7.x' - '8.x' - '9.x' - '10.0' - '10.x' - '11.0' - '11.x' - '12.0' - '12.x' - '13.0' - '13.x' - '14.0' - '14.x' - '15.0' - '15.x' - '16.0' - '16.x' - '17.0' - '17.x' - '18.0' - '18.x' steps: - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - uses: actions/checkout@v4 - run: npm install - if: ${{ matrix.node-version == '4.x' }} run: npm install mocha@5.0.0 nyc@11.8.0 - run: npm test - run: node_modules/.bin/nyc --reporter=text-lcov node_modules/.bin/mocha | tee lcov.info - uses: coverallsapp/github-action@master if: ${{ matrix.node-version == '18.0' }} with: github-token: ${{ secrets.github_token }} flag-name: run-${{ matrix.node-version }} path-to-lcov: lcov.info follow-redirects-1.15.6/.gitignore000066400000000000000000000000311457462373400170710ustar00rootroot00000000000000.nyc_output node_modules follow-redirects-1.15.6/.nycrc000066400000000000000000000000621457462373400162240ustar00rootroot00000000000000{ "exclude": [ "test", "debug.js" ] } follow-redirects-1.15.6/LICENSE000066400000000000000000000021601457462373400161130ustar00rootroot00000000000000Copyright 2014–present Olivier Lalonde , James Talmage , Ruben Verborgh 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: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 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. follow-redirects-1.15.6/README.md000066400000000000000000000144701457462373400163740ustar00rootroot00000000000000## Follow Redirects Drop-in replacement for Node's `http` and `https` modules that automatically follows redirects. [![npm version](https://img.shields.io/npm/v/follow-redirects.svg)](https://www.npmjs.com/package/follow-redirects) [![Build Status](https://github.com/follow-redirects/follow-redirects/workflows/CI/badge.svg)](https://github.com/follow-redirects/follow-redirects/actions) [![Coverage Status](https://coveralls.io/repos/follow-redirects/follow-redirects/badge.svg?branch=master)](https://coveralls.io/r/follow-redirects/follow-redirects?branch=master) [![npm downloads](https://img.shields.io/npm/dm/follow-redirects.svg)](https://www.npmjs.com/package/follow-redirects) [![Sponsor on GitHub](https://img.shields.io/static/v1?label=Sponsor&message=%F0%9F%92%96&logo=GitHub)](https://github.com/sponsors/RubenVerborgh) `follow-redirects` provides [request](https://nodejs.org/api/http.html#http_http_request_options_callback) and [get](https://nodejs.org/api/http.html#http_http_get_options_callback) methods that behave identically to those found on the native [http](https://nodejs.org/api/http.html#http_http_request_options_callback) and [https](https://nodejs.org/api/https.html#https_https_request_options_callback) modules, with the exception that they will seamlessly follow redirects. ```javascript const { http, https } = require('follow-redirects'); http.get('http://bit.ly/900913', response => { response.on('data', chunk => { console.log(chunk); }); }).on('error', err => { console.error(err); }); ``` You can inspect the final redirected URL through the `responseUrl` property on the `response`. If no redirection happened, `responseUrl` is the original request URL. ```javascript const request = https.request({ host: 'bitly.com', path: '/UHfDGO', }, response => { console.log(response.responseUrl); // 'http://duckduckgo.com/robots.txt' }); request.end(); ``` ## Options ### Global options Global options are set directly on the `follow-redirects` module: ```javascript const followRedirects = require('follow-redirects'); followRedirects.maxRedirects = 10; followRedirects.maxBodyLength = 20 * 1024 * 1024; // 20 MB ``` The following global options are supported: - `maxRedirects` (default: `21`) – sets the maximum number of allowed redirects; if exceeded, an error will be emitted. - `maxBodyLength` (default: 10MB) – sets the maximum size of the request body; if exceeded, an error will be emitted. ### Per-request options Per-request options are set by passing an `options` object: ```javascript const url = require('url'); const { http, https } = require('follow-redirects'); const options = url.parse('http://bit.ly/900913'); options.maxRedirects = 10; options.beforeRedirect = (options, response, request) => { // Use this to adjust the request options upon redirecting, // to inspect the latest response headers, // or to cancel the request by throwing an error // response.headers = the redirect response headers // response.statusCode = the redirect response code (eg. 301, 307, etc.) // request.url = the requested URL that resulted in a redirect // request.headers = the headers in the request that resulted in a redirect // request.method = the method of the request that resulted in a redirect if (options.hostname === "example.com") { options.auth = "user:password"; } }; http.request(options); ``` In addition to the [standard HTTP](https://nodejs.org/api/http.html#http_http_request_options_callback) and [HTTPS options](https://nodejs.org/api/https.html#https_https_request_options_callback), the following per-request options are supported: - `followRedirects` (default: `true`) – whether redirects should be followed. - `maxRedirects` (default: `21`) – sets the maximum number of allowed redirects; if exceeded, an error will be emitted. - `maxBodyLength` (default: 10MB) – sets the maximum size of the request body; if exceeded, an error will be emitted. - `beforeRedirect` (default: `undefined`) – optionally change the request `options` on redirects, or abort the request by throwing an error. - `agents` (default: `undefined`) – sets the `agent` option per protocol, since HTTP and HTTPS use different agents. Example value: `{ http: new http.Agent(), https: new https.Agent() }` - `trackRedirects` (default: `false`) – whether to store the redirected response details into the `redirects` array on the response object. ### Advanced usage By default, `follow-redirects` will use the Node.js default implementations of [`http`](https://nodejs.org/api/http.html) and [`https`](https://nodejs.org/api/https.html). To enable features such as caching and/or intermediate request tracking, you might instead want to wrap `follow-redirects` around custom protocol implementations: ```javascript const { http, https } = require('follow-redirects').wrap({ http: require('your-custom-http'), https: require('your-custom-https'), }); ``` Such custom protocols only need an implementation of the `request` method. ## Browser Usage Due to the way the browser works, the `http` and `https` browser equivalents perform redirects by default. By requiring `follow-redirects` this way: ```javascript const http = require('follow-redirects/http'); const https = require('follow-redirects/https'); ``` you can easily tell webpack and friends to replace `follow-redirect` by the built-in versions: ```json { "follow-redirects/http" : "http", "follow-redirects/https" : "https" } ``` ## Contributing Pull Requests are always welcome. Please [file an issue](https://github.com/follow-redirects/follow-redirects/issues) detailing your proposal before you invest your valuable time. Additional features and bug fixes should be accompanied by tests. You can run the test suite locally with a simple `npm test` command. ## Debug Logging `follow-redirects` uses the excellent [debug](https://www.npmjs.com/package/debug) for logging. To turn on logging set the environment variable `DEBUG=follow-redirects` for debug output from just this module. When running the test suite it is sometimes advantageous to set `DEBUG=*` to see output from the express server as well. ## Authors - [Ruben Verborgh](https://ruben.verborgh.org/) - [Olivier Lalonde](mailto:olalonde@gmail.com) - [James Talmage](mailto:james@talmage.io) ## License [MIT License](https://github.com/follow-redirects/follow-redirects/blob/master/LICENSE) follow-redirects-1.15.6/SECURITY.md000066400000000000000000000002721457462373400167010ustar00rootroot00000000000000# Reporting a Vulnerability If you discover a security vulnerability in follow-redirects please disclose it via https://github.com/follow-redirects/follow-redirects/security/advisories follow-redirects-1.15.6/debug.js000066400000000000000000000004731457462373400165370ustar00rootroot00000000000000var debug; module.exports = function () { if (!debug) { try { /* eslint global-require: off */ debug = require("debug")("follow-redirects"); } catch (error) { /* */ } if (typeof debug !== "function") { debug = function () { /* */ }; } } debug.apply(null, arguments); }; follow-redirects-1.15.6/http.js000066400000000000000000000000451457462373400164230ustar00rootroot00000000000000module.exports = require("./").http; follow-redirects-1.15.6/https.js000066400000000000000000000000461457462373400166070ustar00rootroot00000000000000module.exports = require("./").https; follow-redirects-1.15.6/index.js000066400000000000000000000472201457462373400165610ustar00rootroot00000000000000var url = require("url"); var URL = url.URL; var http = require("http"); var https = require("https"); var Writable = require("stream").Writable; var assert = require("assert"); var debug = require("./debug"); // Whether to use the native URL object or the legacy url module var useNativeURL = false; try { assert(new URL()); } catch (error) { useNativeURL = error.code === "ERR_INVALID_URL"; } // URL fields to preserve in copy operations var preservedUrlFields = [ "auth", "host", "hostname", "href", "path", "pathname", "port", "protocol", "query", "search", "hash", ]; // Create handlers that pass events from native requests var events = ["abort", "aborted", "connect", "error", "socket", "timeout"]; var eventHandlers = Object.create(null); events.forEach(function (event) { eventHandlers[event] = function (arg1, arg2, arg3) { this._redirectable.emit(event, arg1, arg2, arg3); }; }); // Error types with codes var InvalidUrlError = createErrorType( "ERR_INVALID_URL", "Invalid URL", TypeError ); var RedirectionError = createErrorType( "ERR_FR_REDIRECTION_FAILURE", "Redirected request failed" ); var TooManyRedirectsError = createErrorType( "ERR_FR_TOO_MANY_REDIRECTS", "Maximum number of redirects exceeded", RedirectionError ); var MaxBodyLengthExceededError = createErrorType( "ERR_FR_MAX_BODY_LENGTH_EXCEEDED", "Request body larger than maxBodyLength limit" ); var WriteAfterEndError = createErrorType( "ERR_STREAM_WRITE_AFTER_END", "write after end" ); // istanbul ignore next var destroy = Writable.prototype.destroy || noop; // An HTTP(S) request that can be redirected function RedirectableRequest(options, responseCallback) { // Initialize the request Writable.call(this); this._sanitizeOptions(options); this._options = options; this._ended = false; this._ending = false; this._redirectCount = 0; this._redirects = []; this._requestBodyLength = 0; this._requestBodyBuffers = []; // Attach a callback if passed if (responseCallback) { this.on("response", responseCallback); } // React to responses of native requests var self = this; this._onNativeResponse = function (response) { try { self._processResponse(response); } catch (cause) { self.emit("error", cause instanceof RedirectionError ? cause : new RedirectionError({ cause: cause })); } }; // Perform the first request this._performRequest(); } RedirectableRequest.prototype = Object.create(Writable.prototype); RedirectableRequest.prototype.abort = function () { destroyRequest(this._currentRequest); this._currentRequest.abort(); this.emit("abort"); }; RedirectableRequest.prototype.destroy = function (error) { destroyRequest(this._currentRequest, error); destroy.call(this, error); return this; }; // Writes buffered data to the current native request RedirectableRequest.prototype.write = function (data, encoding, callback) { // Writing is not allowed if end has been called if (this._ending) { throw new WriteAfterEndError(); } // Validate input and shift parameters if necessary if (!isString(data) && !isBuffer(data)) { throw new TypeError("data should be a string, Buffer or Uint8Array"); } if (isFunction(encoding)) { callback = encoding; encoding = null; } // Ignore empty buffers, since writing them doesn't invoke the callback // https://github.com/nodejs/node/issues/22066 if (data.length === 0) { if (callback) { callback(); } return; } // Only write when we don't exceed the maximum body length if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { this._requestBodyLength += data.length; this._requestBodyBuffers.push({ data: data, encoding: encoding }); this._currentRequest.write(data, encoding, callback); } // Error when we exceed the maximum body length else { this.emit("error", new MaxBodyLengthExceededError()); this.abort(); } }; // Ends the current native request RedirectableRequest.prototype.end = function (data, encoding, callback) { // Shift parameters if necessary if (isFunction(data)) { callback = data; data = encoding = null; } else if (isFunction(encoding)) { callback = encoding; encoding = null; } // Write data if needed and end if (!data) { this._ended = this._ending = true; this._currentRequest.end(null, null, callback); } else { var self = this; var currentRequest = this._currentRequest; this.write(data, encoding, function () { self._ended = true; currentRequest.end(null, null, callback); }); this._ending = true; } }; // Sets a header value on the current native request RedirectableRequest.prototype.setHeader = function (name, value) { this._options.headers[name] = value; this._currentRequest.setHeader(name, value); }; // Clears a header value on the current native request RedirectableRequest.prototype.removeHeader = function (name) { delete this._options.headers[name]; this._currentRequest.removeHeader(name); }; // Global timeout for all underlying requests RedirectableRequest.prototype.setTimeout = function (msecs, callback) { var self = this; // Destroys the socket on timeout function destroyOnTimeout(socket) { socket.setTimeout(msecs); socket.removeListener("timeout", socket.destroy); socket.addListener("timeout", socket.destroy); } // Sets up a timer to trigger a timeout event function startTimer(socket) { if (self._timeout) { clearTimeout(self._timeout); } self._timeout = setTimeout(function () { self.emit("timeout"); clearTimer(); }, msecs); destroyOnTimeout(socket); } // Stops a timeout from triggering function clearTimer() { // Clear the timeout if (self._timeout) { clearTimeout(self._timeout); self._timeout = null; } // Clean up all attached listeners self.removeListener("abort", clearTimer); self.removeListener("error", clearTimer); self.removeListener("response", clearTimer); self.removeListener("close", clearTimer); if (callback) { self.removeListener("timeout", callback); } if (!self.socket) { self._currentRequest.removeListener("socket", startTimer); } } // Attach callback if passed if (callback) { this.on("timeout", callback); } // Start the timer if or when the socket is opened if (this.socket) { startTimer(this.socket); } else { this._currentRequest.once("socket", startTimer); } // Clean up on events this.on("socket", destroyOnTimeout); this.on("abort", clearTimer); this.on("error", clearTimer); this.on("response", clearTimer); this.on("close", clearTimer); return this; }; // Proxy all other public ClientRequest methods [ "flushHeaders", "getHeader", "setNoDelay", "setSocketKeepAlive", ].forEach(function (method) { RedirectableRequest.prototype[method] = function (a, b) { return this._currentRequest[method](a, b); }; }); // Proxy all public ClientRequest properties ["aborted", "connection", "socket"].forEach(function (property) { Object.defineProperty(RedirectableRequest.prototype, property, { get: function () { return this._currentRequest[property]; }, }); }); RedirectableRequest.prototype._sanitizeOptions = function (options) { // Ensure headers are always present if (!options.headers) { options.headers = {}; } // Since http.request treats host as an alias of hostname, // but the url module interprets host as hostname plus port, // eliminate the host property to avoid confusion. if (options.host) { // Use hostname if set, because it has precedence if (!options.hostname) { options.hostname = options.host; } delete options.host; } // Complete the URL object when necessary if (!options.pathname && options.path) { var searchPos = options.path.indexOf("?"); if (searchPos < 0) { options.pathname = options.path; } else { options.pathname = options.path.substring(0, searchPos); options.search = options.path.substring(searchPos); } } }; // Executes the next native request (initial or redirect) RedirectableRequest.prototype._performRequest = function () { // Load the native protocol var protocol = this._options.protocol; var nativeProtocol = this._options.nativeProtocols[protocol]; if (!nativeProtocol) { throw new TypeError("Unsupported protocol " + protocol); } // If specified, use the agent corresponding to the protocol // (HTTP and HTTPS use different types of agents) if (this._options.agents) { var scheme = protocol.slice(0, -1); this._options.agent = this._options.agents[scheme]; } // Create the native request and set up its event handlers var request = this._currentRequest = nativeProtocol.request(this._options, this._onNativeResponse); request._redirectable = this; for (var event of events) { request.on(event, eventHandlers[event]); } // RFC7230§5.3.1: When making a request directly to an origin server, […] // a client MUST send only the absolute path […] as the request-target. this._currentUrl = /^\//.test(this._options.path) ? url.format(this._options) : // When making a request to a proxy, […] // a client MUST send the target URI in absolute-form […]. this._options.path; // End a redirected request // (The first request must be ended explicitly with RedirectableRequest#end) if (this._isRedirect) { // Write the request entity and end var i = 0; var self = this; var buffers = this._requestBodyBuffers; (function writeNext(error) { // Only write if this request has not been redirected yet /* istanbul ignore else */ if (request === self._currentRequest) { // Report any write errors /* istanbul ignore if */ if (error) { self.emit("error", error); } // Write the next buffer if there are still left else if (i < buffers.length) { var buffer = buffers[i++]; /* istanbul ignore else */ if (!request.finished) { request.write(buffer.data, buffer.encoding, writeNext); } } // End the request if `end` has been called on us else if (self._ended) { request.end(); } } }()); } }; // Processes a response from the current native request RedirectableRequest.prototype._processResponse = function (response) { // Store the redirected response var statusCode = response.statusCode; if (this._options.trackRedirects) { this._redirects.push({ url: this._currentUrl, headers: response.headers, statusCode: statusCode, }); } // RFC7231§6.4: The 3xx (Redirection) class of status code indicates // that further action needs to be taken by the user agent in order to // fulfill the request. If a Location header field is provided, // the user agent MAY automatically redirect its request to the URI // referenced by the Location field value, // even if the specific status code is not understood. // If the response is not a redirect; return it as-is var location = response.headers.location; if (!location || this._options.followRedirects === false || statusCode < 300 || statusCode >= 400) { response.responseUrl = this._currentUrl; response.redirects = this._redirects; this.emit("response", response); // Clean up this._requestBodyBuffers = []; return; } // The response is a redirect, so abort the current request destroyRequest(this._currentRequest); // Discard the remainder of the response to avoid waiting for data response.destroy(); // RFC7231§6.4: A client SHOULD detect and intervene // in cyclical redirections (i.e., "infinite" redirection loops). if (++this._redirectCount > this._options.maxRedirects) { throw new TooManyRedirectsError(); } // Store the request headers if applicable var requestHeaders; var beforeRedirect = this._options.beforeRedirect; if (beforeRedirect) { requestHeaders = Object.assign({ // The Host header was set by nativeProtocol.request Host: response.req.getHeader("host"), }, this._options.headers); } // RFC7231§6.4: Automatic redirection needs to done with // care for methods not known to be safe, […] // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change // the request method from POST to GET for the subsequent request. var method = this._options.method; if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" || // RFC7231§6.4.4: The 303 (See Other) status code indicates that // the server is redirecting the user agent to a different resource […] // A user agent can perform a retrieval request targeting that URI // (a GET or HEAD request if using HTTP) […] (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) { this._options.method = "GET"; // Drop a possible entity and headers related to it this._requestBodyBuffers = []; removeMatchingHeaders(/^content-/i, this._options.headers); } // Drop the Host header, as the redirect might lead to a different host var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers); // If the redirect is relative, carry over the host of the last request var currentUrlParts = parseUrl(this._currentUrl); var currentHost = currentHostHeader || currentUrlParts.host; var currentUrl = /^\w+:/.test(location) ? this._currentUrl : url.format(Object.assign(currentUrlParts, { host: currentHost })); // Create the redirected request var redirectUrl = resolveUrl(location, currentUrl); debug("redirecting to", redirectUrl.href); this._isRedirect = true; spreadUrlObject(redirectUrl, this._options); // Drop confidential headers when redirecting to a less secure protocol // or to a different domain that is not a superdomain if (redirectUrl.protocol !== currentUrlParts.protocol && redirectUrl.protocol !== "https:" || redirectUrl.host !== currentHost && !isSubdomain(redirectUrl.host, currentHost)) { removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers); } // Evaluate the beforeRedirect callback if (isFunction(beforeRedirect)) { var responseDetails = { headers: response.headers, statusCode: statusCode, }; var requestDetails = { url: currentUrl, method: method, headers: requestHeaders, }; beforeRedirect(this._options, responseDetails, requestDetails); this._sanitizeOptions(this._options); } // Perform the redirected request this._performRequest(); }; // Wraps the key/value object of protocols with redirect functionality function wrap(protocols) { // Default settings var exports = { maxRedirects: 21, maxBodyLength: 10 * 1024 * 1024, }; // Wrap each protocol var nativeProtocols = {}; Object.keys(protocols).forEach(function (scheme) { var protocol = scheme + ":"; var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol); // Executes a request, following redirects function request(input, options, callback) { // Parse parameters, ensuring that input is an object if (isURL(input)) { input = spreadUrlObject(input); } else if (isString(input)) { input = spreadUrlObject(parseUrl(input)); } else { callback = options; options = validateUrl(input); input = { protocol: protocol }; } if (isFunction(options)) { callback = options; options = null; } // Set defaults options = Object.assign({ maxRedirects: exports.maxRedirects, maxBodyLength: exports.maxBodyLength, }, input, options); options.nativeProtocols = nativeProtocols; if (!isString(options.host) && !isString(options.hostname)) { options.hostname = "::1"; } assert.equal(options.protocol, protocol, "protocol mismatch"); debug("options", options); return new RedirectableRequest(options, callback); } // Executes a GET request, following redirects function get(input, options, callback) { var wrappedRequest = wrappedProtocol.request(input, options, callback); wrappedRequest.end(); return wrappedRequest; } // Expose the properties on the wrapped protocol Object.defineProperties(wrappedProtocol, { request: { value: request, configurable: true, enumerable: true, writable: true }, get: { value: get, configurable: true, enumerable: true, writable: true }, }); }); return exports; } function noop() { /* empty */ } function parseUrl(input) { var parsed; /* istanbul ignore else */ if (useNativeURL) { parsed = new URL(input); } else { // Ensure the URL is valid and absolute parsed = validateUrl(url.parse(input)); if (!isString(parsed.protocol)) { throw new InvalidUrlError({ input }); } } return parsed; } function resolveUrl(relative, base) { /* istanbul ignore next */ return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative)); } function validateUrl(input) { if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) { throw new InvalidUrlError({ input: input.href || input }); } if (/^\[/.test(input.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input.host)) { throw new InvalidUrlError({ input: input.href || input }); } return input; } function spreadUrlObject(urlObject, target) { var spread = target || {}; for (var key of preservedUrlFields) { spread[key] = urlObject[key]; } // Fix IPv6 hostname if (spread.hostname.startsWith("[")) { spread.hostname = spread.hostname.slice(1, -1); } // Ensure port is a number if (spread.port !== "") { spread.port = Number(spread.port); } // Concatenate path spread.path = spread.search ? spread.pathname + spread.search : spread.pathname; return spread; } function removeMatchingHeaders(regex, headers) { var lastValue; for (var header in headers) { if (regex.test(header)) { lastValue = headers[header]; delete headers[header]; } } return (lastValue === null || typeof lastValue === "undefined") ? undefined : String(lastValue).trim(); } function createErrorType(code, message, baseClass) { // Create constructor function CustomError(properties) { Error.captureStackTrace(this, this.constructor); Object.assign(this, properties || {}); this.code = code; this.message = this.cause ? message + ": " + this.cause.message : message; } // Attach constructor and set default properties CustomError.prototype = new (baseClass || Error)(); Object.defineProperties(CustomError.prototype, { constructor: { value: CustomError, enumerable: false, }, name: { value: "Error [" + code + "]", enumerable: false, }, }); return CustomError; } function destroyRequest(request, error) { for (var event of events) { request.removeListener(event, eventHandlers[event]); } request.on("error", noop); request.destroy(error); } function isSubdomain(subdomain, domain) { assert(isString(subdomain) && isString(domain)); var dot = subdomain.length - domain.length - 1; return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); } function isString(value) { return typeof value === "string" || value instanceof String; } function isFunction(value) { return typeof value === "function"; } function isBuffer(value) { return typeof value === "object" && ("length" in value); } function isURL(value) { return URL && value instanceof URL; } // Exports module.exports = wrap({ http: http, https: https }); module.exports.wrap = wrap; follow-redirects-1.15.6/package-lock.json000066400000000000000000006632541457462373400203430ustar00rootroot00000000000000{ "name": "follow-redirects", "version": "1.15.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "follow-redirects", "version": "1.15.6", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], "license": "MIT", "devDependencies": { "concat-stream": "^2.0.0", "eslint": "^5.16.0", "express": "^4.16.4", "lolex": "^3.1.0", "mocha": "^6.0.2", "nyc": "^14.1.1" }, "engines": { "node": ">=4.0" }, "peerDependenciesMeta": { "debug": { "optional": true } } }, "node_modules/@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "dependencies": { "@babel/highlight": "^7.10.4" } }, "node_modules/@babel/generator": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", "dev": true, "dependencies": { "@babel/types": "^7.11.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "node_modules/@babel/helper-function-name": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "dev": true, "dependencies": { "@babel/helper-get-function-arity": "^7.10.4", "@babel/template": "^7.10.4", "@babel/types": "^7.10.4" } }, "node_modules/@babel/helper-get-function-arity": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", "dev": true, "dependencies": { "@babel/types": "^7.10.4" } }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "dev": true, "dependencies": { "@babel/types": "^7.11.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "node_modules/@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "node_modules/@babel/parser": { "version": "7.11.3", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/template": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.10.4", "@babel/types": "^7.10.4" } }, "node_modules/@babel/traverse": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.11.0", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", "@babel/parser": "^7.11.0", "@babel/types": "^7.11.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "node_modules/@babel/types": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } }, "node_modules/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "dependencies": { "mime-types": "~2.1.24", "negotiator": "0.6.2" }, "engines": { "node": ">= 0.6" } }, "node_modules/acorn": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-jsx": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0" } }, "node_modules/ajv": { "version": "6.12.3", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/append-transform": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "dependencies": { "default-require-extensions": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, "node_modules/astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "node_modules/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "dev": true, "dependencies": { "bytes": "3.1.0", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", "http-errors": "1.7.2", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", "qs": "6.7.0", "raw-body": "2.4.0", "type-is": "~1.6.17" }, "engines": { "node": ">= 0.8" } }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "node_modules/bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/caching-transform": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", "dev": true, "dependencies": { "hasha": "^3.0.0", "make-dir": "^2.0.0", "package-hash": "^3.0.0", "write-file-atomic": "^2.4.2" }, "engines": { "node": ">=6" } }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, "node_modules/cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "dependencies": { "restore-cursor": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, "node_modules/cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "dependencies": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.0" } }, "node_modules/cliui/node_modules/ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/cliui/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "dependencies": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" }, "engines": { "node": ">=6" } }, "node_modules/cliui/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "dependencies": { "ansi-regex": "^4.1.0" }, "engines": { "node": ">=6" } }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, "engines": [ "node >= 6.0" ], "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "node_modules/content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "dev": true, "dependencies": { "safe-buffer": "5.1.2" }, "engines": { "node": ">= 0.6" } }, "node_modules/content-disposition/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "dependencies": { "safe-buffer": "~5.1.1" } }, "node_modules/convert-source-map/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "node_modules/cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, "node_modules/cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "make-dir": "^2.0.0", "nested-error-stacks": "^2.0.0", "pify": "^4.0.1", "safe-buffer": "^5.0.1" }, "engines": { "node": ">=6" } }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" }, "engines": { "node": ">=4.8" } }, "node_modules/debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "node_modules/default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "dependencies": { "strip-bom": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "dependencies": { "object-keys": "^1.0.12" }, "engines": { "node": ">= 0.4" } }, "node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, "node_modules/diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true, "engines": { "node": ">=0.3.1" } }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=6.0.0" } }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, "node_modules/emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-abstract": { "version": "1.17.6", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "dependencies": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", "is-callable": "^1.2.0", "is-regex": "^1.1.0", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/eslint": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "ajv": "^6.9.1", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^4.0.3", "eslint-utils": "^1.3.1", "eslint-visitor-keys": "^1.0.0", "espree": "^5.0.1", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", "globals": "^11.7.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "inquirer": "^6.2.2", "js-yaml": "^3.13.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.11", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", "progress": "^2.0.0", "regexpp": "^2.0.1", "semver": "^5.5.1", "strip-ansi": "^4.0.0", "strip-json-comments": "^2.0.1", "table": "^5.2.3", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": "^6.14.0 || ^8.10.0 || >=9.10.0" } }, "node_modules/eslint-scope": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "dependencies": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/eslint-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" } }, "node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/espree": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", "dev": true, "dependencies": { "acorn": "^6.0.7", "acorn-jsx": "^5.0.0", "eslint-visitor-keys": "^1.0.0" }, "engines": { "node": ">=6.0.0" } }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { "node": ">=4" } }, "node_modules/esquery": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "dependencies": { "estraverse": "^5.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/esquery/node_modules/estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "dependencies": { "estraverse": "^4.1.0" }, "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "dev": true, "dependencies": { "accepts": "~1.3.7", "array-flatten": "1.1.1", "body-parser": "1.19.0", "content-disposition": "0.5.3", "content-type": "~1.0.4", "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.1.2", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.5", "qs": "6.7.0", "range-parser": "~1.2.1", "safe-buffer": "5.1.2", "send": "0.17.1", "serve-static": "1.14.1", "setprototypeof": "1.1.1", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "node_modules/express/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" }, "engines": { "node": ">=4" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "node_modules/figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "dependencies": { "escape-string-regexp": "^1.0.5" }, "engines": { "node": ">=4" } }, "node_modules/file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, "dependencies": { "flat-cache": "^2.0.1" }, "engines": { "node": ">=4" } }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "node_modules/find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "dependencies": { "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "dependencies": { "locate-path": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/flat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", "deprecated": "Fixed a prototype pollution security issue in 4.1.0, please upgrade to ^4.1.1 or ^5.0.1.", "dev": true, "dependencies": { "is-buffer": "~2.0.3" }, "bin": { "flat": "cli.js" } }, "node_modules/flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, "dependencies": { "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" }, "engines": { "node": ">=4" } }, "node_modules/flatted": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, "node_modules/foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "dependencies": { "cross-spawn": "^4", "signal-exit": "^3.0.0" } }, "node_modules/foreground-child/node_modules/cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "dependencies": { "lru-cache": "^4.0.1", "which": "^1.2.9" } }, "node_modules/forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true, "engines": { "node": ">=4.x" } }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "dependencies": { "function-bind": "^1.1.1" }, "engines": { "node": ">= 0.4.0" } }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "dev": true, "dependencies": { "is-stream": "^1.0.1" }, "engines": { "node": ">=4" } }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "bin": { "he": "bin/he" } }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, "node_modules/http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "dev": true, "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/http-errors/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true, "engines": { "node": ">=0.8.19" } }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "node_modules/inquirer": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "dependencies": { "ansi-escapes": "^3.2.0", "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^2.0.0", "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^6.4.0", "string-width": "^2.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "engines": { "node": ">=6.0.0" } }, "node_modules/inquirer/node_modules/ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/inquirer/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "dependencies": { "ansi-regex": "^4.1.0" }, "engines": { "node": ">=6" } }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "engines": { "node": ">= 0.10" } }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "node_modules/is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/is-callable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/is-regex": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "dependencies": { "has-symbols": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, "dependencies": { "has-symbols": "^1.0.1" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "node_modules/istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/istanbul-lib-hook": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "dev": true, "dependencies": { "append-transform": "^1.0.0" }, "engines": { "node": ">=6" } }, "node_modules/istanbul-lib-instrument": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "dependencies": { "@babel/generator": "^7.4.0", "@babel/parser": "^7.4.3", "@babel/template": "^7.4.0", "@babel/traverse": "^7.4.3", "@babel/types": "^7.4.0", "istanbul-lib-coverage": "^2.0.5", "semver": "^6.0.0" }, "engines": { "node": ">=6" } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/istanbul-lib-report": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "supports-color": "^6.1.0" }, "engines": { "node": ">=6" } }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "engines": { "node": ">=6" } }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/istanbul-reports": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "node_modules/js-yaml": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, "bin": { "jsesc": "bin/jsesc" }, "engines": { "node": ">=4" } }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/load-json-file/node_modules/pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "node_modules/lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "node_modules/log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "dependencies": { "chalk": "^2.0.1" }, "engines": { "node": ">=4" } }, "node_modules/lolex": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.1.0.tgz", "integrity": "sha512-zFo5MgCJ0rZ7gQg69S4pqBsLURbFw11X68C18OcJjJQbqaXm2NoTrGl1IMM3TIz0/BnN1tIs2tzmmqvCsOMMjw==", "dev": true }, "node_modules/lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" }, "engines": { "node": ">=6" } }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, "node_modules/merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "dependencies": { "source-map": "^0.6.1" } }, "node_modules/merge-source-map/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, "bin": { "mime": "cli.js" }, "engines": { "node": ">=4" } }, "node_modules/mime-db": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.27", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "dev": true, "dependencies": { "mime-db": "1.44.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "node_modules/mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "dependencies": { "minimist": "^1.2.5" }, "bin": { "mkdirp": "bin/cmd.js" } }, "node_modules/mocha": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", "dev": true, "dependencies": { "ansi-colors": "3.2.3", "browser-stdout": "1.3.1", "debug": "3.2.6", "diff": "3.5.0", "escape-string-regexp": "1.0.5", "find-up": "3.0.0", "glob": "7.1.3", "growl": "1.10.5", "he": "1.2.0", "js-yaml": "3.13.1", "log-symbols": "2.2.0", "minimatch": "3.0.4", "mkdirp": "0.5.4", "ms": "2.1.1", "node-environment-flags": "1.0.5", "object.assign": "4.1.0", "strip-json-comments": "2.0.1", "supports-color": "6.0.0", "which": "1.3.1", "wide-align": "1.1.3", "yargs": "13.3.2", "yargs-parser": "13.1.2", "yargs-unparser": "1.6.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha" }, "engines": { "node": ">= 6.0.0" } }, "node_modules/mocha/node_modules/debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/mocha/node_modules/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" } }, "node_modules/mocha/node_modules/js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/mocha/node_modules/mkdirp": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", "dev": true, "dependencies": { "minimist": "^1.2.5" }, "bin": { "mkdirp": "bin/cmd.js" } }, "node_modules/mocha/node_modules/ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, "node_modules/mocha/node_modules/supports-color": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "dev": true, "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "node_modules/negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/nested-error-stacks": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, "node_modules/node-environment-flags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", "dev": true, "dependencies": { "object.getownpropertydescriptors": "^2.0.3", "semver": "^5.7.0" } }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "node_modules/nyc": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, "dependencies": { "archy": "^1.0.0", "caching-transform": "^3.0.2", "convert-source-map": "^1.6.0", "cp-file": "^6.2.0", "find-cache-dir": "^2.1.0", "find-up": "^3.0.0", "foreground-child": "^1.5.6", "glob": "^7.1.3", "istanbul-lib-coverage": "^2.0.5", "istanbul-lib-hook": "^2.0.7", "istanbul-lib-instrument": "^3.3.0", "istanbul-lib-report": "^2.0.8", "istanbul-lib-source-maps": "^3.0.6", "istanbul-reports": "^2.2.4", "js-yaml": "^3.13.1", "make-dir": "^2.1.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", "rimraf": "^2.6.3", "signal-exit": "^3.0.2", "spawn-wrap": "^1.4.2", "test-exclude": "^5.2.3", "uuid": "^3.3.2", "yargs": "^13.2.2", "yargs-parser": "^13.0.0" }, "bin": { "nyc": "bin/nyc.js" }, "engines": { "node": ">=6" } }, "node_modules/object-inspect": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "dependencies": { "define-properties": "^1.1.2", "function-bind": "^1.1.1", "has-symbols": "^1.0.0", "object-keys": "^1.0.11" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.getownpropertydescriptors": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" }, "engines": { "node": ">= 0.8" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true, "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "dependencies": { "mimic-fn": "^1.0.0" }, "engines": { "node": ">=4" } }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "word-wrap": "~1.2.3" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "dependencies": { "p-limit": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", "dev": true, "dependencies": { "graceful-fs": "^4.1.15", "hasha": "^3.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" }, "engines": { "node": ">=6" } }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "dependencies": { "callsites": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" }, "engines": { "node": ">=4" } }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "dev": true }, "node_modules/path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "dependencies": { "pify": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/path-type/node_modules/pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "dependencies": { "find-up": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "dev": true, "dependencies": { "forwarded": "~0.1.2", "ipaddr.js": "1.9.1" }, "engines": { "node": ">= 0.10" } }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true, "engines": { "node": ">=0.6" } }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "dev": true, "dependencies": { "bytes": "3.1.0", "http-errors": "1.7.2", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", "dev": true, "dependencies": { "find-up": "^3.0.0", "read-pkg": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true, "engines": { "node": ">=6.5.0" } }, "node_modules/release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, "dependencies": { "es6-error": "^4.0.1" }, "engines": { "node": ">=4" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "node_modules/resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "dependencies": { "path-parse": "^1.0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" }, "engines": { "node": ">=4" } }, "node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true, "engines": { "node": ">=0.12.0" } }, "node_modules/rxjs": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", "dev": true, "dependencies": { "tslib": "^1.9.0" }, "engines": { "npm": ">=2.0.0" } }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, "bin": { "semver": "bin/semver" } }, "node_modules/send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "dev": true, "dependencies": { "debug": "2.6.9", "depd": "~1.1.2", "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "~1.7.2", "mime": "1.6.0", "ms": "2.1.1", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/send/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "node_modules/send/node_modules/ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, "node_modules/serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "dev": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.17.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "node_modules/setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true }, "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "dependencies": { "shebang-regex": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "node_modules/slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, "dependencies": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/spawn-wrap": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", "dev": true, "dependencies": { "foreground-child": "^1.5.6", "mkdirp": "^0.5.0", "os-homedir": "^1.0.1", "rimraf": "^2.6.2", "signal-exit": "^3.0.2", "which": "^1.3.0" } }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" }, "engines": { "node": ">=4" } }, "node_modules/string.prototype.trimend": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", "dev": true, "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", "dev": true, "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "dependencies": { "ansi-regex": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "dependencies": { "ajv": "^6.10.2", "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, "engines": { "node": ">=6.0.0" } }, "node_modules/table/node_modules/ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/table/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "dependencies": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" }, "engines": { "node": ">=6" } }, "node_modules/table/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "dependencies": { "ansi-regex": "^4.1.0" }, "engines": { "node": ">=6" } }, "node_modules/test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "dev": true, "dependencies": { "glob": "^7.1.3", "minimatch": "^3.0.4", "read-pkg-up": "^4.0.0", "require-main-filename": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "dependencies": { "os-tmpdir": "~1.0.2" }, "engines": { "node": ">=0.6.0" } }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true, "engines": { "node": ">=0.6" } }, "node_modules/tslib": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", "dev": true }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "dependencies": { "prelude-ls": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" }, "engines": { "node": ">= 0.6" } }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "dependencies": { "punycode": "^2.1.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true, "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { "uuid": "bin/uuid" } }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true, "engines": { "node": ">= 0.8" } }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "node_modules/wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "dependencies": { "string-width": "^1.0.2 || 2" } }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "dependencies": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" }, "engines": { "node": ">=6" } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "dependencies": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" }, "engines": { "node": ">=6" } }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "dependencies": { "ansi-regex": "^4.1.0" }, "engines": { "node": ">=6" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "node_modules/write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, "dependencies": { "mkdirp": "^0.5.1" }, "engines": { "node": ">=4" } }, "node_modules/write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "dependencies": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", "signal-exit": "^3.0.2" } }, "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "node_modules/yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "dependencies": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.2" } }, "node_modules/yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "node_modules/yargs-unparser": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, "dependencies": { "flat": "^4.1.0", "lodash": "^4.17.15", "yargs": "^13.3.0" }, "engines": { "node": ">=6" } }, "node_modules/yargs/node_modules/ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/yargs/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "dependencies": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" }, "engines": { "node": ">=6" } }, "node_modules/yargs/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "dependencies": { "ansi-regex": "^4.1.0" }, "engines": { "node": ">=6" } } }, "dependencies": { "@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/generator": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", "dev": true, "requires": { "@babel/types": "^7.11.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.10.4", "@babel/template": "^7.10.4", "@babel/types": "^7.10.4" } }, "@babel/helper-get-function-arity": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", "dev": true, "requires": { "@babel/types": "^7.10.4" } }, "@babel/helper-split-export-declaration": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "dev": true, "requires": { "@babel/types": "^7.11.0" } }, "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { "version": "7.11.3", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==", "dev": true }, "@babel/template": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/parser": "^7.10.4", "@babel/types": "^7.10.4" } }, "@babel/traverse": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.11.0", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", "@babel/parser": "^7.11.0", "@babel/types": "^7.11.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { "mime-types": "~2.1.24", "negotiator": "0.6.2" } }, "acorn": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true }, "acorn-jsx": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", "dev": true, "requires": {} }, "ajv": { "version": "6.12.3", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "ansi-colors": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "dev": true }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" } }, "append-transform": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { "default-require-extensions": "^2.0.0" } }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" } }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "dev": true, "requires": { "bytes": "3.1.0", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "~1.1.2", "http-errors": "1.7.2", "iconv-lite": "0.4.24", "on-finished": "~2.3.0", "qs": "6.7.0", "raw-body": "2.4.0", "type-is": "~1.6.17" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true }, "caching-transform": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", "dev": true, "requires": { "hasha": "^3.0.0", "make-dir": "^2.0.0", "package-hash": "^3.0.0", "write-file-atomic": "^2.4.2" } }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { "restore-cursor": "^2.0.0" } }, "cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.0" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" } } } }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { "color-name": "1.1.3" } }, "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", "dev": true, "requires": { "safe-buffer": "5.1.2" }, "dependencies": { "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true } } }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" }, "dependencies": { "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true } } }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", "dev": true }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "make-dir": "^2.0.0", "nested-error-stacks": "^2.0.0", "pify": "^4.0.1", "safe-buffer": "^5.0.1" } }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { "strip-bom": "^3.0.0" } }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { "object-keys": "^1.0.12" } }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" } }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "es-abstract": { "version": "1.17.6", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", "is-callable": "^1.2.0", "is-regex": "^1.1.0", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" } }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" } }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "eslint": { "version": "5.16.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "ajv": "^6.9.1", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^4.0.3", "eslint-utils": "^1.3.1", "eslint-visitor-keys": "^1.0.0", "espree": "^5.0.1", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", "globals": "^11.7.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "inquirer": "^6.2.2", "js-yaml": "^3.13.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.11", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", "progress": "^2.0.0", "regexpp": "^2.0.1", "semver": "^5.5.1", "strip-ansi": "^4.0.0", "strip-json-comments": "^2.0.1", "table": "^5.2.3", "text-table": "^0.2.0" } }, "eslint-scope": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, "eslint-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", "dev": true, "requires": { "acorn": "^6.0.7", "acorn-jsx": "^5.0.0", "eslint-visitor-keys": "^1.0.0" } }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "esquery": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { "estraverse": "^4.1.0" } }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "dev": true, "requires": { "accepts": "~1.3.7", "array-flatten": "1.1.1", "body-parser": "1.19.0", "content-disposition": "0.5.3", "content-type": "~1.0.4", "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.1.2", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.5", "qs": "6.7.0", "range-parser": "~1.2.1", "safe-buffer": "5.1.2", "send": "0.17.1", "serve-static": "1.14.1", "setprototypeof": "1.1.1", "statuses": "~1.5.0", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true } } }, "external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" } }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, "requires": { "flat-cache": "^2.0.1" } }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" } }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" } }, "flat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", "dev": true, "requires": { "is-buffer": "~2.0.3" } }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, "requires": { "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" } }, "flatted": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { "cross-spawn": "^4", "signal-exit": "^3.0.0" }, "dependencies": { "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" } } } }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", "dev": true }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { "function-bind": "^1.1.1" } }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "dev": true, "requires": { "is-stream": "^1.0.1" } }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" }, "dependencies": { "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true } } }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "import-fresh": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "inquirer": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "requires": { "ansi-escapes": "^3.2.0", "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^2.0.0", "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^6.4.0", "string-width": "^2.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" } } } }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", "dev": true }, "is-callable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-regex": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, "requires": { "has-symbols": "^1.0.1" } }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, "requires": { "has-symbols": "^1.0.1" } }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, "istanbul-lib-hook": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "dev": true, "requires": { "append-transform": "^1.0.0" } }, "istanbul-lib-instrument": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { "@babel/generator": "^7.4.0", "@babel/parser": "^7.4.3", "@babel/template": "^7.4.0", "@babel/traverse": "^7.4.3", "@babel/types": "^7.4.0", "istanbul-lib-coverage": "^2.0.5", "semver": "^6.0.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "istanbul-lib-report": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "supports-color": "^6.1.0" }, "dependencies": { "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "istanbul-reports": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "requires": { "html-escaper": "^2.0.0" } }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" }, "dependencies": { "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "requires": { "chalk": "^2.0.1" } }, "lolex": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.1.0.tgz", "integrity": "sha512-zFo5MgCJ0rZ7gQg69S4pqBsLURbFw11X68C18OcJjJQbqaXm2NoTrGl1IMM3TIz0/BnN1tIs2tzmmqvCsOMMjw==", "dev": true }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" } }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, "merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { "source-map": "^0.6.1" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", "dev": true }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, "mime-db": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", "dev": true }, "mime-types": { "version": "2.1.27", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "dev": true, "requires": { "mime-db": "1.44.0" } }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "mocha": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", "dev": true, "requires": { "ansi-colors": "3.2.3", "browser-stdout": "1.3.1", "debug": "3.2.6", "diff": "3.5.0", "escape-string-regexp": "1.0.5", "find-up": "3.0.0", "glob": "7.1.3", "growl": "1.10.5", "he": "1.2.0", "js-yaml": "3.13.1", "log-symbols": "2.2.0", "minimatch": "3.0.4", "mkdirp": "0.5.4", "ms": "2.1.1", "node-environment-flags": "1.0.5", "object.assign": "4.1.0", "strip-json-comments": "2.0.1", "supports-color": "6.0.0", "which": "1.3.1", "wide-align": "1.1.3", "yargs": "13.3.2", "yargs-parser": "13.1.2", "yargs-unparser": "1.6.0" }, "dependencies": { "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { "ms": "^2.1.1" } }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, "mkdirp": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, "supports-color": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true }, "nested-error-stacks": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, "node-environment-flags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", "dev": true, "requires": { "object.getownpropertydescriptors": "^2.0.3", "semver": "^5.7.0" } }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "nyc": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, "requires": { "archy": "^1.0.0", "caching-transform": "^3.0.2", "convert-source-map": "^1.6.0", "cp-file": "^6.2.0", "find-cache-dir": "^2.1.0", "find-up": "^3.0.0", "foreground-child": "^1.5.6", "glob": "^7.1.3", "istanbul-lib-coverage": "^2.0.5", "istanbul-lib-hook": "^2.0.7", "istanbul-lib-instrument": "^3.3.0", "istanbul-lib-report": "^2.0.8", "istanbul-lib-source-maps": "^3.0.6", "istanbul-reports": "^2.2.4", "js-yaml": "^3.13.1", "make-dir": "^2.1.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", "rimraf": "^2.6.3", "signal-exit": "^3.0.2", "spawn-wrap": "^1.4.2", "test-exclude": "^5.2.3", "uuid": "^3.3.2", "yargs": "^13.2.2", "yargs-parser": "^13.0.0" } }, "object-inspect": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", "dev": true }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, "object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { "define-properties": "^1.1.2", "function-bind": "^1.1.1", "has-symbols": "^1.0.0", "object-keys": "^1.0.11" } }, "object.getownpropertydescriptors": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" } }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", "dev": true, "requires": { "ee-first": "1.1.1" } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" } }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { "mimic-fn": "^1.0.0" } }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "word-wrap": "~1.2.3" } }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", "dev": true, "requires": { "graceful-fs": "^4.1.15", "hasha": "^3.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" } }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { "callsites": "^3.0.0" } }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "dev": true }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { "pify": "^3.0.0" }, "dependencies": { "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { "find-up": "^3.0.0" } }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "dev": true, "requires": { "forwarded": "~0.1.2", "ipaddr.js": "1.9.1" } }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true }, "raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "dev": true, "requires": { "bytes": "3.1.0", "http-errors": "1.7.2", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" } }, "read-pkg-up": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", "dev": true, "requires": { "find-up": "^3.0.0", "read-pkg": "^3.0.0" } }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, "requires": { "es6-error": "^4.0.1" } }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" } }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { "glob": "^7.1.3" } }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, "rxjs": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", "dev": true, "requires": { "tslib": "^1.9.0" } }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "dev": true, "requires": { "debug": "2.6.9", "depd": "~1.1.2", "destroy": "~1.0.4", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "~1.7.2", "mime": "1.6.0", "ms": "2.1.1", "on-finished": "~2.3.0", "range-parser": "~1.2.1", "statuses": "~1.5.0" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" }, "dependencies": { "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true } } }, "serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.17.1" } }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, "requires": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "spawn-wrap": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", "dev": true, "requires": { "foreground-child": "^1.5.6", "mkdirp": "^0.5.0", "os-homedir": "^1.0.1", "rimraf": "^2.6.2", "signal-exit": "^3.0.2", "which": "^1.3.0" } }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { "safe-buffer": "~5.2.0" } }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "string.prototype.trimend": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "string.prototype.trimstart": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" } }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { "ajv": "^6.10.2", "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" } } } }, "test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "dev": true, "requires": { "glob": "^7.1.3", "minimatch": "^3.0.4", "read-pkg-up": "^4.0.0", "require-main-filename": "^2.0.0" } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" } }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, "tslib": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", "dev": true }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { "prelude-ls": "~1.1.2" } }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "requires": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", "dev": true }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "requires": { "string-width": "^1.0.2 || 2" } }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" } } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, "requires": { "mkdirp": "^0.5.1" } }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", "signal-exit": "^3.0.2" } }, "y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.2" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" } } } }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "yargs-unparser": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, "requires": { "flat": "^4.1.0", "lodash": "^4.17.15", "yargs": "^13.3.0" } } } } follow-redirects-1.15.6/package.json000066400000000000000000000023771457462373400174060ustar00rootroot00000000000000{ "name": "follow-redirects", "version": "1.15.6", "description": "HTTP and HTTPS modules that follow redirects.", "license": "MIT", "main": "index.js", "files": [ "*.js" ], "engines": { "node": ">=4.0" }, "scripts": { "lint": "eslint *.js test", "test": "nyc mocha" }, "repository": { "type": "git", "url": "git@github.com:follow-redirects/follow-redirects.git" }, "homepage": "https://github.com/follow-redirects/follow-redirects", "bugs": { "url": "https://github.com/follow-redirects/follow-redirects/issues" }, "keywords": [ "http", "https", "url", "redirect", "client", "location", "utility" ], "author": "Ruben Verborgh (https://ruben.verborgh.org/)", "contributors": [ "Olivier Lalonde (http://www.syskall.com)", "James Talmage " ], "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], "peerDependenciesMeta": { "debug": { "optional": true } }, "devDependencies": { "concat-stream": "^2.0.0", "eslint": "^5.16.0", "express": "^4.16.4", "lolex": "^3.1.0", "mocha": "^6.0.2", "nyc": "^14.1.1" } } follow-redirects-1.15.6/test/000077500000000000000000000000001457462373400160665ustar00rootroot00000000000000follow-redirects-1.15.6/test/.eslintrc000066400000000000000000000004401457462373400177100ustar00rootroot00000000000000{ globals: { describe: true, it: true, before: true, after: true, beforeEach: true, afterEach: true, expect: true, }, rules: { no-sync: "off", // allow sync methods max-nested-callbacks: "off", // Mocha works with deeply nested callbacks }, } follow-redirects-1.15.6/test/assets/000077500000000000000000000000001457462373400173705ustar00rootroot00000000000000follow-redirects-1.15.6/test/assets/ca.crt000066400000000000000000000017001457462373400204630ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICmDCCAYACCQDo0UEmHVSlqjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJC RTAgFw0yMTEwMzAxODEwMDZaGA8yMTIxMTAwNjE4MTAwNlowDTELMAkGA1UEBhMC QkUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYjGqoyk9fKI/Hrl8R 4E/7A3YzvsSnDhxyOT+k7YRTpuHwL7HF/9C5EFbGPgh0c8VsQxEzbPlAwPgajeHR K6zFpqbkA7wozktV/vIm8DZdc5h2flUpjScazAP/MXMp7i0CpR4qmsRl9HuhFmmd D9VxwWjgT4rafrOXhX8HjQ015FvjpFlFAzEiRAuxJzS0zd9OmDOyR4/VxBCHyf9D Wz4yfZdjaXXfbc5ljJiBGS4vR0inx2hPwcxD8YWHI+o9lSCjsr1OFy0bpjJ/aXih Na4pe19Np0IoI+s+mlx568+WqYXbFNovH71gUhhaUtZPWByzPaeHdK5SeylZArHl lkKPAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIIUHDzunkvnZ5DBMOKbEVn0fr2R yvKVNtRp59OWF1nJH9pr318TSk+yIClBRIismMHM6GnFYpDjqiGfJYtSN/amupGK h9b6aMDKKfSr7iAi9DzgPEvYaWcXGMRWmOWqxGS9zsvmM1vGkL7KsCWGIbtstxg+ P8m4HSO6zXuBpe68yRSnNgrusMr1jviDE+aiyZANiZm7TPfIr7NHHmTk82aZtYCH yuDujnE5cNhJHH9iBGOBm51TZDMg9lFm9ItEAfHTC5++KfXMYokg7fqCJFU6d2y8 O2P7e16PvX6lWcwTENq9ENiyEuTch3r+ZemJpoudKeaBcdrvLHSm+Nkvgwg= -----END CERTIFICATE----- follow-redirects-1.15.6/test/assets/input.txt000066400000000000000000001002011457462373400212620ustar00rootroot00000000000000Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vehicula turpis vitae vestibulum blandit. In convallis eleifend tempor. Aenean tempor finibus libero id porttitor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed gravida nibh ut leo hendrerit, quis auctor turpis aliquet. Phasellus faucibus pharetra placerat. Curabitur non arcu enim. Suspendisse rutrum, libero id consectetur lacinia, lectus tortor convallis ipsum, eget placerat urna ligula a tellus. Cras et est eros. Ut finibus elit est, ornare vehicula risus pretium vitae. Cras accumsan libero mi, eget luctus mi rhoncus in. Etiam in velit fringilla, faucibus enim vitae, facilisis quam. Ut vestibulum dolor dolor, non consequat urna egestas ut. Nulla malesuada quam id porta mollis. Quisque efficitur massa a porta dapibus. Nam eget risus odio. Vivamus blandit suscipit risus nec mattis. Maecenas pretium elementum justo, quis rhoncus urna consectetur ut. Suspendisse porttitor varius gravida. Sed aliquet, leo eu rhoncus aliquam, turpis leo vulputate orci, at finibus diam lacus in lectus. Nunc condimentum auctor augue et finibus. In pharetra facilisis lobortis. Cras ac nisl venenatis, dapibus libero at, mattis velit. Donec mattis ex vel turpis gravida mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis sed justo id nibh aliquet rutrum sit amet id velit. Sed ut ex ut tellus mattis ornare id vel lectus. Proin vitae efficitur sem. Fusce pretium, lorem quis tincidunt porta, arcu tortor aliquam felis, sit amet molestie eros neque volutpat ipsum. Etiam ut scelerisque elit, id consequat turpis. Donec non hendrerit mi, sit amet feugiat dolor. Nam at dictum nunc, in facilisis eros. Praesent quam augue, rutrum quis mi vehicula, rhoncus auctor velit. Aliquam condimentum, elit eu aliquet laoreet, justo massa sodales nibh, sed hendrerit eros justo nec ipsum. Nam gravida volutpat lorem sit amet aliquet. Praesent feugiat tristique cursus. Sed eleifend convallis rhoncus. Donec vehicula sit amet nisl a varius. Fusce tristique, augue vitae mollis ullamcorper, sem urna sollicitudin lacus, in finibus odio lorem vitae tellus. Nullam at velit varius, aliquam dolor vel, convallis ipsum. Quisque lobortis vulputate enim, id laoreet velit ultricies a. Maecenas urna tellus, semper eget lectus id, pharetra convallis nulla. Sed sit amet enim quis diam maximus posuere. Pellentesque fringilla lacinia nibh, et placerat sapien fringilla eget. Aliquam ac nunc semper, laoreet nibh vitae, laoreet sem. Vestibulum nec erat at orci interdum dignissim a ac orci. In orci dui, tristique ut laoreet at, dapibus eu lacus. Mauris pretium mauris in nisi dignissim aliquet. Praesent fermentum tincidunt elit, nec commodo lacus ornare non. Quisque tempus vel sapien a feugiat. Aliquam interdum nisl ac neque convallis molestie. Nulla in vestibulum odio. Maecenas eu pharetra enim, in feugiat ex. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum rutrum lectus vel massa hendrerit ullamcorper. Suspendisse at ullamcorper sem, quis blandit nulla. Praesent consequat eleifend laoreet. Aenean finibus mi eget sem blandit tristique. Curabitur malesuada mauris neque, at fermentum orci ultrices at. In hac habitasse platea dictumst. Maecenas condimentum sollicitudin porta. Nunc magna sem, efficitur ut ante vitae, eleifend dictum urna. Donec rutrum tincidunt enim, id suscipit lectus fermentum eu. In suscipit, metus ac sodales fringilla, ligula ligula maximus ante, vitae dignissim ante ante et mi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam sed lectus varius, pulvinar mauris eu, fringilla nunc. Sed viverra nunc ac libero luctus tincidunt. Ut luctus sed nunc a varius. Vestibulum volutpat erat nec leo eleifend, sit amet facilisis sapien finibus. Praesent vel ligula iaculis, sagittis tellus quis, convallis magna. Nam ultrices molestie vestibulum. Aenean at diam nec augue auctor congue. Praesent eu dui vel diam pretium eleifend in consequat leo. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut vehicula venenatis placerat. Nam non ex rhoncus, cursus eros non, venenatis eros. Nam convallis fringilla molestie. Nulla sodales purus ex, at dignissim nisi maximus in. Quisque id arcu odio. Donec porta laoreet sagittis. Vestibulum dignissim auctor porta. In pharetra enim a elit faucibus feugiat. Mauris euismod lectus facilisis, pretium lectus eget, dapibus lectus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque suscipit et leo sed mollis. In venenatis faucibus arcu non aliquam. Aenean semper ligula in sagittis iaculis. Aliquam leo leo, placerat at porta sed, vulputate semper justo. Mauris vestibulum scelerisque sodales. Aliquam odio urna, porttitor non nibh sit amet, facilisis vulputate nunc. Sed pulvinar nisl in diam hendrerit maximus. Sed et est eget arcu semper vulputate at nec nisi. Etiam nec facilisis ligula. Pellentesque imperdiet est eget mauris suscipit imperdiet. Pellentesque venenatis diam sit amet leo egestas, a blandit lorem tempus. Duis et tempor neque, eget interdum leo. Pellentesque felis sapien, gravida eget malesuada eu, auctor in enim. Sed vitae nibh ultricies, ullamcorper odio a, aliquam sapien. Sed tristique, risus vel vestibulum congue, ligula lectus suscipit libero, nec accumsan risus nibh eu lectus. Phasellus at purus neque. Cras non lectus id nibh vehicula vestibulum vitae vel neque. Vestibulum porttitor, urna sit amet tincidunt congue, urna est finibus nisi, eget elementum lorem libero vitae tortor. Sed scelerisque lectus placerat, bibendum urna id, tristique elit. In vel nibh condimentum, lacinia turpis ac, porttitor augue. Sed enim dolor, elementum consequat tristique id, porta in purus. Duis eget volutpat felis. Nulla pretium mattis tellus in efficitur. Ut ultricies nec ligula id varius. In turpis ipsum, convallis ac enim id, tincidunt mollis massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla sollicitudin odio augue, ac vulputate nibh semper vel. Aliquam sapien nulla, tincidunt et ex eget, viverra ornare erat. Integer at ex eu dui aliquet posuere id vitae orci. Sed elit leo, auctor vel leo at, placerat interdum ex. Nam id nibh sed est finibus bibendum et ut erat. Donec maximus volutpat dolor nec vehicula. In tincidunt neque leo, sagittis pellentesque odio ullamcorper at. Nam mi sapien, facilisis eget ante sit amet, hendrerit ornare magna. Sed massa ipsum, tristique a nibh sagittis, faucibus dignissim ex. Vestibulum at odio dolor. Maecenas ornare ligula in eros malesuada, id egestas risus faucibus. Donec ut mattis felis. Vivamus ligula felis, volutpat vel ornare eu, ornare ut ligula. Sed semper erat vitae nulla ultrices aliquam. Aenean interdum, tellus varius imperdiet dictum, elit nisl aliquet velit, et fringilla metus leo hendrerit lacus. Aliquam sem augue, sodales eu mauris sed, rhoncus tincidunt ante. Aenean dapibus porttitor quam quis tempor. Nunc semper rhoncus malesuada. Integer luctus justo a varius laoreet. Proin et gravida risus. Mauris congue eros ut arcu sagittis porttitor. Mauris sit amet fermentum lorem, sed volutpat neque. Ut id feugiat purus. Integer metus ex, egestas ac leo non, pulvinar venenatis nisl. Vestibulum consectetur venenatis magna, vel eleifend eros cursus vitae. Pellentesque erat felis, vestibulum aliquet diam sit amet, tincidunt blandit nisl. Etiam quis pulvinar velit. Nullam lorem dui, rutrum et sodales nec, vestibulum a ex. Quisque finibus nisi nec nulla laoreet, non imperdiet magna pharetra. Nulla aliquet blandit ante, tempus sodales lorem blandit at. Aliquam molestie nunc sit amet risus luctus, sit amet volutpat orci volutpat. Maecenas in risus sit amet dui iaculis laoreet. Nulla convallis lectus vitae est consectetur dignissim. Nulla eget scelerisque metus. Ut eget velit vel ex pretium blandit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas sodales, magna auctor convallis auctor, risus tellus gravida massa, id placerat nisi arcu ac leo. Proin sed leo interdum, accumsan nibh eget, molestie sapien. Donec nec lacinia libero. Proin nibh orci, molestie ut faucibus a, viverra quis magna. Curabitur facilisis, magna non gravida volutpat, ante odio porttitor turpis, eu efficitur nibh lacus a orci. Nam vel vehicula sapien. Aliquam erat volutpat. Duis vehicula diam at lobortis mollis. Cras sodales porttitor lectus eget semper. Duis at efficitur turpis. Pellentesque sollicitudin sodales mi, a blandit turpis. Nulla condimentum posuere mi sed tincidunt. Sed erat lacus, porta gravida suscipit quis, efficitur at eros. Phasellus sed sollicitudin sem, et pharetra enim. Proin a mi neque. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque quis congue nulla. Vestibulum maximus efficitur tincidunt. Pellentesque tristique nisl eu lacinia elementum. Donec sit amet risus varius, porttitor magna ultrices, consequat odio. Nullam pulvinar sapien libero, in sollicitudin nisl gravida sit amet. Vivamus eros felis, pharetra a nunc nec, blandit finibus felis. Curabitur volutpat lacus sed feugiat lacinia. Etiam pretium ipsum ac tortor ullamcorper porttitor. Donec mi massa, sollicitudin eget tincidunt vel, rhoncus sit amet ipsum. Maecenas eleifend tortor at lacus ornare, quis pretium magna gravida. Pellentesque sed pharetra ipsum, sit amet ultrices libero. Vestibulum dignissim porttitor faucibus. Vestibulum placerat imperdiet tellus, et vestibulum urna condimentum in. In dapibus aliquet odio in dictum. Etiam ut felis non dui maximus gravida et nec leo. Suspendisse potenti. Nam sit amet enim eu arcu molestie gravida non dictum tellus. Pellentesque non dignissim erat. Ut auctor dui arcu, pharetra ullamcorper nibh tempor vitae. Pellentesque aliquet id diam in vestibulum. Suspendisse posuere orci vel ligula luctus bibendum. Vivamus non pellentesque tortor, non rhoncus metus. Etiam non iaculis magna. Proin in ornare quam. Nunc finibus pretium odio, in rhoncus libero blandit a. Nam feugiat blandit augue vitae commodo. Duis justo lectus, suscipit quis aliquet vitae, ullamcorper eu orci. Pellentesque tincidunt lectus nec est pellentesque egestas. In consequat lobortis convallis. Nam auctor ullamcorper risus non pretium. Proin ullamcorper quam scelerisque vehicula porttitor. Ut in tempor velit, id sagittis ipsum. Maecenas sit amet egestas massa. Vestibulum nulla erat, lobortis id rutrum eget, fermentum non metus. Nullam suscipit risus non leo tempus, a pellentesque nulla rhoncus. Suspendisse metus nunc, luctus non purus et, pretium lobortis velit. Vivamus sodales varius dui, a dapibus nisl rhoncus vel. Mauris maximus velit a odio aliquam vulputate. Duis mollis tincidunt libero efficitur cursus. Quisque auctor metus metus, vitae tempor sem dictum eget. Nullam suscipit orci augue, non suscipit risus hendrerit pharetra. Aenean a sem quis est euismod volutpat at vel tellus. Curabitur ac orci dictum, maximus ligula eu, posuere metus. Suspendisse consequat velit sit amet turpis varius aliquam. Aenean eu dolor lacus. Curabitur bibendum nec urna ornare lacinia. Maecenas suscipit, risus non consectetur interdum, leo quam fermentum velit, nec convallis lorem augue sed metus. Duis luctus enim at sodales vestibulum. Aliquam a nulla eu dolor tempor tristique ac et eros. Suspendisse vitae nulla nec risus venenatis aliquam vel ut velit. Mauris metus odio, commodo non tristique in, fermentum at nisi. Nunc odio lorem, convallis et neque at, consequat eleifend risus. Aliquam in efficitur est. Vestibulum nec mauris mi. Praesent vitae rhoncus tortor. Maecenas sollicitudin placerat massa, blandit egestas lacus sodales non. Proin varius sagittis sollicitudin. Sed diam lacus, viverra nec congue ut, eleifend a velit. Quisque ullamcorper metus in finibus consectetur. Suspendisse faucibus feugiat semper. In mollis, arcu non tempor euismod, ipsum risus aliquam est, in porta lectus velit ac mauris. Fusce tempus consectetur sodales. Morbi fermentum magna sed est rhoncus, id hendrerit dui posuere. Integer justo ligula, vehicula vitae efficitur eu, consequat id urna. Mauris vitae tellus libero. Integer id massa lacus. Sed non porta velit. Fusce eget tortor sed est tincidunt varius at sed magna. Ut tincidunt eu ipsum sed dignissim. Quisque elementum felis faucibus ante efficitur, ac semper dui rutrum. Cras neque orci, laoreet non lorem sit amet, congue porta libero. Fusce feugiat, nibh at molestie gravida, erat orci lacinia mauris, a tristique risus orci ut magna. Quisque in diam non felis molestie ultrices maximus vitae nunc. Proin sollicitudin risus vitae tortor pharetra, sit amet mattis dui tempor. Donec vel rhoncus massa. Curabitur sit amet mollis nibh. Integer urna nulla, ullamcorper ut lacus vitae, varius volutpat ex. Proin euismod in magna vitae pharetra. In maximus cursus leo in pellentesque. Cras hendrerit odio rutrum arcu rutrum bibendum. Praesent arcu nibh, iaculis nec vestibulum non, cursus eu dui. Aliquam vulputate elit dictum varius dapibus. Vivamus enim lacus, gravida non dictum in, imperdiet ullamcorper libero. Praesent feugiat blandit ante. Nunc sed gravida odio. Duis vel magna ac ipsum commodo tincidunt. Vestibulum aliquam ipsum nibh, sit amet pulvinar velit tempor sit amet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam mi sapien, faucibus nec lacinia maximus, semper at nunc. Vestibulum ac accumsan diam, at accumsan dolor. Sed lacinia purus ac odio sagittis bibendum. Pellentesque euismod ultrices mauris. Vivamus id egestas augue, sit amet tempor orci. Suspendisse ultrices enim odio, quis semper augue auctor nec. In augue nunc, tempor sed tempor quis, consectetur at tellus. Phasellus bibendum, libero sed posuere ultrices, sapien nisi gravida sem, sed ullamcorper tellus ex eu augue. Donec vitae urna a enim iaculis dictum nec non massa. Nam a mauris in metus consequat dictum in condimentum purus. Praesent dui nisi, suscipit nec pellentesque vel, posuere vel velit. Nam malesuada, eros eget pretium efficitur, ipsum mi consectetur eros, id porttitor velit augue sit amet diam. Fusce auctor venenatis metus. Etiam aliquam, arcu consequat rhoncus interdum, nulla purus maximus libero, nec rutrum lectus mi in enim. Etiam porttitor est nisi, non sagittis enim eleifend vel. Praesent rhoncus tincidunt elit, nec blandit magna suscipit ut. Nam accumsan fermentum eros, eget iaculis massa facilisis quis. Maecenas vitae efficitur mauris. Praesent condimentum aliquam mi commodo varius. Nulla commodo euismod sapien non porta. In interdum magna sed mollis aliquam. Duis ligula mi, aliquam in sem nec, maximus gravida nunc. Curabitur diam ipsum, ornare et molestie sit amet, egestas vitae lacus. Nulla nec urna fringilla, convallis diam eu, maximus orci. Quisque varius felis sit amet lacinia lobortis. Mauris quis auctor libero. Curabitur auctor justo nunc, nec feugiat urna commodo efficitur. Sed quam nibh, ornare nec suscipit nec, semper nec tellus. Praesent quis sodales erat, id maximus sapien. Donec in scelerisque odio. In condimentum sem nisi, sit amet faucibus dui rutrum quis. Proin at mi magna. Vestibulum porttitor iaculis semper. Aenean sodales tincidunt ipsum, aliquet posuere elit gravida ac. Duis non volutpat mauris. Aliquam vitae est eu enim sagittis molestie in a neque. Cras fermentum suscipit elementum. Fusce rutrum, libero vitae maximus auctor, metus libero vulputate metus, eu maximus diam dolor id ipsum. Ut ac mauris facilisis, ultricies magna vitae, aliquam ipsum. Donec eu iaculis quam. Integer massa magna, pretium ac ante vel, fermentum semper odio. Cras vel enim purus. Ut tristique ut enim eu cursus. Curabitur rhoncus commodo odio a condimentum. Aenean interdum venenatis semper. Integer cursus finibus tincidunt. Maecenas facilisis suscipit tortor, non sollicitudin purus suscipit non. Maecenas facilisis venenatis diam, ut blandit quam tempus sit amet. Proin pulvinar lorem ac augue accumsan, at viverra quam consectetur. Etiam dignissim ultrices sapien, sit amet fermentum ipsum sagittis pharetra. In libero ante, pharetra a semper vitae, lobortis et dui. Donec tristique eget augue id interdum. Mauris nunc est, porta vitae volutpat id, lacinia id augue. Integer tincidunt aliquam nunc, in laoreet dui efficitur non. Nullam fringilla maximus faucibus. Nam ut lacus faucibus, semper nisi nec, dignissim nisi. Praesent urna metus, suscipit id enim sed, volutpat ornare metus. Nullam a nisl aliquam, semper nulla quis, volutpat leo. Suspendisse vitae molestie libero. Morbi augue leo, facilisis id maximus ac, faucibus sit amet urna. Cras sed lacus erat. Morbi ultrices elit nec fermentum ullamcorper. Morbi porta sapien sit amet magna eleifend euismod. Donec sollicitudin odio erat, nec lobortis tellus accumsan at. Suspendisse eu mollis tortor. Nulla eget cursus lorem, ac fringilla purus. Suspendisse molestie posuere justo, a luctus nunc. Nam hendrerit ex est, sit amet faucibus mi pharetra sit amet. Etiam eu justo sed ante iaculis vestibulum. Duis in lacus eu neque luctus facilisis iaculis in erat. Nunc eget orci sed lacus fringilla finibus id ac sem. Vivamus ut scelerisque mauris, ac malesuada augue. Ut at erat ut lorem aliquet facilisis id venenatis erat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras eget augue dui. Donec tellus enim, maximus at tempor at, tincidunt ut neque. Maecenas eget lectus metus. Duis sagittis at massa ut pharetra. Aenean ac consectetur nulla. Nunc luctus, purus et molestie suscipit, nisi tortor ullamcorper dui, non cursus ante elit quis mi. Maecenas facilisis ornare tincidunt. Sed ornare dui quis elit aliquet, a cursus sapien suscipit. Vivamus pulvinar nibh in maximus facilisis. Sed scelerisque posuere tortor, at faucibus ipsum tempus in. Donec fermentum nisi ut ante elementum, id dignissim magna dignissim. Proin imperdiet sem feugiat nulla dictum varius. Nunc eget ex a elit facilisis tincidunt. Sed sodales ligula sem, ac vulputate nisl consequat ut. Integer eget magna sed leo convallis dictum. In vitae consequat metus, eleifend commodo orci. Vestibulum metus erat, pretium ut volutpat ut, aliquam id tellus. Nunc blandit sit amet libero quis venenatis. Cras auctor est non nulla convallis vulputate at a magna. Aenean venenatis dui eu ultrices dapibus. Morbi aliquet urna nulla, sed venenatis orci pulvinar id. Quisque augue dolor, tincidunt sit amet massa at, fringilla vestibulum eros. In hac habitasse platea dictumst. Cras at magna nec nisi lacinia dictum. Cras at dui vitae nunc aliquam pellentesque. Maecenas nec risus velit. Aliquam maximus auctor mauris. Vivamus placerat condimentum nibh, vel tempus ex tincidunt vitae. Nam mattis neque sit amet dapibus suscipit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec dui sem, sodales sed ligula sit amet, aliquam sagittis risus. Nullam porta eros id ex laoreet, vel molestie arcu egestas. Suspendisse sed nulla nisi. Morbi rutrum magna vel elit varius, at tempor sapien tincidunt. Curabitur commodo velit sed mollis tincidunt. Vivamus vitae mi sapien. Suspendisse feugiat nisl nisi. Donec finibus diam ut tortor cursus, sed posuere dolor dapibus. Integer lobortis ut tellus nec eleifend. Donec quis metus id lacus suscipit tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque egestas turpis quis lacus molestie, varius viverra tellus efficitur. Suspendisse convallis, augue eget tempor efficitur, libero risus varius enim, quis ultricies dui nisl vel libero. Praesent consectetur diam nec sem auctor dignissim. Nullam sed convallis sapien. Cras dolor elit, varius eget velit ut, rhoncus placerat odio. Suspendisse sit amet faucibus nisl. Mauris a porttitor justo. Nam facilisis ornare quam, nec tempus diam elementum et. Donec placerat molestie odio et vestibulum. Mauris vel tincidunt ex. Aliquam iaculis neque sed aliquam faucibus. Sed vel magna vitae metus porta interdum. Quisque at libero nisi. Morbi iaculis tortor eu est fermentum, sit amet molestie elit porta. Ut elementum justo a justo varius, vitae ullamcorper nisl maximus. Cras id interdum est. Proin mollis ornare metus, tristique blandit arcu elementum id. Vestibulum nisi mauris, posuere sit amet ex quis, pulvinar elementum odio. Phasellus ut imperdiet velit, sit amet egestas neque. Nam eleifend quis lacus non tincidunt. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse ultrices in ante nec luctus. Donec eros diam, auctor sit amet purus eu, rutrum sagittis magna. Morbi mattis purus nec lacus pellentesque ultrices. Quisque sit amet nulla non nulla convallis gravida ut non nulla. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam placerat leo a mollis mattis. Duis varius, quam ut tempor ultricies, odio orci facilisis libero, at scelerisque nisl tellus pulvinar mi. Cras maximus mi ante, id convallis nunc suscipit volutpat. Cras semper urna justo, eu congue erat fermentum ut. Etiam nulla elit, pellentesque ut turpis eget, convallis accumsan mauris. In quis justo quam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus vel libero et tortor maximus elementum. Nam condimentum eros risus, et convallis ex vestibulum eget. Etiam id ex malesuada, mattis odio lacinia, placerat lectus. Morbi bibendum purus quis elit fermentum sodales in eget mi. Sed elementum pellentesque arcu quis varius. Cras tincidunt elementum nunc, non semper augue vulputate eu. Maecenas scelerisque sodales volutpat. Donec tempor, velit ut congue pellentesque, leo ante lobortis est, at porta mauris neque non justo. Vestibulum viverra, dolor et consectetur pellentesque, libero augue porttitor dui, et aliquam mauris nisi id diam. Aenean dui velit, vulputate hendrerit eleifend ut, accumsan in arcu. Maecenas a ligula ut eros consequat porttitor in eu urna. Nulla facilisi. Phasellus et sollicitudin tortor. In quis metus lobortis, suscipit ante at, posuere ipsum. Nam sit amet placerat ipsum. Nullam tincidunt nisl sit amet pulvinar sollicitudin. Ut augue nulla, porttitor at velit vel, tristique dapibus nunc. Phasellus lobortis in ante vitae ultrices. Maecenas commodo vehicula nisl, scelerisque commodo justo fermentum ut. Duis sed eros sit amet odio posuere congue. Praesent fermentum ipsum et nulla lacinia, vel interdum augue sollicitudin. Integer in quam malesuada, commodo dui ut, lacinia urna. Aenean aliquet, mauris id sagittis euismod, dui velit fringilla risus, et pharetra diam leo id elit. Proin faucibus feugiat purus, vel fermentum libero dapibus eu. In sodales maximus mauris sit amet congue. Pellentesque tempus orci ac iaculis hendrerit. In sit amet nisi orci. Cras eros orci, luctus a dui at, egestas bibendum erat. Integer erat nulla, tempor quis maximus vitae, cursus non nunc. Pellentesque efficitur nisl eget felis convallis, vitae consectetur urna egestas. Cras dui sapien, elementum eget eleifend sit amet, blandit et nisl. Nam eget erat neque. Suspendisse pretium, tellus viverra egestas tincidunt, nulla urna tristique risus, a auctor lacus odio non felis. Curabitur semper tempus ultrices. Donec nec metus aliquet lectus varius imperdiet. Aliquam ullamcorper ante nec arcu lobortis lacinia. Suspendisse tempus arcu arcu, a feugiat arcu venenatis ut. Proin molestie, lectus non venenatis egestas, nulla justo dapibus risus, sodales euismod ante elit consequat est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean sed mauris ex. Vestibulum varius non libero eu egestas. Donec placerat mauris ut neque luctus, in pellentesque nisl pulvinar. Aliquam efficitur mauris at tellus cursus aliquam. Suspendisse potenti. Quisque dapibus congue orci eu placerat. Etiam eget volutpat mauris. Duis eu libero lacinia, feugiat urna ut, pulvinar lectus. In pulvinar commodo justo, sed sagittis ligula. Phasellus volutpat odio a varius euismod. Integer auctor posuere lobortis. Vivamus eleifend tempus nibh a mattis. Nam dapibus convallis lacus, a consequat ipsum lobortis nec. Quisque viverra lobortis lorem et molestie. Pellentesque imperdiet auctor elit eget tincidunt. In tincidunt bibendum sem eget pretium. Donec vestibulum cursus molestie. Suspendisse et leo sed ante viverra tristique. In at congue lacus. Morbi id justo sed est imperdiet malesuada. Sed et orci nec nisi commodo rhoncus. Etiam at ex sit amet urna varius congue. Nulla libero orci, egestas quis commodo id, egestas vitae nunc. Duis at justo eu massa dictum volutpat vitae ac lacus. Morbi lobortis tellus in nisi lobortis lobortis. Aenean et rhoncus mauris. Donec eget rutrum tellus, sit amet commodo justo. Cras eu luctus lectus. Suspendisse potenti. Fusce a felis vel urna porttitor aliquet non id odio. Donec ullamcorper faucibus volutpat. Praesent fermentum urna non felis gravida, non tempus metus iaculis. Sed tempus, orci pharetra porta finibus, risus mi mattis nisl, vitae tincidunt justo purus eget purus. Maecenas varius tellus non eros bibendum condimentum vel eleifend tortor. Nam fermentum sed purus sit amet venenatis. Quisque in risus ac massa pellentesque maximus ultrices eget mi. Vivamus tincidunt tempor leo, ac vulputate magna hendrerit at. Suspendisse condimentum felis augue. In mattis libero eu finibus efficitur. Maecenas vehicula felis nunc, non blandit metus commodo nec. Nam non nulla eu eros finibus lobortis. Fusce condimentum volutpat placerat. Nulla vitae libero erat. Proin at orci non felis sodales aliquet. Morbi vitae fermentum elit, id pharetra lacus. Vestibulum cursus elementum orci, sed ornare lorem sollicitudin ac. Nullam rutrum vestibulum nunc, ut lacinia leo porta ac. Suspendisse dui odio, posuere sed dolor sit amet, maximus tincidunt libero. Praesent nec euismod felis. Vivamus consectetur lacus nibh, non pellentesque ipsum porta non. Donec suscipit leo et libero accumsan, sit amet semper enim vehicula. Cras sollicitudin leo quis eros rhoncus molestie. Praesent massa justo, interdum vel nisi ut, tristique lacinia justo. Nam vitae ex orci. Nam sit amet aliquet sem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent at euismod metus. Phasellus id tristique ipsum. Integer laoreet commodo neque ac vehicula. Mauris pulvinar ut orci id condimentum. Proin ac tincidunt metus, eu euismod metus. Etiam et ultrices mauris. Proin elementum libero non semper eleifend. Donec laoreet posuere luctus. Vestibulum in finibus nisi. Donec efficitur blandit turpis at sollicitudin. Aenean volutpat ex a varius aliquam. Quisque nec lectus scelerisque, dictum est sit amet, malesuada odio. Nam euismod enim interdum elit feugiat rutrum. Nam at mollis felis. Phasellus ut lectus faucibus neque tempus aliquet nec interdum justo. Ut dapibus varius est. Pellentesque eget fermentum erat, vitae pellentesque dolor. Mauris sollicitudin nibh ac ipsum congue, nec ullamcorper arcu consectetur. Aenean sit amet augue nec lectus interdum luctus consequat ut nisl. Integer vitae ipsum sit amet ex consectetur luctus. Fusce consequat metus non mi luctus, in tincidunt lacus egestas. In tincidunt orci eget tristique tincidunt. Suspendisse potenti. Vestibulum ultricies at tortor ac scelerisque. Morbi egestas lacus sapien, ac tristique orci convallis eget. In hac habitasse platea dictumst. Quisque sed turpis eget elit sollicitudin pharetra. Vivamus urna neque, aliquet sit amet risus vitae, congue porttitor sem. In id nibh enim. Curabitur consectetur condimentum semper. Suspendisse nisl mi, consequat eu finibus vitae, commodo quis est. Nam cursus ornare tortor efficitur commodo. Curabitur mattis luctus ipsum, ac malesuada mi fermentum et. Mauris mattis mi eu sodales efficitur. Cras auctor volutpat diam, eu tristique diam laoreet a. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris cursus velit sed tincidunt luctus. Maecenas eget euismod mauris. Praesent eleifend velit massa, aliquam ullamcorper nisi pulvinar sed. Donec sagittis, mauris sed hendrerit dictum, ligula urna consectetur nunc, non molestie nulla justo at mauris. In eget diam fringilla, ornare mauris at, consequat arcu. Praesent enim turpis, bibendum tincidunt dolor quis, tempor maximus ligula. Cras leo tortor, congue euismod nunc quis, porttitor hendrerit risus. In varius neque laoreet lectus cursus venenatis. Vivamus gravida varius est, sed malesuada diam euismod sit amet. Vivamus cursus aliquet lectus, at bibendum augue rutrum sit amet. Duis sit amet magna vel mauris hendrerit sollicitudin non quis dolor. Proin eleifend arcu in lacus dictum condimentum. Nullam massa lorem, porttitor non felis sed, tristique tincidunt lectus. Nunc accumsan auctor mi, ac dictum tortor scelerisque non. Mauris dui turpis, egestas eget convallis a, rhoncus accumsan enim. Sed facilisis fringilla elit, vel rutrum tellus fermentum at. Etiam lectus arcu, sodales sit amet scelerisque non, vehicula ac ante. Duis sodales consequat sapien, vitae convallis enim eleifend vel. Nullam suscipit ante justo, eget molestie quam ornare ac. Sed id ipsum dictum, accumsan libero consequat, consequat velit. Fusce a sem interdum, tincidunt mi nec, tristique erat. Quisque at venenatis lorem. Etiam volutpat malesuada nisi, nec laoreet urna porttitor sit amet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ut ullamcorper tellus. Vivamus nec leo pretium, porta tortor sed, dictum felis. Donec dignissim faucibus arcu, a hendrerit turpis vestibulum eu. Phasellus ornare purus eget mauris pellentesque, sed fringilla massa egestas. In hac habitasse platea dictumst. Duis at risus varius, sodales ante vitae, consequat mauris. Aenean finibus neque eu arcu ultricies accumsan. Fusce tincidunt, nulla pulvinar fringilla porttitor, nibh lorem mollis lorem, sit amet sollicitudin risus nunc quis diam. Donec imperdiet efficitur gravida. Suspendisse lectus nisi, efficitur eu massa vitae, vulputate mollis sapien. Aliquam erat volutpat. Integer id pulvinar felis. Quisque elementum leo at justo molestie volutpat. Pellentesque faucibus nisl in tortor posuere malesuada. Mauris molestie lacus venenatis dolor tincidunt, eu scelerisque risus pharetra. Curabitur quis arcu congue, mollis eros ac, malesuada urna. Donec neque nisi, faucibus a dolor non, fermentum pellentesque ligula. Maecenas molestie sed nisi sit amet maximus. Suspendisse potenti. Mauris eros ligula, aliquet ac condimentum in, pharetra non tellus. Donec porttitor eget eros ac viverra. Integer quis lectus nisl. Quisque efficitur nunc in turpis commodo, sit amet bibendum eros venenatis. Duis ullamcorper ac urna ut porttitor. Sed sed dui eu neque blandit rutrum id sed nunc. Donec a pretium magna, et elementum arcu. Morbi at sem sed nisi fermentum cursus. Curabitur venenatis vehicula neque, et egestas nibh dignissim ac. Mauris hendrerit turpis enim, vitae pharetra neque scelerisque non. Ut tristique sodales dignissim. Vivamus ornare est et arcu condimentum, eu vehicula mauris ultricies. Vivamus eu ligula ornare, molestie elit vel, facilisis libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla fermentum laoreet nisi quis commodo. In non tortor sapien. Nam condimentum condimentum tristique. Suspendisse dictum nunc urna. Sed eget convallis mi. Pellentesque pulvinar neque eu sapien dapibus, eget sodales urna sollicitudin. Sed tempus odio dolor, et maximus est mollis eget. Integer non semper justo, at mollis mi. Curabitur dictum scelerisque maximus. Quisque ultrices sed mauris vitae condimentum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi vitae hendrerit risus. Nullam vel dolor libero. Integer posuere, lectus a sollicitudin volutpat, neque nisi vehicula lorem, id rutrum arcu est non est. Phasellus magna diam, luctus quis iaculis sit amet, tempor in enim. In tincidunt, lectus id iaculis imperdiet, dui ante fermentum nulla, et semper eros nibh non augue. In libero massa, hendrerit at justo in, porttitor imperdiet turpis. Sed at lorem ut arcu dictum finibus eu quis nisl. Phasellus id sollicitudin arcu, vitae vulputate sem. Pellentesque tempus condimentum pretium. Curabitur euismod erat nec leo mattis facilisis. Mauris luctus, nunc non fringilla gravida, sem lacus gravida nisi, ut placerat libero urna ut du. Phasellus rutrum nibh quis diam porta, quis accumsan justo malesuada. Ut malesuada risus scelerisque volutpat bibendum. Donec interdum, sapien non dapibus rhoncus, nisl nulla dictum libero, vitae varius sapien tellus ac ipsum. Fusce ornare sem eget ex fringilla convallis. follow-redirects-1.15.6/test/assets/localhost.crt000066400000000000000000000021371457462373400220750ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDDDCCAfSgAwIBAgIJALzCVuuVEADhMA0GCSqGSIb3DQEBCwUAMA0xCzAJBgNV BAYTAkJFMCAXDTIxMTAzMDE4MTExNVoYDzIxMjExMDA2MTgxMTE1WjAhMQswCQYD VQQGEwJCRTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAroS25VMhjk1IvVv3gvB4ZMPhwRpeDP/gfdd2mWaqPS9m/S36 9DXGXKBiuNN0GNR8Ng1voaowFPRpvJAR6JBAhpdJsV+rLONg2jqUR49ihDZwpl77 bvYG91DXcWGRAPLjEIHZQFtvZjQxTRGo3c614GyLzO4bz1Cac0TLtSwmlgOzWcg7 g45+uvZOT7bJ7/7ryjUGassKiwE39RIRlFrE6DBj8TPTBmBSA6fzA2mlDX1YQzEz cZw7aM7IyTKEKM5C5Cc2H3ykd+fejPi/zM4ntrAOyeDXOwfskU5eXg8p/tL8USBn pDA94i1CNXBI+FDLwD2NZMVTb3J9vzghaN/5XwIDAQABo1kwVzAnBgNVHSMEIDAe oRGkDzANMQswCQYDVQQGEwJCRYIJAOjRQSYdVKWqMAkGA1UdEwQCMAAwCwYDVR0P BAQDAgTwMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEA PvKbSVKzOBxl5MRczuo/QULzFLu6Rwe7dxVbTH4mOvcf2Njd5rL6oKZNAbPp5TBa HSXXIVJsB0cKVBMtovu+Q343AeMxPHclCOTXnKfTG3OplLuhtkzsjDMrjzynLnUK 8iLdBT44Sa4BEPJwguZMb3fvhUKtbCj3WhoIodOgyD3W+Ufyvn5C9be6G9feBWrJ 52O1HPp72oi54gng0VhqzUXhN6FfFSwFygxf22C1m1grl4CBdfYb6DV17JqINtk8 HK0QOiWXlmUaGHOEYz8FZPOliUPpJWeD0N/tCAbkAYbMPvog93E1yNJjW4SYAh7z kVhFAcus9F4V9K47vx4a5w== -----END CERTIFICATE----- follow-redirects-1.15.6/test/assets/localhost.key000066400000000000000000000032131457462373400220710ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAroS25VMhjk1IvVv3gvB4ZMPhwRpeDP/gfdd2mWaqPS9m/S36 9DXGXKBiuNN0GNR8Ng1voaowFPRpvJAR6JBAhpdJsV+rLONg2jqUR49ihDZwpl77 bvYG91DXcWGRAPLjEIHZQFtvZjQxTRGo3c614GyLzO4bz1Cac0TLtSwmlgOzWcg7 g45+uvZOT7bJ7/7ryjUGassKiwE39RIRlFrE6DBj8TPTBmBSA6fzA2mlDX1YQzEz cZw7aM7IyTKEKM5C5Cc2H3ykd+fejPi/zM4ntrAOyeDXOwfskU5eXg8p/tL8USBn pDA94i1CNXBI+FDLwD2NZMVTb3J9vzghaN/5XwIDAQABAoIBAET0rWupUD3w7Yfc mczEBV4TQ9VP/M94HxS6GON9/FAWtcPd8iWiRdF9keRjsKDK/JVC89PV8g+lj03x QxI4RTao+nY6TeF7ql4v/TzVO+Dvvc0PBJwQXCpGaAoluey9C9kO5W+XcUnZ340L KEUUEyss2IRNpPFicNSQ30ijvE9TWeJ6gdWSqcpGSBhjoFa1Kd/9Aqc06VNSFwLx i4PSuU4YIgl1qlpUC7zN7bkQ3oqhoRpzzYL1p4MAmZ5c0bNAk0/LkIVaJedEbr+j dx8ABqY3LyAznd7IH72UMrN999r1jC0Th3+im6G92U6Ukbotj3AY9iIyqw/xkOUa SwTqLAECgYEA2fCnfVJFSAc5CwxDF9FCVLLgqHb6EiJZBDLOSSXVe6crajujZXlx frawn3SNFR6AqNFHualCkOkrl7anucdG0733DjACqcl0LhNd4C1amxaGWUoYmGDw ousY/ekwtEbJWmY/nAzAn3qOIuXSV+QVndGPjOshF5DeP+Y/DpfcX18CgYEAzP7U M6sCI5pSTTZOY273laVxbPyrK6z8SjW1emrC9tDWeFMDRr9qy9GAj0ov4EhbAtLG 2Frt89jHdSNxaZDe6Rcc8biVFZZWITwkH9QNwX52grNezMXD50GMjzDqVF+2H5pZ Wa65/71ZUPRjsyUu1ePrcQlWcA/YVqet2WBUpgECgYB9LTZmSry0VEG1UMOwiGa6 00sqN7wGcmgCe1P0u6BUt32+NKby/7/qcfAchgsKmEx5qkqyHr+3D9YT+7t2fzj1 IWUnZvgAoU7zr/f5bNNfxJ5B5scdroBIcxQVsrxgr0+zdosOjFyOvQuqi6o3BTBN RzJWVC7bpD+jIBITxbGzrQKBgD4sh+XH1xU/R/j9IJdN36+2hwlcNPpBNB+53Hnt iYZcXsANxW+evOBmgUx0XsLyjw/zJ7YVFhigRhaEEnDHLKSbiv7RUf5DI4pe+EHj Ce0G0yDfEEChNsKcAeqoFlpS0SUSpkjqEqW7IyzHgrmh7GuY/h7Bi0Lfu2jE4JiO e/4BAoGARW4XbEHT2eNd27inCiN4NBeFQbp8UqdPGeL9vTOl5RHCouATx5QjIhtK 7Bb9byt2BOSvxNOJbh7kk1NThd/y1Y7GARR/61s7czx8Ass3bxJ6+rl20PhozMZb BWA6BwWl0DfanuHbgz+jIfU60K5tMHX0dA1tyRi2iee91e2ugyk= -----END RSA PRIVATE KEY----- follow-redirects-1.15.6/test/server.js000066400000000000000000000047111457462373400177350ustar00rootroot00000000000000// provides boilerplate for managing http and https servers during tests var http = require("http"); var https = require("https"); var net = require("net"); var url = require("url"); module.exports = function (defaultPorts) { var servers = []; /** * Starts a server * * If options is a function, uses that the request handler for a `http` server on the default port. * options.protocol - the protocol to use (`http` or `https`). Defaults to `http`. * options.port - the port to use, will fall back to defaultPorts[protocol]. * options.app - the request handler passed to http|https.createServer * * the options object will also be passed to as the https config for https servers * * @param options * @returns {Promise} that resolves when the server successfully started */ function start(options) { return new Promise(function (resolve, reject) { // Create server var app = typeof options === "function" ? options : options.app; var isHttps = /^https/.test(options.protocol || "http"); var server = !isHttps ? http.createServer(app) : https.createServer(options, app); servers.push(server); // Set up CONNECT functionality server.on("connect", (req, clientSocket, head) => { var remote = url.parse("http://" + req.url); var remoteSocket = net.connect(remote.port, remote.hostname, function () { clientSocket.write("HTTP/1.1 200 Connection Established\r\n" + "Proxy-agent: Test proxy\r\n" + "\r\n"); remoteSocket.write(head); remoteSocket.pipe(clientSocket); clientSocket.pipe(remoteSocket); }); }); // Start the server var port = options.port || (isHttps ? defaultPorts.https : defaultPorts.http); server.listen(port, function (error) { return error ? reject(error) : resolve(); }); }); } /** * Stops all the currently running servers previously created with `start` * @returns {Promise} that resolves when all servers have successfully shut down. */ function stop() { return Promise.all(servers.map(stopServer)).then(clearServers); } function stopServer(server) { return new Promise(function (resolve, reject) { server.close(function (error) { return error ? reject(error) : resolve(); }); }); } function clearServers() { servers = []; } return { start: start, stop: stop }; }; follow-redirects-1.15.6/test/test.js000066400000000000000000002367601457462373400174210ustar00rootroot00000000000000var express = require("express"); var assert = require("assert"); var net = require("net"); var server = require("./server")({ https: 3601, http: 3600 }); var url = require("url"); var followRedirects = require(".."); var http = followRedirects.http; var https = followRedirects.https; var fs = require("fs"); var path = require("path"); var lolex = require("lolex"); var util = require("./util"); var concat = require("concat-stream"); var concatJson = util.concatJson; var delay = util.delay; var redirectsTo = util.redirectsTo; var sendsJson = util.sendsJson; var asPromise = util.asPromise; var proxy = util.proxy; var testFile = path.resolve(__dirname, "assets/input.txt"); var testFileBuffer = fs.readFileSync(testFile); var testFileString = testFileBuffer.toString(); var nodeMajorVersion = Number.parseInt(process.version.match(/\d+/)[0], 10); describe("follow-redirects", function () { function httpsOptions(app) { return { app: app, protocol: "https", cert: fs.readFileSync(path.resolve(__dirname, "assets/localhost.crt")), key: fs.readFileSync(path.resolve(__dirname, "assets/localhost.key")), }; } var ca = fs.readFileSync(path.resolve(__dirname, "assets/ca.crt")); var app; var app2; var originalMaxRedirects; var originalMaxBodyLength; beforeEach(function () { originalMaxRedirects = followRedirects.maxRedirects; originalMaxBodyLength = followRedirects.maxBodyLength; app = express(); app2 = express(); }); afterEach(function () { followRedirects.maxRedirects = originalMaxRedirects; followRedirects.maxBodyLength = originalMaxBodyLength; return server.stop(); }); it("http.get with string and callback - redirect", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", redirectsTo("/d")); app.get("/d", redirectsTo("/e")); app.get("/e", redirectsTo("/f")); app.get("/f", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/f"); }); }); it("http.get with URL object and callback - redirect", function () { if (nodeMajorVersion < 10) { this.skip(); } app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", redirectsTo("/d")); app.get("/d", redirectsTo("/e")); app.get("/e", redirectsTo("/f")); app.get("/f", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get( new URL("http://localhost:3600/a"), concatJson(resolve, reject) ).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/f"); }); }); it("http.get with options object and callback - redirect", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", redirectsTo("/d")); app.get("/d", redirectsTo("/e")); app.get("/e", redirectsTo("/f")); app.get("/f", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { var options = { hostname: "localhost", port: 3600, path: "/a", method: "GET", }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/f"); }); }); it("http.get with string and callback - no redirect", function () { app.get("/a", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); }); }); it("http.get with options object and callback - no redirect", function () { app.get("/a", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { var options = { hostname: "localhost", port: 3600, path: "/a?xyz", method: "GET", }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/a?xyz"); }); }); it("http.get with host option and callback - redirect", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", redirectsTo("/d")); app.get("/d", redirectsTo("/e")); app.get("/e", redirectsTo("/f")); app.get("/f", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "GET", }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/f"); }); }); it("http.get to IPv4 address", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", redirectsTo("/d")); app.get("/d", redirectsTo("/e")); app.get("/e", redirectsTo("/f")); app.get("/f", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://127.0.0.1:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://127.0.0.1:3600/f"); }); }); it("http.get to IPv6 address", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", redirectsTo("/d")); app.get("/d", redirectsTo("/e")); app.get("/e", redirectsTo("/f")); app.get("/f", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://[::1]:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://[::1]:3600/f"); }); }); it("http.get to bracketed IPv4 address", function () { var error = null; try { http.get("http://[127.0.0.1]:3600/a"); } catch (err) { error = err; } assert(error instanceof Error); assert(error instanceof TypeError); assert.equal(error.code, "ERR_INVALID_URL"); assert.equal(error.input, "http://[127.0.0.1]:3600/a"); }); it("http.get to bracketed IPv4 address specified as host", function () { var error = null; try { http.get({ host: "[127.0.0.1]:3600", path: "/a", }); } catch (err) { error = err; } assert(error instanceof Error); assert(error instanceof TypeError); assert.equal(error.code, "ERR_INVALID_URL"); }); it("http.get to bracketed IPv4 address specified as hostname", function () { var error = null; try { http.get({ hostname: "[127.0.0.1]", port: 3600, path: "/a", }); } catch (err) { error = err; } assert(error instanceof Error); assert(error instanceof TypeError); assert.equal(error.code, "ERR_INVALID_URL"); }); it("http.get to bracketed hostname", function () { var error = null; try { http.get("http://[localhost]:3600/a"); } catch (err) { error = err; } assert(error instanceof Error); assert(error instanceof TypeError); assert.equal(error.code, "ERR_INVALID_URL"); assert.equal(error.input, "http://[localhost]:3600/a"); }); it("http.get redirecting to IPv4 address", function () { app.get("/a", redirectsTo("http://127.0.0.1:3600/b")); app.get("/b", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://127.0.0.1:3600/b"); }); }); it("http.get redirecting to IPv6 address", function () { app.get("/a", redirectsTo("http://[::1]:3600/b")); app.get("/b", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://[::1]:3600/b"); }); }); it("http.get redirecting to bracketed IPv4 address", function () { app.get("/a", redirectsTo("http://[127.0.0.1]:3600/b")); app.get("/b", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(reject)).on("error", resolve); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_FR_REDIRECTION_FAILURE"); var cause = error.cause; assert(cause instanceof Error); assert(cause instanceof TypeError); assert.equal(cause.code, "ERR_INVALID_URL"); assert.equal(cause.input, "http://[127.0.0.1]:3600/b"); }); }); it("http.get redirecting to bracketed hostname", function () { app.get("/a", redirectsTo("http://[localhost]:3600/b")); app.get("/b", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(reject)).on("error", resolve); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_FR_REDIRECTION_FAILURE"); var cause = error.cause; assert(cause instanceof Error); assert(cause instanceof TypeError); assert.equal(cause.code, "ERR_INVALID_URL"); assert.equal(cause.input, "http://[localhost]:3600/b"); }); }); it("http.get with response event", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", redirectsTo("/d")); app.get("/d", redirectsTo("/e")); app.get("/e", redirectsTo("/f")); app.get("/f", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a") .on("response", concatJson(resolve, reject)) .on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/f"); }); }); it("http.get with relative URL path", function () { var error = null; try { http.get("/relative"); } catch (err) { error = err; } assert(error instanceof Error); assert(error instanceof TypeError); assert.equal(error.code, "ERR_INVALID_URL"); assert.equal(error.input, "/relative"); }); it("redirect to URL with fragment", function () { app.get("/a", redirectsTo("/b#abc")); app.get("/b", redirectsTo("/c#def")); app.get("/c", redirectsTo("/d#ghi")); app.get("/d", redirectsTo("/e#jkl")); app.get("/e", redirectsTo("/f#mno")); app.get("/f", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/f#mno"); }); }); it("should return with the original status code if the response does not contain a location header", function () { app.get("/a", function (req, res) { res.status(307).end(); }); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", resolve).on("error", reject); })) .then(function (res) { assert.equal(res.statusCode, 307); assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); res.on("data", function () { // noop to consume the stream (server won't shut down otherwise). }); }); }); it("should emit connection errors on the returned stream", function () { app.get("/a", redirectsTo("http://localhost:36002/b")); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", reject).on("error", resolve); })) .then(function (error) { assert.equal(error.code, "ECONNREFUSED"); }); }); it("should emit socket events on the returned stream", function () { app.get("/a", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a") .on("socket", resolve) .on("error", reject); })) .then(function (socket) { assert(socket instanceof net.Socket, "socket event should emit with socket"); }); }); it("should emit connect events on the returned stream", function () { app.get("/a", sendsJson({ a: "b" })); var req; return server.start(app) .then(asPromise(function (resolve, reject) { req = http.get("http://localhost:3600/a"); req.on("connect", function (response, socket, head) { resolve({ response: response, socket: socket, head: head }); }); req.on("error", reject); req._currentRequest.emit("connect", "r", "s", "h"); })) .then(function (args) { req.destroy(); assert.equal(args.response, "r"); assert.equal(args.socket, "s"); assert.equal(args.head, "h"); }); }); it("emits an error on redirects with an invalid location", function () { if (nodeMajorVersion < 10) { this.skip(); } app.get("/a", function (req, res) { // Explictly send response with invalid Location header res.socket.write("HTTP/1.1 301 Moved Permanently\r\n"); res.socket.write("Location: http://смольный-институт.рф\r\n"); res.socket.write("\r\n"); res.socket.end(); }); return server.start(app) .then(asPromise(function (resolve) { http.get("http://localhost:3600/a").on("error", resolve); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_FR_REDIRECTION_FAILURE"); assert(error.cause instanceof Error); switch (error.cause.code) { // Node 17+ case "ERR_INVALID_URL": assert(/^Redirected request failed: Invalid URL/.test(error.message)); break; // Older Node versions case "ERR_UNESCAPED_CHARACTERS": assert.equal(error.message, "Redirected request failed: Request path contains unescaped characters"); break; default: throw new Error("Unexpected error code " + error.code); } }); }); it("emits an error when the request fails for another reason", function () { app.get("/a", function (req, res) { res.socket.write("HTTP/1.1 301 Moved Permanently\r\n"); res.socket.write("Location: other\r\n"); res.socket.write("\r\n"); res.socket.end(); }); return server.start(app) .then(asPromise(function (resolve) { var request = http.get("http://localhost:3600/a"); request._performRequest = function () { throw new Error("custom"); }; request.on("error", resolve); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.message, "Redirected request failed: custom"); }); }); describe("setTimeout", function () { var clock; beforeEach(function () { clock = lolex.install(); }); afterEach(function () { clock.uninstall(); }); it("clears timeouts after a successful response", function () { app.get("/redirect", redirectsTo("/timeout")); app.get("/timeout", delay(clock, 2000, sendsJson({ didnot: "timeout" }))); var req; return server.start(app) .then(asPromise(function (resolve, reject) { req = http.get("http://localhost:3600/redirect", concatJson(resolve, reject)); req.on("error", reject); req.setTimeout(3000, function () { throw new Error("should not have timed out"); }); })) .then(function (res) { assert.deepEqual(res.parsedJson, { didnot: "timeout" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/timeout"); clock.tick(5000); }); }); it("clears timeouts after an error response", function () { app.get("/redirect", redirectsTo("http://localhost:3602/b")); var req; return server.start(app) .then(asPromise(function (resolve, reject) { req = http.get("http://localhost:3600/redirect", reject); req.setTimeout(3000, function () { throw new Error("should not have timed out"); }); req.on("error", resolve); })) .then(function (error) { assert.equal(error.code, "ECONNREFUSED"); clock.tick(5000); }); }); it("handles errors occuring before a socket is established", function () { app.get("/redirect", redirectsTo("http://localhost:3602/b")); var req; return server.start(app) .then(asPromise(function (resolve, reject) { req = http.get("http://localhost:3600/redirect", reject); req.setTimeout(3000, function () { throw new Error("should not have timed out"); }); req.emit("error", new Error()); req.on("error", resolve); })) .then(function (error) { assert.equal(error.code, "ECONNREFUSED"); clock.tick(5000); }); }); it("sets a timeout when the socket already exists", function () { app.get("/timeout", delay(clock, 5000, sendsJson({ timed: "out" }))); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.get("http://localhost:3600/timeout", function () { throw new Error("should have timed out"); }); req.on("error", reject); req.on("socket", function () { assert(req.socket instanceof net.Socket); req.setTimeout(3000, function () { req.destroy(); resolve(); }); }); })); }); it("destroys the socket after configured inactivity period", function () { app.get("/data", delay(clock, 3000, sendsJson({ took: "toolongtosenddata" }))); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.get("http://localhost:3600/data", concatJson(reject, reject)); req.on("error", reject); req.setTimeout(100, function () { throw new Error("should not have timed out"); }); req.on("socket", function () { req.socket.on("timeout", function () { resolve(); }); }); })); }); it("should timeout on the final request", function () { app.get("/redirect1", redirectsTo("/redirect2")); app.get("/redirect2", redirectsTo("/timeout")); app.get("/timeout", delay(clock, 5000, sendsJson({ timed: "out" }))); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.get("http://localhost:3600/redirect1", function () { throw new Error("should have timed out"); }); req.on("error", reject); req.setTimeout(1000, function () { req.destroy(); resolve(); }); })); }); it("should include redirect delays in the timeout", function () { app.get("/redirect1", delay(clock, 1000, redirectsTo("/redirect2"))); app.get("/redirect2", delay(clock, 1000, redirectsTo("/redirect3"))); app.get("/redirect3", delay(clock, 1000, "/timeout")); app.get("/timeout", delay(clock, 1000, sendsJson({ timed: "out" }))); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.get("http://localhost:3600/redirect1", function () { throw new Error("should have timed out"); }); req.on("error", reject); req.setTimeout(2000, function () { req.destroy(); resolve(); }); })); }); it("overrides existing timeouts", function () { app.get("/redirect", redirectsTo("/timeout")); app.get("/timeout", delay(clock, 5000, sendsJson({ timed: "out" }))); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.get("http://localhost:3600/redirect", function () { throw new Error("should have timed out"); }); req.on("error", reject); var callbacks = 0; function timeoutCallback() { if (++callbacks === 3) { req.destroy(); resolve(callbacks); } } req.setTimeout(10000, timeoutCallback); req.setTimeout(10000, timeoutCallback); req.setTimeout(1000, timeoutCallback); })); }); }); it("should follow redirects over https", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", sendsJson({ baz: "quz" })); return server.start(httpsOptions(app)) .then(asPromise(function (resolve, reject) { var opts = url.parse("https://localhost:3601/a"); opts.ca = ca; https.get(opts, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { baz: "quz" }); assert.deepEqual(res.responseUrl, "https://localhost:3601/c"); }); }); it("should destroy responses", function () { app.get("/a", hangingRedirectTo("/b")); app.get("/b", hangingRedirectTo("/c")); app.get("/c", hangingRedirectTo("/d")); app.get("/d", hangingRedirectTo("/e")); app.get("/e", hangingRedirectTo("/f")); app.get("/f", sendsJson({ a: "b" })); function hangingRedirectTo(destination) { return function (req, res) { res.writeHead(301, { location: destination }); res.write(new Array(128).join(" ")); }; } return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/f"); }); }); it("should honor query params in redirects", function () { app.get("/a", redirectsTo("/b?greeting=hello")); app.get("/b", function (req, res) { res.json({ greeting: req.query.greeting }); }); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { greeting: "hello" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/b?greeting=hello"); }); }); it("should allow aborting", function () { var request; app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", function () { request.abort(); }); return server.start(app) .then(asPromise(function (resolve, reject) { var currentTime = Date.now(); request = http.get("http://localhost:3600/a", resolve); assert(request.aborted === false || // Node >= v11.0.0 typeof request.aborted === "undefined"); // Node < v11.0.0 request.on("response", reject); request.on("error", reject); request.on("abort", onAbort); function onAbort() { assert(request.aborted === true || // Node >= v11.0.0 typeof request.aborted === "number" && request.aborted > currentTime); // Node < v11.0.0 request.removeListener("error", reject); request.on("error", noop); resolve(); } })); }); it("should provide connection", function () { var request; app.get("/a", sendsJson({})); return server.start(app) .then(asPromise(function (resolve) { request = http.get("http://localhost:3600/a", resolve); })) .then(function () { assert(request.connection instanceof net.Socket); }); }); it("should provide flushHeaders", function () { app.get("/a", redirectsTo("/b")); app.get("/b", sendsJson({ foo: "bar" })); return server.start(app) .then(asPromise(function (resolve, reject) { var request = http.get("http://localhost:3600/a", resolve); request.flushHeaders(); request.on("error", reject); })); }); it("should provide getHeader", function () { var req = http.request("http://localhost:3600/a"); req.setHeader("my-header", "my value"); assert.equal(req.getHeader("my-header"), "my value"); req.destroy(); }); it("should provide removeHeader", function () { app.get("/a", redirectsTo("/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", concatJson(resolve, reject)); req.setHeader("my-header", "my value"); assert.equal(req.getHeader("my-header"), "my value"); req.removeHeader("my-header"); assert.equal(req.getHeader("my-header"), undefined); req.end(); })) .then(function (res) { var headers = res.parsedJson; assert.equal(headers["my-header"], undefined); }); }); it("should provide setHeader", function () { app.get("/a", redirectsTo("/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", concatJson(resolve, reject)); req.setHeader("my-header", "my value"); assert.equal(req.getHeader("my-header"), "my value"); req.end(); })) .then(function (res) { var headers = res.parsedJson; assert.equal(headers["my-header"], "my value"); }); }); it("should provide setNoDelay", function () { app.get("/a", redirectsTo("/b")); app.get("/b", sendsJson({ foo: "bar" })); return server.start(app) .then(asPromise(function (resolve, reject) { var request = http.get("http://localhost:3600/a", resolve); request.setNoDelay(true); request.on("error", reject); })); }); it("should provide setSocketKeepAlive", function () { app.get("/a", redirectsTo("/b")); app.get("/b", sendsJson({ foo: "bar" })); return server.start(app) .then(asPromise(function (resolve) { var request = http.get("http://localhost:3600/a", resolve); request.setSocketKeepAlive(true); })); }); it("should provide setTimeout", function () { app.get("/a", redirectsTo("/b")); app.get("/b", sendsJson({ foo: "bar" })); return server.start(app) .then(asPromise(function (resolve) { var request = http.get("http://localhost:3600/a", resolve); request.setTimeout(1000); })); }); it("should provide socket", function () { var request; app.get("/a", sendsJson({})); return server.start(app) .then(asPromise(function (resolve) { request = http.get("http://localhost:3600/a", resolve); })) .then(function () { assert(request.socket instanceof net.Socket); }); }); describe("should obey a `maxRedirects` property", function () { beforeEach(function () { var i = 22; while (i > 0) { app.get("/r" + i, redirectsTo("/r" + --i)); } app.get("/r0", sendsJson({ foo: "bar" })); }); it("which defaults to 21", function () { return server.start(app) // 21 redirects should work fine .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/r21", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { foo: "bar" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/r0"); }) // 22 redirects should fail .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/r22", reject).on("error", resolve); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_FR_TOO_MANY_REDIRECTS"); assert.equal(error.message, "Maximum number of redirects exceeded"); }); }); it("which can be set globally", function () { followRedirects.maxRedirects = 22; return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/r22", concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { foo: "bar" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/r0"); }); }); it("set as an option on an individual request", function () { var u = url.parse("http://localhost:3600/r2"); u.maxRedirects = 1; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(u, reject).on("error", resolve); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_FR_TOO_MANY_REDIRECTS"); assert.equal(error.message, "Maximum number of redirects exceeded"); }); }); }); describe("the trackRedirects option", function () { beforeEach(function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", sendsJson({})); }); describe("when not set", function () { it("should not track redirects", function () { return server.start(app) .then(asPromise(function (resolve, reject) { var opts = url.parse("http://localhost:3600/a"); http.get(opts, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { var redirects = res.redirects; assert.equal(redirects.length, 0); }); }); }); describe("when set to true", function () { it("should track redirects", function () { return server.start(app) .then(asPromise(function (resolve, reject) { var opts = url.parse("http://localhost:3600/a"); opts.trackRedirects = true; http.get(opts, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { var redirects = res.redirects; assert.equal(redirects.length, 3); assert.equal(redirects[0].url, "http://localhost:3600/a"); assert.equal(redirects[0].statusCode, 302); assert.equal(redirects[0].headers["content-type"], "text/plain; charset=utf-8"); assert.equal(redirects[1].url, "http://localhost:3600/b"); assert.equal(redirects[1].statusCode, 302); assert.equal(redirects[1].headers["content-type"], "text/plain; charset=utf-8"); assert.equal(redirects[2].url, "http://localhost:3600/c"); assert.equal(redirects[2].statusCode, 200); assert.equal(redirects[2].headers["content-type"], "application/json; charset=utf-8"); }); }); }); }); describe("should switch to safe methods when appropriate", function () { function itChangesMethod(statusCode, postToGet, changeAll) { describe("when redirecting with status code " + statusCode, function () { itRedirectsWith(statusCode, "GET", "GET"); itRedirectsWith(statusCode, "HEAD", "HEAD"); itRedirectsWith(statusCode, "POST", postToGet ? "GET" : "POST"); itRedirectsWith(statusCode, "PUT", changeAll ? "GET" : "PUT"); itRedirectsWith(statusCode, "DELETE", changeAll ? "GET" : "DELETE"); }); } function itRedirectsWith(statusCode, originalMethod, redirectedMethod) { var description = "should " + (originalMethod === redirectedMethod ? "reuse " + originalMethod : "switch from " + originalMethod + " to " + redirectedMethod); it(description, function () { app[originalMethod.toLowerCase()]("/a", redirectsTo(statusCode, "/b")); app[redirectedMethod.toLowerCase()]("/b", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { var opts = url.parse("http://localhost:3600/a"); opts.method = originalMethod; http.request(opts, resolve).on("error", reject).end(); })) .then(function (res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/b"); if (res.statusCode !== 200) { throw new Error("Did not use " + redirectedMethod); } }); }); } itChangesMethod(300, false); itChangesMethod(301, true); itChangesMethod(302, true); itChangesMethod(303, true, true); itChangesMethod(307, false); }); describe("should handle cross protocol redirects ", function () { it("(https -> http -> https)", function () { app.get("/a", redirectsTo("http://localhost:3600/b")); app2.get("/b", redirectsTo("https://localhost:3601/c")); app.get("/c", sendsJson({ yes: "no" })); return Promise.all([server.start(httpsOptions(app)), server.start(app2)]) .then(asPromise(function (resolve, reject) { var opts = url.parse("https://localhost:3601/a"); opts.ca = ca; https.get(opts, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { yes: "no" }); assert.deepEqual(res.responseUrl, "https://localhost:3601/c"); }); }); it("(http -> https -> http)", function () { app.get("/a", redirectsTo("https://localhost:3601/b")); app2.get("/b", redirectsTo("http://localhost:3600/c")); app.get("/c", sendsJson({ hello: "goodbye" })); return Promise.all([server.start(app), server.start(httpsOptions(app2))]) .then(asPromise(function (resolve, reject) { var opts = url.parse("http://localhost:3600/a"); opts.ca = ca; http.get(opts, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { hello: "goodbye" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/c"); }); }); }); describe("should error on an unsupported protocol redirect", function () { it("(http -> about)", function () { app.get("/a", redirectsTo("about:blank")); return server.start(app) .then(asPromise(function (resolve, reject) { http.get("http://localhost:3600/a") .on("response", function () { return reject(new Error("unexpected response")); }) .on("error", resolve); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.message, "Redirected request failed: Unsupported protocol about:"); var cause = error.cause; assert(cause instanceof Error); assert(cause instanceof TypeError); assert.equal(cause.message, "Unsupported protocol about:"); }); }); }); it("should wait for an explicit call to end", function () { var redirected = false; app.post("/a", redirectsTo(307, "http://localhost:3600/b")); app.post("/b", redirectsTo(307, "http://localhost:3600/c")); app.post("/c", redirectsTo(307, "http://localhost:3600/d")); app.post("/d", function (req, res) { redirected = true; req.pipe(res); }); var req; return server.start(app) .then(asPromise(function (resolve, reject) { req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.write(testFileString); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert(redirected); // If we can still write to the request, it wasn't closed yet req.write(testFileString); req.end(); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { assert.equal(str, testFileString + testFileString); }); }); it("errors on write after end", function () { app.post("/a", function (req, res) { req.pipe(res); }); return server.start(app) .then(function () { var req = http.request("http://localhost:3600/a", { method: "POST" }); req.write(testFileString); req.end(); try { req.write(testFileString); } catch (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_STREAM_WRITE_AFTER_END"); assert.equal(error.message, "write after end"); return; } finally { req.destroy(); } throw new Error("no error"); }); }); it("should support writing into request stream without redirects", function () { app.post("/a", function (req, res) { req.pipe(res); }); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end(testFileBuffer, "buffer"); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { assert.equal(str, testFileString); }); }); it("should support writing into request stream with redirects", function () { app.post("/a", redirectsTo(307, "http://localhost:3600/b")); app.post("/b", redirectsTo(307, "http://localhost:3600/c")); app.post("/c", redirectsTo(307, "http://localhost:3600/d")); app.post("/d", function (req, res) { req.pipe(res); }); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end(testFileBuffer, "buffer"); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { assert.equal(str, testFileString); }); }); it("should support piping into request stream without redirects", function () { app.post("/a", function (req, res) { req.pipe(res); }); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); fs.createReadStream(testFile).pipe(req); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { assert.equal(str, testFileString); }); }); it("should support piping into request stream with redirects", function () { app.post("/a", redirectsTo(307, "http://localhost:3600/b")); app.post("/b", redirectsTo(307, "http://localhost:3600/c")); app.post("/c", redirectsTo(307, "http://localhost:3600/d")); app.post("/d", function (req, res) { req.pipe(res); }); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); fs.createReadStream(testFile).pipe(req); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { assert.equal(str, testFileString); }); }); it("should support piping into request stream with explicit Content-Length without redirects", function () { app.post("/a", function (req, res) { req.pipe(res); }); var opts = url.parse("http://localhost:3600/a"); opts.method = "POST"; opts.headers = { "Content-Length": testFileBuffer.byteLength, }; return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request(opts, resolve); fs.createReadStream(testFile).pipe(req); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { assert.equal(str, testFileString); }); }); it("should support piping into request stream with explicit Content-Length with redirects", function () { app.post("/a", redirectsTo(307, "http://localhost:3600/b")); app.post("/b", redirectsTo(307, "http://localhost:3600/c")); app.post("/c", redirectsTo(307, "http://localhost:3600/d")); app.post("/d", function (req, res) { req.pipe(res); }); var opts = url.parse("http://localhost:3600/a"); opts.method = "POST"; opts.headers = { "Content-Length": testFileBuffer.byteLength, }; return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request(opts, resolve); fs.createReadStream(testFile).pipe(req); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { assert.equal(str, testFileString); }); }); describe("should obey a `maxBodyLength` property", function () { it("which defaults to 10MB", function () { assert.equal(followRedirects.maxBodyLength, 10 * 1024 * 1024); }); it("set globally, on write", function () { app.post("/a", function (req, res) { req.pipe(res); }); followRedirects.maxBodyLength = 8; return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, reject); req.write("12345678"); req.on("error", resolve); req.write("9"); })) .then(function (error) { assert.equal(error.message, "Request body larger than maxBodyLength limit"); }); }); it("set per request, on write", function () { app.post("/a", function (req, res) { req.pipe(res); }); var opts = url.parse("http://localhost:3600/a"); opts.method = "POST"; opts.maxBodyLength = 8; return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request(opts, reject); req.write("12345678"); req.on("error", resolve); req.write("9"); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_FR_MAX_BODY_LENGTH_EXCEEDED"); assert.equal(error.message, "Request body larger than maxBodyLength limit"); }); }); it("set globally, on end", function () { app.post("/a", function (req, res) { req.pipe(res); }); followRedirects.maxBodyLength = 8; return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, reject); req.write("12345678"); req.on("error", resolve); req.end("9"); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_FR_MAX_BODY_LENGTH_EXCEEDED"); assert.equal(error.message, "Request body larger than maxBodyLength limit"); }); }); it("set per request, on end", function () { app.post("/a", function (req, res) { req.pipe(res); }); var opts = url.parse("http://localhost:3600/a"); opts.method = "POST"; opts.maxBodyLength = 8; return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request(opts, reject); req.write("12345678"); req.on("error", resolve); req.end("9"); })) .then(function (error) { assert(error instanceof Error); assert.equal(error.code, "ERR_FR_MAX_BODY_LENGTH_EXCEEDED"); assert.equal(error.message, "Request body larger than maxBodyLength limit"); }); }); }); describe("writing invalid data", function () { it("throws an error", function () { var req = http.request("http://example.org/"); var error = null; try { req.write(12345678); } catch (err) { error = err; } req.destroy(); assert(error instanceof Error); assert(error instanceof TypeError); assert.equal(error.message, "data should be a string, Buffer or Uint8Array"); }); }); describe("when switching from POST to GET", function () { it("should drop the entity and associated headers", function () { app.post("/a", redirectsTo(302, "http://localhost:3600/b")); app.get("/b", function (req, res) { res.write(JSON.stringify(req.headers)); req.pipe(res); // will invalidate JSON if non-empty }); var opts = url.parse("http://localhost:3600/a"); opts.method = "POST"; opts.headers = { "other": "value", "content-type": "application/javascript", "Content-Length": testFileBuffer.byteLength, }; return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request(opts, resolve); fs.createReadStream(testFile).pipe(req); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); assert.equal(body.other, "value"); assert.equal(body["content-type"], undefined); assert.equal(body["content-length"], undefined); }); }); }); describe("when redirecting to a different host while the host header is set", function () { it("uses the new host header if redirect host is different", function () { app.get("/a", redirectsTo(302, "http://localhost:3600/b")); app.get("/b", function (req, res) { res.write(JSON.stringify(req.headers)); req.pipe(res); // will invalidate JSON if non-empty }); return server.start(app) .then(asPromise(function (resolve, reject) { var opts = url.parse("http://localhost:3600/a"); opts.headers = { hOsT: "otherhost.com" }; http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.statusCode, 200); assert.deepEqual(res.responseUrl, "http://localhost:3600/b"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); }); }); it("uses the location host if redirect host is the same", function () { app.get("/a", redirectsTo(302, "http://localhost:3600/b")); app.get("/b", function (req, res) { res.write(JSON.stringify(req.headers)); req.pipe(res); // will invalidate JSON if non-empty }); return server.start(app) .then(asPromise(function (resolve, reject) { var opts = url.parse("http://127.0.0.1:3600/a"); opts.headers = { hOsT: "localhost:3600" }; http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.statusCode, 200); assert.deepEqual(res.responseUrl, "http://localhost:3600/b"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); }); }); it("uses the existing host header if redirect host is relative", function () { app.get("/a", redirectsTo(302, "/b")); app.get("/b", function (req, res) { res.write(JSON.stringify(req.headers)); req.pipe(res); // will invalidate JSON if non-empty }); return server.start(app) .then(asPromise(function (resolve, reject) { var opts = url.parse("http://127.0.0.1:3600/a"); opts.headers = { hOsT: "localhost:3600" }; http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.statusCode, 200); assert.deepEqual(res.responseUrl, "http://localhost:3600/b"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); }); }); it("defaults to localhost for relative redirect if no host given", function () { app.get("/a", redirectsTo(302, "/b")); app.get("/b", function (req, res) { res.write(JSON.stringify(req.headers)); req.pipe(res); // will invalidate JSON if non-empty }); return server.start(app) .then(asPromise(function (resolve, reject) { var opts = { port: 3600, path: "/a" }; http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.statusCode, 200); assert(res.responseUrl.endsWith("/b")); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert(body.host.endsWith(":3600")); }); }); }); [ "Authorization", "Proxy-Authorization", "Cookie", ].forEach(function (header) { describe("when the client passes an header named " + header, function () { it("ignores it when null", function () { app.get("/a", redirectsTo(302, "http://localhost:3600/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://127.0.0.1:3600/a"); opts.headers = { host: "localhost" }; opts.headers[header] = null; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); assert.equal(body[header.toLowerCase()], undefined); }); }); it("keeps the header when redirected to the same host", function () { app.get("/a", redirectsTo(302, "/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://localhost:3600/a"); opts.headers = {}; opts.headers[header] = "the header value"; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); assert.equal(body[header.toLowerCase()], "the header value"); }); }); it("keeps the header when redirected to the same host via header", function () { app.get("/a", redirectsTo(302, "http://localhost:3600/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://127.0.0.1:3600/a"); opts.headers = { host: "localhost:3600" }; opts.headers[header] = "the header value"; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); assert.equal(body[header.toLowerCase()], "the header value"); }); }); it("keeps the header when redirected to the same host via header", function () { app.get("/a", redirectsTo(302, "http://localhost:3600/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://127.0.0.1:3600/a"); opts.headers = { host: "localhost:3600" }; opts.headers[header] = "the header value"; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); assert.equal(body[header.toLowerCase()], "the header value"); }); }); it("keeps the header when redirected to a subdomain", function () { app.get("/a", redirectsTo(302, "http://sub.localhost:3600/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://localhost:3600/a"); opts.headers = {}; opts.headers[header] = "the header value"; // Intercept the hostname, as no DNS entry is defined for it opts.beforeRedirect = function (options) { assert.equal(options.hostname, "sub.localhost"); options.hostname = "localhost"; }; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); assert.equal(body[header.toLowerCase()], "the header value"); }); }); it("drops the header when redirected to a different host (same hostname and different port)", function () { app.get("/a", redirectsTo(302, "http://localhost:3600/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://127.0.0.1:3600/a"); opts.headers = { host: "localhost" }; opts.headers[header] = "the header value"; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "localhost:3600"); assert.equal(body[header.toLowerCase()], undefined); }); }); it("drops the header when redirected to a different host", function () { app.get("/a", redirectsTo(302, "http://127.0.0.1:3600/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://localhost:3600/a"); opts.headers = {}; opts.headers[header] = "the header value"; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "127.0.0.1:3600"); assert.equal(body[header.toLowerCase()], undefined); }); }); it("drops the header when redirected from a different host via header", function () { app.get("/a", redirectsTo(302, "http://127.0.0.1:3600/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://127.0.0.1:3600/a"); opts.headers = { host: "localhost" }; opts.headers[header] = "the header value"; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body.host, "127.0.0.1:3600"); assert.equal(body[header.toLowerCase()], undefined); }); }); }); it("keeps the header when redirected from HTTP to HTTPS", function () { app.get("/a", redirectsTo(302, "https://localhost:3600/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("http://localhost:3600/a"); opts.headers = {}; opts.headers[header] = "the header value"; // Intercept the scheme opts.beforeRedirect = function (options) { assert.equal(options.protocol, "https:"); options.protocol = "http:"; }; return server.start(app) .then(asPromise(function (resolve, reject) { http.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body[header.toLowerCase()], "the header value"); }); }); it("drops the header when redirected from HTTPS to HTTP", function () { app.get("/a", redirectsTo(302, "http://localhost:3601/b")); app.get("/b", function (req, res) { res.end(JSON.stringify(req.headers)); }); var opts = url.parse("https://localhost:3601/a"); opts.ca = ca; opts.headers = {}; opts.headers[header] = "the header value"; // Intercept the scheme opts.beforeRedirect = function (options) { assert.equal(options.protocol, "http:"); options.protocol = "https:"; }; return server.start(httpsOptions(app)) .then(asPromise(function (resolve, reject) { https.get(opts, resolve).on("error", reject); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })) .then(function (str) { var body = JSON.parse(str); assert.equal(body[header.toLowerCase()], undefined); }); }); it("passes the redirect status code to beforeRedirect", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c", 301)); app.get("/c", redirectsTo("/d", 302)); app.get("/d", redirectsTo("/e", 303)); app.get("/e", redirectsTo("/f", 307)); app.get("/f", redirectsTo("/g", 308)); app.get("/g", sendsJson({ a: "b" })); const statusCodes = []; return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "GET", beforeRedirect: function (_, response) { statusCodes.push(response.statusCode); }, }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/g"); assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(statusCodes, [302, 301, 302, 303, 307, 308]); }); }); it("passes the request method to beforeRedirect", function () { app.post("/a", redirectsTo("/b", 308)); app.post("/b", redirectsTo("/c", 301)); app.get("/c", redirectsTo("/d", 301)); app.get("/d", sendsJson({ a: "b" })); const requestMethods = []; return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "POST", beforeRedirect: function (_, __, request) { requestMethods.push(request.method); }, }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/d"); assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(requestMethods, ["POST", "POST", "GET"]); }); }); it("passes the request headers to beforeRedirect", function () { app.post("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", redirectsTo("/d")); app.get("/d", sendsJson({ a: "b" })); const headerChain = []; return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "POST", headers: { "X-Foo": "bar", }, beforeRedirect: function (optionz, __, request) { optionz.headers["X-Redirect"] = `${request.url} => ${optionz.href}`; headerChain.push(request.headers); }, }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/d"); assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(headerChain, [ { "Host": "localhost:3600", "X-Foo": "bar", }, { "Host": "localhost:3600", "X-Foo": "bar", "X-Redirect": "http://localhost:3600/a => http://localhost:3600/b", }, { "Host": "localhost:3600", "X-Foo": "bar", "X-Redirect": "http://localhost:3600/b => http://localhost:3600/c", }, ]); }); }); it("passes the request URL to beforeRedirect", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", sendsJson({ a: "b" })); const urlChain = []; return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "GET", beforeRedirect: function (_, __, request) { urlChain.push(request.url); }, }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/c"); assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(urlChain, [ "http://localhost:3600/a", "http://localhost:3600/b", ]); }); }); }); describe("when the followRedirects option is set to false", function () { it("does not redirect", function () { app.get("/a", redirectsTo(302, "/b")); app.get("/b", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { var opts = url.parse("http://localhost:3600/a"); opts.followRedirects = false; http.get(opts, resolve).on("error", reject); })) .then(function (res) { assert.deepEqual(res.statusCode, 302); assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); }); }); }); describe("should choose the right agent per protocol", function () { it("(https -> http -> https)", function () { app.get("/a", redirectsTo("http://localhost:3600/b")); app2.get("/b", redirectsTo("https://localhost:3601/c")); app.get("/c", sendsJson({ yes: "no" })); var httpAgent = addRequestLogging(new http.Agent()); var httpsAgent = addRequestLogging(new https.Agent()); function addRequestLogging(agent) { agent._requests = []; agent._addRequest = agent.addRequest; agent.addRequest = function (request, options) { this._requests.push(options.path); this._addRequest(request, options); }; return agent; } return Promise.all([server.start(httpsOptions(app)), server.start(app2)]) .then(asPromise(function (resolve, reject) { var opts = url.parse("https://localhost:3601/a"); opts.ca = ca; opts.agents = { http: httpAgent, https: httpsAgent }; https.get(opts, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(httpAgent._requests, ["/b"]); assert.deepEqual(httpsAgent._requests, ["/a", "/c"]); assert.deepEqual(res.parsedJson, { yes: "no" }); assert.deepEqual(res.responseUrl, "https://localhost:3601/c"); }); }); }); describe("should not hang on empty writes", function () { it("when data is the empty string without encoding", function () { app.post("/a", sendsJson({ foo: "bar" })); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.write(""); req.write("", function () { req.end(""); }); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })); }); it("when data is the empty string with encoding", function () { app.post("/a", sendsJson({ foo: "bar" })); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.write(""); req.write("", "utf8", function () { req.end("", "utf8"); }); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })); }); it("when data is Buffer.from('')", function () { app.post("/a", sendsJson({ foo: "bar" })); return server.start(app) .then(asPromise(function (resolve, reject) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.write(Buffer.from("")); req.write(Buffer.from(""), function () { req.end(Buffer.from("")); }); req.on("error", reject); })) .then(asPromise(function (resolve, reject, res) { assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); res.pipe(concat({ encoding: "string" }, resolve)).on("error", reject); })); }); }); describe("end accepts as arguments", function () { var called; function setCalled() { called = true; } beforeEach(function () { app.post("/a", function (req, res) { req.pipe(res); }); called = false; }); it("(none)", function () { return server.start(app) .then(asPromise(function (resolve) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end(); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)); })) .then(function (body) { assert.equal(body, ""); }); }); it("the empty string", function () { return server.start(app) .then(asPromise(function (resolve) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end(""); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)); })) .then(function (body) { assert.equal(body, ""); }); }); it("a non-empty string", function () { return server.start(app) .then(asPromise(function (resolve) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end("abc"); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)); })) .then(function (body) { assert.equal(body, "abc"); }); }); it("a non-empty string and an encoding", function () { return server.start(app) .then(asPromise(function (resolve) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end("abc", "utf8"); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)); })) .then(function (body) { assert.equal(body, "abc"); }); }); it("a non-empty string, an encoding, and a callback", function () { return server.start(app) .then(asPromise(function (resolve) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end("abc", "utf8", setCalled); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)); })) .then(function (body) { assert.equal(body, "abc"); assert.equal(called, true); }); }); it("a non-empty string and a callback", function () { return server.start(app) .then(asPromise(function (resolve) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end("abc", setCalled); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)); })) .then(function (body) { assert.equal(body, "abc"); assert.equal(called, true); }); }); it("a callback", function () { return server.start(app) .then(asPromise(function (resolve) { var req = http.request("http://localhost:3600/a", { method: "POST" }, resolve); req.end(setCalled); })) .then(asPromise(function (resolve, reject, res) { res.pipe(concat({ encoding: "string" }, resolve)); })) .then(function (body) { assert.equal(body, ""); assert.equal(called, true); }); }); }); describe("change request options before redirects", function () { it("only call beforeRedirect on redirects, not the inital http call", function () { app.get("/a", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "GET", beforeRedirect: function () { assert.fail("this should only be called on redirects"); }, }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/a"); }); }); it("ignore beforeRedirect if not a function", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", sendsJson({ a: "b" })); return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "GET", beforeRedirect: 42, }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { a: "b" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/c"); }); }); it("append new header with every redirect", function () { app.get("/a", redirectsTo("/b")); app.get("/b", redirectsTo("/c")); app.get("/c", function (req, res) { res.json(req.headers); }); var callsToTransform = 0; return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "GET", beforeRedirect: function (optionz) { callsToTransform++; if (optionz.path === "/b") { optionz.headers["header-a"] = "value A"; } else if (optionz.path === "/c") { optionz.headers["header-b"] = "value B"; } }, }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.strictEqual(callsToTransform, 2); assert.strictEqual(res.parsedJson["header-a"], "value A"); assert.strictEqual(res.parsedJson["header-b"], "value B"); assert.deepEqual(res.responseUrl, "http://localhost:3600/c"); }); }); it("abort request chain after throwing an error", function () { var redirected = false; app.get("/a", redirectsTo("/b")); app.get("/b", function () { redirected = true; throw new Error("redirected request should have been aborted"); }); return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "GET", beforeRedirect: function () { throw new Error("no redirects!"); }, }; http.get(options, concatJson(reject)).on("error", resolve); })) .then(function (error) { assert(!redirected); assert(error instanceof Error); assert.equal(error.message, "Redirected request failed: no redirects!"); assert(error.cause instanceof Error); assert.equal(error.cause.message, "no redirects!"); }); }); it("access response header in beforeRedirect", function () { app.get("/a", redirectsTo("/b")); app.get("/b", function (req, res) { res.json(req.headers); }); return server.start(app) .then(asPromise(function (resolve, reject) { var options = { host: "localhost", port: 3600, path: "/a", method: "GET", beforeRedirect: function (optionz, response) { optionz.headers.testheader = "itsAtest" + response.headers.location; }, }; http.get(options, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.strictEqual(res.parsedJson.testheader, "itsAtest/b"); assert.deepEqual(res.responseUrl, "http://localhost:3600/b"); }); }); }); describe("when request is going through an HTTP proxy (without a tunnel)", function () { [ { redirectType: "absolute", redirectUrl: "http://localhost:3600/b" }, { redirectType: "relative", redirectUrl: "/b" }, ].forEach(function (testCase) { it("redirects to proper URL when Location header is " + testCase.redirectType, function () { app.get("/a", redirectsTo(testCase.redirectUrl)); app.get("/b", sendsJson({ good: "yes" })); app2.port = 3601; app2.all("*", proxy("localhost:3601")); function setProxy(opts) { // assuming opts is a url.parse result // Update path and Host header opts.path = opts.href; opts.pathname = opts.href; // Update port and host to target proxy host opts.port = 3601; opts.host = opts.hostname + ":" + opts.port; // redirected requests use proxy too opts.beforeRedirect = setProxy; } return Promise.all([server.start(app), server.start(app2)]) .then(asPromise(function (resolve, reject) { var opts = Object.assign({}, url.parse("http://localhost:3600/a")); setProxy(opts); http.get(opts, concatJson(resolve, reject)).on("error", reject); })) .then(function (res) { assert.deepEqual(res.parsedJson, { good: "yes" }); assert.deepEqual(res.responseUrl, "http://localhost:3600/b"); }); }); }); }); }); function noop() { /* noop */ } follow-redirects-1.15.6/test/util.js000066400000000000000000000034721457462373400174070ustar00rootroot00000000000000var concat = require("concat-stream"); var http = require("http"); var https = require("https"); var url = require("url"); function redirectsTo() { var args = Array.prototype.slice.call(arguments); return function (req, res) { res.redirect.apply(res, args); }; } function sendsJson(json) { return function (req, res) { res.json(json); }; } function concatJson(resolve, reject) { return function (res) { res.pipe(concat({ encoding: "string" }, function (string) { try { res.parsedJson = JSON.parse(string); resolve(res); } catch (err) { reject(new Error("error parsing " + JSON.stringify(string) + "\n caused by: " + err.message)); } })).on("error", reject); }; } function delay(clock, msecs, handler) { return function (req, res) { clock.tick(msecs); handler(req, res); }; } function asPromise(cb) { return function (result) { return new Promise(function (resolve, reject) { cb(resolve, reject, result); }); }; } function proxy(proxyHost) { return function (req, res) { var upstreamUrl = url.parse(req.originalUrl); if (upstreamUrl.host === proxyHost) { res.writeHead(400, "Bad request"); res.write(JSON.stringify({ bad: "detected proxy recursion" })); res.end(); } else { var transport = /https:?/.test(upstreamUrl.protocol) ? https : http; upstreamUrl.headers = req.headers; var upstreamReq = transport.request(upstreamUrl, function (upstreamRes) { res.writeHead(upstreamRes.statusCode, upstreamRes.statusMessage, upstreamRes.headers); upstreamRes.pipe(res); }); upstreamReq.end(); } }; } module.exports = { asPromise: asPromise, concatJson: concatJson, delay: delay, proxy: proxy, redirectsTo: redirectsTo, sendsJson: sendsJson, };