text: module.exports =
  /******/ (function(modules, runtime) { // webpackBootstrap
  /******/ 	"use strict";
  /******/ 	// The module cache
  /******/ 	var installedModules = {};
  /******/
  /******/ 	// The require function
  /******/ 	function __webpack_require__(moduleId) {
  /******/
  /******/ 		// Check if module is in cache
  /******/ 		if(installedModules[moduleId]) {
  /******/ 			return installedModules[moduleId].exports;
  /******/ 		}
  /******/ 		// Create a new module (and put it into the cache)
  /******/ 		var module = installedModules[moduleId] = {
  /******/ 			i: moduleId,
  /******/ 			l: false,
  /******/ 			exports: {}
  /******/ 		};
  /******/
  /******/ 		// Execute the module function
  /******/ 		var threw = true;
  /******/ 		try {
  /******/ 			modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  /******/ 			threw = false;
  /******/ 		} finally {
  /******/ 			if(threw) delete installedModules[moduleId];
  /******/ 		}
  /******/
  /******/ 		// Flag the module as loaded
  /******/ 		module.l = true;
  /******/
  /******/ 		// Return the exports of the module
  /******/ 		return module.exports;
  /******/ 	}
  /******/
  /******/
  /******/ 	__webpack_require__.ab = __dirname + "/";
  /******/
  /******/ 	// the startup function
  /******/ 	function startup() {
  /******/ 		// Load entry module and return exports
  /******/ 		return __webpack_require__(492);
  /******/ 	};
  /******/
  /******/ 	// run startup
  /******/ 	return startup();
  /******/ })
  /************************************************************************/
  /******/ ({
  
  /***/ 9:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  var once = __webpack_require__(49);
  
  var noop = function() {};
  
  var isRequest = function(stream) {
  	return stream.setHeader && typeof stream.abort === 'function';
  };
  
  var isChildProcess = function(stream) {
  	return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3
  };
  
  var eos = function(stream, opts, callback) {
  	if (typeof opts === 'function') return eos(stream, null, opts);
  	if (!opts) opts = {};
  
  	callback = once(callback || noop);
  
  	var ws = stream._writableState;
  	var rs = stream._readableState;
  	var readable = opts.readable || (opts.readable !== false && stream.readable);
  	var writable = opts.writable || (opts.writable !== false && stream.writable);
  
  	var onlegacyfinish = function() {
  		if (!stream.writable) onfinish();
  	};
  
  	var onfinish = function() {
  		writable = false;
  		if (!readable) callback.call(stream);
  	};
  
  	var onend = function() {
  		readable = false;
  		if (!writable) callback.call(stream);
  	};
  
  	var onexit = function(exitCode) {
  		callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null);
  	};
  
  	var onerror = function(err) {
  		callback.call(stream, err);
  	};
  
  	var onclose = function() {
  		if (readable && !(rs && rs.ended)) return callback.call(stream, new Error('premature close'));
  		if (writable && !(ws && ws.ended)) return callback.call(stream, new Error('premature close'));
  	};
  
  	var onrequest = function() {
  		stream.req.on('finish', onfinish);
  	};
  
  	if (isRequest(stream)) {
  		stream.on('complete', onfinish);
  		stream.on('abort', onclose);
  		if (stream.req) onrequest();
  		else stream.on('request', onrequest);
  	} else if (writable && !ws) { // legacy streams
  		stream.on('end', onlegacyfinish);
  		stream.on('close', onlegacyfinish);
  	}
  
  	if (isChildProcess(stream)) stream.on('exit', onexit);
  
  	stream.on('end', onend);
  	stream.on('finish', onfinish);
  	if (opts.error !== false) stream.on('error', onerror);
  	stream.on('close', onclose);
  
  	return function() {
  		stream.removeListener('complete', onfinish);
  		stream.removeListener('abort', onclose);
  		stream.removeListener('request', onrequest);
  		if (stream.req) stream.req.removeListener('finish', onfinish);
  		stream.removeListener('end', onlegacyfinish);
  		stream.removeListener('close', onlegacyfinish);
  		stream.removeListener('finish', onfinish);
  		stream.removeListener('exit', onexit);
  		stream.removeListener('end', onend);
  		stream.removeListener('error', onerror);
  		stream.removeListener('close', onclose);
  	};
  };
  
  module.exports = eos;
  
  
  /***/ }),
  
  /***/ 10:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const is_1 = __webpack_require__(534);
  exports.default = (url) => {
      // Cast to URL
      url = url;
      const options = {
          protocol: url.protocol,
          hostname: is_1.default.string(url.hostname) && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname,
          host: url.host,
          hash: url.hash,
          search: url.search,
          pathname: url.pathname,
          href: url.href,
          path: `${url.pathname || ''}${url.search || ''}`
      };
      if (is_1.default.string(url.port) && url.port.length !== 0) {
          options.port = Number(url.port);
      }
      if (url.username || url.password) {
          options.auth = `${url.username || ''}:${url.password || ''}`;
      }
      return options;
  };
  
  
  /***/ }),
  
  /***/ 11:
  /***/ (function(module) {
  
  // Returns a wrapper function that returns a wrapped callback
  // The wrapper function should do some stuff, and return a
  // presumably different callback function.
  // This makes sure that own properties are retained, so that
  // decorations and such are not lost along the way.
  module.exports = wrappy
  function wrappy (fn, cb) {
    if (fn && cb) return wrappy(fn)(cb)
  
    if (typeof fn !== 'function')
      throw new TypeError('need wrapper function')
  
    Object.keys(fn).forEach(function (k) {
      wrapper[k] = fn[k]
    })
  
    return wrapper
  
    function wrapper() {
      var args = new Array(arguments.length)
      for (var i = 0; i < args.length; i++) {
        args[i] = arguments[i]
      }
      var ret = fn.apply(this, args)
      var cb = args[args.length-1]
      if (typeof ret === 'function' && ret !== cb) {
        Object.keys(cb).forEach(function (k) {
          ret[k] = cb[k]
        })
      }
      return ret
    }
  }
  
  
  /***/ }),
  
  /***/ 16:
  /***/ (function(module) {
  
  module.exports = require("tls");
  
  /***/ }),
  
  /***/ 36:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
      for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.CancelError = exports.ParseError = void 0;
  const core_1 = __webpack_require__(946);
  /**
  An error to be thrown when server response code is 2xx, and parsing body fails.
  Includes a `response` property.
  */
  class ParseError extends core_1.RequestError {
      constructor(error, response) {
          const { options } = response.request;
          super(`${error.message} in "${options.url.toString()}"`, error, response.request);
          this.name = 'ParseError';
      }
  }
  exports.ParseError = ParseError;
  /**
  An error to be thrown when the request is aborted with `.cancel()`.
  */
  class CancelError extends core_1.RequestError {
      constructor(request) {
          super('Promise was canceled', {}, request);
          this.name = 'CancelError';
      }
      get isCanceled() {
          return true;
      }
  }
  exports.CancelError = CancelError;
  __exportStar(__webpack_require__(946), exports);
  
  
  /***/ }),
  
  /***/ 48:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  class WeakableMap {
      constructor() {
          this.weakMap = new WeakMap();
          this.map = new Map();
      }
      set(key, value) {
          if (typeof key === 'object') {
              this.weakMap.set(key, value);
          }
          else {
              this.map.set(key, value);
          }
      }
      get(key) {
          if (typeof key === 'object') {
              return this.weakMap.get(key);
          }
          return this.map.get(key);
      }
      has(key) {
          if (typeof key === 'object') {
              return this.weakMap.has(key);
          }
          return this.map.has(key);
      }
  }
  exports.default = WeakableMap;
  
  
  /***/ }),
  
  /***/ 49:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  var wrappy = __webpack_require__(11)
  module.exports = wrappy(once)
  module.exports.strict = wrappy(onceStrict)
  
  once.proto = once(function () {
    Object.defineProperty(Function.prototype, 'once', {
      value: function () {
        return once(this)
      },
      configurable: true
    })
  
    Object.defineProperty(Function.prototype, 'onceStrict', {
      value: function () {
        return onceStrict(this)
      },
      configurable: true
    })
  })
  
  function once (fn) {
    var f = function () {
      if (f.called) return f.value
      f.called = true
      return f.value = fn.apply(this, arguments)
    }
    f.called = false
    return f
  }
  
  function onceStrict (fn) {
    var f = function () {
      if (f.called)
        throw new Error(f.onceError)
      f.called = true
      return f.value = fn.apply(this, arguments)
    }
    var name = fn.name || 'Function wrapped with `once`'
    f.onceError = name + " shouldn't be called more than once"
    f.called = false
    return f
  }
  
  
  /***/ }),
  
  /***/ 53:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  // TODO: Use the `URL` global when targeting Node.js 10
  const URLParser = typeof URL === 'undefined' ? __webpack_require__(835).URL : URL;
  
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
  const DATA_URL_DEFAULT_MIME_TYPE = 'text/plain';
  const DATA_URL_DEFAULT_CHARSET = 'us-ascii';
  
  const testParameter = (name, filters) => {
  	return filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name);
  };
  
  const normalizeDataURL = (urlString, {stripHash}) => {
  	const parts = urlString.match(/^data:(.*?),(.*?)(?:#(.*))?$/);
  
  	if (!parts) {
  		throw new Error(`Invalid URL: ${urlString}`);
  	}
  
  	const mediaType = parts[1].split(';');
  	const body = parts[2];
  	const hash = stripHash ? '' : parts[3];
  
  	let base64 = false;
  
  	if (mediaType[mediaType.length - 1] === 'base64') {
  		mediaType.pop();
  		base64 = true;
  	}
  
  	// Lowercase MIME type
  	const mimeType = (mediaType.shift() || '').toLowerCase();
  	const attributes = mediaType
  		.map(attribute => {
  			let [key, value = ''] = attribute.split('=').map(string => string.trim());
  
  			// Lowercase `charset`
  			if (key === 'charset') {
  				value = value.toLowerCase();
  
  				if (value === DATA_URL_DEFAULT_CHARSET) {
  					return '';
  				}
  			}
  
  			return `${key}${value ? `=${value}` : ''}`;
  		})
  		.filter(Boolean);
  
  	const normalizedMediaType = [
  		...attributes
  	];
  
  	if (base64) {
  		normalizedMediaType.push('base64');
  	}
  
  	if (normalizedMediaType.length !== 0 || (mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE)) {
  		normalizedMediaType.unshift(mimeType);
  	}
  
  	return `data:${normalizedMediaType.join(';')},${base64 ? body.trim() : body}${hash ? `#${hash}` : ''}`;
  };
  
  const normalizeUrl = (urlString, options) => {
  	options = {
  		defaultProtocol: 'http:',
  		normalizeProtocol: true,
  		forceHttp: false,
  		forceHttps: false,
  		stripAuthentication: true,
  		stripHash: false,
  		stripWWW: true,
  		removeQueryParameters: [/^utm_\w+/i],
  		removeTrailingSlash: true,
  		removeDirectoryIndex: false,
  		sortQueryParameters: true,
  		...options
  	};
  
  	// TODO: Remove this at some point in the future
  	if (Reflect.has(options, 'normalizeHttps')) {
  		throw new Error('options.normalizeHttps is renamed to options.forceHttp');
  	}
  
  	if (Reflect.has(options, 'normalizeHttp')) {
  		throw new Error('options.normalizeHttp is renamed to options.forceHttps');
  	}
  
  	if (Reflect.has(options, 'stripFragment')) {
  		throw new Error('options.stripFragment is renamed to options.stripHash');
  	}
  
  	urlString = urlString.trim();
  
  	// Data URL
  	if (/^data:/i.test(urlString)) {
  		return normalizeDataURL(urlString, options);
  	}
  
  	const hasRelativeProtocol = urlString.startsWith('//');
  	const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
  
  	// Prepend protocol
  	if (!isRelativeUrl) {
  		urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
  	}
  
  	const urlObj = new URLParser(urlString);
  
  	if (options.forceHttp && options.forceHttps) {
  		throw new Error('The `forceHttp` and `forceHttps` options cannot be used together');
  	}
  
  	if (options.forceHttp && urlObj.protocol === 'https:') {
  		urlObj.protocol = 'http:';
  	}
  
  	if (options.forceHttps && urlObj.protocol === 'http:') {
  		urlObj.protocol = 'https:';
  	}
  
  	// Remove auth
  	if (options.stripAuthentication) {
  		urlObj.username = '';
  		urlObj.password = '';
  	}
  
  	// Remove hash
  	if (options.stripHash) {
  		urlObj.hash = '';
  	}
  
  	// Remove duplicate slashes if not preceded by a protocol
  	if (urlObj.pathname) {
  		// TODO: Use the following instead when targeting Node.js 10
  		// `urlObj.pathname = urlObj.pathname.replace(/(?<!https?:)\/{2,}/g, '/');`
  		urlObj.pathname = urlObj.pathname.replace(/((?!:).|^)\/{2,}/g, (_, p1) => {
  			if (/^(?!\/)/g.test(p1)) {
  				return `${p1}/`;
  			}
  
  			return '/';
  		});
  	}
  
  	// Decode URI octets
  	if (urlObj.pathname) {
  		urlObj.pathname = decodeURI(urlObj.pathname);
  	}
  
  	// Remove directory index
  	if (options.removeDirectoryIndex === true) {
  		options.removeDirectoryIndex = [/^index\.[a-z]+$/];
  	}
  
  	if (Array.isArray(options.removeDirectoryIndex) && options.removeDirectoryIndex.length > 0) {
  		let pathComponents = urlObj.pathname.split('/');
  		const lastComponent = pathComponents[pathComponents.length - 1];
  
  		if (testParameter(lastComponent, options.removeDirectoryIndex)) {
  			pathComponents = pathComponents.slice(0, pathComponents.length - 1);
  			urlObj.pathname = pathComponents.slice(1).join('/') + '/';
  		}
  	}
  
  	if (urlObj.hostname) {
  		// Remove trailing dot
  		urlObj.hostname = urlObj.hostname.replace(/\.$/, '');
  
  		// Remove `www.`
  		if (options.stripWWW && /^www\.([a-z\-\d]{2,63})\.([a-z.]{2,5})$/.test(urlObj.hostname)) {
  			// Each label should be max 63 at length (min: 2).
  			// The extension should be max 5 at length (min: 2).
  			// Source: https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
  			urlObj.hostname = urlObj.hostname.replace(/^www\./, '');
  		}
  	}
  
  	// Remove query unwanted parameters
  	if (Array.isArray(options.removeQueryParameters)) {
  		for (const key of [...urlObj.searchParams.keys()]) {
  			if (testParameter(key, options.removeQueryParameters)) {
  				urlObj.searchParams.delete(key);
  			}
  		}
  	}
  
  	// Sort query parameters
  	if (options.sortQueryParameters) {
  		urlObj.searchParams.sort();
  	}
  
  	if (options.removeTrailingSlash) {
  		urlObj.pathname = urlObj.pathname.replace(/\/$/, '');
  	}
  
  	// Take advantage of many of the Node `url` normalizations
  	urlString = urlObj.toString();
  
  	// Remove ending `/`
  	if ((options.removeTrailingSlash || urlObj.pathname === '/') && urlObj.hash === '') {
  		urlString = urlString.replace(/\/$/, '');
  	}
  
  	// Restore relative protocol, if applicable
  	if (hasRelativeProtocol && !options.normalizeProtocol) {
  		urlString = urlString.replace(/^http:\/\//, '//');
  	}
  
  	// Remove http/https
  	if (options.stripProtocol) {
  		urlString = urlString.replace(/^(?:https?:)?\/\//, '');
  	}
  
  	return urlString;
  };
  
  module.exports = normalizeUrl;
  // TODO: Remove this for the next major release
  module.exports.default = normalizeUrl;
  
  
  /***/ }),
  
  /***/ 77:
  /***/ (function(module, exports, __webpack_require__) {
  
  "use strict";
  
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
      for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const url_1 = __webpack_require__(835);
  const create_1 = __webpack_require__(323);
  const defaults = {
      options: {
          method: 'GET',
          retry: {
              limit: 2,
              methods: [
                  'GET',
                  'PUT',
                  'HEAD',
                  'DELETE',
                  'OPTIONS',
                  'TRACE'
              ],
              statusCodes: [
                  408,
                  413,
                  429,
                  500,
                  502,
                  503,
                  504,
                  521,
                  522,
                  524
              ],
              errorCodes: [
                  'ETIMEDOUT',
                  'ECONNRESET',
                  'EADDRINUSE',
                  'ECONNREFUSED',
                  'EPIPE',
                  'ENOTFOUND',
                  'ENETUNREACH',
                  'EAI_AGAIN'
              ],
              maxRetryAfter: undefined,
              calculateDelay: ({ computedValue }) => computedValue
          },
          timeout: {},
          headers: {
              'user-agent': 'got (https://github.com/sindresorhus/got)'
          },
          hooks: {
              init: [],
              beforeRequest: [],
              beforeRedirect: [],
              beforeRetry: [],
              beforeError: [],
              afterResponse: []
          },
          cache: undefined,
          dnsCache: undefined,
          decompress: true,
          throwHttpErrors: true,
          followRedirect: true,
          isStream: false,
          responseType: 'text',
          resolveBodyOnly: false,
          maxRedirects: 10,
          prefixUrl: '',
          methodRewriting: true,
          ignoreInvalidCookies: false,
          context: {},
          // TODO: Set this to `true` when Got 12 gets released
          http2: false,
          allowGetBody: false,
          https: undefined,
          pagination: {
              transform: (response) => {
                  if (response.request.options.responseType === 'json') {
                      return response.body;
                  }
                  return JSON.parse(response.body);
              },
              paginate: response => {
                  if (!Reflect.has(response.headers, 'link')) {
                      return false;
                  }
                  const items = response.headers.link.split(',');
                  let next;
                  for (const item of items) {
                      const parsed = item.split(';');
                      if (parsed[1].includes('next')) {
                          next = parsed[0].trimStart().trim();
                          next = next.slice(1, -1);
                          break;
                      }
                  }
                  if (next) {
                      const options = {
                          url: new url_1.URL(next)
                      };
                      return options;
                  }
                  return false;
              },
              filter: () => true,
              shouldContinue: () => true,
              countLimit: Infinity,
              backoff: 0,
              requestLimit: 10000,
              stackAllItems: true
          },
          parseJson: (text) => JSON.parse(text),
          stringifyJson: (object) => JSON.stringify(object),
          cacheOptions: {}
      },
      handlers: [create_1.defaultHandler],
      mutableDefaults: false
  };
  const got = create_1.default(defaults);
  exports.default = got;
  // For CommonJS default export support
  module.exports = got;
  module.exports.default = got;
  module.exports.__esModule = true; // Workaround for TS issue: https://github.com/sindresorhus/got/pull/1267
  __exportStar(__webpack_require__(323), exports);
  __exportStar(__webpack_require__(577), exports);
  
  
  /***/ }),
  
  /***/ 87:
  /***/ (function(module) {
  
  module.exports = require("os");
  
  /***/ }),
  
  /***/ 89:
  /***/ (function(module) {
  
  "use strict";
  
  
  // We define these manually to ensure they're always copied
  // even if they would move up the prototype chain
  // https://nodejs.org/api/http.html#http_class_http_incomingmessage
  const knownProps = [
  	'destroy',
  	'setTimeout',
  	'socket',
  	'headers',
  	'trailers',
  	'rawHeaders',
  	'statusCode',
  	'httpVersion',
  	'httpVersionMinor',
  	'httpVersionMajor',
  	'rawTrailers',
  	'statusMessage'
  ];
  
  module.exports = (fromStream, toStream) => {
  	const fromProps = new Set(Object.keys(fromStream).concat(knownProps));
  
  	for (const prop of fromProps) {
  		// Don't overwrite existing properties
  		if (prop in toStream) {
  			continue;
  		}
  
  		toStream[prop] = typeof fromStream[prop] === 'function' ? fromStream[prop].bind(fromStream) : fromStream[prop];
  	}
  };
  
  
  /***/ }),
  
  /***/ 93:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  
  const Readable = __webpack_require__(413).Readable;
  const lowercaseKeys = __webpack_require__(474);
  
  class Response extends Readable {
  	constructor(statusCode, headers, body, url) {
  		if (typeof statusCode !== 'number') {
  			throw new TypeError('Argument `statusCode` should be a number');
  		}
  		if (typeof headers !== 'object') {
  			throw new TypeError('Argument `headers` should be an object');
  		}
  		if (!(body instanceof Buffer)) {
  			throw new TypeError('Argument `body` should be a buffer');
  		}
  		if (typeof url !== 'string') {
  			throw new TypeError('Argument `url` should be a string');
  		}
  
  		super();
  		this.statusCode = statusCode;
  		this.headers = lowercaseKeys(headers);
  		this.body = body;
  		this.url = url;
  	}
  
  	_read() {
  		this.push(this.body);
  		this.push(null);
  	}
  }
  
  module.exports = Response;
  
  
  /***/ }),
  
  /***/ 121:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const types_1 = __webpack_require__(36);
  const parseBody = (response, responseType, parseJson, encoding) => {
      const { rawBody } = response;
      try {
          if (responseType === 'text') {
              return rawBody.toString(encoding);
          }
          if (responseType === 'json') {
              return rawBody.length === 0 ? '' : parseJson(rawBody.toString());
          }
          if (responseType === 'buffer') {
              return Buffer.from(rawBody);
          }
          throw new types_1.ParseError({
              message: `Unknown body type '${responseType}'`,
              name: 'Error'
          }, response);
      }
      catch (error) {
          throw new types_1.ParseError(error, response);
      }
  };
  exports.default = parseBody;
  
  
  /***/ }),
  
  /***/ 151:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  // @ts-check
  const core = __webpack_require__(470);
  
  /***
   * Authenticate with Vault and retrieve a Vault token that can be used for requests.
   * @param {string} method
   * @param {import('got').Got} client
   */
  async function retrieveToken(method, client) {
      switch (method) {
          case 'approle': {
              const vaultRoleId = core.getInput('roleId', { required: true });
              const vaultSecretId = core.getInput('secretId', { required: true });
              return await getClientToken(client, method, { role_id: vaultRoleId, secret_id: vaultSecretId });
          }
          case 'github': {
              const githubToken = core.getInput('githubToken', { required: true });
              return await getClientToken(client, method, { token: githubToken });
          }
          default: {
              if (!method || method === 'token') {
                  return core.getInput('token', { required: true });
              } else {
                  /** @type {string} */
                  const payload = core.getInput('authPayload', { required: true });
                  if (!payload) {
                      throw Error('When using a custom authentication method, you must provide the payload');
                  }
                  return await getClientToken(client, method, JSON.parse(payload.trim()));
              }
          }
      }
  }
  
  /***
   * Call the appropriate login endpoint and parse out the token in the response.
   * @param {import('got').Got} client
   * @param {string} method
   * @param {any} payload
   */
  async function getClientToken(client, method, payload) {
      /** @type {'json'} */
      const responseType = 'json';
      var options = {
          json: payload,
          responseType,
      };
  
      core.debug(`Retrieving Vault Token from v1/auth/${method}/login endpoint`);
  
      /** @type {import('got').Response<VaultLoginResponse>} */
      const response = await client.post(`v1/auth/${method}/login`, options);
      if (response && response.body && response.body.auth && response.body.auth.client_token) {
          core.debug('✔ Vault Token successfully retrieved');
  
          core.startGroup('Token Info');
          core.debug(`Operating under policies: ${JSON.stringify(response.body.auth.policies)}`);
          core.debug(`Token Metadata: ${JSON.stringify(response.body.auth.metadata)}`);
          core.endGroup();
  
          return response.body.auth.client_token;
      } else {
          throw Error(`Unable to retrieve token from ${method}'s login endpoint.`);
      }
  }
  
  /***
   * @typedef {Object} VaultLoginResponse
   * @property {{
   *  client_token: string;
   *  accessor: string;
   *  policies: string[];
   *  metadata: unknown;
   *  lease_duration: number;
   *  renewable: boolean;
   * }} auth
   */
  
  module.exports = {
      retrieveToken,
  };
  
  
  /***/ }),
  
  /***/ 154:
  /***/ (function(module) {
  
  "use strict";
  
  // rfc7231 6.1
  const statusCodeCacheableByDefault = new Set([
      200,
      203,
      204,
      206,
      300,
      301,
      404,
      405,
      410,
      414,
      501,
  ]);
  
  // This implementation does not understand partial responses (206)
  const understoodStatuses = new Set([
      200,
      203,
      204,
      300,
      301,
      302,
      303,
      307,
      308,
      404,
      405,
      410,
      414,
      501,
  ]);
  
  const errorStatusCodes = new Set([
      500,
      502,
      503, 
      504,
  ]);
  
  const hopByHopHeaders = {
      date: true, // included, because we add Age update Date
      connection: true,
      'keep-alive': true,
      'proxy-authenticate': true,
      'proxy-authorization': true,
      te: true,
      trailer: true,
      'transfer-encoding': true,
      upgrade: true,
  };
  
  const excludedFromRevalidationUpdate = {
      // Since the old body is reused, it doesn't make sense to change properties of the body
      'content-length': true,
      'content-encoding': true,
      'transfer-encoding': true,
      'content-range': true,
  };
  
  function toNumberOrZero(s) {
      const n = parseInt(s, 10);
      return isFinite(n) ? n : 0;
  }
  
  // RFC 5861
  function isErrorResponse(response) {
      // consider undefined response as faulty
      if(!response) {
          return true
      }
      return errorStatusCodes.has(response.status);
  }
  
  function parseCacheControl(header) {
      const cc = {};
      if (!header) return cc;
  
      // TODO: When there is more than one value present for a given directive (e.g., two Expires header fields, multiple Cache-Control: max-age directives),
      // the directive's value is considered invalid. Caches are encouraged to consider responses that have invalid freshness information to be stale
      const parts = header.trim().split(/\s*,\s*/); // TODO: lame parsing
      for (const part of parts) {
          const [k, v] = part.split(/\s*=\s*/, 2);
          cc[k] = v === undefined ? true : v.replace(/^"|"$/g, ''); // TODO: lame unquoting
      }
  
      return cc;
  }
  
  function formatCacheControl(cc) {
      let parts = [];
      for (const k in cc) {
          const v = cc[k];
          parts.push(v === true ? k : k + '=' + v);
      }
      if (!parts.length) {
          return undefined;
      }
      return parts.join(', ');
  }
  
  module.exports = class CachePolicy {
      constructor(
          req,
          res,
          {
              shared,
              cacheHeuristic,
              immutableMinTimeToLive,
              ignoreCargoCult,
              _fromObject,
          } = {}
      ) {
          if (_fromObject) {
              this._fromObject(_fromObject);
              return;
          }
  
          if (!res || !res.headers) {
              throw Error('Response headers missing');
          }
          this._assertRequestHasHeaders(req);
  
          this._responseTime = this.now();
          this._isShared = shared !== false;
          this._cacheHeuristic =
              undefined !== cacheHeuristic ? cacheHeuristic : 0.1; // 10% matches IE
          this._immutableMinTtl =
              undefined !== immutableMinTimeToLive
                  ? immutableMinTimeToLive
                  : 24 * 3600 * 1000;
  
          this._status = 'status' in res ? res.status : 200;
          this._resHeaders = res.headers;
          this._rescc = parseCacheControl(res.headers['cache-control']);
          this._method = 'method' in req ? req.method : 'GET';
          this._url = req.url;
          this._host = req.headers.host;
          this._noAuthorization = !req.headers.authorization;
          this._reqHeaders = res.headers.vary ? req.headers : null; // Don't keep all request headers if they won't be used
          this._reqcc = parseCacheControl(req.headers['cache-control']);
  
          // Assume that if someone uses legacy, non-standard uncecessary options they don't understand caching,
          // so there's no point stricly adhering to the blindly copy&pasted directives.
          if (
              ignoreCargoCult &&
              'pre-check' in this._rescc &&
              'post-check' in this._rescc
          ) {
              delete this._rescc['pre-check'];
              delete this._rescc['post-check'];
              delete this._rescc['no-cache'];
              delete this._rescc['no-store'];
              delete this._rescc['must-revalidate'];
              this._resHeaders = Object.assign({}, this._resHeaders, {
                  'cache-control': formatCacheControl(this._rescc),
              });
              delete this._resHeaders.expires;
              delete this._resHeaders.pragma;
          }
  
          // When the Cache-Control header field is not present in a request, caches MUST consider the no-cache request pragma-directive
          // as having the same effect as if "Cache-Control: no-cache" were present (see Section 5.2.1).
          if (
              res.headers['cache-control'] == null &&
              /no-cache/.test(res.headers.pragma)
          ) {
              this._rescc['no-cache'] = true;
          }
      }
  
      now() {
          return Date.now();
      }
  
      storable() {
          // The "no-store" request directive indicates that a cache MUST NOT store any part of either this request or any response to it.
          return !!(
              !this._reqcc['no-store'] &&
              // A cache MUST NOT store a response to any request, unless:
              // The request method is understood by the cache and defined as being cacheable, and
              ('GET' === this._method ||
                  'HEAD' === this._method ||
                  ('POST' === this._method && this._hasExplicitExpiration())) &&
              // the response status code is understood by the cache, and
              understoodStatuses.has(this._status) &&
              // the "no-store" cache directive does not appear in request or response header fields, and
              !this._rescc['no-store'] &&
              // the "private" response directive does not appear in the response, if the cache is shared, and
              (!this._isShared || !this._rescc.private) &&
              // the Authorization header field does not appear in the request, if the cache is shared,
              (!this._isShared ||
                  this._noAuthorization ||
                  this._allowsStoringAuthenticated()) &&
              // the response either:
              // contains an Expires header field, or
              (this._resHeaders.expires ||
                  // contains a max-age response directive, or
                  // contains a s-maxage response directive and the cache is shared, or
                  // contains a public response directive.
                  this._rescc['max-age'] ||
                  (this._isShared && this._rescc['s-maxage']) ||
                  this._rescc.public ||
                  // has a status code that is defined as cacheable by default
                  statusCodeCacheableByDefault.has(this._status))
          );
      }
  
      _hasExplicitExpiration() {
          // 4.2.1 Calculating Freshness Lifetime
          return (
              (this._isShared && this._rescc['s-maxage']) ||
              this._rescc['max-age'] ||
              this._resHeaders.expires
          );
      }
  
      _assertRequestHasHeaders(req) {
          if (!req || !req.headers) {
              throw Error('Request headers missing');
          }
      }
  
      satisfiesWithoutRevalidation(req) {
          this._assertRequestHasHeaders(req);
  
          // When presented with a request, a cache MUST NOT reuse a stored response, unless:
          // the presented request does not contain the no-cache pragma (Section 5.4), nor the no-cache cache directive,
          // unless the stored response is successfully validated (Section 4.3), and
          const requestCC = parseCacheControl(req.headers['cache-control']);
          if (requestCC['no-cache'] || /no-cache/.test(req.headers.pragma)) {
              return false;
          }
  
          if (requestCC['max-age'] && this.age() > requestCC['max-age']) {
              return false;
          }
  
          if (
              requestCC['min-fresh'] &&
              this.timeToLive() < 1000 * requestCC['min-fresh']
          ) {
              return false;
          }
  
          // the stored response is either:
          // fresh, or allowed to be served stale
          if (this.stale()) {
              const allowsStale =
                  requestCC['max-stale'] &&
                  !this._rescc['must-revalidate'] &&
                  (true === requestCC['max-stale'] ||
                      requestCC['max-stale'] > this.age() - this.maxAge());
              if (!allowsStale) {
                  return false;
              }
          }
  
          return this._requestMatches(req, false);
      }
  
      _requestMatches(req, allowHeadMethod) {
          // The presented effective request URI and that of the stored response match, and
          return (
              (!this._url || this._url === req.url) &&
              this._host === req.headers.host &&
              // the request method associated with the stored response allows it to be used for the presented request, and
              (!req.method ||
                  this._method === req.method ||
                  (allowHeadMethod && 'HEAD' === req.method)) &&
              // selecting header fields nominated by the stored response (if any) match those presented, and
              this._varyMatches(req)
          );
      }
  
      _allowsStoringAuthenticated() {
          //  following Cache-Control response directives (Section 5.2.2) have such an effect: must-revalidate, public, and s-maxage.
          return (
              this._rescc['must-revalidate'] ||
              this._rescc.public ||
              this._rescc['s-maxage']
          );
      }
  
      _varyMatches(req) {
          if (!this._resHeaders.vary) {
              return true;
          }
  
          // A Vary header field-value of "*" always fails to match
          if (this._resHeaders.vary === '*') {
              return false;
          }
  
          const fields = this._resHeaders.vary
              .trim()
              .toLowerCase()
              .split(/\s*,\s*/);
          for (const name of fields) {
              if (req.headers[name] !== this._reqHeaders[name]) return false;
          }
          return true;
      }
  
      _copyWithoutHopByHopHeaders(inHeaders) {
          const headers = {};
          for (const name in inHeaders) {
              if (hopByHopHeaders[name]) continue;
              headers[name] = inHeaders[name];
          }
          // 9.1.  Connection
          if (inHeaders.connection) {
              const tokens = inHeaders.connection.trim().split(/\s*,\s*/);
              for (const name of tokens) {
                  delete headers[name];
              }
          }
          if (headers.warning) {
              const warnings = headers.warning.split(/,/).filter(warning => {
                  return !/^\s*1[0-9][0-9]/.test(warning);
              });
              if (!warnings.length) {
                  delete headers.warning;
              } else {
                  headers.warning = warnings.join(',').trim();
              }
          }
          return headers;
      }
  
      responseHeaders() {
          const headers = this._copyWithoutHopByHopHeaders(this._resHeaders);
          const age = this.age();
  
          // A cache SHOULD generate 113 warning if it heuristically chose a freshness
          // lifetime greater than 24 hours and the response's age is greater than 24 hours.
          if (
              age > 3600 * 24 &&
              !this._hasExplicitExpiration() &&
              this.maxAge() > 3600 * 24
          ) {
              headers.warning =
                  (headers.warning ? `${headers.warning}, ` : '') +
                  '113 - "rfc7234 5.5.4"';
          }
          headers.age = `${Math.round(age)}`;
          headers.date = new Date(this.now()).toUTCString();
          return headers;
      }
  
      /**
       * Value of the Date response header or current time if Date was invalid
       * @return timestamp
       */
      date() {
          const serverDate = Date.parse(this._resHeaders.date);
          if (isFinite(serverDate)) {
              return serverDate;
          }
          return this._responseTime;
      }
  
      /**
       * Value of the Age header, in seconds, updated for the current time.
       * May be fractional.
       *
       * @return Number
       */
      age() {
          let age = this._ageValue();
  
          const residentTime = (this.now() - this._responseTime) / 1000;
          return age + residentTime;
      }
  
      _ageValue() {
          return toNumberOrZero(this._resHeaders.age);
      }
  
      /**
       * Value of applicable max-age (or heuristic equivalent) in seconds. This counts since response's `Date`.
       *
       * For an up-to-date value, see `timeToLive()`.
       *
       * @return Number
       */
      maxAge() {
          if (!this.storable() || this._rescc['no-cache']) {
              return 0;
          }
  
          // Shared responses with cookies are cacheable according to the RFC, but IMHO it'd be unwise to do so by default
          // so this implementation requires explicit opt-in via public header
          if (
              this._isShared &&
              (this._resHeaders['set-cookie'] &&
                  !this._rescc.public &&
                  !this._rescc.immutable)
          ) {
              return 0;
          }
  
          if (this._resHeaders.vary === '*') {
              return 0;
          }
  
          if (this._isShared) {
              if (this._rescc['proxy-revalidate']) {
                  return 0;
              }
              // if a response includes the s-maxage directive, a shared cache recipient MUST ignore the Expires field.
              if (this._rescc['s-maxage']) {
                  return toNumberOrZero(this._rescc['s-maxage']);
              }
          }
  
          // If a response includes a Cache-Control field with the max-age directive, a recipient MUST ignore the Expires field.
          if (this._rescc['max-age']) {
              return toNumberOrZero(this._rescc['max-age']);
          }
  
          const defaultMinTtl = this._rescc.immutable ? this._immutableMinTtl : 0;
  
          const serverDate = this.date();
          if (this._resHeaders.expires) {
              const expires = Date.parse(this._resHeaders.expires);
              // A cache recipient MUST interpret invalid date formats, especially the value "0", as representing a time in the past (i.e., "already expired").
              if (Number.isNaN(expires) || expires < serverDate) {
                  return 0;
              }
              return Math.max(defaultMinTtl, (expires - serverDate) / 1000);
          }
  
          if (this._resHeaders['last-modified']) {
              const lastModified = Date.parse(this._resHeaders['last-modified']);
              if (isFinite(lastModified) && serverDate > lastModified) {
                  return Math.max(
                      defaultMinTtl,
                      ((serverDate - lastModified) / 1000) * this._cacheHeuristic
                  );
              }
          }
  
          return defaultMinTtl;
      }
  
      timeToLive() {
          const age = this.maxAge() - this.age();
          const staleIfErrorAge = age + toNumberOrZero(this._rescc['stale-if-error']);
          const staleWhileRevalidateAge = age + toNumberOrZero(this._rescc['stale-while-revalidate']);
          return Math.max(0, age, staleIfErrorAge, staleWhileRevalidateAge) * 1000;
      }
  
      stale() {
          return this.maxAge() <= this.age();
      }
  
      _useStaleIfError() {
          return this.maxAge() + toNumberOrZero(this._rescc['stale-if-error']) > this.age();
      }
  
      useStaleWhileRevalidate() {
          return this.maxAge() + toNumberOrZero(this._rescc['stale-while-revalidate']) > this.age();
      }
  
      static fromObject(obj) {
          return new this(undefined, undefined, { _fromObject: obj });
      }
  
      _fromObject(obj) {
          if (this._responseTime) throw Error('Reinitialized');
          if (!obj || obj.v !== 1) throw Error('Invalid serialization');
  
          this._responseTime = obj.t;
          this._isShared = obj.sh;
          this._cacheHeuristic = obj.ch;
          this._immutableMinTtl =
              obj.imm !== undefined ? obj.imm : 24 * 3600 * 1000;
          this._status = obj.st;
          this._resHeaders = obj.resh;
          this._rescc = obj.rescc;
          this._method = obj.m;
          this._url = obj.u;
          this._host = obj.h;
          this._noAuthorization = obj.a;
          this._reqHeaders = obj.reqh;
          this._reqcc = obj.reqcc;
      }
  
      toObject() {
          return {
              v: 1,
              t: this._responseTime,
              sh: this._isShared,
              ch: this._cacheHeuristic,
              imm: this._immutableMinTtl,
              st: this._status,
              resh: this._resHeaders,
              rescc: this._rescc,
              m: this._method,
              u: this._url,
              h: this._host,
              a: this._noAuthorization,
              reqh: this._reqHeaders,
              reqcc: this._reqcc,
          };
      }
  
      /**
       * Headers for sending to the origin server to revalidate stale response.
       * Allows server to return 304 to allow reuse of the previous response.
       *
       * Hop by hop headers are always stripped.
       * Revalidation headers may be added or removed, depending on request.
       */
      revalidationHeaders(incomingReq) {
          this._assertRequestHasHeaders(incomingReq);
          const headers = this._copyWithoutHopByHopHeaders(incomingReq.headers);
  
          // This implementation does not understand range requests
          delete headers['if-range'];
  
          if (!this._requestMatches(incomingReq, true) || !this.storable()) {
              // revalidation allowed via HEAD
              // not for the same resource, or wasn't allowed to be cached anyway
              delete headers['if-none-match'];
              delete headers['if-modified-since'];
              return headers;
          }
  
          /* MUST send that entity-tag in any cache validation request (using If-Match or If-None-Match) if an entity-tag has been provided by the origin server. */
          if (this._resHeaders.etag) {
              headers['if-none-match'] = headers['if-none-match']
                  ? `${headers['if-none-match']}, ${this._resHeaders.etag}`
                  : this._resHeaders.etag;
          }
  
          // Clients MAY issue simple (non-subrange) GET requests with either weak validators or strong validators. Clients MUST NOT use weak validators in other forms of request.
          const forbidsWeakValidators =
              headers['accept-ranges'] ||
              headers['if-match'] ||
              headers['if-unmodified-since'] ||
              (this._method && this._method != 'GET');
  
          /* SHOULD send the Last-Modified value in non-subrange cache validation requests (using If-Modified-Since) if only a Last-Modified value has been provided by the origin server.
          Note: This implementation does not understand partial responses (206) */
          if (forbidsWeakValidators) {
              delete headers['if-modified-since'];
  
              if (headers['if-none-match']) {
                  const etags = headers['if-none-match']
                      .split(/,/)
                      .filter(etag => {
                          return !/^\s*W\//.test(etag);
                      });
                  if (!etags.length) {
                      delete headers['if-none-match'];
                  } else {
                      headers['if-none-match'] = etags.join(',').trim();
                  }
              }
          } else if (
              this._resHeaders['last-modified'] &&
              !headers['if-modified-since']
          ) {
              headers['if-modified-since'] = this._resHeaders['last-modified'];
          }
  
          return headers;
      }
  
      /**
       * Creates new CachePolicy with information combined from the previews response,
       * and the new revalidation response.
       *
       * Returns {policy, modified} where modified is a boolean indicating
       * whether the response body has been modified, and old cached body can't be used.
       *
       * @return {Object} {policy: CachePolicy, modified: Boolean}
       */
      revalidatedPolicy(request, response) {
          this._assertRequestHasHeaders(request);
          if(this._useStaleIfError() && isErrorResponse(response)) {  // I consider the revalidation request unsuccessful
            return {
              modified: false,
              matches: false,
              policy: this,
            };
          }
          if (!response || !response.headers) {
              throw Error('Response headers missing');
          }
  
          // These aren't going to be supported exactly, since one CachePolicy object
          // doesn't know about all the other cached objects.
          let matches = false;
          if (response.status !== undefined && response.status != 304) {
              matches = false;
          } else if (
              response.headers.etag &&
              !/^\s*W\//.test(response.headers.etag)
          ) {
              // "All of the stored responses with the same strong validator are selected.
              // If none of the stored responses contain the same strong validator,
              // then the cache MUST NOT use the new response to update any stored responses."
              matches =
                  this._resHeaders.etag &&
                  this._resHeaders.etag.replace(/^\s*W\//, '') ===
                      response.headers.etag;
          } else if (this._resHeaders.etag && response.headers.etag) {
              // "If the new response contains a weak validator and that validator corresponds
              // to one of the cache's stored responses,
              // then the most recent of those matching stored responses is selected for update."
              matches =
                  this._resHeaders.etag.replace(/^\s*W\//, '') ===
                  response.headers.etag.replace(/^\s*W\//, '');
          } else if (this._resHeaders['last-modified']) {
              matches =
                  this._resHeaders['last-modified'] ===
                  response.headers['last-modified'];
          } else {
              // If the new response does not include any form of validator (such as in the case where
              // a client generates an If-Modified-Since request from a source other than the Last-Modified
              // response header field), and there is only one stored response, and that stored response also
              // lacks a validator, then that stored response is selected for update.
              if (
                  !this._resHeaders.etag &&
                  !this._resHeaders['last-modified'] &&
                  !response.headers.etag &&
                  !response.headers['last-modified']
              ) {
                  matches = true;
              }
          }
  
          if (!matches) {
              return {
                  policy: new this.constructor(request, response),
                  // Client receiving 304 without body, even if it's invalid/mismatched has no option
                  // but to reuse a cached body. We don't have a good way to tell clients to do
                  // error recovery in such case.
                  modified: response.status != 304,
                  matches: false,
              };
          }
  
          // use other header fields provided in the 304 (Not Modified) response to replace all instances
          // of the corresponding header fields in the stored response.
          const headers = {};
          for (const k in this._resHeaders) {
              headers[k] =
                  k in response.headers && !excludedFromRevalidationUpdate[k]
                      ? response.headers[k]
                      : this._resHeaders[k];
          }
  
          const newResponse = Object.assign({}, response, {
              status: this._status,
              method: this._method,
              headers,
          });
          return {
              policy: new this.constructor(request, newResponse, {
                  shared: this._isShared,
                  cacheHeuristic: this._cacheHeuristic,
                  immutableMinTimeToLive: this._immutableMinTtl,
              }),
              modified: false,
              matches: true,
          };
      }
  };
  
  
  /***/ }),
  
  /***/ 157:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const http2 = __webpack_require__(565);
  const agent = __webpack_require__(899);
  const ClientRequest = __webpack_require__(181);
  const IncomingMessage = __webpack_require__(750);
  const auto = __webpack_require__(988);
  
  const request = (url, options, callback) => {
  	return new ClientRequest(url, options, callback);
  };
  
  const get = (url, options, callback) => {
  	// eslint-disable-next-line unicorn/prevent-abbreviations
  	const req = new ClientRequest(url, options, callback);
  	req.end();
  
  	return req;
  };
  
  module.exports = {
  	...http2,
  	ClientRequest,
  	IncomingMessage,
  	...agent,
  	request,
  	get,
  	auto
  };
  
  
  /***/ }),
  
  /***/ 181:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const http2 = __webpack_require__(565);
  const {Writable} = __webpack_require__(413);
  const {Agent, globalAgent} = __webpack_require__(899);
  const IncomingMessage = __webpack_require__(750);
  const urlToOptions = __webpack_require__(507);
  const proxyEvents = __webpack_require__(231);
  const isRequestPseudoHeader = __webpack_require__(723);
  const {
  	ERR_INVALID_ARG_TYPE,
  	ERR_INVALID_PROTOCOL,
  	ERR_HTTP_HEADERS_SENT,
  	ERR_INVALID_HTTP_TOKEN,
  	ERR_HTTP_INVALID_HEADER_VALUE,
  	ERR_INVALID_CHAR
  } = __webpack_require__(699);
  
  const {
  	HTTP2_HEADER_STATUS,
  	HTTP2_HEADER_METHOD,
  	HTTP2_HEADER_PATH,
  	HTTP2_METHOD_CONNECT
  } = http2.constants;
  
  const kHeaders = Symbol('headers');
  const kOrigin = Symbol('origin');
  const kSession = Symbol('session');
  const kOptions = Symbol('options');
  const kFlushedHeaders = Symbol('flushedHeaders');
  const kJobs = Symbol('jobs');
  
  const isValidHttpToken = /^[\^`\-\w!#$%&*+.|~]+$/;
  const isInvalidHeaderValue = /[^\t\u0020-\u007E\u0080-\u00FF]/;
  
  class ClientRequest extends Writable {
  	constructor(input, options, callback) {
  		super({
  			autoDestroy: false
  		});
  
  		const hasInput = typeof input === 'string' || input instanceof URL;
  		if (hasInput) {
  			input = urlToOptions(input instanceof URL ? input : new URL(input));
  		}
  
  		if (typeof options === 'function' || options === undefined) {
  			// (options, callback)
  			callback = options;
  			options = hasInput ? input : {...input};
  		} else {
  			// (input, options, callback)
  			options = {...input, ...options};
  		}
  
  		if (options.h2session) {
  			this[kSession] = options.h2session;
  		} else if (options.agent === false) {
  			this.agent = new Agent({maxFreeSessions: 0});
  		} else if (typeof options.agent === 'undefined' || options.agent === null) {
  			if (typeof options.createConnection === 'function') {
  				// This is a workaround - we don't have to create the session on our own.
  				this.agent = new Agent({maxFreeSessions: 0});
  				this.agent.createConnection = options.createConnection;
  			} else {
  				this.agent = globalAgent;
  			}
  		} else if (typeof options.agent.request === 'function') {
  			this.agent = options.agent;
  		} else {
  			throw new ERR_INVALID_ARG_TYPE('options.agent', ['Agent-like Object', 'undefined', 'false'], options.agent);
  		}
  
  		if (options.protocol && options.protocol !== 'https:') {
  			throw new ERR_INVALID_PROTOCOL(options.protocol, 'https:');
  		}
  
  		const port = options.port || options.defaultPort || (this.agent && this.agent.defaultPort) || 443;
  		const host = options.hostname || options.host || 'localhost';
  
  		// Don't enforce the origin via options. It may be changed in an Agent.
  		delete options.hostname;
  		delete options.host;
  		delete options.port;
  
  		const {timeout} = options;
  		options.timeout = undefined;
  
  		this[kHeaders] = Object.create(null);
  		this[kJobs] = [];
  
  		this.socket = null;
  		this.connection = null;
  
  		this.method = options.method || 'GET';
  		this.path = options.path;
  
  		this.res = null;
  		this.aborted = false;
  		this.reusedSocket = false;
  
  		if (options.headers) {
  			for (const [header, value] of Object.entries(options.headers)) {
  				this.setHeader(header, value);
  			}
  		}
  
  		if (options.auth && !('authorization' in this[kHeaders])) {
  			this[kHeaders].authorization = 'Basic ' + Buffer.from(options.auth).toString('base64');
  		}
  
  		options.session = options.tlsSession;
  		options.path = options.socketPath;
  
  		this[kOptions] = options;
  
  		// Clients that generate HTTP/2 requests directly SHOULD use the :authority pseudo-header field instead of the Host header field.
  		if (port === 443) {
  			this[kOrigin] = `https://${host}`;
  
  			if (!(':authority' in this[kHeaders])) {
  				this[kHeaders][':authority'] = host;
  			}
  		} else {
  			this[kOrigin] = `https://${host}:${port}`;
  
  			if (!(':authority' in this[kHeaders])) {
  				this[kHeaders][':authority'] = `${host}:${port}`;
  			}
  		}
  
  		if (timeout) {
  			this.setTimeout(timeout);
  		}
  
  		if (callback) {
  			this.once('response', callback);
  		}
  
  		this[kFlushedHeaders] = false;
  	}
  
  	get method() {
  		return this[kHeaders][HTTP2_HEADER_METHOD];
  	}
  
  	set method(value) {
  		if (value) {
  			this[kHeaders][HTTP2_HEADER_METHOD] = value.toUpperCase();
  		}
  	}
  
  	get path() {
  		return this[kHeaders][HTTP2_HEADER_PATH];
  	}
  
  	set path(value) {
  		if (value) {
  			this[kHeaders][HTTP2_HEADER_PATH] = value;
  		}
  	}
  
  	get _mustNotHaveABody() {
  		return this.method === 'GET' || this.method === 'HEAD' || this.method === 'DELETE';
  	}
  
  	_write(chunk, encoding, callback) {
  		// https://github.com/nodejs/node/blob/654df09ae0c5e17d1b52a900a545f0664d8c7627/lib/internal/http2/util.js#L148-L156
  		if (this._mustNotHaveABody) {
  			callback(new Error('The GET, HEAD and DELETE methods must NOT have a body'));
  			/* istanbul ignore next: Node.js 12 throws directly */
  			return;
  		}
  
  		this.flushHeaders();
  
  		const callWrite = () => this._request.write(chunk, encoding, callback);
  		if (this._request) {
  			callWrite();
  		} else {
  			this[kJobs].push(callWrite);
  		}
  	}
  
  	_final(callback) {
  		if (this.destroyed) {
  			return;
  		}
  
  		this.flushHeaders();
  
  		const callEnd = () => {
  			// For GET, HEAD and DELETE
  			if (this._mustNotHaveABody) {
  				callback();
  				return;
  			}
  
  			this._request.end(callback);
  		};
  
  		if (this._request) {
  			callEnd();
  		} else {
  			this[kJobs].push(callEnd);
  		}
  	}
  
  	abort() {
  		if (this.res && this.res.complete) {
  			return;
  		}
  
  		if (!this.aborted) {
  			process.nextTick(() => this.emit('abort'));
  		}
  
  		this.aborted = true;
  
  		this.destroy();
  	}
  
  	_destroy(error, callback) {
  		if (this.res) {
  			this.res._dump();
  		}
  
  		if (this._request) {
  			this._request.destroy();
  		}
  
  		callback(error);
  	}
  
  	async flushHeaders() {
  		if (this[kFlushedHeaders] || this.destroyed) {
  			return;
  		}
  
  		this[kFlushedHeaders] = true;
  
  		const isConnectMethod = this.method === HTTP2_METHOD_CONNECT;
  
  		// The real magic is here
  		const onStream = stream => {
  			this._request = stream;
  
  			if (this.destroyed) {
  				stream.destroy();
  				return;
  			}
  
  			// Forwards `timeout`, `continue`, `close` and `error` events to this instance.
  			if (!isConnectMethod) {
  				proxyEvents(stream, this, ['timeout', 'continue', 'close', 'error']);
  			}
  
  			// Wait for the `finish` event. We don't want to emit the `response` event
  			// before `request.end()` is called.
  			const waitForEnd = fn => {
  				return (...args) => {
  					if (!this.writable && !this.destroyed) {
  						fn(...args);
  					} else {
  						this.once('finish', () => {
  							fn(...args);
  						});
  					}
  				};
  			};
  
  			// This event tells we are ready to listen for the data.
  			stream.once('response', waitForEnd((headers, flags, rawHeaders) => {
  				// If we were to emit raw request stream, it would be as fast as the native approach.
  				// Note that wrapping the raw stream in a Proxy instance won't improve the performance (already tested it).
  				const response = new IncomingMessage(this.socket, stream.readableHighWaterMark);
  				this.res = response;
  
  				response.req = this;
  				response.statusCode = headers[HTTP2_HEADER_STATUS];
  				response.headers = headers;
  				response.rawHeaders = rawHeaders;
  
  				response.once('end', () => {
  					if (this.aborted) {
  						response.aborted = true;
  						response.emit('aborted');
  					} else {
  						response.complete = true;
  
  						// Has no effect, just be consistent with the Node.js behavior
  						response.socket = null;
  						response.connection = null;
  					}
  				});
  
  				if (isConnectMethod) {
  					response.upgrade = true;
  
  					// The HTTP1 API says the socket is detached here,
  					// but we can't do that so we pass the original HTTP2 request.
  					if (this.emit('connect', response, stream, Buffer.alloc(0))) {
  						this.emit('close');
  					} else {
  						// No listeners attached, destroy the original request.
  						stream.destroy();
  					}
  				} else {
  					// Forwards data
  					stream.on('data', chunk => {
  						if (!response._dumped && !response.push(chunk)) {
  							stream.pause();
  						}
  					});
  
  					stream.once('end', () => {
  						response.push(null);
  					});
  
  					if (!this.emit('response', response)) {
  						// No listeners attached, dump the response.
  						response._dump();
  					}
  				}
  			}));
  
  			// Emits `information` event
  			stream.once('headers', waitForEnd(
  				headers => this.emit('information', {statusCode: headers[HTTP2_HEADER_STATUS]})
  			));
  
  			stream.once('trailers', waitForEnd((trailers, flags, rawTrailers) => {
  				const {res} = this;
  
  				// Assigns trailers to the response object.
  				res.trailers = trailers;
  				res.rawTrailers = rawTrailers;
  			}));
  
  			const {socket} = stream.session;
  			this.socket = socket;
  			this.connection = socket;
  
  			for (const job of this[kJobs]) {
  				job();
  			}
  
  			this.emit('socket', this.socket);
  		};
  
  		// Makes a HTTP2 request
  		if (this[kSession]) {
  			try {
  				onStream(this[kSession].request(this[kHeaders]));
  			} catch (error) {
  				this.emit('error', error);
  			}
  		} else {
  			this.reusedSocket = true;
  
  			try {
  				onStream(await this.agent.request(this[kOrigin], this[kOptions], this[kHeaders]));
  			} catch (error) {
  				this.emit('error', error);
  			}
  		}
  	}
  
  	getHeader(name) {
  		if (typeof name !== 'string') {
  			throw new ERR_INVALID_ARG_TYPE('name', 'string', name);
  		}
  
  		return this[kHeaders][name.toLowerCase()];
  	}
  
  	get headersSent() {
  		return this[kFlushedHeaders];
  	}
  
  	removeHeader(name) {
  		if (typeof name !== 'string') {
  			throw new ERR_INVALID_ARG_TYPE('name', 'string', name);
  		}
  
  		if (this.headersSent) {
  			throw new ERR_HTTP_HEADERS_SENT('remove');
  		}
  
  		delete this[kHeaders][name.toLowerCase()];
  	}
  
  	setHeader(name, value) {
  		if (this.headersSent) {
  			throw new ERR_HTTP_HEADERS_SENT('set');
  		}
  
  		if (typeof name !== 'string' || (!isValidHttpToken.test(name) && !isRequestPseudoHeader(name))) {
  			throw new ERR_INVALID_HTTP_TOKEN('Header name', name);
  		}
  
  		if (typeof value === 'undefined') {
  			throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name);
  		}
  
  		if (isInvalidHeaderValue.test(value)) {
  			throw new ERR_INVALID_CHAR('header content', name);
  		}
  
  		this[kHeaders][name.toLowerCase()] = value;
  	}
  
  	setNoDelay() {
  		// HTTP2 sockets cannot be malformed, do nothing.
  	}
  
  	setSocketKeepAlive() {
  		// HTTP2 sockets cannot be malformed, do nothing.
  	}
  
  	setTimeout(ms, callback) {
  		const applyTimeout = () => this._request.setTimeout(ms, callback);
  
  		if (this._request) {
  			applyTimeout();
  		} else {
  			this[kJobs].push(applyTimeout);
  		}
  
  		return this;
  	}
  
  	get maxHeadersCount() {
  		if (!this.destroyed && this._request) {
  			return this._request.session.localSettings.maxHeaderListSize;
  		}
  
  		return undefined;
  	}
  
  	set maxHeadersCount(_value) {
  		// Updating HTTP2 settings would affect all requests, do nothing.
  	}
  }
  
  module.exports = ClientRequest;
  
  
  /***/ }),
  
  /***/ 189:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const alreadyWarned = new Set();
  exports.default = (message) => {
      if (alreadyWarned.has(message)) {
          return;
      }
      alreadyWarned.add(message);
      // @ts-expect-error Missing types.
      process.emitWarning(`Got: ${message}`, {
          type: 'DeprecationWarning'
      });
  };
  
  
  /***/ }),
  
  /***/ 205:
  /***/ (function(__unusedmodule, exports) {
  
  //TODO: handle reviver/dehydrate function like normal
  //and handle indentation, like normal.
  //if anyone needs this... please send pull request.
  
  exports.stringify = function stringify (o) {
    if('undefined' == typeof o) return o
  
    if(o && Buffer.isBuffer(o))
      return JSON.stringify(':base64:' + o.toString('base64'))
  
    if(o && o.toJSON)
      o =  o.toJSON()
  
    if(o && 'object' === typeof o) {
      var s = ''
      var array = Array.isArray(o)
      s = array ? '[' : '{'
      var first = true
  
      for(var k in o) {
        var ignore = 'function' == typeof o[k] || (!array && 'undefined' === typeof o[k])
        if(Object.hasOwnProperty.call(o, k) && !ignore) {
          if(!first)
            s += ','
          first = false
          if (array) {
            if(o[k] == undefined)
              s += 'null'
            else
              s += stringify(o[k])
          } else if (o[k] !== void(0)) {
            s += stringify(k) + ':' + stringify(o[k])
          }
        }
      }
  
      s += array ? ']' : '}'
  
      return s
    } else if ('string' === typeof o) {
      return JSON.stringify(/^:/.test(o) ? ':' + o : o)
    } else if ('undefined' === typeof o) {
      return 'null';
    } else
      return JSON.stringify(o)
  }
  
  exports.parse = function (s) {
    return JSON.parse(s, function (key, value) {
      if('string' === typeof value) {
        if(/^:base64:/.test(value))
          return Buffer.from(value.substring(8), 'base64')
        else
          return /^:/.test(value) ? value.substring(1) : value 
      }
      return value
    })
  }
  
  
  /***/ }),
  
  /***/ 211:
  /***/ (function(module) {
  
  module.exports = require("https");
  
  /***/ }),
  
  /***/ 231:
  /***/ (function(module) {
  
  "use strict";
  
  
  module.exports = (from, to, events) => {
  	for (const event of events) {
  		from.on(event, (...args) => to.emit(event, ...args));
  	}
  };
  
  
  /***/ }),
  
  /***/ 291:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const is_1 = __webpack_require__(534);
  function deepFreeze(object) {
      for (const value of Object.values(object)) {
          if (is_1.default.plainObject(value) || is_1.default.array(value)) {
              deepFreeze(value);
          }
      }
      return Object.freeze(object);
  }
  exports.default = deepFreeze;
  
  
  /***/ }),
  
  /***/ 293:
  /***/ (function(module) {
  
  module.exports = require("buffer");
  
  /***/ }),
  
  /***/ 303:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  
  const EventEmitter = __webpack_require__(614);
  const JSONB = __webpack_require__(205);
  
  const loadStore = opts => {
  	const adapters = {
  		redis: '@keyv/redis',
  		mongodb: '@keyv/mongo',
  		mongo: '@keyv/mongo',
  		sqlite: '@keyv/sqlite',
  		postgresql: '@keyv/postgres',
  		postgres: '@keyv/postgres',
  		mysql: '@keyv/mysql'
  	};
  	if (opts.adapter || opts.uri) {
  		const adapter = opts.adapter || /^[^:]*/.exec(opts.uri)[0];
  		return new (require(adapters[adapter]))(opts);
  	}
  
  	return new Map();
  };
  
  class Keyv extends EventEmitter {
  	constructor(uri, opts) {
  		super();
  		this.opts = Object.assign(
  			{
  				namespace: 'keyv',
  				serialize: JSONB.stringify,
  				deserialize: JSONB.parse
  			},
  			(typeof uri === 'string') ? { uri } : uri,
  			opts
  		);
  
  		if (!this.opts.store) {
  			const adapterOpts = Object.assign({}, this.opts);
  			this.opts.store = loadStore(adapterOpts);
  		}
  
  		if (typeof this.opts.store.on === 'function') {
  			this.opts.store.on('error', err => this.emit('error', err));
  		}
  
  		this.opts.store.namespace = this.opts.namespace;
  	}
  
  	_getKeyPrefix(key) {
  		return `${this.opts.namespace}:${key}`;
  	}
  
  	get(key, opts) {
  		const keyPrefixed = this._getKeyPrefix(key);
  		const { store } = this.opts;
  		return Promise.resolve()
  			.then(() => store.get(keyPrefixed))
  			.then(data => {
  				return (typeof data === 'string') ? this.opts.deserialize(data) : data;
  			})
  			.then(data => {
  				if (data === undefined) {
  					return undefined;
  				}
  
  				if (typeof data.expires === 'number' && Date.now() > data.expires) {
  					this.delete(key);
  					return undefined;
  				}
  
  				return (opts && opts.raw) ? data : data.value;
  			});
  	}
  
  	set(key, value, ttl) {
  		const keyPrefixed = this._getKeyPrefix(key);
  		if (typeof ttl === 'undefined') {
  			ttl = this.opts.ttl;
  		}
  
  		if (ttl === 0) {
  			ttl = undefined;
  		}
  
  		const { store } = this.opts;
  
  		return Promise.resolve()
  			.then(() => {
  				const expires = (typeof ttl === 'number') ? (Date.now() + ttl) : null;
  				value = { value, expires };
  				return this.opts.serialize(value);
  			})
  			.then(value => store.set(keyPrefixed, value, ttl))
  			.then(() => true);
  	}
  
  	delete(key) {
  		const keyPrefixed = this._getKeyPrefix(key);
  		const { store } = this.opts;
  		return Promise.resolve()
  			.then(() => store.delete(keyPrefixed));
  	}
  
  	clear() {
  		const { store } = this.opts;
  		return Promise.resolve()
  			.then(() => store.clear());
  	}
  }
  
  module.exports = Keyv;
  
  
  /***/ }),
  
  /***/ 323:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
      for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.defaultHandler = void 0;
  const is_1 = __webpack_require__(534);
  const as_promise_1 = __webpack_require__(577);
  const create_rejection_1 = __webpack_require__(910);
  const core_1 = __webpack_require__(946);
  const deep_freeze_1 = __webpack_require__(291);
  const errors = {
      RequestError: as_promise_1.RequestError,
      CacheError: as_promise_1.CacheError,
      ReadError: as_promise_1.ReadError,
      HTTPError: as_promise_1.HTTPError,
      MaxRedirectsError: as_promise_1.MaxRedirectsError,
      TimeoutError: as_promise_1.TimeoutError,
      ParseError: as_promise_1.ParseError,
      CancelError: as_promise_1.CancelError,
      UnsupportedProtocolError: as_promise_1.UnsupportedProtocolError,
      UploadError: as_promise_1.UploadError
  };
  // The `delay` package weighs 10KB (!)
  const delay = async (ms) => new Promise(resolve => {
      setTimeout(resolve, ms);
  });
  const { normalizeArguments } = core_1.default;
  const mergeOptions = (...sources) => {
      let mergedOptions;
      for (const source of sources) {
          mergedOptions = normalizeArguments(undefined, source, mergedOptions);
      }
      return mergedOptions;
  };
  const getPromiseOrStream = (options) => options.isStream ? new core_1.default(undefined, options) : as_promise_1.default(options);
  const isGotInstance = (value) => ('defaults' in value && 'options' in value.defaults);
  const aliases = [
      'get',
      'post',
      'put',
      'patch',
      'head',
      'delete'
  ];
  exports.defaultHandler = (options, next) => next(options);
  const callInitHooks = (hooks, options) => {
      if (hooks) {
          for (const hook of hooks) {
              hook(options);
          }
      }
  };
  const create = (defaults) => {
      // Proxy properties from next handlers
      defaults._rawHandlers = defaults.handlers;
      defaults.handlers = defaults.handlers.map(fn => ((options, next) => {
          // This will be assigned by assigning result
          let root;
          const result = fn(options, newOptions => {
              root = next(newOptions);
              return root;
          });
          if (result !== root && !options.isStream && root) {
              const typedResult = result;
              const { then: promiseThen, catch: promiseCatch, finally: promiseFianlly } = typedResult;
              Object.setPrototypeOf(typedResult, Object.getPrototypeOf(root));
              Object.defineProperties(typedResult, Object.getOwnPropertyDescriptors(root));
              // These should point to the new promise
              // eslint-disable-next-line promise/prefer-await-to-then
              typedResult.then = promiseThen;
              typedResult.catch = promiseCatch;
              typedResult.finally = promiseFianlly;
          }
          return result;
      }));
      // Got interface
      const got = ((url, options, _defaults) => {
          var _a, _b;
          let iteration = 0;
          const iterateHandlers = (newOptions) => {
              return defaults.handlers[iteration++](newOptions, iteration === defaults.handlers.length ? getPromiseOrStream : iterateHandlers);
          };
          // TODO: Remove this in Got 12.
          if (is_1.default.plainObject(url)) {
              const mergedOptions = {
                  ...url,
                  ...options
              };
              core_1.setNonEnumerableProperties([url, options], mergedOptions);
              options = mergedOptions;
              url = undefined;
          }
          try {
              // Call `init` hooks
              let initHookError;
              try {
                  callInitHooks(defaults.options.hooks.init, options);
                  callInitHooks((_a = options === null || options === void 0 ? void 0 : options.hooks) === null || _a === void 0 ? void 0 : _a.init, options);
              }
              catch (error) {
                  initHookError = error;
              }
              // Normalize options & call handlers
              const normalizedOptions = normalizeArguments(url, options, _defaults !== null && _defaults !== void 0 ? _defaults : defaults.options);
              normalizedOptions[core_1.kIsNormalizedAlready] = true;
              if (initHookError) {
                  throw new as_promise_1.RequestError(initHookError.message, initHookError, normalizedOptions);
              }
              return iterateHandlers(normalizedOptions);
          }
          catch (error) {
              if (options === null || options === void 0 ? void 0 : options.isStream) {
                  throw error;
              }
              else {
                  return create_rejection_1.default(error, defaults.options.hooks.beforeError, (_b = options === null || options === void 0 ? void 0 : options.hooks) === null || _b === void 0 ? void 0 : _b.beforeError);
              }
          }
      });
      got.extend = (...instancesOrOptions) => {
          const optionsArray = [defaults.options];
          let handlers = [...defaults._rawHandlers];
          let isMutableDefaults;
          for (const value of instancesOrOptions) {
              if (isGotInstance(value)) {
                  optionsArray.push(value.defaults.options);
                  handlers.push(...value.defaults._rawHandlers);
                  isMutableDefaults = value.defaults.mutableDefaults;
              }
              else {
                  optionsArray.push(value);
                  if ('handlers' in value) {
                      handlers.push(...value.handlers);
                  }
                  isMutableDefaults = value.mutableDefaults;
              }
          }
          handlers = handlers.filter(handler => handler !== exports.defaultHandler);
          if (handlers.length === 0) {
              handlers.push(exports.defaultHandler);
          }
          return create({
              options: mergeOptions(...optionsArray),
              handlers,
              mutableDefaults: Boolean(isMutableDefaults)
          });
      };
      // Pagination
      const paginateEach = (async function* (url, options) {
          // TODO: Remove this `@ts-expect-error` when upgrading to TypeScript 4.
          // Error: Argument of type 'Merge<Options, PaginationOptions<T, R>> | undefined' is not assignable to parameter of type 'Options | undefined'.
          // @ts-expect-error
          let normalizedOptions = normalizeArguments(url, options, defaults.options);
          normalizedOptions.resolveBodyOnly = false;
          const pagination = normalizedOptions.pagination;
          if (!is_1.default.object(pagination)) {
              throw new TypeError('`options.pagination` must be implemented');
          }
          const all = [];
          let { countLimit } = pagination;
          let numberOfRequests = 0;
          while (numberOfRequests < pagination.requestLimit) {
              if (numberOfRequests !== 0) {
                  // eslint-disable-next-line no-await-in-loop
                  await delay(pagination.backoff);
              }
              // @ts-expect-error FIXME!
              // TODO: Throw when result is not an instance of Response
              // eslint-disable-next-line no-await-in-loop
              const result = (await got(undefined, undefined, normalizedOptions));
              // eslint-disable-next-line no-await-in-loop
              const parsed = await pagination.transform(result);
              const current = [];
              for (const item of parsed) {
                  if (pagination.filter(item, all, current)) {
                      if (!pagination.shouldContinue(item, all, current)) {
                          return;
                      }
                      yield item;
                      if (pagination.stackAllItems) {
                          all.push(item);
                      }
                      current.push(item);
                      if (--countLimit <= 0) {
                          return;
                      }
                  }
              }
              const optionsToMerge = pagination.paginate(result, all, current);
              if (optionsToMerge === false) {
                  return;
              }
              if (optionsToMerge === result.request.options) {
                  normalizedOptions = result.request.options;
              }
              else if (optionsToMerge !== undefined) {
                  normalizedOptions = normalizeArguments(undefined, optionsToMerge, normalizedOptions);
              }
              numberOfRequests++;
          }
      });
      got.paginate = paginateEach;
      got.paginate.all = (async (url, options) => {
          const results = [];
          for await (const item of paginateEach(url, options)) {
              results.push(item);
          }
          return results;
      });
      // For those who like very descriptive names
      got.paginate.each = paginateEach;
      // Stream API
      got.stream = ((url, options) => got(url, { ...options, isStream: true }));
      // Shortcuts
      for (const method of aliases) {
          got[method] = ((url, options) => got(url, { ...options, method }));
          got.stream[method] = ((url, options) => {
              return got(url, { ...options, method, isStream: true });
          });
      }
      Object.assign(got, errors);
      Object.defineProperty(got, 'defaults', {
          value: defaults.mutableDefaults ? defaults : deep_freeze_1.default(defaults),
          writable: defaults.mutableDefaults,
          configurable: defaults.mutableDefaults,
          enumerable: true
      });
      got.mergeOptions = mergeOptions;
      return got;
  };
  exports.default = create;
  __exportStar(__webpack_require__(839), exports);
  
  
  /***/ }),
  
  /***/ 325:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  
  const PassThrough = __webpack_require__(413).PassThrough;
  const mimicResponse = __webpack_require__(89);
  
  const cloneResponse = response => {
  	if (!(response && response.pipe)) {
  		throw new TypeError('Parameter `response` must be a response stream.');
  	}
  
  	const clone = new PassThrough();
  	mimicResponse(response, clone);
  
  	return response.pipe(clone);
  };
  
  module.exports = cloneResponse;
  
  
  /***/ }),
  
  /***/ 350:
  /***/ (function(module) {
  
  (function(f){if(true){module.exports=f()}else { var g; }})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
  /**
   * © Copyright IBM Corp. 2018 All Rights Reserved
   *   Project name: JSONata
   *   This project is licensed under the MIT License, see LICENSE
   */
  
  const utils = require('./utils');
  
  /**
   * DateTime formatting and parsing functions
   * Implements the xpath-functions format-date-time specification
   * @type {{formatInteger, formatDateTime, parseInteger, parseDateTime}}
   */
  const dateTime = (function () {
      'use strict';
  
      const stringToArray = utils.stringToArray;
  
      const few = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten',
          'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'];
      const ordinals = ['Zeroth', 'First', 'Second', 'Third', 'Fourth', 'Fifth', 'Sixth', 'Seventh', 'Eighth', 'Ninth', 'Tenth',
          'Eleventh', 'Twelfth', 'Thirteenth', 'Fourteenth', 'Fifteenth', 'Sixteenth', 'Seventeenth', 'Eighteenth', 'Nineteenth'];
      const decades = ['Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety', 'Hundred'];
      const magnitudes = ['Thousand', 'Million', 'Billion', 'Trillion'];
  
      /**
       * converts a number into english words
       * @param {string} value - the value to format
       * @param {boolean} ordinal - ordinal or cardinal form
       * @returns {string} - representation in words
       */
      function numberToWords(value, ordinal) {
          var lookup = function (num, prev, ord) {
              var words = '';
              if (num <= 19) {
                  words = (prev ? ' and ' : '') + (ord ? ordinals[num] : few[num]);
              } else if (num < 100) {
                  const tens = Math.floor(num / 10);
                  const remainder = num % 10;
                  words = (prev ? ' and ' : '') + decades[tens - 2];
                  if (remainder > 0) {
                      words += '-' + lookup(remainder, false, ord);
                  } else if (ord) {
                      words = words.substring(0, words.length - 1) + 'ieth';
                  }
              } else if (num < 1000) {
                  const hundreds = Math.floor(num / 100);
                  const remainder = num % 100;
                  words = (prev ? ', ' : '') + few[hundreds] + ' Hundred';
                  if (remainder > 0) {
                      words += lookup(remainder, true, ord);
                  } else if (ord) {
                      words += 'th';
                  }
              } else {
                  var mag = Math.floor(Math.log10(num) / 3);
                  if (mag > magnitudes.length) {
                      mag = magnitudes.length; // the largest word
                  }
                  const factor = Math.pow(10, mag * 3);
                  const mant = Math.floor(num / factor);
                  const remainder = num - mant * factor;
                  words = (prev ? ', ' : '') + lookup(mant, false, false) + ' ' + magnitudes[mag - 1];
                  if (remainder > 0) {
                      words += lookup(remainder, true, ord);
                  } else if (ord) {
                      words += 'th';
                  }
              }
              return words;
          };
  
          var words = lookup(value, false, ordinal);
          return words;
      }
  
      const wordValues = {};
      few.forEach(function (word, index) {
          wordValues[word.toLowerCase()] = index;
      });
      ordinals.forEach(function (word, index) {
          wordValues[word.toLowerCase()] = index;
      });
      decades.forEach(function (word, index) {
          const lword = word.toLowerCase();
          wordValues[lword] = (index + 2) * 10;
          wordValues[lword.substring(0, word.length - 1) + 'ieth'] = wordValues[lword];
      });
      wordValues.hundredth = 100;
      magnitudes.forEach(function (word, index) {
          const lword = word.toLowerCase();
          const val = Math.pow(10, (index + 1) * 3);
          wordValues[lword] = val;
          wordValues[lword + 'th'] = val;
      });
  
      /**
       * Converts a number in english words to numeric value
       * @param {string} text - the number in words
       * @returns {number} - the numeric value
       */
      function wordsToNumber(text) {
          const parts = text.split(/,\s|\sand\s|[\s\\-]/);
          const values = parts.map(part => wordValues[part]);
          let segs = [0];
          values.forEach(value => {
              if (value < 100) {
                  let top = segs.pop();
                  if (top >= 1000) {
                      segs.push(top);
                      top = 0;
                  }
                  segs.push(top + value);
              } else {
                  segs.push(segs.pop() * value);
              }
          });
          const result = segs.reduce((a, b) => a + b, 0);
          return result;
      }
  
      const romanNumerals = [
          [1000, 'm'],
          [900, 'cm'],
          [500, 'd'],
          [400, 'cd'],
          [100, 'c'],
          [90, 'xc'],
          [50, 'l'],
          [40, 'xl'],
          [10, 'x'],
          [9, 'ix'],
          [5, 'v'],
          [4, 'iv'],
          [1, 'i']
      ];
  
      const romanValues = {'M': 1000, 'D': 500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1};
  
      /**
       * converts a number to roman numerals
       * @param {number} value - the number
       * @returns {string} - the number in roman numerals
       */
      function decimalToRoman(value) {
          for (var index = 0; index < romanNumerals.length; index++) {
              const numeral = romanNumerals[index];
              if (value >= numeral[0]) {
                  return numeral[1] + decimalToRoman(value - numeral[0]);
              }
          }
          return '';
      }
  
      /**
       * converts roman numerals to a number
       * @param {string} roman - roman number
       * @returns {number} - the numeric value
       */
      function romanToDecimal(roman) {
          var decimal = 0;
          var max = 1;
          for (var i = roman.length - 1; i >= 0; i--) {
              const digit = roman[i];
              const value = romanValues[digit];
              if (value < max) {
                  decimal -= value;
              } else {
                  max = value;
                  decimal += value;
              }
          }
          return decimal;
      }
  
      /**
       * converts a number to spreadsheet style letters
       * @param {number} value - the number
       * @param {string} aChar - the character representing the start of the sequence, e.g. 'A'
       * @returns {string} - the letters
       */
      function decimalToLetters(value, aChar) {
          var letters = [];
          var aCode = aChar.charCodeAt(0);
          while (value > 0) {
              letters.unshift(String.fromCharCode((value - 1) % 26 + aCode));
              value = Math.floor((value - 1) / 26);
          }
          return letters.join('');
      }
  
      /**
       * converts spreadsheet style letters to a number
       * @param {string} letters - the letters
       * @param {string} aChar - the character representing the start of the sequence, e.g. 'A'
       * @returns {number} - the numeric value
       */
      function lettersToDecimal(letters, aChar) {
          var aCode = aChar.charCodeAt(0);
          var decimal = 0;
          for (var i = 0; i < letters.length; i++) {
              decimal += (letters.charCodeAt(letters.length - i - 1) - aCode + 1) * Math.pow(26, i);
          }
          return decimal;
      }
  
      /**
       * Formats an integer as specified by the XPath fn:format-integer function
       * See https://www.w3.org/TR/xpath-functions-31/#func-format-integer
       * @param {number} value - the number to be formatted
       * @param {string} picture - the picture string that specifies the format
       * @returns {string} - the formatted number
       */
      function formatInteger(value, picture) {
          if (typeof value === 'undefined') {
              return undefined;
          }
  
          value = Math.floor(value);
  
          const format = analyseIntegerPicture(picture);
          return _formatInteger(value, format);
      }
  
      const formats = {
          DECIMAL: 'decimal',
          LETTERS: 'letters',
          ROMAN: 'roman',
          WORDS: 'words',
          SEQUENCE: 'sequence'
      };
  
      const tcase = {
          UPPER: 'upper',
          LOWER: 'lower',
          TITLE: 'title'
      };
  
      /**
       * formats an integer using a preprocessed representation of the picture string
       * @param {number} value - the number to be formatted
       * @param {object} format - the preprocessed representation of the pucture string
       * @returns {string} - the formatted number
       * @private
       */
      function _formatInteger(value, format) {
          let formattedInteger;
          const negative = value < 0;
          value = Math.abs(value);
          switch (format.primary) {
              case formats.LETTERS:
                  formattedInteger = decimalToLetters(value, format.case === tcase.UPPER ? 'A' : 'a');
                  break;
              case formats.ROMAN:
                  formattedInteger = decimalToRoman(value);
                  if (format.case === tcase.UPPER) {
                      formattedInteger = formattedInteger.toUpperCase();
                  }
                  break;
              case formats.WORDS:
                  formattedInteger = numberToWords(value, format.ordinal);
                  if (format.case === tcase.UPPER) {
                      formattedInteger = formattedInteger.toUpperCase();
                  } else if (format.case === tcase.LOWER) {
                      formattedInteger = formattedInteger.toLowerCase();
                  }
                  break;
              case formats.DECIMAL:
                  formattedInteger = '' + value;
                  // TODO use functionPad
                  var padLength = format.mandatoryDigits - formattedInteger.length;
                  if (padLength > 0) {
                      var padding = (new Array(padLength + 1)).join('0');
                      formattedInteger = padding + formattedInteger;
                  }
                  if (format.zeroCode !== 0x30) {
                      formattedInteger = stringToArray(formattedInteger).map(code => {
                          return String.fromCodePoint(code.codePointAt(0) + format.zeroCode - 0x30);
                      }).join('');
                  }
                  // insert the grouping-separator-signs, if any
                  if (format.regular) {
                      const n = Math.floor((formattedInteger.length - 1) / format.groupingSeparators.position);
                      for (let ii = n; ii > 0; ii--) {
                          const pos = formattedInteger.length - ii * format.groupingSeparators.position;
                          formattedInteger = formattedInteger.substr(0, pos) + format.groupingSeparators.character + formattedInteger.substr(pos);
                      }
                  } else {
                      format.groupingSeparators.reverse().forEach(separator => {
                          const pos = formattedInteger.length - separator.position;
                          formattedInteger = formattedInteger.substr(0, pos) + separator.character + formattedInteger.substr(pos);
                      });
                  }
  
                  if (format.ordinal) {
                      var suffix123 = {'1': 'st', '2': 'nd', '3': 'rd'};
                      var lastDigit = formattedInteger[formattedInteger.length - 1];
                      var suffix = suffix123[lastDigit];
                      if (!suffix || (formattedInteger.length > 1 && formattedInteger[formattedInteger.length - 2] === '1')) {
                          suffix = 'th';
                      }
                      formattedInteger = formattedInteger + suffix;
                  }
                  break;
              case formats.SEQUENCE:
                  throw {
                      code: 'D3130',
                      value: format.token
                  };
          }
          if (negative) {
              formattedInteger = '-' + formattedInteger;
          }
  
          return formattedInteger;
      }
  
      //TODO what about decimal groups in the unicode supplementary planes (surrogate pairs) ???
      const decimalGroups = [0x30, 0x0660, 0x06F0, 0x07C0, 0x0966, 0x09E6, 0x0A66, 0x0AE6, 0x0B66, 0x0BE6, 0x0C66, 0x0CE6, 0x0D66, 0x0DE6, 0x0E50, 0x0ED0, 0x0F20, 0x1040, 0x1090, 0x17E0, 0x1810, 0x1946, 0x19D0, 0x1A80, 0x1A90, 0x1B50, 0x1BB0, 0x1C40, 0x1C50, 0xA620, 0xA8D0, 0xA900, 0xA9D0, 0xA9F0, 0xAA50, 0xABF0, 0xFF10];
  
      /**
       * preprocesses the picture string
       * @param {string} picture - picture string
       * @returns {{type: string, primary: string, case: string, ordinal: boolean}} - analysed picture
       */
      function analyseIntegerPicture(picture) {
          const format = {
              type: 'integer',
              primary: formats.DECIMAL,
              case: tcase.LOWER,
              ordinal: false
          };
  
          let primaryFormat, formatModifier;
          const semicolon = picture.lastIndexOf(';');
          if (semicolon === -1) {
              primaryFormat = picture;
          } else {
              primaryFormat = picture.substring(0, semicolon);
              formatModifier = picture.substring(semicolon + 1);
              if (formatModifier[0] === 'o') {
                  format.ordinal = true;
              }
          }
  
          /* eslnt-disable-next no-fallthrough */
          switch (primaryFormat) {
              case 'A':
                  format.case = tcase.UPPER;
              /* eslnt-disable-next-line no-fallthrough */
              case 'a':
                  format.primary = formats.LETTERS;
                  break;
              case 'I':
                  format.case = tcase.UPPER;
              /* eslnt-disable-next-line no-fallthrough */
              case 'i':
                  format.primary = formats.ROMAN;
                  break;
              case 'W':
                  format.case = tcase.UPPER;
                  format.primary = formats.WORDS;
                  break;
              case 'Ww':
                  format.case = tcase.TITLE;
                  format.primary = formats.WORDS;
                  break;
              case 'w':
                  format.primary = formats.WORDS;
                  break;
              default: {
                  // this is a decimal-digit-pattern if it contains a decimal digit (from any unicode decimal digit group)
                  let zeroCode = null;
                  let mandatoryDigits = 0;
                  let optionalDigits = 0;
                  let groupingSeparators = [];
                  let separatorPosition = 0;
                  const formatCodepoints = stringToArray(primaryFormat).map(c => c.codePointAt(0)).reverse(); // reverse the array to determine positions of grouping-separator-signs
                  formatCodepoints.forEach((codePoint) => {
                      // step though each char in the picture to determine the digit group
                      let digit = false;
                      for (let ii = 0; ii < decimalGroups.length; ii++) {
                          const group = decimalGroups[ii];
                          if (codePoint >= group && codePoint <= group + 9) {
                              // codepoint is part of this decimal group
                              digit = true;
                              mandatoryDigits++;
                              separatorPosition++;
                              if (zeroCode === null) {
                                  zeroCode = group;
                              } else if (group !== zeroCode) {
                                  // error! different decimal groups in the same pattern
                                  throw {
                                      code: 'D3131'
                                  };
                              }
                              break;
                          }
                      }
                      if (!digit) {
                          if (codePoint === 0x23) { // # - optional-digit-sign
                              separatorPosition++;
                              optionalDigits++;
                          } else {
                              // neither a decimal-digit-sign ot optional-digit-sign, assume it is a grouping-separator-sign
                              groupingSeparators.push({
                                  position: separatorPosition,
                                  character: String.fromCodePoint(codePoint)
                              });
                          }
                      }
                  });
                  if (mandatoryDigits > 0) {
                      format.primary = formats.DECIMAL;
                      // TODO validate decimal-digit-pattern
  
                      // the decimal digit family (codepoint offset)
                      format.zeroCode = zeroCode;
                      // the number of mandatory digits
                      format.mandatoryDigits = mandatoryDigits;
                      // the number of optional digits
                      format.optionalDigits = optionalDigits;
                      // grouping separator template
                      // are the grouping-separator-signs 'regular'?
                      const regularRepeat = function (separators) {
                          // are the grouping positions regular? i.e. same interval between each of them
                          // is there at least one separator?
                          if (separators.length === 0) {
                              return 0;
                          }
                          // are all the characters the same?
                          const sepChar = separators[0].character;
                          for (let ii = 1; ii < separators.length; ii++) {
                              if (separators[ii].character !== sepChar) {
                                  return 0;
                              }
                          }
                          // are they equally spaced?
                          const indexes = separators.map(separator => separator.position);
                          const gcd = function (a, b) {
                              return b === 0 ? a : gcd(b, a % b);
                          };
                          // find the greatest common divisor of all the positions
                          const factor = indexes.reduce(gcd);
                          // is every position separated by this divisor? If so, it's regular
                          for (let index = 1; index <= indexes.length; index++) {
                              if (indexes.indexOf(index * factor) === -1) {
                                  return 0;
                              }
                          }
                          return factor;
                      };
  
                      const regular = regularRepeat(groupingSeparators);
                      if (regular > 0) {
                          format.regular = true;
                          format.groupingSeparators = {
                              position: regular,
                              character: groupingSeparators[0].character
                          };
                      } else {
                          format.regular = false;
                          format.groupingSeparators = groupingSeparators;
                      }
  
                  } else {
                      // this is a 'numbering sequence' which the spec says is implementation-defined
                      // this implementation doesn't support any numbering sequences at the moment.
                      format.primary = formats.SEQUENCE;
                      format.token = primaryFormat;
                  }
              }
          }
  
          return format;
      }
  
      const defaultPresentationModifiers = {
          Y: '1', M: '1', D: '1', d: '1', F: 'n', W: '1', w: '1', X: '1', x: '1', H: '1', h: '1',
          P: 'n', m: '01', s: '01', f: '1', Z: '01:01', z: '01:01', C: 'n', E: 'n'
      };
  
      // §9.8.4.1 the format specifier is an array of string literals and variable markers
      /**
       * analyse the date-time picture string
       * @param {string} picture - picture string
       * @returns {{type: string, parts: Array}} - the analysed string
       */
      function analyseDateTimePicture(picture) {
          var spec = [];
          const format = {
              type: 'datetime',
              parts: spec
          };
          const addLiteral = function (start, end) {
              if (end > start) {
                  let literal = picture.substring(start, end);
                  // replace any doubled ]] with single ]
                  // what if there are instances of single ']' ? - the spec doesn't say
                  literal = literal.split(']]').join(']');
                  spec.push({type: 'literal', value: literal});
              }
          };
  
          var start = 0, pos = 0;
          while (pos < picture.length) {
              if (picture.charAt(pos) === '[') {
                  // check it's not a doubled [[
                  if (picture.charAt(pos + 1) === '[') {
                      // literal [
                      addLiteral(start, pos);
                      spec.push({type: 'literal', value: '['});
                      pos += 2;
                      start = pos;
                      continue;
                  }
                  // start of variable marker
                  // push the string literal (if there is one) onto the array
                  addLiteral(start, pos);
                  start = pos;
                  // search forward to closing ]
                  pos = picture.indexOf(']', start);
                  // TODO handle error case if pos === -1
                  if(pos === -1) {
                      // error - no closing bracket
                      throw {
                          code: 'D3135'
                      };
                  }
                  let marker = picture.substring(start + 1, pos);
                  // whitespace within a variable marker is ignored (i.e. remove it)
                  marker = marker.split(/\s+/).join('');
                  var def = {
                      type: 'marker',
                      component: marker.charAt(0)  // 1. The component specifier is always present and is always a single letter.
                  };
                  var comma = marker.lastIndexOf(','); // 2. The width modifier may be recognized by the presence of a comma
                  var presMod; // the presentation modifiers
                  if (comma !== -1) {
                      // §9.8.4.2 The Width Modifier
                      const widthMod = marker.substring(comma + 1);
                      const dash = widthMod.indexOf('-');
                      let min, max;
                      const parseWidth = function (wm) {
                          if (typeof wm === 'undefined' || wm === '*') {
                              return undefined;
                          } else {
                              // TODO validate wm is an unsigned int
                              return parseInt(wm);
                          }
                      };
                      if (dash === -1) {
                          min = widthMod;
                      } else {
                          min = widthMod.substring(0, dash);
                          max = widthMod.substring(dash + 1);
                      }
                      const widthDef = {
                          min: parseWidth(min),
                          max: parseWidth(max)
                      };
                      def.width = widthDef;
                      presMod = marker.substring(1, comma);
                  } else {
                      presMod = marker.substring(1);
                  }
                  if (presMod.length === 1) {
                      def.presentation1 = presMod; // first presentation modifier
                      //TODO validate the first presentation modifier - it's either N, n, Nn or it passes analyseIntegerPicture
                  } else if (presMod.length > 1) {
                      var lastChar = presMod.charAt(presMod.length - 1);
                      if ('atco'.indexOf(lastChar) !== -1) {
                          def.presentation2 = lastChar;
                          if (lastChar === 'o') {
                              def.ordinal = true;
                          }
                          // 'c' means 'cardinal' and is the default (i.e. not 'ordinal')
                          // 'a' & 't' are ignored (not sure of their relevance to English numbering)
                          def.presentation1 = presMod.substring(0, presMod.length - 1);
                      } else {
                          def.presentation1 = presMod;
                          //TODO validate the first presentation modifier - it's either N, n, Nn or it passes analyseIntegerPicture,
                          // doesn't use ] as grouping separator, and if grouping separator is , then must have width modifier
                      }
                  } else {
                      // no presentation modifier specified - apply the default;
                      def.presentation1 = defaultPresentationModifiers[def.component];
                  }
                  if (typeof def.presentation1 === 'undefined') {
                      // unknown component specifier
                      throw {
                          code: 'D3132',
                          value: def.component
                      };
                  }
                  if (def.presentation1[0] === 'n') {
                      def.names = tcase.LOWER;
                  } else if (def.presentation1[0] === 'N') {
                      if (def.presentation1[1] === 'n') {
                          def.names = tcase.TITLE;
                      } else {
                          def.names = tcase.UPPER;
                      }
                  } else if ('YMDdFWwXxHhmsf'.indexOf(def.component) !== -1) {
                      var integerPattern = def.presentation1;
                      if (def.presentation2) {
                          integerPattern += ';' + def.presentation2;
                      }
                      def.integerFormat = analyseIntegerPicture(integerPattern);
                      if (def.width && def.width.min !== undefined) {
                          if (def.integerFormat.mandatoryDigits < def.width.min) {
                              def.integerFormat.mandatoryDigits = def.width.min;
                          }
                      }
                      if (def.component === 'Y') {
                          // §9.8.4.4
                          def.n = -1;
                          if (def.width && def.width.max !== undefined) {
                              def.n = def.width.max;
                              def.integerFormat.mandatoryDigits = def.n;
                          } else {
                              var w = def.integerFormat.mandatoryDigits + def.integerFormat.optionalDigits;
                              if (w >= 2) {
                                  def.n = w;
                              }
                          }
                      }
                  }
                  if (def.component === 'Z' || def.component === 'z') {
                      def.integerFormat = analyseIntegerPicture(def.presentation1);
                  }
                  spec.push(def);
                  start = pos + 1;
              }
              pos++;
          }
          addLiteral(start, pos);
          return format;
      }
  
      const days = ['', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
      const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
      const millisInADay = 1000 * 60 * 60 * 24;
  
      const startOfFirstWeek = function (ym) {
          // ISO 8601 defines the first week of the year to be the week that contains the first Thursday
          // XPath F&O extends this same definition for the first week of a month
          // the week starts on a Monday - calculate the millis for the start of the first week
          // millis for given 1st Jan of that year (at 00:00 UTC)
          const jan1 = Date.UTC(ym.year, ym.month);
          var dayOfJan1 = (new Date(jan1)).getUTCDay();
          if (dayOfJan1 === 0) {
              dayOfJan1 = 7;
          }
          // if Jan 1 is Fri, Sat or Sun, then add the number of days (in millis) to jan1 to get the start of week 1
          return dayOfJan1 > 4 ? jan1 + (8 - dayOfJan1) * millisInADay : jan1 - (dayOfJan1 - 1) * millisInADay;
      };
  
      const yearMonth = function (year, month) {
          return {
              year: year,
              month: month,
              nextMonth: function () {
                  return (month === 11) ? yearMonth(year + 1, 0) : yearMonth(year, month + 1);
              },
              previousMonth: function () {
                  return (month === 0) ? yearMonth(year - 1, 11) : yearMonth(year, month - 1);
              },
              nextYear: function () {
                  return yearMonth(year + 1, month);
              },
              previousYear: function () {
                  return yearMonth(year - 1, month);
              }
          };
      };
  
      const deltaWeeks = function (start, end) {
          return (end - start) / (millisInADay * 7) + 1;
      };
  
      const getDateTimeFragment = (date, component) => {
          let componentValue;
          switch (component) {
              case 'Y': // year
                  componentValue = date.getUTCFullYear();
                  break;
              case 'M': // month in year
                  componentValue = date.getUTCMonth() + 1;
                  break;
              case 'D': // day in month
                  componentValue = date.getUTCDate();
                  break;
              case 'd': { // day in year
                  // millis for given date (at 00:00 UTC)
                  const today = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
                  // millis for given 1st Jan of that year (at 00:00 UTC)
                  const firstJan = Date.UTC(date.getUTCFullYear(), 0);
                  componentValue = (today - firstJan) / millisInADay + 1;
                  break;
              }
              case 'F': // day of week
                  componentValue = date.getUTCDay();
                  if (componentValue === 0) {
                      // ISO 8601 defines days 1-7: Mon-Sun
                      componentValue = 7;
                  }
                  break;
              case 'W': { // week in year
                  const thisYear = yearMonth(date.getUTCFullYear(), 0);
                  const startOfWeek1 = startOfFirstWeek(thisYear);
                  const today = Date.UTC(thisYear.year, date.getUTCMonth(), date.getUTCDate());
                  let week = deltaWeeks(startOfWeek1, today);
                  if (week > 52) {
                      // might be first week of the following year
                      const startOfFollowingYear = startOfFirstWeek(thisYear.nextYear());
                      if (today >= startOfFollowingYear) {
                          week = 1;
                      }
                  } else if (week < 1) {
                      // must be end of the previous year
                      const startOfPreviousYear = startOfFirstWeek(thisYear.previousYear());
                      week = deltaWeeks(startOfPreviousYear, today);
                  }
                  componentValue = Math.floor(week);
                  break;
              }
              case 'w': { // week in month
                  const thisMonth = yearMonth(date.getUTCFullYear(), date.getUTCMonth());
                  const startOfWeek1 = startOfFirstWeek(thisMonth);
                  const today = Date.UTC(thisMonth.year, thisMonth.month, date.getUTCDate());
                  let week = deltaWeeks(startOfWeek1, today);
                  if (week > 4) {
                      // might be first week of the following month
                      const startOfFollowingMonth = startOfFirstWeek(thisMonth.nextMonth());
                      if (today >= startOfFollowingMonth) {
                          week = 1;
                      }
                  } else if (week < 1) {
                      // must be end of the previous month
                      const startOfPreviousMonth = startOfFirstWeek(thisMonth.previousMonth());
                      week = deltaWeeks(startOfPreviousMonth, today);
                  }
                  componentValue = Math.floor(week);
                  break;
              }
              case 'X': { // ISO week-numbering year
                  // Extension: The F&O spec says nothing about how to access the year associated with the week-of-the-year
                  // e.g. Sat 1 Jan 2005 is in the 53rd week of 2004.
                  // The 'W' component specifier gives 53, but 'Y' will give 2005.
                  // I propose to add 'X' as the component specifier to give the ISO week-numbering year (2004 in this example)
                  const thisYear = yearMonth(date.getUTCFullYear(), 0);
                  const startOfISOYear = startOfFirstWeek(thisYear);
                  const endOfISOYear = startOfFirstWeek(thisYear.nextYear());
                  const now = date.getTime();
                  if (now < startOfISOYear) {
                      componentValue = thisYear.year - 1;
                  } else if (now >= endOfISOYear) {
                      componentValue = thisYear.year + 1;
                  } else {
                      componentValue = thisYear.year;
                  }
                  break;
              }
              case 'x': { // ISO week-numbering month
                  // Extension: The F&O spec says nothing about how to access the month associated with the week-of-the-month
                  // e.g. Sat 1 Jan 2005 is in the 5th week of December 2004.
                  // The 'w' component specifier gives 5, but 'W' will give January and 'Y' will give 2005.
                  // I propose to add 'x' as the component specifier to give the 'week-numbering' month (December in this example)
                  const thisMonth = yearMonth(date.getUTCFullYear(), date.getUTCMonth());
                  const startOfISOMonth = startOfFirstWeek(thisMonth);
                  const nextMonth = thisMonth.nextMonth();
                  const endOfISOMonth = startOfFirstWeek(nextMonth);
                  const now = date.getTime();
                  if (now < startOfISOMonth) {
                      componentValue = thisMonth.previousMonth().month + 1;
                  } else if (now >= endOfISOMonth) {
                      componentValue = nextMonth.month + 1;
                  } else {
                      componentValue = thisMonth.month + 1;
                  }
                  break;
              }
              case 'H': // hour in day (24 hours)
                  componentValue = date.getUTCHours();
                  break;
              case 'h': // hour in half-day (12 hours)
                  componentValue = date.getUTCHours();
                  componentValue = componentValue % 12;
                  if (componentValue === 0) {
                      componentValue = 12;
                  }
                  break;
              case 'P': // am/pm marker
                  componentValue = date.getUTCHours() >= 12 ? 'pm' : 'am';
                  break;
              case 'm': // minute in hour
                  componentValue = date.getUTCMinutes();
                  break;
              case 's': // second in minute
                  componentValue = date.getUTCSeconds();
                  break;
              case 'f': // fractional seconds
                  componentValue = date.getUTCMilliseconds();
                  break;
              case 'Z': // timezone
              case 'z':
                  // since the date object is constructed from epoch millis, the TZ component is always be UTC.
                  break;
              case 'C': // calendar name
                  componentValue = 'ISO';
                  break;
              case 'E': // era
                  componentValue = 'ISO';
                  break;
          }
          return componentValue;
      };
  
      let iso8601Spec = null;
  
      /**
       * formats the date/time as specified by the XPath fn:format-dateTime function
       * @param {number} millis - the timestamp to be formatted, in millis since the epoch
       * @param {string} picture - the picture string that specifies the format
       * @param {string} timezone - the timezone to use
       * @returns {string} - the formatted timestamp
       */
      function formatDateTime(millis, picture, timezone) {
          var offsetHours = 0;
          var offsetMinutes = 0;
  
          if (typeof timezone !== 'undefined') {
              // parse the hour and minute offsets
              // assume for now the format supplied is +hhmm
              const offset = parseInt(timezone);
              offsetHours = Math.floor(offset / 100);
              offsetMinutes = offset % 100;
          }
  
          var formatComponent = function (date, markerSpec) {
              var componentValue = getDateTimeFragment(date, markerSpec.component);
  
              // §9.8.4.3 Formatting Integer-Valued Date/Time Components
              if ('YMDdFWwXxHhms'.indexOf(markerSpec.component) !== -1) {
                  if (markerSpec.component === 'Y') {
                      // §9.8.4.4 Formatting the Year Component
                      if (markerSpec.n !== -1) {
                          componentValue = componentValue % Math.pow(10, markerSpec.n);
                      }
                  }
                  if (markerSpec.names) {
                      if (markerSpec.component === 'M' || markerSpec.component === 'x') {
                          componentValue = months[componentValue - 1];
                      } else if (markerSpec.component === 'F') {
                          componentValue = days[componentValue];
                      } else {
                          throw {
                              code: 'D3133',
                              value: markerSpec.component
                          };
                      }
                      if (markerSpec.names === tcase.UPPER) {
                          componentValue = componentValue.toUpperCase();
                      } else if (markerSpec.names === tcase.LOWER) {
                          componentValue = componentValue.toLowerCase();
                      }
                      if (markerSpec.width && componentValue.length > markerSpec.width.max) {
                          componentValue = componentValue.substring(0, markerSpec.width.max);
                      }
                  } else {
                      componentValue = _formatInteger(componentValue, markerSpec.integerFormat);
                  }
              } else if (markerSpec.component === 'f') {
                  // TODO §9.8.4.5 Formatting Fractional Seconds
                  componentValue = _formatInteger(componentValue, markerSpec.integerFormat);
              } else if (markerSpec.component === 'Z' || markerSpec.component === 'z') {
                  // §9.8.4.6 Formatting timezones
                  const offset = offsetHours * 100 + offsetMinutes;
                  if (markerSpec.integerFormat.regular) {
                      componentValue = _formatInteger(offset, markerSpec.integerFormat);
                  } else {
                      const numDigits = markerSpec.integerFormat.mandatoryDigits;
                      if (numDigits === 1 || numDigits === 2) {
                          componentValue = _formatInteger(offsetHours, markerSpec.integerFormat);
                          if (offsetMinutes !== 0) {
                              componentValue += ':' + formatInteger(offsetMinutes, '00');
                          }
                      } else if (numDigits === 3 || numDigits === 4) {
                          componentValue = _formatInteger(offset, markerSpec.integerFormat);
                      } else {
                          throw {
                              code: 'D3134',
                              value: numDigits
                          };
                      }
                  }
                  if (offset >= 0) {
                      componentValue = '+' + componentValue;
                  }
                  if (markerSpec.component === 'z') {
                      componentValue = 'GMT' + componentValue;
                  }
                  if (offset === 0 && markerSpec.presentation2 === 't') {
                      componentValue = 'Z';
                  }
              }
              return componentValue;
          };
  
          let formatSpec;
          if(typeof picture === 'undefined') {
              // default to ISO 8601 format
              if (iso8601Spec === null) {
                  iso8601Spec = analyseDateTimePicture('[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f001][Z01:01t]');
              }
              formatSpec = iso8601Spec;
          } else {
              formatSpec = analyseDateTimePicture(picture);
          }
  
          const offsetMillis = (60 * offsetHours + offsetMinutes) * 60 * 1000;
          const dateTime = new Date(millis + offsetMillis);
  
          let result = '';
          formatSpec.parts.forEach(function (part) {
              if (part.type === 'literal') {
                  result += part.value;
              } else {
                  result += formatComponent(dateTime, part);
              }
          });
  
          return result;
      }
  
      /**
       * Generate a regex to parse integers or timestamps
       * @param {object} formatSpec - object representing the format
       * @returns {object} - regex
       */
      function generateRegex(formatSpec) {
          var matcher = {};
          if (formatSpec.type === 'datetime') {
              matcher.type = 'datetime';
              matcher.parts = formatSpec.parts.map(function (part) {
                  var res = {};
                  if (part.type === 'literal') {
                      res.regex = part.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                  } else if (part.integerFormat) {
                      res = generateRegex(part.integerFormat);
                  } else {
                      // must be a month or day name
                      res.regex = '[a-zA-Z]+';
                      var lookup = {};
                      if (part.component === 'M' || part.component === 'x') {
                          // months
                          months.forEach(function (name, index) {
                              if (part.width && part.width.max) {
                                  lookup[name.substring(0, part.width.max)] = index + 1;
                              } else {
                                  lookup[name] = index + 1;
                              }
                          });
                      } else if (part.component === 'F') {
                          // days
                          days.forEach(function (name, index) {
                              if (index > 0) {
                                  if (part.width && part.width.max) {
                                      lookup[name.substring(0, part.width.max)] = index;
                                  } else {
                                      lookup[name] = index;
                                  }
                              }
                          });
                      } else if (part.component === 'P') {
                          lookup = {'am': 0, 'AM': 0, 'pm': 1, 'PM': 1};
                      } else {
                          // unsupported 'name' option for this component
                          throw {
                              code: 'D3133',
                              value: part.component
                          };
                      }
                      res.parse = function (value) {
                          return lookup[value];
                      };
                  }
                  res.component = part.component;
                  return res;
              });
          } else { // type === 'integer'
              matcher.type = 'integer';
              const isUpper = formatSpec.case === tcase.UPPER;
              switch (formatSpec.primary) {
                  case formats.LETTERS:
                      matcher.regex = isUpper ? '[A-Z]+' : '[a-z]+';
                      matcher.parse = function (value) {
                          return lettersToDecimal(value, isUpper ? 'A' : 'a');
                      };
                      break;
                  case formats.ROMAN:
                      matcher.regex = isUpper ? '[MDCLXVI]+' : '[mdclxvi]+';
                      matcher.parse = function (value) {
                          return romanToDecimal(isUpper ? value : value.toUpperCase());
                      };
                      break;
                  case formats.WORDS:
                      matcher.regex = '(?:' + Object.keys(wordValues).concat('and', '[\\-, ]').join('|') + ')+';
                      matcher.parse = function (value) {
                          return wordsToNumber(value.toLowerCase());
                      };
                      break;
                  case formats.DECIMAL:
                      matcher.regex = '[0-9]+';
                      if (formatSpec.ordinal) {
                          // ordinals
                          matcher.regex += '(?:th|st|nd|rd)';
                      }
                      matcher.parse = function (value) {
                          let digits = value;
                          if (formatSpec.ordinal) {
                              // strip off the suffix
                              digits = value.substring(0, value.length - 2);
                          }
                          // strip out the separators
                          if (formatSpec.regular) {
                              digits = digits.split(',').join('');
                          } else {
                              formatSpec.groupingSeparators.forEach(sep => {
                                  digits = digits.split(sep.character).join('');
                              });
                          }
                          if (formatSpec.zeroCode !== 0x30) {
                              // apply offset
                              digits = digits.split('').map(char => String.fromCodePoint(char.codePointAt(0) - formatSpec.zeroCode + 0x30)).join('');
                          }
                          return parseInt(digits);
                      };
                      break;
                  case formats.SEQUENCE:
                      throw {
                          code: 'D3130',
                          value: formatSpec.token
                      };
              }
  
          }
          return matcher;
      }
  
      /**
       * parse a string containing an integer as specified by the picture string
       * @param {string} value - the string to parse
       * @param {string} picture - the picture string
       * @returns {number} - the parsed number
       */
      function parseInteger(value, picture) {
          if (typeof value === 'undefined') {
              return undefined;
          }
  
          const formatSpec = analyseIntegerPicture(picture);
          const matchSpec = generateRegex(formatSpec);
          //const fullRegex = '^' + matchSpec.regex + '$';
          //const matcher = new RegExp(fullRegex);
          // TODO validate input based on the matcher regex
          const result = matchSpec.parse(value);
          return result;
      }
  
      /**
       * parse a string containing a timestamp as specified by the picture string
       * @param {string} timestamp - the string to parse
       * @param {string} picture - the picture string
       * @returns {number} - the parsed timestamp in millis since the epoch
       */
      function parseDateTime(timestamp, picture) {
          const formatSpec = analyseDateTimePicture(picture);
          const matchSpec = generateRegex(formatSpec);
          const fullRegex = '^' + matchSpec.parts.map(part => '(' + part.regex + ')').join('') + '$';
  
          const matcher = new RegExp(fullRegex, 'i'); // TODO can cache this against the picture
          var info = matcher.exec(timestamp);
          if (info !== null) {
              // validate what we've just parsed - do we have enough information to create a timestamp?
              // rules:
              // The date is specified by one of:
              //    {Y, M, D}    (dateA)
              // or {Y, d}       (dateB)
              // or {Y, x, w, F} (dateC)
              // or {X, W, F}    (dateD)
              // The time is specified by one of:
              //    {H, m, s, f}    (timeA)
              // or {P, h, m, s, f} (timeB)
              // All sets can have an optional Z
              // To create a timestamp (epoch millis) we need both date and time, but we can default missing
              // information according to the following rules:
              // - line up one combination of the above from date, and one from time, most significant value (MSV) to least significant (LSV
              // - for the values that have been captured, if there are any gaps between MSV and LSV, then throw an error
              //     (e.g.) if hour and seconds, but not minutes is given - throw
              //     (e.g.) if month, hour and minutes, but not day-of-month is given - throw
              // - anything right of the LSV should be defaulted to zero
              //     (e.g.) if hour and minutes given, default seconds and fractional seconds to zero
              //     (e.g.) if date only given, default the time to 0:00:00.000 (midnight)
              // - anything left of the MSV should be defaulted to the value of that component returned by $now()
              //     (e.g.) if time only given, default the date to today
              //     (e.g.) if month and date given, default to this year (and midnight, by previous rule)
              //   -- default values for X, x, W, w, F will be derived from the values returned by $now()
  
              // implement the above rules
              // determine which of the above date/time combinations we have by using bit masks
  
              //        Y X M x W w d D F P H h m s f Z
              // dateA  1 0 1 0 0 0 0 1 ?                     0 - must not appear
              // dateB  1 0 0 0 0 0 1 0 ?                     1 - can appear - relevant
              // dateC  0 1 0 1 0 1 0 0 1                     ? - can appear - ignored
              // dateD  0 1 0 0 1 0 0 0 1
              // timeA                    0 1 0 1 1 1
              // timeB                    1 0 1 1 1 1
  
              // create bitmasks based on the above
              //    date mask             YXMxWwdD
              const dmA = 161;  // binary 10100001
              const dmB = 130;  // binary 10000010
              const dmC = 84;   // binary 01010100
              const dmD = 72;   // binary 01001000
              //    time mask             PHhmsf
              const tmA = 23;   // binary 010111
              const tmB = 47;   // binary 101111
  
              const components = {};
              for (let i = 1; i < info.length; i++) {
                  const mpart = matchSpec.parts[i - 1];
                  if (mpart.parse) {
                      components[mpart.component] = mpart.parse(info[i]);
                  }
              }
  
              if(Object.getOwnPropertyNames(components).length === 0) {
                  // nothing specified
                  return undefined;
              }
  
              let mask = 0;
  
              const shift = bit => {
                  mask <<= 1;
                  mask += bit ? 1 : 0;
              };
  
              const isType = type => {
                  // shouldn't match any 0's, must match at least one 1
                  return !(~type & mask) && !!(type & mask);
              };
  
              'YXMxWwdD'.split('').forEach(part => shift(components[part]));
  
              const dateA = isType(dmA);
              const dateB = !dateA && isType(dmB);
              const dateC = isType(dmC);
              const dateD = !dateC && isType(dmD);
  
              mask = 0;
              'PHhmsf'.split('').forEach(part => shift(components[part]));
  
              const timeA = isType(tmA);
              const timeB = !timeA && isType(tmB);
  
              // should only be zero or one date type and zero or one time type
  
              const dateComps = dateB ? 'YD' : dateC ? 'XxwF' : dateD? 'XWF' : 'YMD';
              const timeComps = timeB ? 'Phmsf' : 'Hmsf';
  
              const comps = dateComps + timeComps;
  
              // step through the candidate parts from most significant to least significant
              // default the most significant unspecified parts to current timestamp component
              // default the least significant unspecified parts to zero
              // if any gaps in between the specified parts, throw an error
  
              const now = this.environment.timestamp; // must get the fixed timestamp from jsonata
  
              let startSpecified = false;
              let endSpecified = false;
              comps.split('').forEach(part => {
                  if(typeof components[part] === 'undefined') {
                      if(startSpecified) {
                          // past the specified block - default to zero
                          components[part] = ('MDd'.indexOf(part) !== -1) ? 1 : 0;
                          endSpecified = true;
                      } else {
                          // haven't hit the specified block yet, default to current timestamp
                          components[part] = getDateTimeFragment(now, part);
                      }
                  } else {
                      startSpecified = true;
                      if(endSpecified) {
                          throw {
                              code: 'D3136'
                          };
                      }
                  }
              });
  
              // validate and fill in components
              if (components.M > 0) {
                  components.M -= 1;  // Date.UTC requires a zero-indexed month
              } else {
                  components.M = 0; // default to January
              }
              if (dateB) {
                  // millis for given 1st Jan of that year (at 00:00 UTC)
                  const firstJan = Date.UTC(components.Y, 0);
                  const offsetMillis = (components.d - 1) * 1000 * 60 * 60 * 24;
                  const derivedDate = new Date(firstJan + offsetMillis);
                  components.M = derivedDate.getUTCMonth();
                  components.D = derivedDate.getUTCDate();
              }
              if (dateC) {
                  // TODO implement this
                  // parsing this format not currently supported
                  throw {
                      code: 'D3136'
                  };
              }
              if (dateD) {
                  // TODO implement this
                  // parsing this format (ISO week date) not currently supported
                  throw {
                      code: 'D3136'
                  };
              }
              if (timeB) {
                  // 12hr to 24hr
                  components.H = components.h === 12 ? 0 : components.h;
                  if (components.P === 1) {
                      components.H += 12;
                  }
              }
  
              var millis = Date.UTC(components.Y, components.M, components.D, components.H, components.m, components.s, components.f);
              return millis;
          }
      }
  
      // Regular expression to match an ISO 8601 formatted timestamp
      var iso8601regex = new RegExp('^\\d{4}(-[01]\\d)*(-[0-3]\\d)*(T[0-2]\\d:[0-5]\\d:[0-5]\\d)*(\\.\\d+)?([+-][0-2]\\d:?[0-5]\\d|Z)?$');
  
      /**
       * Converts an ISO 8601 timestamp to milliseconds since the epoch
       *
       * @param {string} timestamp - the timestamp to be converted
       * @param {string} [picture] - the picture string defining the format of the timestamp (defaults to ISO 8601)
       * @returns {Number} - milliseconds since the epoch
       */
      function toMillis(timestamp, picture) {
          // undefined inputs always return undefined
          if(typeof timestamp === 'undefined') {
              return undefined;
          }
  
          if(typeof picture === 'undefined') {
              if (!iso8601regex.test(timestamp)) {
                  throw {
                      stack: (new Error()).stack,
                      code: "D3110",
                      value: timestamp
                  };
              }
  
              return Date.parse(timestamp);
          } else {
              return parseDateTime.call(this, timestamp, picture);
          }
      }
  
      /**
       * Converts milliseconds since the epoch to an ISO 8601 timestamp
       * @param {Number} millis - milliseconds since the epoch to be converted
       * @param {string} [picture] - the picture string defining the format of the timestamp (defaults to ISO 8601)
       * @param {string} [timezone] - the timezone to format the timestamp in (defaults to UTC)
       * @returns {String} - the formatted timestamp
       */
      function fromMillis(millis, picture, timezone) {
          // undefined inputs always return undefined
          if(typeof millis === 'undefined') {
              return undefined;
          }
  
          return formatDateTime.call(this, millis, picture, timezone);
      }
  
      return {
          formatInteger, parseInteger, fromMillis, toMillis
      };
  })();
  
  module.exports = dateTime;
  
  },{"./utils":6}],2:[function(require,module,exports){
  (function (global){
  /**
   * © Copyright IBM Corp. 2016, 2018 All Rights Reserved
   *   Project name: JSONata
   *   This project is licensed under the MIT License, see LICENSE
   */
  
  var utils = require('./utils');
  
  const functions = (() => {
      'use strict';
  
      var isNumeric = utils.isNumeric;
      var isArrayOfStrings = utils.isArrayOfStrings;
      var isArrayOfNumbers = utils.isArrayOfNumbers;
      var createSequence = utils.createSequence;
      var isSequence = utils.isSequence;
      var isFunction = utils.isFunction;
      var isLambda = utils.isLambda;
      var isIterable = utils.isIterable;
      var getFunctionArity = utils.getFunctionArity;
      var deepEquals = utils.isDeepEqual;
      var stringToArray = utils.stringToArray;
  
      /**
       * Sum function
       * @param {Object} args - Arguments
       * @returns {number} Total value of arguments
       */
      function sum(args) {
          // undefined inputs always return undefined
          if (typeof args === 'undefined') {
              return undefined;
          }
  
          var total = 0;
          args.forEach(function (num) {
              total += num;
          });
          return total;
      }
  
      /**
       * Count function
       * @param {Object} args - Arguments
       * @returns {number} Number of elements in the array
       */
      function count(args) {
          // undefined inputs always return undefined
          if (typeof args === 'undefined') {
              return 0;
          }
  
          return args.length;
      }
  
      /**
       * Max function
       * @param {Object} args - Arguments
       * @returns {number} Max element in the array
       */
      function max(args) {
          // undefined inputs always return undefined
          if (typeof args === 'undefined' || args.length === 0) {
              return undefined;
          }
  
          return Math.max.apply(Math, args);
      }
  
      /**
       * Min function
       * @param {Object} args - Arguments
       * @returns {number} Min element in the array
       */
      function min(args) {
          // undefined inputs always return undefined
          if (typeof args === 'undefined' || args.length === 0) {
              return undefined;
          }
  
          return Math.min.apply(Math, args);
      }
  
      /**
       * Average function
       * @param {Object} args - Arguments
       * @returns {number} Average element in the array
       */
      function average(args) {
          // undefined inputs always return undefined
          if (typeof args === 'undefined' || args.length === 0) {
              return undefined;
          }
  
          var total = 0;
          args.forEach(function (num) {
              total += num;
          });
          return total / args.length;
      }
  
      /**
       * Stringify arguments
       * @param {Object} arg - Arguments
       * @param {boolean} [prettify] - Pretty print the result
       * @returns {String} String from arguments
       */
      function string(arg, prettify = false) {
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          var str;
  
          if (typeof arg === 'string') {
              // already a string
              str = arg;
          } else if (isFunction(arg)) {
              // functions (built-in and lambda convert to empty string
              str = '';
          } else if (typeof arg === 'number' && !isFinite(arg)) {
              throw {
                  code: "D3001",
                  value: arg,
                  stack: (new Error()).stack
              };
          } else {
              var space = prettify ? 2 : 0;
              if(Array.isArray(arg) && arg.outerWrapper) {
                  arg = arg[0];
              }
              str = JSON.stringify(arg, function (key, val) {
                  return (typeof val !== 'undefined' && val !== null && val.toPrecision && isNumeric(val)) ? Number(val.toPrecision(15)) :
                      (val && isFunction(val)) ? '' : val;
              }, space);
          }
          return str;
      }
  
      /**
       * Create substring based on character number and length
       * @param {String} str - String to evaluate
       * @param {Integer} start - Character number to start substring
       * @param {Integer} [length] - Number of characters in substring
       * @returns {string|*} Substring
       */
      function substring(str, start, length) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          var strArray = stringToArray(str);
          var strLength = strArray.length;
  
          if (strLength + start < 0) {
              start = 0;
          }
  
          if (typeof length !== 'undefined') {
              if (length <= 0) {
                  return '';
              }
              var end = start >= 0 ? start + length : strLength + start + length;
              return strArray.slice(start, end).join('');
          }
  
          return strArray.slice(start).join('');
      }
  
      /**
       * Create substring up until a character
       * @param {String} str - String to evaluate
       * @param {String} chars - Character to define substring boundary
       * @returns {*} Substring
       */
      function substringBefore(str, chars) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          var pos = str.indexOf(chars);
          if (pos > -1) {
              return str.substr(0, pos);
          } else {
              return str;
          }
      }
  
      /**
       * Create substring after a character
       * @param {String} str - String to evaluate
       * @param {String} chars - Character to define substring boundary
       * @returns {*} Substring
       */
      function substringAfter(str, chars) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          var pos = str.indexOf(chars);
          if (pos > -1) {
              return str.substr(pos + chars.length);
          } else {
              return str;
          }
      }
  
      /**
       * Lowercase a string
       * @param {String} str - String to evaluate
       * @returns {string} Lowercase string
       */
      function lowercase(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          return str.toLowerCase();
      }
  
      /**
       * Uppercase a string
       * @param {String} str - String to evaluate
       * @returns {string} Uppercase string
       */
      function uppercase(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          return str.toUpperCase();
      }
  
      /**
       * length of a string
       * @param {String} str - string
       * @returns {Number} The number of characters in the string
       */
      function length(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          return stringToArray(str).length;
      }
  
      /**
       * Normalize and trim whitespace within a string
       * @param {string} str - string to be trimmed
       * @returns {string} - trimmed string
       */
      function trim(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          // normalize whitespace
          var result = str.replace(/[ \t\n\r]+/gm, ' ');
          if (result.charAt(0) === ' ') {
              // strip leading space
              result = result.substring(1);
          }
          if (result.charAt(result.length - 1) === ' ') {
              // strip trailing space
              result = result.substring(0, result.length - 1);
          }
          return result;
      }
  
      /**
       * Pad a string to a minimum width by adding characters to the start or end
       * @param {string} str - string to be padded
       * @param {number} width - the minimum width; +ve pads to the right, -ve pads to the left
       * @param {string} [char] - the pad character(s); defaults to ' '
       * @returns {string} - padded string
       */
      function pad(str, width, char) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          if (typeof char === 'undefined' || char.length === 0) {
              char = ' ';
          }
  
          var result;
          var padLength = Math.abs(width) - length(str);
          if (padLength > 0) {
              var padding = (new Array(padLength + 1)).join(char);
              if (char.length > 1) {
                  padding = substring(padding, 0, padLength);
              }
              if (width > 0) {
                  result = str + padding;
              } else {
                  result = padding + str;
              }
          } else {
              result = str;
          }
          return result;
      }
  
      /**
       * Evaluate the matcher function against the str arg
       *
       * @param {*} matcher - matching function (native or lambda)
       * @param {string} str - the string to match against
       * @returns {object} - structure that represents the match(es)
       */
      function* evaluateMatcher(matcher, str) {
          var result = matcher.apply(this, [str]); // eslint-disable-line no-useless-call
          if(isIterable(result)) {
              result = yield * result;
          }
          if(result && !(typeof result.start === 'number' || result.end === 'number' || Array.isArray(result.groups) || isFunction(result.next))) {
              // the matcher function didn't return the correct structure
              throw {
                  code: "T1010",
                  stack: (new Error()).stack,
              };
          }
          return result;
      }
  
      /**
       * Tests if the str contains the token
       * @param {String} str - string to test
       * @param {String} token - substring or regex to find
       * @returns {Boolean} - true if str contains token
       */
      function* contains(str, token) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          var result;
  
          if (typeof token === 'string') {
              result = (str.indexOf(token) !== -1);
          } else {
              var matches = yield* evaluateMatcher(token, str);
              result = (typeof matches !== 'undefined');
          }
  
          return result;
      }
  
      /**
       * Match a string with a regex returning an array of object containing details of each match
       * @param {String} str - string
       * @param {String} regex - the regex applied to the string
       * @param {Integer} [limit] - max number of matches to return
       * @returns {Array} The array of match objects
       */
      function* match(str, regex, limit) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          // limit, if specified, must be a non-negative number
          if (limit < 0) {
              throw {
                  stack: (new Error()).stack,
                  value: limit,
                  code: 'D3040',
                  index: 3
              };
          }
  
          var result = createSequence();
  
          if (typeof limit === 'undefined' || limit > 0) {
              var count = 0;
              var matches = yield* evaluateMatcher(regex, str);
              if (typeof matches !== 'undefined') {
                  while (typeof matches !== 'undefined' && (typeof limit === 'undefined' || count < limit)) {
                      result.push({
                          match: matches.match,
                          index: matches.start,
                          groups: matches.groups
                      });
                      matches = yield* evaluateMatcher(matches.next);
                      count++;
                  }
              }
          }
  
          return result;
      }
  
      /**
       * Match a string with a regex returning an array of object containing details of each match
       * @param {String} str - string
       * @param {String} pattern - the substring/regex applied to the string
       * @param {String} replacement - text to replace the matched substrings
       * @param {Integer} [limit] - max number of matches to return
       * @returns {Array} The array of match objects
       */
      function* replace(str, pattern, replacement, limit) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          var self = this;
  
          // pattern cannot be an empty string
          if (pattern === '') {
              throw {
                  code: "D3010",
                  stack: (new Error()).stack,
                  value: pattern,
                  index: 2
              };
          }
  
          // limit, if specified, must be a non-negative number
          if (limit < 0) {
              throw {
                  code: "D3011",
                  stack: (new Error()).stack,
                  value: limit,
                  index: 4
              };
          }
  
          var replacer;
          if (typeof replacement === 'string') {
              replacer = function (regexMatch) {
                  var substitute = '';
                  // scan forward, copying the replacement text into the substitute string
                  // and replace any occurrence of $n with the values matched by the regex
                  var position = 0;
                  var index = replacement.indexOf('$', position);
                  while (index !== -1 && position < replacement.length) {
                      substitute += replacement.substring(position, index);
                      position = index + 1;
                      var dollarVal = replacement.charAt(position);
                      if (dollarVal === '$') {
                          // literal $
                          substitute += '$';
                          position++;
                      } else if (dollarVal === '0') {
                          substitute += regexMatch.match;
                          position++;
                      } else {
                          var maxDigits;
                          if (regexMatch.groups.length === 0) {
                              // no sub-matches; any $ followed by a digit will be replaced by an empty string
                              maxDigits = 1;
                          } else {
                              // max number of digits to parse following the $
                              maxDigits = Math.floor(Math.log(regexMatch.groups.length) * Math.LOG10E) + 1;
                          }
                          index = parseInt(replacement.substring(position, position + maxDigits), 10);
                          if (maxDigits > 1 && index > regexMatch.groups.length) {
                              index = parseInt(replacement.substring(position, position + maxDigits - 1), 10);
                          }
                          if (!isNaN(index)) {
                              if (regexMatch.groups.length > 0) {
                                  var submatch = regexMatch.groups[index - 1];
                                  if (typeof submatch !== 'undefined') {
                                      substitute += submatch;
                                  }
                              }
                              position += index.toString().length;
                          } else {
                              // not a capture group, treat the $ as literal
                              substitute += '$';
                          }
                      }
                      index = replacement.indexOf('$', position);
                  }
                  substitute += replacement.substring(position);
                  return substitute;
              };
          } else {
              replacer = replacement;
          }
  
          var result = '';
          var position = 0;
  
          if (typeof limit === 'undefined' || limit > 0) {
              var count = 0;
              if (typeof pattern === 'string') {
                  var index = str.indexOf(pattern, position);
                  while (index !== -1 && (typeof limit === 'undefined' || count < limit)) {
                      result += str.substring(position, index);
                      result += replacement;
                      position = index + pattern.length;
                      count++;
                      index = str.indexOf(pattern, position);
                  }
                  result += str.substring(position);
              } else {
                  var matches = yield* evaluateMatcher(pattern, str);
                  if (typeof matches !== 'undefined') {
                      while (typeof matches !== 'undefined' && (typeof limit === 'undefined' || count < limit)) {
                          result += str.substring(position, matches.start);
                          var replacedWith = replacer.apply(self, [matches]);
                          if (isIterable(replacedWith)) {
                              replacedWith = yield* replacedWith;
                          }
                          // check replacedWith is a string
                          if (typeof replacedWith === 'string') {
                              result += replacedWith;
                          } else {
                              // not a string - throw error
                              throw {
                                  code: "D3012",
                                  stack: (new Error()).stack,
                                  value: replacedWith
                              };
                          }
                          position = matches.start + matches.match.length;
                          count++;
                          matches = yield* evaluateMatcher(matches.next);
                      }
                      result += str.substring(position);
                  } else {
                      result = str;
                  }
              }
          } else {
              result = str;
          }
  
          return result;
      }
  
      /**
       * Base64 encode a string
       * @param {String} str - string
       * @returns {String} Base 64 encoding of the binary data
       */
      function base64encode(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
          // Use btoa in a browser, or Buffer in Node.js
  
          var btoa = typeof window !== 'undefined' ?
              /* istanbul ignore next */ window.btoa :
              function (str) {
                  // Simply doing `new Buffer` at this point causes Browserify to pull
                  // in the entire Buffer browser library, which is large and unnecessary.
                  // Using `global.Buffer` defeats this.
                  return new global.Buffer.from(str, 'binary').toString('base64'); // eslint-disable-line new-cap
              };
          return btoa(str);
      }
  
      /**
       * Base64 decode a string
       * @param {String} str - string
       * @returns {String} Base 64 encoding of the binary data
       */
      function base64decode(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
          // Use btoa in a browser, or Buffer in Node.js
          var atob = typeof window !== 'undefined' ?
              /* istanbul ignore next */ window.atob :
              function (str) {
                  // Simply doing `new Buffer` at this point causes Browserify to pull
                  // in the entire Buffer browser library, which is large and unnecessary.
                  // Using `global.Buffer` defeats this.
                  return new global.Buffer(str, 'base64').toString('binary');
              };
          return atob(str);
      }
  
      /**
       * Encode a string into a component for a url
       * @param {String} str - String to encode
       * @returns {string} Encoded string
       */
      function encodeUrlComponent(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          // Catch URIErrors when URI sequence is malformed
          var returnVal;
          try {
              returnVal = encodeURIComponent(str);
          } catch (e) {
              throw {
                  code: "D3140",
                  stack: (new Error()).stack,
                  value: str,
                  functionName: "encodeUrlComponent"
              };
          }
          return returnVal;
      }
  
      /**
       * Encode a string into a url
       * @param {String} str - String to encode
       * @returns {string} Encoded string
       */
      function encodeUrl(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          // Catch URIErrors when URI sequence is malformed
          var returnVal;
          try {
              returnVal = encodeURI(str);
          } catch (e) {
              throw {
                  code: "D3140",
                  stack: (new Error()).stack,
                  value: str,
                  functionName: "encodeUrl"
              };
          }
          return returnVal;
      }
  
      /**
       * Decode a string from a component for a url
       * @param {String} str - String to decode
       * @returns {string} Decoded string
       */
      function decodeUrlComponent(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          // Catch URIErrors when URI sequence is malformed
          var returnVal;
          try {
              returnVal = decodeURIComponent(str);
          } catch (e) {
              throw {
                  code: "D3140",
                  stack: (new Error()).stack,
                  value: str,
                  functionName: "decodeUrlComponent"
              };
          }
          return returnVal;
      }
  
      /**
       * Decode a string from a url
       * @param {String} str - String to decode
       * @returns {string} Decoded string
       */
      function decodeUrl(str) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          // Catch URIErrors when URI sequence is malformed
          var returnVal;
          try {
              returnVal = decodeURI(str);
          } catch (e) {
              throw {
                  code: "D3140",
                  stack: (new Error()).stack,
                  value: str,
                  functionName: "decodeUrl"
              };
          }
          return returnVal;
      }
  
      /**
       * Split a string into an array of substrings
       * @param {String} str - string
       * @param {String} separator - the token or regex that splits the string
       * @param {Integer} [limit] - max number of substrings
       * @returns {Array} The array of string
       */
      function* split(str, separator, limit) {
          // undefined inputs always return undefined
          if (typeof str === 'undefined') {
              return undefined;
          }
  
          // limit, if specified, must be a non-negative number
          if (limit < 0) {
              throw {
                  code: "D3020",
                  stack: (new Error()).stack,
                  value: limit,
                  index: 3
              };
          }
  
          var result = [];
  
          if (typeof limit === 'undefined' || limit > 0) {
              if (typeof separator === 'string') {
                  result = str.split(separator, limit);
              } else {
                  var count = 0;
                  var matches = yield* evaluateMatcher(separator, str);
                  if (typeof matches !== 'undefined') {
                      var start = 0;
                      while (typeof matches !== 'undefined' && (typeof limit === 'undefined' || count < limit)) {
                          result.push(str.substring(start, matches.start));
                          start = matches.end;
                          matches = yield* evaluateMatcher(matches.next);
                          count++;
                      }
                      if (typeof limit === 'undefined' || count < limit) {
                          result.push(str.substring(start));
                      }
                  } else {
                      result.push(str);
                  }
              }
          }
  
          return result;
      }
  
      /**
       * Join an array of strings
       * @param {Array} strs - array of string
       * @param {String} [separator] - the token that splits the string
       * @returns {String} The concatenated string
       */
      function join(strs, separator) {
          // undefined inputs always return undefined
          if (typeof strs === 'undefined') {
              return undefined;
          }
  
          // if separator is not specified, default to empty string
          if (typeof separator === 'undefined') {
              separator = "";
          }
  
          return strs.join(separator);
      }
  
      /**
       * Formats a number into a decimal string representation using XPath 3.1 F&O fn:format-number spec
       * @param {number} value - number to format
       * @param {String} picture - picture string definition
       * @param {Object} [options] - override locale defaults
       * @returns {String} The formatted string
       */
      function formatNumber(value, picture, options) {
          // undefined inputs always return undefined
          if (typeof value === 'undefined') {
              return undefined;
          }
  
          var defaults = {
              "decimal-separator": ".",
              "grouping-separator": ",",
              "exponent-separator": "e",
              "infinity": "Infinity",
              "minus-sign": "-",
              "NaN": "NaN",
              "percent": "%",
              "per-mille": "\u2030",
              "zero-digit": "0",
              "digit": "#",
              "pattern-separator": ";"
          };
  
          // if `options` is specified, then its entries override defaults
          var properties = defaults;
          if (typeof options !== 'undefined') {
              Object.keys(options).forEach(function (key) {
                  properties[key] = options[key];
              });
          }
  
          var decimalDigitFamily = [];
          var zeroCharCode = properties['zero-digit'].charCodeAt(0);
          for (var ii = zeroCharCode; ii < zeroCharCode + 10; ii++) {
              decimalDigitFamily.push(String.fromCharCode(ii));
          }
  
          var activeChars = decimalDigitFamily.concat([properties['decimal-separator'], properties['exponent-separator'], properties['grouping-separator'], properties.digit, properties['pattern-separator']]);
  
          var subPictures = picture.split(properties['pattern-separator']);
  
          if (subPictures.length > 2) {
              throw {
                  code: 'D3080',
                  stack: (new Error()).stack
              };
          }
  
          var splitParts = function (subpicture) {
              var prefix = (function () {
                  var ch;
                  for (var ii = 0; ii < subpicture.length; ii++) {
                      ch = subpicture.charAt(ii);
                      if (activeChars.indexOf(ch) !== -1 && ch !== properties['exponent-separator']) {
                          return subpicture.substring(0, ii);
                      }
                  }
              })();
              var suffix = (function () {
                  var ch;
                  for (var ii = subpicture.length - 1; ii >= 0; ii--) {
                      ch = subpicture.charAt(ii);
                      if (activeChars.indexOf(ch) !== -1 && ch !== properties['exponent-separator']) {
                          return subpicture.substring(ii + 1);
                      }
                  }
              })();
              var activePart = subpicture.substring(prefix.length, subpicture.length - suffix.length);
              var mantissaPart, exponentPart, integerPart, fractionalPart;
              var exponentPosition = subpicture.indexOf(properties['exponent-separator'], prefix.length);
              if (exponentPosition === -1 || exponentPosition > subpicture.length - suffix.length) {
                  mantissaPart = activePart;
                  exponentPart = undefined;
              } else {
                  mantissaPart = activePart.substring(0, exponentPosition);
                  exponentPart = activePart.substring(exponentPosition + 1);
              }
              var decimalPosition = mantissaPart.indexOf(properties['decimal-separator']);
              if (decimalPosition === -1) {
                  integerPart = mantissaPart;
                  fractionalPart = suffix;
              } else {
                  integerPart = mantissaPart.substring(0, decimalPosition);
                  fractionalPart = mantissaPart.substring(decimalPosition + 1);
              }
              return {
                  prefix: prefix,
                  suffix: suffix,
                  activePart: activePart,
                  mantissaPart: mantissaPart,
                  exponentPart: exponentPart,
                  integerPart: integerPart,
                  fractionalPart: fractionalPart,
                  subpicture: subpicture
              };
          };
  
          // validate the picture string, F&O 4.7.3
          var validate = function (parts) {
              var error;
              var ii;
              var subpicture = parts.subpicture;
              var decimalPos = subpicture.indexOf(properties['decimal-separator']);
              if (decimalPos !== subpicture.lastIndexOf(properties['decimal-separator'])) {
                  error = 'D3081';
              }
              if (subpicture.indexOf(properties.percent) !== subpicture.lastIndexOf(properties.percent)) {
                  error = 'D3082';
              }
              if (subpicture.indexOf(properties['per-mille']) !== subpicture.lastIndexOf(properties['per-mille'])) {
                  error = 'D3083';
              }
              if (subpicture.indexOf(properties.percent) !== -1 && subpicture.indexOf(properties['per-mille']) !== -1) {
                  error = 'D3084';
              }
              var valid = false;
              for (ii = 0; ii < parts.mantissaPart.length; ii++) {
                  var ch = parts.mantissaPart.charAt(ii);
                  if (decimalDigitFamily.indexOf(ch) !== -1 || ch === properties.digit) {
                      valid = true;
                      break;
                  }
              }
              if (!valid) {
                  error = 'D3085';
              }
              var charTypes = parts.activePart.split('').map(function (char) {
                  return activeChars.indexOf(char) === -1 ? 'p' : 'a';
              }).join('');
              if (charTypes.indexOf('p') !== -1) {
                  error = 'D3086';
              }
              if (decimalPos !== -1) {
                  if (subpicture.charAt(decimalPos - 1) === properties['grouping-separator'] || subpicture.charAt(decimalPos + 1) === properties['grouping-separator']) {
                      error = 'D3087';
                  }
              } else if (parts.integerPart.charAt(parts.integerPart.length - 1) === properties['grouping-separator']) {
                  error = 'D3088';
              }
              if (subpicture.indexOf(properties['grouping-separator'] + properties['grouping-separator']) !== -1) {
                  error = 'D3089';
              }
              var optionalDigitPos = parts.integerPart.indexOf(properties.digit);
              if (optionalDigitPos !== -1 && parts.integerPart.substring(0, optionalDigitPos).split('').filter(function (char) {
                  return decimalDigitFamily.indexOf(char) > -1;
              }).length > 0) {
                  error = 'D3090';
              }
              optionalDigitPos = parts.fractionalPart.lastIndexOf(properties.digit);
              if (optionalDigitPos !== -1 && parts.fractionalPart.substring(optionalDigitPos).split('').filter(function (char) {
                  return decimalDigitFamily.indexOf(char) > -1;
              }).length > 0) {
                  error = 'D3091';
              }
              var exponentExists = (typeof parts.exponentPart === 'string');
              if (exponentExists && parts.exponentPart.length > 0 && (subpicture.indexOf(properties.percent) !== -1 || subpicture.indexOf(properties['per-mille']) !== -1)) {
                  error = 'D3092';
              }
              if (exponentExists && (parts.exponentPart.length === 0 || parts.exponentPart.split('').filter(function (char) {
                  return decimalDigitFamily.indexOf(char) === -1;
              }).length > 0)) {
                  error = 'D3093';
              }
              if (error) {
                  throw {
                      code: error,
                      stack: (new Error()).stack
                  };
              }
          };
  
          // analyse the picture string, F&O 4.7.4
          var analyse = function (parts) {
              var getGroupingPositions = function (part, toLeft) {
                  var positions = [];
                  var groupingPosition = part.indexOf(properties['grouping-separator']);
                  while (groupingPosition !== -1) {
                      var charsToTheRight = (toLeft ? part.substring(0, groupingPosition) : part.substring(groupingPosition)).split('').filter(function (char) {
                          return decimalDigitFamily.indexOf(char) !== -1 || char === properties.digit;
                      }).length;
                      positions.push(charsToTheRight);
                      groupingPosition = parts.integerPart.indexOf(properties['grouping-separator'], groupingPosition + 1);
                  }
                  return positions;
              };
              var integerPartGroupingPositions = getGroupingPositions(parts.integerPart);
              var regular = function (indexes) {
                  // are the grouping positions regular? i.e. same interval between each of them
                  if (indexes.length === 0) {
                      return 0;
                  }
                  var gcd = function (a, b) {
                      return b === 0 ? a : gcd(b, a % b);
                  };
                  // find the greatest common divisor of all the positions
                  var factor = indexes.reduce(gcd);
                  // is every position separated by this divisor? If so, it's regular
                  for (var index = 1; index <= indexes.length; index++) {
                      if (indexes.indexOf(index * factor) === -1) {
                          return 0;
                      }
                  }
                  return factor;
              };
  
              var regularGrouping = regular(integerPartGroupingPositions);
              var fractionalPartGroupingPositions = getGroupingPositions(parts.fractionalPart, true);
  
              var minimumIntegerPartSize = parts.integerPart.split('').filter(function (char) {
                  return decimalDigitFamily.indexOf(char) !== -1;
              }).length;
              var scalingFactor = minimumIntegerPartSize;
  
              var fractionalPartArray = parts.fractionalPart.split('');
              var minimumFactionalPartSize = fractionalPartArray.filter(function (char) {
                  return decimalDigitFamily.indexOf(char) !== -1;
              }).length;
              var maximumFactionalPartSize = fractionalPartArray.filter(function (char) {
                  return decimalDigitFamily.indexOf(char) !== -1 || char === properties.digit;
              }).length;
              var exponentPresent = typeof parts.exponentPart === 'string';
              if (minimumIntegerPartSize === 0 && maximumFactionalPartSize === 0) {
                  if (exponentPresent) {
                      minimumFactionalPartSize = 1;
                      maximumFactionalPartSize = 1;
                  } else {
                      minimumIntegerPartSize = 1;
                  }
              }
              if (exponentPresent && minimumIntegerPartSize === 0 && parts.integerPart.indexOf(properties.digit) !== -1) {
                  minimumIntegerPartSize = 1;
              }
              if (minimumIntegerPartSize === 0 && minimumFactionalPartSize === 0) {
                  minimumFactionalPartSize = 1;
              }
              var minimumExponentSize = 0;
              if (exponentPresent) {
                  minimumExponentSize = parts.exponentPart.split('').filter(function (char) {
                      return decimalDigitFamily.indexOf(char) !== -1;
                  }).length;
              }
  
              return {
                  integerPartGroupingPositions: integerPartGroupingPositions,
                  regularGrouping: regularGrouping,
                  minimumIntegerPartSize: minimumIntegerPartSize,
                  scalingFactor: scalingFactor,
                  prefix: parts.prefix,
                  fractionalPartGroupingPositions: fractionalPartGroupingPositions,
                  minimumFactionalPartSize: minimumFactionalPartSize,
                  maximumFactionalPartSize: maximumFactionalPartSize,
                  minimumExponentSize: minimumExponentSize,
                  suffix: parts.suffix,
                  picture: parts.subpicture
              };
          };
  
          var parts = subPictures.map(splitParts);
          parts.forEach(validate);
  
          var variables = parts.map(analyse);
  
          var minus_sign = properties['minus-sign'];
          var zero_digit = properties['zero-digit'];
          var decimal_separator = properties['decimal-separator'];
          var grouping_separator = properties['grouping-separator'];
  
          if (variables.length === 1) {
              variables.push(JSON.parse(JSON.stringify(variables[0])));
              variables[1].prefix = minus_sign + variables[1].prefix;
          }
  
          // TODO cache the result of the analysis
  
          // format the number
          // bullet 1: TODO: NaN - not sure we'd ever get this in JSON
          var pic;
          // bullet 2:
          if (value >= 0) {
              pic = variables[0];
          } else {
              pic = variables[1];
          }
          var adjustedNumber;
          // bullet 3:
          if (pic.picture.indexOf(properties.percent) !== -1) {
              adjustedNumber = value * 100;
          } else if (pic.picture.indexOf(properties['per-mille']) !== -1) {
              adjustedNumber = value * 1000;
          } else {
              adjustedNumber = value;
          }
          // bullet 4:
          // TODO: infinity - not sure we'd ever get this in JSON
          // bullet 5:
          var mantissa, exponent;
          if (pic.minimumExponentSize === 0) {
              mantissa = adjustedNumber;
          } else {
              // mantissa * 10^exponent = adjustedNumber
              var maxMantissa = Math.pow(10, pic.scalingFactor);
              var minMantissa = Math.pow(10, pic.scalingFactor - 1);
              mantissa = adjustedNumber;
              exponent = 0;
              while (mantissa < minMantissa) {
                  mantissa *= 10;
                  exponent -= 1;
              }
              while (mantissa > maxMantissa) {
                  mantissa /= 10;
                  exponent += 1;
              }
          }
          // bullet 6:
          var roundedNumber = round(mantissa, pic.maximumFactionalPartSize);
          // bullet 7:
          var makeString = function (value, dp) {
              var str = Math.abs(value).toFixed(dp);
              if (zero_digit !== '0') {
                  str = str.split('').map(function (digit) {
                      if (digit >= '0' && digit <= '9') {
                          return decimalDigitFamily[digit.charCodeAt(0) - 48];
                      } else {
                          return digit;
                      }
                  }).join('');
              }
              return str;
          };
          var stringValue = makeString(roundedNumber, pic.maximumFactionalPartSize);
          var decimalPos = stringValue.indexOf('.');
          if (decimalPos === -1) {
              stringValue = stringValue + decimal_separator;
          } else {
              stringValue = stringValue.replace('.', decimal_separator);
          }
          while (stringValue.charAt(0) === zero_digit) {
              stringValue = stringValue.substring(1);
          }
          while (stringValue.charAt(stringValue.length - 1) === zero_digit) {
              stringValue = stringValue.substring(0, stringValue.length - 1);
          }
          // bullets 8 & 9:
          decimalPos = stringValue.indexOf(decimal_separator);
          var padLeft = pic.minimumIntegerPartSize - decimalPos;
          var padRight = pic.minimumFactionalPartSize - (stringValue.length - decimalPos - 1);
          stringValue = (padLeft > 0 ? new Array(padLeft + 1).join(zero_digit) : '') + stringValue;
          stringValue = stringValue + (padRight > 0 ? new Array(padRight + 1).join(zero_digit) : '');
          decimalPos = stringValue.indexOf(decimal_separator);
          // bullet 10:
          if (pic.regularGrouping > 0) {
              var groupCount = Math.floor((decimalPos - 1) / pic.regularGrouping);
              for (var group = 1; group <= groupCount; group++) {
                  stringValue = [stringValue.slice(0, decimalPos - group * pic.regularGrouping), grouping_separator, stringValue.slice(decimalPos - group * pic.regularGrouping)].join('');
              }
          } else {
              pic.integerPartGroupingPositions.forEach(function (pos) {
                  stringValue = [stringValue.slice(0, decimalPos - pos), grouping_separator, stringValue.slice(decimalPos - pos)].join('');
                  decimalPos++;
              });
          }
          // bullet 11:
          decimalPos = stringValue.indexOf(decimal_separator);
          pic.fractionalPartGroupingPositions.forEach(function (pos) {
              stringValue = [stringValue.slice(0, pos + decimalPos + 1), grouping_separator, stringValue.slice(pos + decimalPos + 1)].join('');
          });
          // bullet 12:
          decimalPos = stringValue.indexOf(decimal_separator);
          if (pic.picture.indexOf(decimal_separator) === -1 || decimalPos === stringValue.length - 1) {
              stringValue = stringValue.substring(0, stringValue.length - 1);
          }
          // bullet 13:
          if (typeof exponent !== 'undefined') {
              var stringExponent = makeString(exponent, 0);
              padLeft = pic.minimumExponentSize - stringExponent.length;
              if (padLeft > 0) {
                  stringExponent = new Array(padLeft + 1).join(zero_digit) + stringExponent;
              }
              stringValue = stringValue + properties['exponent-separator'] + (exponent < 0 ? minus_sign : '') + stringExponent;
          }
          // bullet 14:
          stringValue = pic.prefix + stringValue + pic.suffix;
          return stringValue;
      }
  
      /**
       * Converts a number to a string using a specified number base
       * @param {number} value - the number to convert
       * @param {number} [radix] - the number base; must be between 2 and 36. Defaults to 10
       * @returns {string} - the converted string
       */
      function formatBase(value, radix) {
          // undefined inputs always return undefined
          if (typeof value === 'undefined') {
              return undefined;
          }
  
          value = round(value);
  
          if (typeof radix === 'undefined') {
              radix = 10;
          } else {
              radix = round(radix);
          }
  
          if (radix < 2 || radix > 36) {
              throw {
                  code: 'D3100',
                  stack: (new Error()).stack,
                  value: radix
              };
  
          }
  
          var result = value.toString(radix);
  
          return result;
      }
  
      /**
       * Cast argument to number
       * @param {Object} arg - Argument
       * @returns {Number} numeric value of argument
       */
      function number(arg) {
          var result;
  
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          if (typeof arg === 'number') {
              // already a number
              result = arg;
          } else if (typeof arg === 'string' && /^-?[0-9]+(\.[0-9]+)?([Ee][-+]?[0-9]+)?$/.test(arg) && !isNaN(parseFloat(arg)) && isFinite(arg)) {
              result = parseFloat(arg);
          } else if (arg === true) {
              // boolean true casts to 1
              result = 1;
          } else if (arg === false) {
              // boolean false casts to 0
              result = 0;
          } else {
              throw {
                  code: "D3030",
                  value: arg,
                  stack: (new Error()).stack,
                  index: 1
              };
          }
          return result;
      }
  
      /**
       * Absolute value of a number
       * @param {Number} arg - Argument
       * @returns {Number} absolute value of argument
       */
      function abs(arg) {
          var result;
  
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          result = Math.abs(arg);
          return result;
      }
  
      /**
       * Rounds a number down to integer
       * @param {Number} arg - Argument
       * @returns {Number} rounded integer
       */
      function floor(arg) {
          var result;
  
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          result = Math.floor(arg);
          return result;
      }
  
      /**
       * Rounds a number up to integer
       * @param {Number} arg - Argument
       * @returns {Number} rounded integer
       */
      function ceil(arg) {
          var result;
  
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          result = Math.ceil(arg);
          return result;
      }
  
      /**
       * Round to half even
       * @param {Number} arg - Argument
       * @param {Number} [precision] - number of decimal places
       * @returns {Number} rounded integer
       */
      function round(arg, precision) {
          var result;
  
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          if (precision) {
              // shift the decimal place - this needs to be done in a string since multiplying
              // by a power of ten can introduce floating point precision errors which mess up
              // this rounding algorithm - See 'Decimal rounding' in
              // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
              // Shift
              var value = arg.toString().split('e');
              arg = +(value[0] + 'e' + (value[1] ? (+value[1] + precision) : precision));
  
          }
  
          // round up to nearest int
          result = Math.round(arg);
          var diff = result - arg;
          if (Math.abs(diff) === 0.5 && Math.abs(result % 2) === 1) {
              // rounded the wrong way - adjust to nearest even number
              result = result - 1;
          }
          if (precision) {
              // Shift back
              value = result.toString().split('e');
              /* istanbul ignore next */
              result = +(value[0] + 'e' + (value[1] ? (+value[1] - precision) : -precision));
          }
          if (Object.is(result, -0)) { // ESLint rule 'no-compare-neg-zero' suggests this way
              // JSON doesn't do -0
              result = 0;
          }
          return result;
      }
  
      /**
       * Square root of number
       * @param {Number} arg - Argument
       * @returns {Number} square root
       */
      function sqrt(arg) {
          var result;
  
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          if (arg < 0) {
              throw {
                  stack: (new Error()).stack,
                  code: "D3060",
                  index: 1,
                  value: arg
              };
          }
  
          result = Math.sqrt(arg);
  
          return result;
      }
  
      /**
       * Raises number to the power of the second number
       * @param {Number} arg - the base
       * @param {Number} exp - the exponent
       * @returns {Number} rounded integer
       */
      function power(arg, exp) {
          var result;
  
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          result = Math.pow(arg, exp);
  
          if (!isFinite(result)) {
              throw {
                  stack: (new Error()).stack,
                  code: "D3061",
                  index: 1,
                  value: arg,
                  exp: exp
              };
          }
  
          return result;
      }
  
      /**
       * Returns a random number 0 <= n < 1
       * @returns {number} random number
       */
      function random() {
          return Math.random();
      }
  
      /**
       * Evaluate an input and return a boolean
       * @param {*} arg - Arguments
       * @returns {boolean} Boolean
       */
      function boolean(arg) {
          // cast arg to its effective boolean value
          // boolean: unchanged
          // string: zero-length -> false; otherwise -> true
          // number: 0 -> false; otherwise -> true
          // null -> false
          // array: empty -> false; length > 1 -> true
          // object: empty -> false; non-empty -> true
          // function -> false
  
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          var result = false;
          if (Array.isArray(arg)) {
              if (arg.length === 1) {
                  result = boolean(arg[0]);
              } else if (arg.length > 1) {
                  var trues = arg.filter(function (val) {
                      return boolean(val);
                  });
                  result = trues.length > 0;
              }
          } else if (typeof arg === 'string') {
              if (arg.length > 0) {
                  result = true;
              }
          } else if (isNumeric(arg)) {
              if (arg !== 0) {
                  result = true;
              }
          } else if (arg !== null && typeof arg === 'object') {
              if (Object.keys(arg).length > 0) {
                  result = true;
              }
          } else if (typeof arg === 'boolean' && arg === true) {
              result = true;
          }
          return result;
      }
  
      /**
       * returns the Boolean NOT of the arg
       * @param {*} arg - argument
       * @returns {boolean} - NOT arg
       */
      function not(arg) {
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          return !boolean(arg);
      }
  
      /**
       * Helper function to build the arguments to be supplied to the function arg of the
       * HOFs map, filter, each, sift and single
       * @param {function} func - the function to be invoked
       * @param {*} arg1 - the first (required) arg - the value
       * @param {*} arg2 - the second (optional) arg - the position (index or key)
       * @param {*} arg3 - the third (optional) arg - the whole structure (array or object)
       * @returns {*[]} the argument list
       */
      function hofFuncArgs(func, arg1, arg2, arg3) {
          var func_args = [arg1]; // the first arg (the value) is required
          // the other two are optional - only supply it if the function can take it
          var length = getFunctionArity(func);
          if (length >= 2) {
              func_args.push(arg2);
          }
          if (length >= 3) {
              func_args.push(arg3);
          }
          return func_args;
      }
  
      /**
       * Create a map from an array of arguments
       * @param {Array} [arr] - array to map over
       * @param {Function} func - function to apply
       * @returns {Array} Map array
       */
      function* map(arr, func) {
          // undefined inputs always return undefined
          if (typeof arr === 'undefined') {
              return undefined;
          }
  
          var result = createSequence();
          // do the map - iterate over the arrays, and invoke func
          for (var i = 0; i < arr.length; i++) {
              var func_args = hofFuncArgs(func, arr[i], i, arr);
              // invoke func
              var res = yield* func.apply(this, func_args);
              if (typeof res !== 'undefined') {
                  result.push(res);
              }
          }
  
          return result;
      }
  
      /**
       * Create a map from an array of arguments
       * @param {Array} [arr] - array to filter
       * @param {Function} func - predicate function
       * @returns {Array} Map array
       */
      function* filter(arr, func) { // eslint-disable-line require-yield
          // undefined inputs always return undefined
          if (typeof arr === 'undefined') {
              return undefined;
          }
  
          var result = createSequence();
  
          for (var i = 0; i < arr.length; i++) {
              var entry = arr[i];
              var func_args = hofFuncArgs(func, entry, i, arr);
              // invoke func
              var res = yield* func.apply(this, func_args);
              if (boolean(res)) {
                  result.push(entry);
              }
          }
  
          return result;
      }
  
      /**
       * Given an array, find the single element matching a specified condition
       * Throws an exception if the number of matching elements is not exactly one
       * @param {Array} [arr] - array to filter
       * @param {Function} [func] - predicate function
       * @returns {*} Matching element
       */
      function* single(arr, func) { // eslint-disable-line require-yield
          // undefined inputs always return undefined
          if (typeof arr === 'undefined') {
              return undefined;
          }
  
          var hasFoundMatch = false;
          var result;
  
          for (var i = 0; i < arr.length; i++) {
              var entry = arr[i];
              var positiveResult = true;
              if (typeof func !== 'undefined') {
                  var func_args = hofFuncArgs(func, entry, i, arr);
                  // invoke func
                  var res = yield* func.apply(this, func_args);
                  positiveResult = boolean(res);
              }
              if (positiveResult) {
                  if(!hasFoundMatch) {
                      result = entry;
                      hasFoundMatch = true;
                  } else {
                      throw {
                          stack: (new Error()).stack,
                          code: "D3138",
                          index: i
                      };
                  }
              }
          }
  
          if(!hasFoundMatch) {
              throw {
                  stack: (new Error()).stack,
                  code: "D3139"
              };
          }
  
          return result;
      }
  
      /**
       * Convolves (zips) each value from a set of arrays
       * @param {Array} [args] - arrays to zip
       * @returns {Array} Zipped array
       */
      function zip() {
          // this can take a variable number of arguments
          var result = [];
          var args = Array.prototype.slice.call(arguments);
          // length of the shortest array
          var length = Math.min.apply(Math, args.map(function (arg) {
              if (Array.isArray(arg)) {
                  return arg.length;
              }
              return 0;
          }));
          for (var i = 0; i < length; i++) {
              var tuple = args.map((arg) => {
                  return arg[i];
              });
              result.push(tuple);
          }
          return result;
      }
  
      /**
       * Fold left function
       * @param {Array} sequence - Sequence
       * @param {Function} func - Function
       * @param {Object} init - Initial value
       * @returns {*} Result
       */
      function* foldLeft(sequence, func, init) {
          // undefined inputs always return undefined
          if (typeof sequence === 'undefined') {
              return undefined;
          }
  
          var result;
  
          var arity = getFunctionArity(func);
          if (arity < 2) {
              throw {
                  stack: (new Error()).stack,
                  code: "D3050",
                  index: 1
              };
          }
  
          var index;
          if (typeof init === 'undefined' && sequence.length > 0) {
              result = sequence[0];
              index = 1;
          } else {
              result = init;
              index = 0;
          }
  
          while (index < sequence.length) {
              var args = [result, sequence[index]];
              if (arity >= 3) {
                  args.push(index);
              }
              if (arity >= 4) {
                  args.push(sequence);
              }
              result = yield* func.apply(this, args);
              index++;
          }
  
          return result;
      }
  
      /**
       * Return keys for an object
       * @param {Object} arg - Object
       * @returns {Array} Array of keys
       */
      function keys(arg) {
          var result = createSequence();
  
          if (Array.isArray(arg)) {
              // merge the keys of all of the items in the array
              var merge = {};
              arg.forEach(function (item) {
                  var allkeys = keys(item);
                  allkeys.forEach(function (key) {
                      merge[key] = true;
                  });
              });
              result = keys(merge);
          } else if (arg !== null && typeof arg === 'object' && !(isLambda(arg))) {
              Object.keys(arg).forEach(key => result.push(key));
          }
          return result;
      }
  
      /**
       * Return value from an object for a given key
       * @param {Object} input - Object/Array
       * @param {String} key - Key in object
       * @returns {*} Value of key in object
       */
      function lookup(input, key) {
          // lookup the 'name' item in the input
          var result;
          if (Array.isArray(input)) {
              result = createSequence();
              for(var ii = 0; ii < input.length; ii++) {
                  var res =  lookup(input[ii], key);
                  if (typeof res !== 'undefined') {
                      if (Array.isArray(res)) {
                          res.forEach(val => result.push(val));
                      } else {
                          result.push(res);
                      }
                  }
              }
          } else if (input !== null && typeof input === 'object') {
              result = input[key];
          }
          return result;
      }
  
      /**
       * Append second argument to first
       * @param {Array|Object} arg1 - First argument
       * @param {Array|Object} arg2 - Second argument
       * @returns {*} Appended arguments
       */
      function append(arg1, arg2) {
          // disregard undefined args
          if (typeof arg1 === 'undefined') {
              return arg2;
          }
          if (typeof arg2 === 'undefined') {
              return arg1;
          }
          // if either argument is not an array, make it so
          if (!Array.isArray(arg1)) {
              arg1 = createSequence(arg1);
          }
          if (!Array.isArray(arg2)) {
              arg2 = [arg2];
          }
          return arg1.concat(arg2);
      }
  
      /**
       * Determines if the argument is undefined
       * @param {*} arg - argument
       * @returns {boolean} False if argument undefined, otherwise true
       */
      function exists(arg) {
          if (typeof arg === 'undefined') {
              return false;
          } else {
              return true;
          }
      }
  
      /**
       * Splits an object into an array of object with one property each
       * @param {*} arg - the object to split
       * @returns {*} - the array
       */
      function spread(arg) {
          var result = createSequence();
  
          if (Array.isArray(arg)) {
              // spread all of the items in the array
              arg.forEach(function (item) {
                  result = append(result, spread(item));
              });
          } else if (arg !== null && typeof arg === 'object' && !isLambda(arg)) {
              for (var key in arg) {
                  var obj = {};
                  obj[key] = arg[key];
                  result.push(obj);
              }
          } else {
              result = arg;
          }
          return result;
      }
  
      /**
       * Merges an array of objects into a single object.  Duplicate properties are
       * overridden by entries later in the array
       * @param {*} arg - the objects to merge
       * @returns {*} - the object
       */
      function merge(arg) {
          // undefined inputs always return undefined
          if (typeof arg === 'undefined') {
              return undefined;
          }
  
          var result = {};
  
          arg.forEach(function (obj) {
              for (var prop in obj) {
                  result[prop] = obj[prop];
              }
          });
          return result;
      }
  
      /**
       * Reverses the order of items in an array
       * @param {Array} arr - the array to reverse
       * @returns {Array} - the reversed array
       */
      function reverse(arr) {
          // undefined inputs always return undefined
          if (typeof arr === 'undefined') {
              return undefined;
          }
  
          if (arr.length <= 1) {
              return arr;
          }
  
          var length = arr.length;
          var result = new Array(length);
          for (var i = 0; i < length; i++) {
              result[length - i - 1] = arr[i];
          }
  
          return result;
      }
  
      /**
       *
       * @param {*} obj - the input object to iterate over
       * @param {*} func - the function to apply to each key/value pair
       * @returns {Array} - the resultant array
       */
      function* each(obj, func) {
          var result = createSequence();
  
          for (var key in obj) {
              var func_args = hofFuncArgs(func, obj[key], key, obj);
              // invoke func
              var val = yield* func.apply(this, func_args);
              if(typeof val !== 'undefined') {
                  result.push(val);
              }
          }
  
          return result;
      }
  
      /**
       *
       * @param {string} [message] - the message to attach to the error
       * @throws custom error with code 'D3137'
       */
      function error(message) {
          throw {
              code: "D3137",
              stack: (new Error()).stack,
              message: message || "$error() function evaluated"
          };
      }
  
      /**
       *
       * @param {boolean} condition - the condition to evaluate
       * @param {string} [message] - the message to attach to the error
       * @throws custom error with code 'D3137'
       * @returns {undefined}
       */
      function assert(condition, message) {
          if(!condition) {
              throw {
                  code: "D3141",
                  stack: (new Error()).stack,
                  message: message || "$assert() statement failed"
              };
          }
  
          return undefined;
      }
  
      /**
       *
       * @param {*} [value] - the input to which the type will be checked
       * @returns {string} - the type of the input
       */
      function type(value) {
          if (value === undefined) {
              return undefined;
          }
  
          if (value === null) {
              return 'null';
          }
  
          if (isNumeric(value)) {
              return 'number';
          }
  
          if (typeof value === 'string') {
              return 'string';
          }
  
          if (typeof value === 'boolean') {
              return 'boolean';
          }
  
          if(Array.isArray(value)) {
              return 'array';
          }
  
          if(isFunction(value)) {
              return 'function';
          }
  
          return 'object';
      }
  
      /**
       * Implements the merge sort (stable) with optional comparator function
       *
       * @param {Array} arr - the array to sort
       * @param {*} comparator - comparator function
       * @returns {Array} - sorted array
       */
      function* sort(arr, comparator) {
          // undefined inputs always return undefined
          if (typeof arr === 'undefined') {
              return undefined;
          }
  
          if (arr.length <= 1) {
              return arr;
          }
  
          var comp;
          if (typeof comparator === 'undefined') {
              // inject a default comparator - only works for numeric or string arrays
              if (!isArrayOfNumbers(arr) && !isArrayOfStrings(arr)) {
                  throw {
                      stack: (new Error()).stack,
                      code: "D3070",
                      index: 1
                  };
              }
  
              comp = function* (a, b) {  // eslint-disable-line require-yield
                  return a > b;
              };
          } else {
              // for internal usage of functionSort (i.e. order-by syntax)
              comp = comparator;
          }
  
          var merge = function* (l, r) {
              var merge_iter = function* (result, left, right) {
                  if (left.length === 0) {
                      Array.prototype.push.apply(result, right);
                  } else if (right.length === 0) {
                      Array.prototype.push.apply(result, left);
                  } else if (yield* comp(left[0], right[0])) { // invoke the comparator function
                      // if it returns true - swap left and right
                      result.push(right[0]);
                      yield* merge_iter(result, left, right.slice(1));
                  } else {
                      // otherwise keep the same order
                      result.push(left[0]);
                      yield* merge_iter(result, left.slice(1), right);
                  }
              };
              var merged = [];
              yield* merge_iter(merged, l, r);
              return merged;
          };
  
          var msort = function* (array) {
              if (!Array.isArray(array) || array.length <= 1) {
                  return array;
              } else {
                  var middle = Math.floor(array.length / 2);
                  var left = array.slice(0, middle);
                  var right = array.slice(middle);
                  left = yield* msort(left);
                  right = yield* msort(right);
                  return yield* merge(left, right);
              }
          };
  
          var result = yield* msort(arr);
  
          return result;
      }
  
      /**
       * Randomly shuffles the contents of an array
       * @param {Array} arr - the input array
       * @returns {Array} the shuffled array
       */
      function shuffle(arr) {
          // undefined inputs always return undefined
          if (typeof arr === 'undefined') {
              return undefined;
          }
  
          if (arr.length <= 1) {
              return arr;
          }
  
          // shuffle using the 'inside-out' variant of the Fisher-Yates algorithm
          var result = new Array(arr.length);
          for (var i = 0; i < arr.length; i++) {
              var j = Math.floor(Math.random() * (i + 1)); // random integer such that 0 ≤ j ≤ i
              if (i !== j) {
                  result[i] = result[j];
              }
              result[j] = arr[i];
          }
  
          return result;
      }
  
      /**
       * Returns the values that appear in a sequence, with duplicates eliminated.
       * @param {Array} arr - An array or sequence of values
       * @returns {Array} - sequence of distinct values
       */
      function distinct(arr) {
          // undefined inputs always return undefined
          if (typeof arr === 'undefined') {
              return undefined;
          }
  
          if(!Array.isArray(arr) || arr.length <= 1) {
              return arr;
          }
  
          var results = isSequence(arr) ? createSequence() : [];
  
          for(var ii = 0; ii < arr.length; ii++) {
              var value = arr[ii];
              // is this value already in the result sequence?
              var includes = false;
              for(var jj = 0; jj < results.length; jj++) {
                  if (deepEquals(value, results[jj])) {
                      includes = true;
                      break;
                  }
              }
              if(!includes) {
                  results.push(value);
              }
          }
          return results;
      }
  
      /**
       * Applies a predicate function to each key/value pair in an object, and returns an object containing
       * only the key/value pairs that passed the predicate
       *
       * @param {object} arg - the object to be sifted
       * @param {object} func - the predicate function (lambda or native)
       * @returns {object} - sifted object
       */
      function* sift(arg, func) {
          var result = {};
  
          for (var item in arg) {
              var entry = arg[item];
              var func_args = hofFuncArgs(func, entry, item, arg);
              // invoke func
              var res = yield* func.apply(this, func_args);
              if (boolean(res)) {
                  result[item] = entry;
              }
          }
  
          // empty objects should be changed to undefined
          if (Object.keys(result).length === 0) {
              result = undefined;
          }
  
          return result;
      }
  
      return {
          sum, count, max, min, average,
          string, substring, substringBefore, substringAfter, lowercase, uppercase, length, trim, pad,
          match, contains, replace, split, join,
          formatNumber, formatBase, number, floor, ceil, round, abs, sqrt, power, random,
          boolean, not,
          map, zip, filter, single, foldLeft, sift,
          keys, lookup, append, exists, spread, merge, reverse, each, error, assert, type, sort, shuffle, distinct,
          base64encode, base64decode,  encodeUrlComponent, encodeUrl, decodeUrlComponent, decodeUrl
      };
  })();
  
  module.exports = functions;
  
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{"./utils":6}],3:[function(require,module,exports){
  /**
   * © Copyright IBM Corp. 2016, 2017 All Rights Reserved
   *   Project name: JSONata
   *   This project is licensed under the MIT License, see LICENSE
   */
  
  /**
   * @module JSONata
   * @description JSON query and transformation language
   */
  
  var datetime = require('./datetime');
  var fn = require('./functions');
  var utils = require('./utils');
  var parser = require('./parser');
  var parseSignature = require('./signature');
  
  /**
   * jsonata
   * @function
   * @param {Object} expr - JSONata expression
   * @returns {{evaluate: evaluate, assign: assign}} Evaluated expression
   */
  var jsonata = (function() {
      'use strict';
  
      var isNumeric = utils.isNumeric;
      var isArrayOfStrings = utils.isArrayOfStrings;
      var isArrayOfNumbers = utils.isArrayOfNumbers;
      var createSequence = utils.createSequence;
      var isSequence = utils.isSequence;
      var isFunction = utils.isFunction;
      var isLambda = utils.isLambda;
      var isIterable = utils.isIterable;
      var getFunctionArity = utils.getFunctionArity;
      var isDeepEqual = utils.isDeepEqual;
  
      // Start of Evaluator code
  
      var staticFrame = createFrame(null);
  
      /**
       * Evaluate expression against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluate(expr, input, environment) {
          var result;
  
          var entryCallback = environment.lookup('__evaluate_entry');
          if(entryCallback) {
              entryCallback(expr, input, environment);
          }
  
          switch (expr.type) {
              case 'path':
                  result = yield * evaluatePath(expr, input, environment);
                  break;
              case 'binary':
                  result = yield * evaluateBinary(expr, input, environment);
                  break;
              case 'unary':
                  result = yield * evaluateUnary(expr, input, environment);
                  break;
              case 'name':
                  result = evaluateName(expr, input, environment);
                  break;
              case 'string':
              case 'number':
              case 'value':
                  result = evaluateLiteral(expr, input, environment);
                  break;
              case 'wildcard':
                  result = evaluateWildcard(expr, input, environment);
                  break;
              case 'descendant':
                  result = evaluateDescendants(expr, input, environment);
                  break;
              case 'parent':
                  result = environment.lookup(expr.slot.label);
                  break;
              case 'condition':
                  result = yield * evaluateCondition(expr, input, environment);
                  break;
              case 'block':
                  result = yield * evaluateBlock(expr, input, environment);
                  break;
              case 'bind':
                  result = yield * evaluateBindExpression(expr, input, environment);
                  break;
              case 'regex':
                  result = evaluateRegex(expr, input, environment);
                  break;
              case 'function':
                  result = yield * evaluateFunction(expr, input, environment);
                  break;
              case 'variable':
                  result = evaluateVariable(expr, input, environment);
                  break;
              case 'lambda':
                  result = evaluateLambda(expr, input, environment);
                  break;
              case 'partial':
                  result = yield * evaluatePartialApplication(expr, input, environment);
                  break;
              case 'apply':
                  result = yield * evaluateApplyExpression(expr, input, environment);
                  break;
              case 'transform':
                  result = evaluateTransformExpression(expr, input, environment);
                  break;
          }
  
          if(environment.async &&
              (typeof result === 'undefined' || result === null || typeof result.then !== 'function')) {
              result = Promise.resolve(result);
          }
          if(environment.async && typeof result.then === 'function' && expr.nextFunction && typeof result[expr.nextFunction] === 'function') {
              // although this is a 'thenable', it is chaining a different function
              // so don't yield since yielding will trigger the .then()
          } else {
              result = yield result;
          }
  
          if (Object.prototype.hasOwnProperty.call(expr, 'predicate')) {
              for(var ii = 0; ii < expr.predicate.length; ii++) {
                  result = yield * evaluateFilter(expr.predicate[ii].expr, result, environment);
              }
          }
  
          if (expr.type !== 'path' && Object.prototype.hasOwnProperty.call(expr, 'group')) {
              result = yield * evaluateGroupExpression(expr.group, result, environment);
          }
  
          var exitCallback = environment.lookup('__evaluate_exit');
          if(exitCallback) {
              exitCallback(expr, input, environment, result);
          }
  
          if(result && isSequence(result) && !result.tupleStream) {
              if(expr.keepArray) {
                  result.keepSingleton = true;
              }
              if(result.length === 0) {
                  result = undefined;
              } else if(result.length === 1) {
                  result =  result.keepSingleton ? result : result[0];
              }
  
          }
  
          return result;
      }
  
      /**
       * Evaluate path expression against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluatePath(expr, input, environment) {
          var inputSequence;
          // expr is an array of steps
          // if the first step is a variable reference ($...), including root reference ($$),
          //   then the path is absolute rather than relative
          if (Array.isArray(input) && expr.steps[0].type !== 'variable') {
              inputSequence = input;
          } else {
              // if input is not an array, make it so
              inputSequence = createSequence(input);
          }
  
          var resultSequence;
          var isTupleStream = false;
          var tupleBindings = undefined;
  
          // evaluate each step in turn
          for(var ii = 0; ii < expr.steps.length; ii++) {
              var step = expr.steps[ii];
  
              if(step.tuple) {
                  isTupleStream = true;
              }
  
              // if the first step is an explicit array constructor, then just evaluate that (i.e. don't iterate over a context array)
              if(ii === 0 && step.consarray) {
                  resultSequence = yield * evaluate(step, inputSequence, environment);
              } else {
                  if(isTupleStream) {
                      tupleBindings = yield * evaluateTupleStep(step, inputSequence, tupleBindings, environment);
                  } else {
                      resultSequence = yield * evaluateStep(step, inputSequence, environment, ii === expr.steps.length - 1);
                  }
              }
  
              if (!isTupleStream && (typeof resultSequence === 'undefined' || resultSequence.length === 0)) {
                  break;
              }
  
              if(typeof step.focus === 'undefined') {
                  inputSequence = resultSequence;
              }
  
          }
  
          if(isTupleStream) {
              if(expr.tuple) {
                  // tuple stream is carrying ancestry information - keep this
                  resultSequence = tupleBindings;
              } else {
                  resultSequence = createSequence();
                  for (ii = 0; ii < tupleBindings.length; ii++) {
                      resultSequence.push(tupleBindings[ii]['@']);
                  }
              }
          }
  
          if(expr.keepSingletonArray) {
              if(!isSequence(resultSequence)) {
                  resultSequence = createSequence(resultSequence);
              }
              resultSequence.keepSingleton = true;
          }
  
          if (expr.hasOwnProperty('group')) {
              resultSequence = yield* evaluateGroupExpression(expr.group, isTupleStream ? tupleBindings : resultSequence, environment)
          }
  
          return resultSequence;
      }
  
      function createFrameFromTuple(environment, tuple) {
          var frame = createFrame(environment);
          for(const prop in tuple) {
              frame.bind(prop, tuple[prop]);
          }
          return frame;
      }
  
      /**
       * Evaluate a step within a path
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @param {boolean} lastStep - flag the last step in a path
       * @returns {*} Evaluated input data
       */
      function* evaluateStep(expr, input, environment, lastStep) {
          var result;
          if(expr.type === 'sort') {
               result = yield* evaluateSortExpression(expr, input, environment);
               if(expr.stages) {
                   result = yield* evaluateStages(expr.stages, result, environment);
               }
               return result;
          }
  
          result = createSequence();
  
          for(var ii = 0; ii < input.length; ii++) {
              var res = yield * evaluate(expr, input[ii], environment);
              if(expr.stages) {
                  for(var ss = 0; ss < expr.stages.length; ss++) {
                      res = yield* evaluateFilter(expr.stages[ss].expr, res, environment);
                  }
              }
              if(typeof res !== 'undefined') {
                  result.push(res);
              }
          }
  
          var resultSequence = createSequence();
          if(lastStep && result.length === 1 && Array.isArray(result[0]) && !isSequence(result[0])) {
              resultSequence = result[0];
          } else {
              // flatten the sequence
              result.forEach(function(res) {
                  if (!Array.isArray(res) || res.cons) {
                      // it's not an array - just push into the result sequence
                      resultSequence.push(res);
                  } else {
                      // res is a sequence - flatten it into the parent sequence
                      res.forEach(val => resultSequence.push(val));
                  }
              });
          }
  
          return resultSequence;
      }
  
      function* evaluateStages(stages, input, environment) {
          var result = input;
          for(var ss = 0; ss < stages.length; ss++) {
              var stage = stages[ss];
              switch(stage.type) {
                  case 'filter':
                      result = yield * evaluateFilter(stage.expr, result, environment);
                      break;
                  case 'index':
                      for(var ee = 0; ee < result.length; ee++) {
                          var tuple = result[ee];
                          tuple[stage.value] = ee;
                      }
                      break;
              }
          }
          return result;
      }
  
      /**
       * Evaluate a step within a path
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} tupleBindings - The tuple stream
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluateTupleStep(expr, input, tupleBindings, environment) {
          var result;
          if(expr.type === 'sort') {
              if(tupleBindings) {
                  result = yield* evaluateSortExpression(expr, tupleBindings, environment);
              } else {
                  var sorted = yield* evaluateSortExpression(expr, input, environment);
                  result = createSequence();
                  result.tupleStream = true;
                  for(var ss = 0; ss < sorted.length; ss++) {
                      var tuple = {'@': sorted[ss]};
                      tuple[expr.index] = ss;
                      result.push(tuple);
                  }
              }
              if(expr.stages) {
                  result = yield* evaluateStages(expr.stages, result, environment);
              }
              return result;
          }
  
          result = createSequence();
          result.tupleStream = true;
          var stepEnv = environment;
          if(tupleBindings === undefined) {
              tupleBindings = input.map(item => { return {'@': item} });
          }
  
          for(var ee = 0; ee < tupleBindings.length; ee++) {
              stepEnv = createFrameFromTuple(environment, tupleBindings[ee]);
              var res = yield* evaluate(expr, tupleBindings[ee]['@'], stepEnv);
              // res is the binding sequence for the output tuple stream
              if(typeof res !== 'undefined') {
                  if (!Array.isArray(res)) {
                      res = [res];
                  }
                  for (var bb = 0; bb < res.length; bb++) {
                      tuple = {};
                      Object.assign(tuple, tupleBindings[ee]);
                      if(res.tupleStream) {
                          Object.assign(tuple, res[bb]);
                      } else {
                          if (expr.focus) {
                              tuple[expr.focus] = res[bb];
                              tuple['@'] = tupleBindings[ee]['@'];
                          } else {
                              tuple['@'] = res[bb];
                          }
                          if (expr.index) {
                              tuple[expr.index] = bb;
                          }
                          if (expr.ancestor) {
                              tuple[expr.ancestor.label] = tupleBindings[ee]['@'];
                          }
                      }
                      result.push(tuple);
                  }
              }
          }
  
          if(expr.stages) {
              result = yield * evaluateStages(expr.stages, result, environment);
          }
  
          return result;
      }
  
      /**
       * Apply filter predicate to input data
       * @param {Object} predicate - filter expression
       * @param {Object} input - Input data to apply predicates against
       * @param {Object} environment - Environment
       * @returns {*} Result after applying predicates
       */
      function* evaluateFilter(predicate, input, environment) {
          var results = createSequence();
          if( input && input.tupleStream) {
              results.tupleStream = true;
          }
          if (!Array.isArray(input)) {
              input = createSequence(input);
          }
          if (predicate.type === 'number') {
              var index = Math.floor(predicate.value);  // round it down
              if (index < 0) {
                  // count in from end of array
                  index = input.length + index;
              }
              var item = input[index];
              if(typeof item !== 'undefined') {
                  if(Array.isArray(item)) {
                      results = item;
                  } else {
                      results.push(item);
                  }
              }
          } else {
              for (index = 0; index < input.length; index++) {
                  var item = input[index];
                  var context = item;
                  var env = environment;
                  if(input.tupleStream) {
                      context = item['@'];
                      env = createFrameFromTuple(environment, item);
                  }
                  var res = yield* evaluate(predicate, context, env);
                  if (isNumeric(res)) {
                      res = [res];
                  }
                  if (isArrayOfNumbers(res)) {
                      res.forEach(function (ires) {
                          // round it down
                          var ii = Math.floor(ires);
                          if (ii < 0) {
                              // count in from end of array
                              ii = input.length + ii;
                          }
                          if (ii === index) {
                              results.push(item);
                          }
                      });
                  } else if (fn.boolean(res)) { // truthy
                      results.push(item);
                  }
              }
          }
          return results;
      }
  
      /**
       * Evaluate binary expression against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function * evaluateBinary(expr, input, environment) {
          var result;
          var lhs = yield * evaluate(expr.lhs, input, environment);
          var rhs = yield * evaluate(expr.rhs, input, environment);
          var op = expr.value;
  
          try {
              switch (op) {
                  case '+':
                  case '-':
                  case '*':
                  case '/':
                  case '%':
                      result = evaluateNumericExpression(lhs, rhs, op);
                      break;
                  case '=':
                  case '!=':
                      result = evaluateEqualityExpression(lhs, rhs, op);
                      break;
                  case '<':
                  case '<=':
                  case '>':
                  case '>=':
                      result = evaluateComparisonExpression(lhs, rhs, op);
                      break;
                  case '&':
                      result = evaluateStringConcat(lhs, rhs);
                      break;
                  case 'and':
                  case 'or':
                      result = evaluateBooleanExpression(lhs, rhs, op);
                      break;
                  case '..':
                      result = evaluateRangeExpression(lhs, rhs);
                      break;
                  case 'in':
                      result = evaluateIncludesExpression(lhs, rhs);
                      break;
              }
          } catch(err) {
              err.position = expr.position;
              err.token = op;
              throw err;
          }
          return result;
      }
  
      /**
       * Evaluate unary expression against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluateUnary(expr, input, environment) {
          var result;
  
          switch (expr.value) {
              case '-':
                  result = yield * evaluate(expr.expression, input, environment);
                  if(typeof result === 'undefined') {
                      result = undefined;
                  } else if (isNumeric(result)) {
                      result = -result;
                  } else {
                      throw {
                          code: "D1002",
                          stack: (new Error()).stack,
                          position: expr.position,
                          token: expr.value,
                          value: result
                      };
                  }
                  break;
              case '[':
                  // array constructor - evaluate each item
                  result = [];
                  for(var ii = 0; ii < expr.expressions.length; ii++) {
                      var item = expr.expressions[ii];
                      var value = yield * evaluate(item, input, environment);
                      if (typeof value !== 'undefined') {
                          if(item.value === '[') {
                              result.push(value);
                          } else {
                              result = fn.append(result, value);
                          }
                      }
                  }
                  if(expr.consarray) {
                      Object.defineProperty(result, 'cons', {
                          enumerable: false,
                          configurable: false,
                          value: true
                      });
                  }
                  break;
              case '{':
                  // object constructor - apply grouping
                  result = yield * evaluateGroupExpression(expr, input, environment);
                  break;
  
          }
          return result;
      }
  
      /**
       * Evaluate name object against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function evaluateName(expr, input, environment) {
          // lookup the 'name' item in the input
          return fn.lookup(input, expr.value);
      }
  
      /**
       * Evaluate literal against input data
       * @param {Object} expr - JSONata expression
       * @returns {*} Evaluated input data
       */
      function evaluateLiteral(expr) {
          return expr.value;
      }
  
      /**
       * Evaluate wildcard against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @returns {*} Evaluated input data
       */
      function evaluateWildcard(expr, input) {
          var results = createSequence();
          if (input !== null && typeof input === 'object') {
              Object.keys(input).forEach(function (key) {
                  var value = input[key];
                  if(Array.isArray(value)) {
                      value = flatten(value);
                      results = fn.append(results, value);
                  } else {
                      results.push(value);
                  }
              });
          }
  
          //        result = normalizeSequence(results);
          return results;
      }
  
      /**
       * Returns a flattened array
       * @param {Array} arg - the array to be flatten
       * @param {Array} flattened - carries the flattened array - if not defined, will initialize to []
       * @returns {Array} - the flattened array
       */
      function flatten(arg, flattened) {
          if(typeof flattened === 'undefined') {
              flattened = [];
          }
          if(Array.isArray(arg)) {
              arg.forEach(function (item) {
                  flatten(item, flattened);
              });
          } else {
              flattened.push(arg);
          }
          return flattened;
      }
  
      /**
       * Evaluate descendants against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @returns {*} Evaluated input data
       */
      function evaluateDescendants(expr, input) {
          var result;
          var resultSequence = createSequence();
          if (typeof input !== 'undefined') {
              // traverse all descendants of this object/array
              recurseDescendants(input, resultSequence);
              if (resultSequence.length === 1) {
                  result = resultSequence[0];
              } else {
                  result = resultSequence;
              }
          }
          return result;
      }
  
      /**
       * Recurse through descendants
       * @param {Object} input - Input data
       * @param {Object} results - Results
       */
      function recurseDescendants(input, results) {
          // this is the equivalent of //* in XPath
          if (!Array.isArray(input)) {
              results.push(input);
          }
          if (Array.isArray(input)) {
              input.forEach(function (member) {
                  recurseDescendants(member, results);
              });
          } else if (input !== null && typeof input === 'object') {
              Object.keys(input).forEach(function (key) {
                  recurseDescendants(input[key], results);
              });
          }
      }
  
      /**
       * Evaluate numeric expression against input data
       * @param {Object} lhs - LHS value
       * @param {Object} rhs - RHS value
       * @param {Object} op - opcode
       * @returns {*} Result
       */
      function evaluateNumericExpression(lhs, rhs, op) {
          var result;
  
          if (typeof lhs !== 'undefined' && !isNumeric(lhs)) {
              throw {
                  code: "T2001",
                  stack: (new Error()).stack,
                  value: lhs
              };
          }
          if (typeof rhs !== 'undefined' && !isNumeric(rhs)) {
              throw {
                  code: "T2002",
                  stack: (new Error()).stack,
                  value: rhs
              };
          }
  
          if (typeof lhs === 'undefined' || typeof rhs === 'undefined') {
              // if either side is undefined, the result is undefined
              return result;
          }
  
          switch (op) {
              case '+':
                  result = lhs + rhs;
                  break;
              case '-':
                  result = lhs - rhs;
                  break;
              case '*':
                  result = lhs * rhs;
                  break;
              case '/':
                  result = lhs / rhs;
                  break;
              case '%':
                  result = lhs % rhs;
                  break;
          }
          return result;
      }
  
      /**
       * Evaluate equality expression against input data
       * @param {Object} lhs - LHS value
       * @param {Object} rhs - RHS value
       * @param {Object} op - opcode
       * @returns {*} Result
       */
      function evaluateEqualityExpression(lhs, rhs, op) {
          var result;
  
          // type checks
          var ltype = typeof lhs;
          var rtype = typeof rhs;
  
          if (ltype === 'undefined' || rtype === 'undefined') {
              // if either side is undefined, the result is false
              return false;
          }
  
          switch (op) {
              case '=':
                  result = isDeepEqual(lhs, rhs);
                  break;
              case '!=':
                  result = !isDeepEqual(lhs, rhs);
                  break;
          }
          return result;
      }
  
      /**
       * Evaluate comparison expression against input data
       * @param {Object} lhs - LHS value
       * @param {Object} rhs - RHS value
       * @param {Object} op - opcode
       * @returns {*} Result
       */
      function evaluateComparisonExpression(lhs, rhs, op) {
          var result;
  
          // type checks
          var ltype = typeof lhs;
          var rtype = typeof rhs;
  
          var lcomparable = (ltype === 'undefined' || ltype === 'string' || ltype === 'number');
          var rcomparable = (rtype === 'undefined' || rtype === 'string' || rtype === 'number');
  
          // if either aa or bb are not comparable (string or numeric) values, then throw an error
          if (!lcomparable || !rcomparable) {
              throw {
                  code: "T2010",
                  stack: (new Error()).stack,
                  value: !(ltype === 'string' || ltype === 'number') ? lhs : rhs
              };
          }
  
          // if either side is undefined, the result is undefined
          if (ltype === 'undefined' || rtype === 'undefined') {
              return undefined;
          }
  
          //if aa and bb are not of the same type
          if (ltype !== rtype) {
              throw {
                  code: "T2009",
                  stack: (new Error()).stack,
                  value: lhs,
                  value2: rhs
              };
          }
  
          switch (op) {
              case '<':
                  result = lhs < rhs;
                  break;
              case '<=':
                  result = lhs <= rhs;
                  break;
              case '>':
                  result = lhs > rhs;
                  break;
              case '>=':
                  result = lhs >= rhs;
                  break;
          }
          return result;
      }
  
      /**
       * Inclusion operator - in
       *
       * @param {Object} lhs - LHS value
       * @param {Object} rhs - RHS value
       * @returns {boolean} - true if lhs is a member of rhs
       */
      function evaluateIncludesExpression(lhs, rhs) {
          var result = false;
  
          if (typeof lhs === 'undefined' || typeof rhs === 'undefined') {
              // if either side is undefined, the result is false
              return false;
          }
  
          if(!Array.isArray(rhs)) {
              rhs = [rhs];
          }
  
          for(var i = 0; i < rhs.length; i++) {
              if(rhs[i] === lhs) {
                  result = true;
                  break;
              }
          }
  
          return result;
      }
  
      /**
       * Evaluate boolean expression against input data
       * @param {Object} lhs - LHS value
       * @param {Object} rhs - RHS value
       * @param {Object} op - opcode
       * @returns {*} Result
       */
      function evaluateBooleanExpression(lhs, rhs, op) {
          var result;
  
          var lBool = fn.boolean(lhs);
          var rBool = fn.boolean(rhs);
  
          if (typeof  lBool === 'undefined') {
              lBool = false;
          }
  
          if (typeof  rBool === 'undefined') {
              rBool = false;
          }
  
          switch (op) {
              case 'and':
                  result = lBool && rBool;
                  break;
              case 'or':
                  result = lBool || rBool;
                  break;
          }
          return result;
      }
  
      /**
       * Evaluate string concatenation against input data
       * @param {Object} lhs - LHS value
       * @param {Object} rhs - RHS value
       * @returns {string|*} Concatenated string
       */
      function evaluateStringConcat(lhs, rhs) {
          var result;
  
          var lstr = '';
          var rstr = '';
          if (typeof lhs !== 'undefined') {
              lstr = fn.string(lhs);
          }
          if (typeof rhs !== 'undefined') {
              rstr = fn.string(rhs);
          }
  
          result = lstr.concat(rstr);
          return result;
      }
  
      /**
       * Evaluate group expression against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {{}} Evaluated input data
       */
      function* evaluateGroupExpression(expr, input, environment) {
          var result = {};
          var groups = {};
          var reduce = input && input.tupleStream ? true : false;
          // group the input sequence by 'key' expression
          if (!Array.isArray(input)) {
              input = createSequence(input);
          }
  
          for(var itemIndex = 0; itemIndex < input.length; itemIndex++) {
              var item = input[itemIndex];
              var env = reduce ? createFrameFromTuple(environment, item) : environment;
              for(var pairIndex = 0; pairIndex < expr.lhs.length; pairIndex++) {
                  var pair = expr.lhs[pairIndex];
                  var key = yield * evaluate(pair[0], reduce ? item['@'] : item, env);
                  // key has to be a string
                  if (typeof  key !== 'string') {
                      throw {
                          code: "T1003",
                          stack: (new Error()).stack,
                          position: expr.position,
                          value: key
                      };
                  }
                  var entry = {data: item, exprIndex: pairIndex};
                  if (groups.hasOwnProperty(key)) {
                      // a value already exists in this slot
                      if(groups[key].exprIndex !== pairIndex) {
                          // this key has been generated by another expression in this group
                          // when multiple key expressions evaluate to the same key, then error D1009 must be thrown
                          throw {
                              code: "D1009",
                              stack: (new Error()).stack,
                              position: expr.position,
                              value: key
                          };
                      }
  
                      // append it as an array
                      groups[key].data = fn.append(groups[key].data, item);
                  } else {
                      groups[key] = entry;
                  }
              }
          }
  
          // iterate over the groups to evaluate the 'value' expression
          for (key in groups) {
              entry = groups[key];
              var context = entry.data;
              var env = environment;
              if (reduce) {
                  var tuple = reduceTupleStream(entry.data);
                  context = tuple['@'];
                  delete tuple['@'];
                  env = createFrameFromTuple(environment, tuple);
              }
              var value = yield * evaluate(expr.lhs[entry.exprIndex][1], context, env);
              if(typeof value !== 'undefined') {
                  result[key] = value;
              }
          }
  
          return result;
      }
  
      function reduceTupleStream(tupleStream) {
          if(!Array.isArray(tupleStream)) {
              return tupleStream;
          }
          var result = {};
          Object.assign(result, tupleStream[0]);
          for(var ii = 1; ii < tupleStream.length; ii++) {
              for(const prop in tupleStream[ii]) {
                  result[prop] = fn.append(result[prop], tupleStream[ii][prop]);
              }
          }
          return result;
      }
  
      /**
       * Evaluate range expression against input data
       * @param {Object} lhs - LHS value
       * @param {Object} rhs - RHS value
       * @returns {Array} Resultant array
       */
      function evaluateRangeExpression(lhs, rhs) {
          var result;
  
          if (typeof lhs !== 'undefined' && !Number.isInteger(lhs)) {
              throw {
                  code: "T2003",
                  stack: (new Error()).stack,
                  value: lhs
              };
          }
          if (typeof rhs !== 'undefined' && !Number.isInteger(rhs)) {
              throw {
                  code: "T2004",
                  stack: (new Error()).stack,
                  value: rhs
              };
          }
  
          if (typeof lhs === 'undefined' || typeof rhs === 'undefined') {
              // if either side is undefined, the result is undefined
              return result;
          }
  
          if (lhs > rhs) {
              // if the lhs is greater than the rhs, return undefined
              return result;
          }
  
          // limit the size of the array to ten million entries (1e7)
          // this is an implementation defined limit to protect against
          // memory and performance issues.  This value may increase in the future.
          var size = rhs - lhs + 1;
          if(size > 1e7) {
              throw {
                  code: "D2014",
                  stack: (new Error()).stack,
                  value: size
              };
          }
  
          result = new Array(size);
          for (var item = lhs, index = 0; item <= rhs; item++, index++) {
              result[index] = item;
          }
          result.sequence = true;
          return result;
      }
  
      /**
       * Evaluate bind expression against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluateBindExpression(expr, input, environment) {
          // The RHS is the expression to evaluate
          // The LHS is the name of the variable to bind to - should be a VARIABLE token (enforced by parser)
          var value = yield * evaluate(expr.rhs, input, environment);
          environment.bind(expr.lhs.value, value);
          return value;
      }
  
      /**
       * Evaluate condition against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluateCondition(expr, input, environment) {
          var result;
          var condition = yield * evaluate(expr.condition, input, environment);
          if (fn.boolean(condition)) {
              result = yield * evaluate(expr.then, input, environment);
          } else if (typeof expr.else !== 'undefined') {
              result = yield * evaluate(expr.else, input, environment);
          }
          return result;
      }
  
      /**
       * Evaluate block against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluateBlock(expr, input, environment) {
          var result;
          // create a new frame to limit the scope of variable assignments
          // TODO, only do this if the post-parse stage has flagged this as required
          var frame = createFrame(environment);
          // invoke each expression in turn
          // only return the result of the last one
          for(var ii = 0; ii < expr.expressions.length; ii++) {
              result = yield * evaluate(expr.expressions[ii], input, frame);
          }
  
          return result;
      }
  
      /**
       * Prepare a regex
       * @param {Object} expr - expression containing regex
       * @returns {Function} Higher order function representing prepared regex
       */
      function evaluateRegex(expr) {
          var re = new RegExp(expr.value);
          var closure = function(str, fromIndex) {
              var result;
              re.lastIndex = fromIndex || 0;
              var match = re.exec(str);
              if(match !== null) {
                  result = {
                      match: match[0],
                      start: match.index,
                      end: match.index + match[0].length,
                      groups: []
                  };
                  if(match.length > 1) {
                      for(var i = 1; i < match.length; i++) {
                          result.groups.push(match[i]);
                      }
                  }
                  result.next = function() {
                      if(re.lastIndex >= str.length) {
                          return undefined;
                      } else {
                          var next = closure(str, re.lastIndex);
                          if(next && next.match === '') {
                              // matches zero length string; this will never progress
                              throw {
                                  code: "D1004",
                                  stack: (new Error()).stack,
                                  position: expr.position,
                                  value: expr.value.source
                              };
                          }
                          return next;
                      }
                  };
              }
  
              return result;
          };
          return closure;
      }
  
      /**
       * Evaluate variable against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function evaluateVariable(expr, input, environment) {
          // lookup the variable value in the environment
          var result;
          // if the variable name is empty string, then it refers to context value
          if (expr.value === '') {
              result = input && input.outerWrapper ? input[0] : input;
          } else {
              result = environment.lookup(expr.value);
          }
          return result;
      }
  
      /**
       * sort / order-by operator
       * @param {Object} expr - AST for operator
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Ordered sequence
       */
      function* evaluateSortExpression(expr, input, environment) {
          var result;
  
          // evaluate the lhs, then sort the results in order according to rhs expression
          //var lhs = yield * evaluate(expr.lhs, input, environment);
          var lhs = input;
          var isTupleSort = input.tupleStream ? true : false;
  
          // sort the lhs array
          // use comparator function
          var comparator = function*(a, b) { // eslint-disable-line require-yield
              // expr.terms is an array of order-by in priority order
              var comp = 0;
              for(var index = 0; comp === 0 && index < expr.terms.length; index++) {
                  var term = expr.terms[index];
                  //evaluate the sort term in the context of a
                  var context = a;
                  var env = environment;
                  if(isTupleSort) {
                      context = a['@'];
                      env = createFrameFromTuple(environment, a);
                  }
                  var aa = yield * evaluate(term.expression, context, env);
                  //evaluate the sort term in the context of b
                  context = b;
                  env = environment;
                  if(isTupleSort) {
                      context = b['@'];
                      env = createFrameFromTuple(environment, b);
                  }
                  var bb = yield * evaluate(term.expression, context, env);
  
                  // type checks
                  var atype = typeof aa;
                  var btype = typeof bb;
                  // undefined should be last in sort order
                  if(atype === 'undefined') {
                      // swap them, unless btype is also undefined
                      comp = (btype === 'undefined') ? 0 : 1;
                      continue;
                  }
                  if(btype === 'undefined') {
                      comp = -1;
                      continue;
                  }
  
                  // if aa or bb are not string or numeric values, then throw an error
                  if(!(atype === 'string' || atype === 'number') || !(btype === 'string' || btype === 'number')) {
                      throw {
                          code: "T2008",
                          stack: (new Error()).stack,
                          position: expr.position,
                          value: !(atype === 'string' || atype === 'number') ? aa : bb
                      };
                  }
  
                  //if aa and bb are not of the same type
                  if(atype !== btype) {
                      throw {
                          code: "T2007",
                          stack: (new Error()).stack,
                          position: expr.position,
                          value: aa,
                          value2: bb
                      };
                  }
                  if(aa === bb) {
                      // both the same - move on to next term
                      continue;
                  } else if (aa < bb) {
                      comp = -1;
                  } else {
                      comp = 1;
                  }
                  if(term.descending === true) {
                      comp = -comp;
                  }
              }
              // only swap a & b if comp equals 1
              return comp === 1;
          };
  
          var focus = {
              environment: environment,
              input: input
          };
          // the `focus` is passed in as the `this` for the invoked function
          result = yield * fn.sort.apply(focus, [lhs, comparator]);
  
          return result;
      }
  
      /**
       * create a transformer function
       * @param {Object} expr - AST for operator
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} tranformer function
       */
      function evaluateTransformExpression(expr, input, environment) {
          // create a function to implement the transform definition
          var transformer = function*(obj) { // signature <(oa):o>
              // undefined inputs always return undefined
              if(typeof obj === 'undefined') {
                  return undefined;
              }
  
              // this function returns a copy of obj with changes specified by the pattern/operation
              var cloneFunction = environment.lookup('clone');
              if(!isFunction(cloneFunction)) {
                  // throw type error
                  throw {
                      code: "T2013",
                      stack: (new Error()).stack,
                      position: expr.position
                  };
              }
              var result = yield * apply(cloneFunction, [obj], null, environment);
              var matches = yield * evaluate(expr.pattern, result, environment);
              if(typeof matches !== 'undefined') {
                  if(!Array.isArray(matches)) {
                      matches = [matches];
                  }
                  for(var ii = 0; ii < matches.length; ii++) {
                      var match = matches[ii];
                      // evaluate the update value for each match
                      var update = yield * evaluate(expr.update, match, environment);
                      // update must be an object
                      var updateType = typeof update;
                      if(updateType !== 'undefined') {
                          if(updateType !== 'object' || update === null || Array.isArray(update)) {
                              // throw type error
                              throw {
                                  code: "T2011",
                                  stack: (new Error()).stack,
                                  position: expr.update.position,
                                  value: update
                              };
                          }
                          // merge the update
                          for(var prop in update) {
                              match[prop] = update[prop];
                          }
                      }
  
                      // delete, if specified, must be an array of strings (or single string)
                      if(typeof expr.delete !== 'undefined') {
                          var deletions = yield * evaluate(expr.delete, match, environment);
                          if(typeof deletions !== 'undefined') {
                              var val = deletions;
                              if (!Array.isArray(deletions)) {
                                  deletions = [deletions];
                              }
                              if (!isArrayOfStrings(deletions)) {
                                  // throw type error
                                  throw {
                                      code: "T2012",
                                      stack: (new Error()).stack,
                                      position: expr.delete.position,
                                      value: val
                                  };
                              }
                              for (var jj = 0; jj < deletions.length; jj++) {
                                  if(typeof match === 'object' && match !== null) {
                                      delete match[deletions[jj]];
                                  }
                              }
                          }
                      }
                  }
              }
  
              return result;
          };
  
          return defineFunction(transformer, '<(oa):o>');
      }
  
      var chainAST = parser('function($f, $g) { function($x){ $g($f($x)) } }');
  
      /**
       * Apply the function on the RHS using the sequence on the LHS as the first argument
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluateApplyExpression(expr, input, environment) {
          var result;
  
  
          var lhs = yield * evaluate(expr.lhs, input, environment);
          if(expr.rhs.type === 'function') {
              // this is a function _invocation_; invoke it with lhs expression as the first argument
              result = yield * evaluateFunction(expr.rhs, input, environment, { context: lhs });
          } else {
              var func = yield * evaluate(expr.rhs, input, environment);
  
              if(!isFunction(func)) {
                  throw {
                      code: "T2006",
                      stack: (new Error()).stack,
                      position: expr.position,
                      value: func
                  };
              }
  
              if(isFunction(lhs)) {
                  // this is function chaining (func1 ~> func2)
                  // λ($f, $g) { λ($x){ $g($f($x)) } }
                  var chain = yield * evaluate(chainAST, null, environment);
                  result = yield * apply(chain, [lhs, func], null, environment);
              } else {
                  result = yield * apply(func, [lhs], null, environment);
              }
  
          }
  
          return result;
      }
  
      /**
       * Evaluate function against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluateFunction(expr, input, environment, applyto) {
          var result;
  
          // create the procedure
          // can't assume that expr.procedure is a lambda type directly
          // could be an expression that evaluates to a function (e.g. variable reference, parens expr etc.
          // evaluate it generically first, then check that it is a function.  Throw error if not.
          var proc = yield * evaluate(expr.procedure, input, environment);
  
          if (typeof proc === 'undefined' && expr.procedure.type === 'path' && environment.lookup(expr.procedure.steps[0].value)) {
              // help the user out here if they simply forgot the leading $
              throw {
                  code: "T1005",
                  stack: (new Error()).stack,
                  position: expr.position,
                  token: expr.procedure.steps[0].value
              };
          }
  
          var evaluatedArgs = [];
          if(typeof applyto !== 'undefined') {
              evaluatedArgs.push(applyto.context);
          }
          // eager evaluation - evaluate the arguments
          for (var jj = 0; jj < expr.arguments.length; jj++) {
              const arg = yield* evaluate(expr.arguments[jj], input, environment);
              if(isFunction(arg)) {
                  // wrap this in a closure
                  const closure = function* (...params) {
                      // invoke func
                      return yield * apply(arg, params, null, environment);
                  };
                  closure.arity = getFunctionArity(arg);
                  evaluatedArgs.push(closure);
              } else {
                  evaluatedArgs.push(arg);
              }
          }
          // apply the procedure
          var procName = expr.procedure.type === 'path' ? expr.procedure.steps[0].value : expr.procedure.value;
          try {
              if(typeof proc === 'object') {
                  proc.token = procName;
                  proc.position = expr.position;
              }
              result = yield * apply(proc, evaluatedArgs, input, environment);
          } catch (err) {
              if(!err.position) {
                  // add the position field to the error
                  err.position = expr.position;
              }
              if (!err.token) {
                  // and the function identifier
                  err.token = procName;
              }
              throw err;
          }
          return result;
      }
  
      /**
       * Apply procedure or function
       * @param {Object} proc - Procedure
       * @param {Array} args - Arguments
       * @param {Object} input - input
       * @param {Object} environment - environment
       * @returns {*} Result of procedure
       */
      function* apply(proc, args, input, environment) {
          var result;
          result = yield * applyInner(proc, args, input, environment);
          while(isLambda(result) && result.thunk === true) {
              // trampoline loop - this gets invoked as a result of tail-call optimization
              // the function returned a tail-call thunk
              // unpack it, evaluate its arguments, and apply the tail call
              var next = yield * evaluate(result.body.procedure, result.input, result.environment);
              if(result.body.procedure.type === 'variable') {
                  next.token = result.body.procedure.value;
              }
              next.position = result.body.procedure.position;
              var evaluatedArgs = [];
              for(var ii = 0; ii < result.body.arguments.length; ii++) {
                  evaluatedArgs.push(yield * evaluate(result.body.arguments[ii], result.input, result.environment));
              }
  
              result = yield * applyInner(next, evaluatedArgs, input, environment);
          }
          return result;
      }
  
      /**
       * Apply procedure or function
       * @param {Object} proc - Procedure
       * @param {Array} args - Arguments
       * @param {Object} input - input
       * @param {Object} environment - environment
       * @returns {*} Result of procedure
       */
      function* applyInner(proc, args, input, environment) {
          var result;
          try {
              var validatedArgs = args;
              if (proc) {
                  validatedArgs = validateArguments(proc.signature, args, input);
              }
  
              if (isLambda(proc)) {
                  result = yield* applyProcedure(proc, validatedArgs);
              } else if (proc && proc._jsonata_function === true) {
                  var focus = {
                      environment: environment,
                      input: input
                  };
                  // the `focus` is passed in as the `this` for the invoked function
                  result = proc.implementation.apply(focus, validatedArgs);
                  // `proc.implementation` might be a generator function
                  // and `result` might be a generator - if so, yield
                  if (isIterable(result)) {
                      result = yield* result;
                  }
              } else if (typeof proc === 'function') {
                  // typically these are functions that are returned by the invocation of plugin functions
                  // the `input` is being passed in as the `this` for the invoked function
                  // this is so that functions that return objects containing functions can chain
                  // e.g. $func().next().next()
                  result = proc.apply(input, validatedArgs);
                  /* istanbul ignore next */
                  if (isIterable(result)) {
                      result = yield* result;
                  }
              } else {
                  throw {
                      code: "T1006",
                      stack: (new Error()).stack
                  };
              }
          } catch(err) {
              if(proc) {
                  if (typeof err.token == 'undefined' && typeof proc.token !== 'undefined') {
                      err.token = proc.token;
                  }
                  err.position = proc.position;
              }
              throw err;
          }
          return result;
      }
  
      /**
       * Evaluate lambda against input data
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {{lambda: boolean, input: *, environment: *, arguments: *, body: *}} Evaluated input data
       */
      function evaluateLambda(expr, input, environment) {
          // make a function (closure)
          var procedure = {
              _jsonata_lambda: true,
              input: input,
              environment: environment,
              arguments: expr.arguments,
              signature: expr.signature,
              body: expr.body
          };
          if(expr.thunk === true) {
              procedure.thunk = true;
          }
          procedure.apply = function*(self, args) {
              return yield * apply(procedure, args, input, self.environment);
          };
          return procedure;
      }
  
      /**
       * Evaluate partial application
       * @param {Object} expr - JSONata expression
       * @param {Object} input - Input data to evaluate against
       * @param {Object} environment - Environment
       * @returns {*} Evaluated input data
       */
      function* evaluatePartialApplication(expr, input, environment) {
          // partially apply a function
          var result;
          // evaluate the arguments
          var evaluatedArgs = [];
          for(var ii = 0; ii < expr.arguments.length; ii++) {
              var arg = expr.arguments[ii];
              if (arg.type === 'operator' && arg.value === '?') {
                  evaluatedArgs.push(arg);
              } else {
                  evaluatedArgs.push(yield * evaluate(arg, input, environment));
              }
          }
          // lookup the procedure
          var proc = yield * evaluate(expr.procedure, input, environment);
          if (typeof proc === 'undefined' && expr.procedure.type === 'path' && environment.lookup(expr.procedure.steps[0].value)) {
              // help the user out here if they simply forgot the leading $
              throw {
                  code: "T1007",
                  stack: (new Error()).stack,
                  position: expr.position,
                  token: expr.procedure.steps[0].value
              };
          }
          if (isLambda(proc)) {
              result = partialApplyProcedure(proc, evaluatedArgs);
          } else if (proc && proc._jsonata_function === true) {
              result = partialApplyNativeFunction(proc.implementation, evaluatedArgs);
          } else if (typeof proc === 'function') {
              result = partialApplyNativeFunction(proc, evaluatedArgs);
          } else {
              throw {
                  code: "T1008",
                  stack: (new Error()).stack,
                  position: expr.position,
                  token: expr.procedure.type === 'path' ? expr.procedure.steps[0].value : expr.procedure.value
              };
          }
          return result;
      }
  
      /**
       * Validate the arguments against the signature validator (if it exists)
       * @param {Function} signature - validator function
       * @param {Array} args - function arguments
       * @param {*} context - context value
       * @returns {Array} - validated arguments
       */
      function validateArguments(signature, args, context) {
          if(typeof signature === 'undefined') {
              // nothing to validate
              return args;
          }
          var validatedArgs = signature.validate(args, context);
          return validatedArgs;
      }
  
      /**
       * Apply procedure
       * @param {Object} proc - Procedure
       * @param {Array} args - Arguments
       * @returns {*} Result of procedure
       */
      function* applyProcedure(proc, args) {
          var result;
          var env = createFrame(proc.environment);
          proc.arguments.forEach(function (param, index) {
              env.bind(param.value, args[index]);
          });
          if (typeof proc.body === 'function') {
              // this is a lambda that wraps a native function - generated by partially evaluating a native
              result = yield * applyNativeFunction(proc.body, env);
          } else {
              result = yield * evaluate(proc.body, proc.input, env);
          }
          return result;
      }
  
      /**
       * Partially apply procedure
       * @param {Object} proc - Procedure
       * @param {Array} args - Arguments
       * @returns {{lambda: boolean, input: *, environment: {bind, lookup}, arguments: Array, body: *}} Result of partially applied procedure
       */
      function partialApplyProcedure(proc, args) {
          // create a closure, bind the supplied parameters and return a function that takes the remaining (?) parameters
          var env = createFrame(proc.environment);
          var unboundArgs = [];
          proc.arguments.forEach(function (param, index) {
              var arg = args[index];
              if (arg && arg.type === 'operator' && arg.value === '?') {
                  unboundArgs.push(param);
              } else {
                  env.bind(param.value, arg);
              }
          });
          var procedure = {
              _jsonata_lambda: true,
              input: proc.input,
              environment: env,
              arguments: unboundArgs,
              body: proc.body
          };
          return procedure;
      }
  
      /**
       * Partially apply native function
       * @param {Function} native - Native function
       * @param {Array} args - Arguments
       * @returns {{lambda: boolean, input: *, environment: {bind, lookup}, arguments: Array, body: *}} Result of partially applying native function
       */
      function partialApplyNativeFunction(native, args) {
          // create a lambda function that wraps and invokes the native function
          // get the list of declared arguments from the native function
          // this has to be picked out from the toString() value
          var sigArgs = getNativeFunctionArguments(native);
          sigArgs = sigArgs.map(function (sigArg) {
              return '$' + sigArg.trim();
          });
          var body = 'function(' + sigArgs.join(', ') + '){ _ }';
  
          var bodyAST = parser(body);
          bodyAST.body = native;
  
          var partial = partialApplyProcedure(bodyAST, args);
          return partial;
      }
  
      /**
       * Apply native function
       * @param {Object} proc - Procedure
       * @param {Object} env - Environment
       * @returns {*} Result of applying native function
       */
      function* applyNativeFunction(proc, env) {
          var sigArgs = getNativeFunctionArguments(proc);
          // generate the array of arguments for invoking the function - look them up in the environment
          var args = sigArgs.map(function (sigArg) {
              return env.lookup(sigArg.trim());
          });
  
          var focus = {
              environment: env
          };
          var result = proc.apply(focus, args);
          if(isIterable(result)) {
              result = yield * result;
          }
          return result;
      }
  
      /**
       * Get native function arguments
       * @param {Function} func - Function
       * @returns {*|Array} Native function arguments
       */
      function getNativeFunctionArguments(func) {
          var signature = func.toString();
          var sigParens = /\(([^)]*)\)/.exec(signature)[1]; // the contents of the parens
          var sigArgs = sigParens.split(',');
          return sigArgs;
      }
  
      /**
       * Creates a function definition
       * @param {Function} func - function implementation in Javascript
       * @param {string} signature - JSONata function signature definition
       * @returns {{implementation: *, signature: *}} function definition
       */
      function defineFunction(func, signature) {
          var definition = {
              _jsonata_function: true,
              implementation: func
          };
          if(typeof signature !== 'undefined') {
              definition.signature = parseSignature(signature);
          }
          return definition;
      }
  
  
      /**
       * parses and evaluates the supplied expression
       * @param {string} expr - expression to evaluate
       * @returns {*} - result of evaluating the expression
       */
      function* functionEval(expr, focus) {
          // undefined inputs always return undefined
          if(typeof expr === 'undefined') {
              return undefined;
          }
          var input = this.input;
          if(typeof focus !== 'undefined') {
              input = focus;
          }
  
          try {
              var ast = parser(expr, false);
          } catch(err) {
              // error parsing the expression passed to $eval
              populateMessage(err);
              throw {
                  stack: (new Error()).stack,
                  code: "D3120",
                  value: err.message,
                  error: err
              };
          }
          try {
              var result = yield* evaluate(ast, input, this.environment);
          } catch(err) {
              // error evaluating the expression passed to $eval
              populateMessage(err);
              throw {
                  stack: (new Error()).stack,
                  code: "D3121",
                  value:err.message,
                  error: err
              };
          }
  
          return result;
      }
  
      /**
       * Clones an object
       * @param {Object} arg - object to clone (deep copy)
       * @returns {*} - the cloned object
       */
      function functionClone(arg) {
          // undefined inputs always return undefined
          if(typeof arg === 'undefined') {
              return undefined;
          }
  
          return JSON.parse(fn.string(arg));
      }
  
      /**
       * Create frame
       * @param {Object} enclosingEnvironment - Enclosing environment
       * @returns {{bind: bind, lookup: lookup}} Created frame
       */
      function createFrame(enclosingEnvironment) {
          var bindings = {};
          return {
              bind: function (name, value) {
                  bindings[name] = value;
              },
              lookup: function (name) {
                  var value;
                  if(bindings.hasOwnProperty(name)) {
                      value = bindings[name];
                  } else if (enclosingEnvironment) {
                      value = enclosingEnvironment.lookup(name);
                  }
                  return value;
              },
              timestamp: enclosingEnvironment ? enclosingEnvironment.timestamp : null,
              async: enclosingEnvironment ? enclosingEnvironment.async : false,
              global: enclosingEnvironment ? enclosingEnvironment.global : {
                  ancestry: [ null ]
              }
          };
      }
  
      // Function registration
      staticFrame.bind('sum', defineFunction(fn.sum, '<a<n>:n>'));
      staticFrame.bind('count', defineFunction(fn.count, '<a:n>'));
      staticFrame.bind('max', defineFunction(fn.max, '<a<n>:n>'));
      staticFrame.bind('min', defineFunction(fn.min, '<a<n>:n>'));
      staticFrame.bind('average', defineFunction(fn.average, '<a<n>:n>'));
      staticFrame.bind('string', defineFunction(fn.string, '<x-b?:s>'));
      staticFrame.bind('substring', defineFunction(fn.substring, '<s-nn?:s>'));
      staticFrame.bind('substringBefore', defineFunction(fn.substringBefore, '<s-s:s>'));
      staticFrame.bind('substringAfter', defineFunction(fn.substringAfter, '<s-s:s>'));
      staticFrame.bind('lowercase', defineFunction(fn.lowercase, '<s-:s>'));
      staticFrame.bind('uppercase', defineFunction(fn.uppercase, '<s-:s>'));
      staticFrame.bind('length', defineFunction(fn.length, '<s-:n>'));
      staticFrame.bind('trim', defineFunction(fn.trim, '<s-:s>'));
      staticFrame.bind('pad', defineFunction(fn.pad, '<s-ns?:s>'));
      staticFrame.bind('match', defineFunction(fn.match, '<s-f<s:o>n?:a<o>>'));
      staticFrame.bind('contains', defineFunction(fn.contains, '<s-(sf):b>')); // TODO <s-(sf<s:o>):b>
      staticFrame.bind('replace', defineFunction(fn.replace, '<s-(sf)(sf)n?:s>')); // TODO <s-(sf<s:o>)(sf<o:s>)n?:s>
      staticFrame.bind('split', defineFunction(fn.split, '<s-(sf)n?:a<s>>')); // TODO <s-(sf<s:o>)n?:a<s>>
      staticFrame.bind('join', defineFunction(fn.join, '<a<s>s?:s>'));
      staticFrame.bind('formatNumber', defineFunction(fn.formatNumber, '<n-so?:s>'));
      staticFrame.bind('formatBase', defineFunction(fn.formatBase, '<n-n?:s>'));
      staticFrame.bind('formatInteger', defineFunction(datetime.formatInteger, '<n-s:s>'));
      staticFrame.bind('parseInteger', defineFunction(datetime.parseInteger, '<s-s:n>'));
      staticFrame.bind('number', defineFunction(fn.number, '<(nsb)-:n>'));
      staticFrame.bind('floor', defineFunction(fn.floor, '<n-:n>'));
      staticFrame.bind('ceil', defineFunction(fn.ceil, '<n-:n>'));
      staticFrame.bind('round', defineFunction(fn.round, '<n-n?:n>'));
      staticFrame.bind('abs', defineFunction(fn.abs, '<n-:n>'));
      staticFrame.bind('sqrt', defineFunction(fn.sqrt, '<n-:n>'));
      staticFrame.bind('power', defineFunction(fn.power, '<n-n:n>'));
      staticFrame.bind('random', defineFunction(fn.random, '<:n>'));
      staticFrame.bind('boolean', defineFunction(fn.boolean, '<x-:b>'));
      staticFrame.bind('not', defineFunction(fn.not, '<x-:b>'));
      staticFrame.bind('map', defineFunction(fn.map, '<af>'));
      staticFrame.bind('zip', defineFunction(fn.zip, '<a+>'));
      staticFrame.bind('filter', defineFunction(fn.filter, '<af>'));
      staticFrame.bind('single', defineFunction(fn.single, '<af?>'));
      staticFrame.bind('reduce', defineFunction(fn.foldLeft, '<afj?:j>')); // TODO <f<jj:j>a<j>j?:j>
      staticFrame.bind('sift', defineFunction(fn.sift, '<o-f?:o>'));
      staticFrame.bind('keys', defineFunction(fn.keys, '<x-:a<s>>'));
      staticFrame.bind('lookup', defineFunction(fn.lookup, '<x-s:x>'));
      staticFrame.bind('append', defineFunction(fn.append, '<xx:a>'));
      staticFrame.bind('exists', defineFunction(fn.exists, '<x:b>'));
      staticFrame.bind('spread', defineFunction(fn.spread, '<x-:a<o>>'));
      staticFrame.bind('merge', defineFunction(fn.merge, '<a<o>:o>'));
      staticFrame.bind('reverse', defineFunction(fn.reverse, '<a:a>'));
      staticFrame.bind('each', defineFunction(fn.each, '<o-f:a>'));
      staticFrame.bind('error', defineFunction(fn.error, '<s?:x>'));
      staticFrame.bind('assert', defineFunction(fn.assert, '<bs?:x>'));
      staticFrame.bind('type', defineFunction(fn.type, '<x:s>'));
      staticFrame.bind('sort', defineFunction(fn.sort, '<af?:a>'));
      staticFrame.bind('shuffle', defineFunction(fn.shuffle, '<a:a>'));
      staticFrame.bind('distinct', defineFunction(fn.distinct, '<x:x>'));
      staticFrame.bind('base64encode', defineFunction(fn.base64encode, '<s-:s>'));
      staticFrame.bind('base64decode', defineFunction(fn.base64decode, '<s-:s>'));
      staticFrame.bind('encodeUrlComponent', defineFunction(fn.encodeUrlComponent, '<s-:s>'));
      staticFrame.bind('encodeUrl', defineFunction(fn.encodeUrl, '<s-:s>'));
      staticFrame.bind('decodeUrlComponent', defineFunction(fn.decodeUrlComponent, '<s-:s>'));
      staticFrame.bind('decodeUrl', defineFunction(fn.decodeUrl, '<s-:s>'));
      staticFrame.bind('eval', defineFunction(functionEval, '<sx?:x>'));
      staticFrame.bind('toMillis', defineFunction(datetime.toMillis, '<s-s?:n>'));
      staticFrame.bind('fromMillis', defineFunction(datetime.fromMillis, '<n-s?s?:s>'));
      staticFrame.bind('clone', defineFunction(functionClone, '<(oa)-:o>'));
  
      /**
       * Error codes
       *
       * Sxxxx    - Static errors (compile time)
       * Txxxx    - Type errors
       * Dxxxx    - Dynamic errors (evaluate time)
       *  01xx    - tokenizer
       *  02xx    - parser
       *  03xx    - regex parser
       *  04xx    - function signature parser/evaluator
       *  10xx    - evaluator
       *  20xx    - operators
       *  3xxx    - functions (blocks of 10 for each function)
       */
      var errorCodes = {
          "S0101": "String literal must be terminated by a matching quote",
          "S0102": "Number out of range: {{token}}",
          "S0103": "Unsupported escape sequence: \\{{token}}",
          "S0104": "The escape sequence \\u must be followed by 4 hex digits",
          "S0105": "Quoted property name must be terminated with a backquote (`)",
          "S0106": "Comment has no closing tag",
          "S0201": "Syntax error: {{token}}",
          "S0202": "Expected {{value}}, got {{token}}",
          "S0203": "Expected {{value}} before end of expression",
          "S0204": "Unknown operator: {{token}}",
          "S0205": "Unexpected token: {{token}}",
          "S0206": "Unknown expression type: {{token}}",
          "S0207": "Unexpected end of expression",
          "S0208": "Parameter {{value}} of function definition must be a variable name (start with $)",
          "S0209": "A predicate cannot follow a grouping expression in a step",
          "S0210": "Each step can only have one grouping expression",
          "S0211": "The symbol {{token}} cannot be used as a unary operator",
          "S0212": "The left side of := must be a variable name (start with $)",
          "S0213": "The literal value {{value}} cannot be used as a step within a path expression",
          "S0214": "The right side of {{token}} must be a variable name (start with $)",
          "S0215": "A context variable binding must precede any predicates on a step",
          "S0216": "A context variable binding must precede the 'order-by' clause on a step",
          "S0217": "The object representing the 'parent' cannot be derived from this expression",
          "S0301": "Empty regular expressions are not allowed",
          "S0302": "No terminating / in regular expression",
          "S0402": "Choice groups containing parameterized types are not supported",
          "S0401": "Type parameters can only be applied to functions and arrays",
          "S0500": "Attempted to evaluate an expression containing syntax error(s)",
          "T0410": "Argument {{index}} of function {{token}} does not match function signature",
          "T0411": "Context value is not a compatible type with argument {{index}} of function {{token}}",
          "T0412": "Argument {{index}} of function {{token}} must be an array of {{type}}",
          "D1001": "Number out of range: {{value}}",
          "D1002": "Cannot negate a non-numeric value: {{value}}",
          "T1003": "Key in object structure must evaluate to a string; got: {{value}}",
          "D1004": "Regular expression matches zero length string",
          "T1005": "Attempted to invoke a non-function. Did you mean ${{{token}}}?",
          "T1006": "Attempted to invoke a non-function",
          "T1007": "Attempted to partially apply a non-function. Did you mean ${{{token}}}?",
          "T1008": "Attempted to partially apply a non-function",
          "D1009": "Multiple key definitions evaluate to same key: {{value}}",
          "T1010": "The matcher function argument passed to function {{token}} does not return the correct object structure",
          "T2001": "The left side of the {{token}} operator must evaluate to a number",
          "T2002": "The right side of the {{token}} operator must evaluate to a number",
          "T2003": "The left side of the range operator (..) must evaluate to an integer",
          "T2004": "The right side of the range operator (..) must evaluate to an integer",
          "D2005": "The left side of := must be a variable name (start with $)",  // defunct - replaced by S0212 parser error
          "T2006": "The right side of the function application operator ~> must be a function",
          "T2007": "Type mismatch when comparing values {{value}} and {{value2}} in order-by clause",
          "T2008": "The expressions within an order-by clause must evaluate to numeric or string values",
          "T2009": "The values {{value}} and {{value2}} either side of operator {{token}} must be of the same data type",
          "T2010": "The expressions either side of operator {{token}} must evaluate to numeric or string values",
          "T2011": "The insert/update clause of the transform expression must evaluate to an object: {{value}}",
          "T2012": "The delete clause of the transform expression must evaluate to a string or array of strings: {{value}}",
          "T2013": "The transform expression clones the input object using the $clone() function.  This has been overridden in the current scope by a non-function.",
          "D2014": "The size of the sequence allocated by the range operator (..) must not exceed 1e6.  Attempted to allocate {{value}}.",
          "D3001": "Attempting to invoke string function on Infinity or NaN",
          "D3010": "Second argument of replace function cannot be an empty string",
          "D3011": "Fourth argument of replace function must evaluate to a positive number",
          "D3012": "Attempted to replace a matched string with a non-string value",
          "D3020": "Third argument of split function must evaluate to a positive number",
          "D3030": "Unable to cast value to a number: {{value}}",
          "D3040": "Third argument of match function must evaluate to a positive number",
          "D3050": "The second argument of reduce function must be a function with at least two arguments",
          "D3060": "The sqrt function cannot be applied to a negative number: {{value}}",
          "D3061": "The power function has resulted in a value that cannot be represented as a JSON number: base={{value}}, exponent={{exp}}",
          "D3070": "The single argument form of the sort function can only be applied to an array of strings or an array of numbers.  Use the second argument to specify a comparison function",
          "D3080": "The picture string must only contain a maximum of two sub-pictures",
          "D3081": "The sub-picture must not contain more than one instance of the 'decimal-separator' character",
          "D3082": "The sub-picture must not contain more than one instance of the 'percent' character",
          "D3083": "The sub-picture must not contain more than one instance of the 'per-mille' character",
          "D3084": "The sub-picture must not contain both a 'percent' and a 'per-mille' character",
          "D3085": "The mantissa part of a sub-picture must contain at least one character that is either an 'optional digit character' or a member of the 'decimal digit family'",
          "D3086": "The sub-picture must not contain a passive character that is preceded by an active character and that is followed by another active character",
          "D3087": "The sub-picture must not contain a 'grouping-separator' character that appears adjacent to a 'decimal-separator' character",
          "D3088": "The sub-picture must not contain a 'grouping-separator' at the end of the integer part",
          "D3089": "The sub-picture must not contain two adjacent instances of the 'grouping-separator' character",
          "D3090": "The integer part of the sub-picture must not contain a member of the 'decimal digit family' that is followed by an instance of the 'optional digit character'",
          "D3091": "The fractional part of the sub-picture must not contain an instance of the 'optional digit character' that is followed by a member of the 'decimal digit family'",
          "D3092": "A sub-picture that contains a 'percent' or 'per-mille' character must not contain a character treated as an 'exponent-separator'",
          "D3093": "The exponent part of the sub-picture must comprise only of one or more characters that are members of the 'decimal digit family'",
          "D3100": "The radix of the formatBase function must be between 2 and 36.  It was given {{value}}",
          "D3110": "The argument of the toMillis function must be an ISO 8601 formatted timestamp. Given {{value}}",
          "D3120": "Syntax error in expression passed to function eval: {{value}}",
          "D3121": "Dynamic error evaluating the expression passed to function eval: {{value}}",
          "D3130": "Formatting or parsing an integer as a sequence starting with {{value}} is not supported by this implementation",
          "D3131": "In a decimal digit pattern, all digits must be from the same decimal group",
          "D3132": "Unknown component specifier {{value}} in date/time picture string",
          "D3133": "The 'name' modifier can only be applied to months and days in the date/time picture string, not {{value}}",
          "D3134": "The timezone integer format specifier cannot have more than four digits",
          "D3135": "No matching closing bracket ']' in date/time picture string",
          "D3136": "The date/time picture string is missing specifiers required to parse the timestamp",
          "D3137": "{{{message}}}",
          "D3138": "The $single() function expected exactly 1 matching result.  Instead it matched more.",
          "D3139": "The $single() function expected exactly 1 matching result.  Instead it matched 0.",
          "D3140": "Malformed URL passed to ${{{functionName}}}(): {{value}}",
          "D3141": "{{{message}}}"
      };
  
      /**
       * lookup a message template from the catalog and substitute the inserts.
       * Populates `err.message` with the substituted message. Leaves `err.message`
       * untouched if code lookup fails.
       * @param {string} err - error code to lookup
       * @returns {undefined} - `err` is modified in place
       */
      function populateMessage(err) {
          var template = errorCodes[err.code];
          if(typeof template !== 'undefined') {
              // if there are any handlebars, replace them with the field references
              // triple braces - replace with value
              // double braces - replace with json stringified value
              var message = template.replace(/\{\{\{([^}]+)}}}/g, function() {
                  return err[arguments[1]];
              });
              message = message.replace(/\{\{([^}]+)}}/g, function() {
                  return JSON.stringify(err[arguments[1]]);
              });
              err.message = message;
          }
          // Otherwise retain the original `err.message`
      }
  
      /**
       * JSONata
       * @param {Object} expr - JSONata expression
       * @param {boolean} options - recover: attempt to recover on parse error
       * @returns {{evaluate: evaluate, assign: assign}} Evaluated expression
       */
      function jsonata(expr, options) {
          var ast;
          var errors;
          try {
              ast = parser(expr, options && options.recover);
              errors = ast.errors;
              delete ast.errors;
          } catch(err) {
              // insert error message into structure
              populateMessage(err); // possible side-effects on `err`
              throw err;
          }
          var environment = createFrame(staticFrame);
  
          var timestamp = new Date(); // will be overridden on each call to evalute()
          environment.bind('now', defineFunction(function(picture, timezone) {
              return datetime.fromMillis(timestamp.getTime(), picture, timezone);
          }, '<s?s?:s>'));
          environment.bind('millis', defineFunction(function() {
              return timestamp.getTime();
          }, '<:n>'));
  
          return {
              evaluate: function (input, bindings, callback) {
                  // throw if the expression compiled with syntax errors
                  if(typeof errors !== 'undefined') {
                      var err = {
                          code: 'S0500',
                          position: 0
                      };
                      populateMessage(err); // possible side-effects on `err`
                      throw err;
                  }
  
                  if (typeof bindings !== 'undefined') {
                      var exec_env;
                      // the variable bindings have been passed in - create a frame to hold these
                      exec_env = createFrame(environment);
                      for (var v in bindings) {
                          exec_env.bind(v, bindings[v]);
                      }
                  } else {
                      exec_env = environment;
                  }
                  // put the input document into the environment as the root object
                  exec_env.bind('$', input);
  
                  // capture the timestamp and put it in the execution environment
                  // the $now() and $millis() functions will return this value - whenever it is called
                  timestamp = new Date();
                  exec_env.timestamp = timestamp;
  
                  // if the input is a JSON array, then wrap it in a singleton sequence so it gets treated as a single input
                  if(Array.isArray(input) && !isSequence(input)) {
                      input = createSequence(input);
                      input.outerWrapper = true;
                  }
  
                  var result, it;
                  // if a callback function is supplied, then drive the generator in a promise chain
                  if(typeof callback === 'function') {
                      exec_env.async = true;
                      var catchHandler = function (err) {
                          populateMessage(err); // possible side-effects on `err`
                          callback(err, null);
                      };
                      var thenHandler = function (response) {
                          result = it.next(response);
                          if (result.done) {
                              callback(null, result.value);
                          } else {
                              result.value.then(thenHandler).catch(catchHandler);
                          }
                      };
                      it = evaluate(ast, input, exec_env);
                      result = it.next();
                      result.value.then(thenHandler).catch(catchHandler);
                  } else {
                      // no callback function - drive the generator to completion synchronously
                      try {
                          it = evaluate(ast, input, exec_env);
                          result = it.next();
                          while (!result.done) {
                              result = it.next(result.value);
                          }
                          return result.value;
                      } catch (err) {
                          // insert error message into structure
                          populateMessage(err); // possible side-effects on `err`
                          throw err;
                      }
                  }
              },
              assign: function (name, value) {
                  environment.bind(name, value);
              },
              registerFunction: function(name, implementation, signature) {
                  var func = defineFunction(implementation, signature);
                  environment.bind(name, func);
              },
              ast: function() {
                  return ast;
              },
              errors: function() {
                  return errors;
              }
          };
      }
  
      jsonata.parser = parser; // TODO remove this in a future release - use ast() instead
  
      return jsonata;
  
  })();
  
  module.exports = jsonata;
  
  },{"./datetime":1,"./functions":2,"./parser":4,"./signature":5,"./utils":6}],4:[function(require,module,exports){
  /**
   * © Copyright IBM Corp. 2016, 2018 All Rights Reserved
   *   Project name: JSONata
   *   This project is licensed under the MIT License, see LICENSE
   */
  
  var parseSignature = require('./signature');
  
  const parser = (() => {
      'use strict';
  
      var operators = {
          '.': 75,
          '[': 80,
          ']': 0,
          '{': 70,
          '}': 0,
          '(': 80,
          ')': 0,
          ',': 0,
          '@': 80,
          '#': 80,
          ';': 80,
          ':': 80,
          '?': 20,
          '+': 50,
          '-': 50,
          '*': 60,
          '/': 60,
          '%': 60,
          '|': 20,
          '=': 40,
          '<': 40,
          '>': 40,
          '^': 40,
          '**': 60,
          '..': 20,
          ':=': 10,
          '!=': 40,
          '<=': 40,
          '>=': 40,
          '~>': 40,
          'and': 30,
          'or': 25,
          'in': 40,
          '&': 50,
          '!': 0,   // not an operator, but needed as a stop character for name tokens
          '~': 0   // not an operator, but needed as a stop character for name tokens
      };
  
      var escapes = {  // JSON string escape sequences - see json.org
          '"': '"',
          '\\': '\\',
          '/': '/',
          'b': '\b',
          'f': '\f',
          'n': '\n',
          'r': '\r',
          't': '\t'
      };
  
      // Tokenizer (lexer) - invoked by the parser to return one token at a time
      var tokenizer = function (path) {
          var position = 0;
          var length = path.length;
  
          var create = function (type, value) {
              var obj = {type: type, value: value, position: position};
              return obj;
          };
  
          var scanRegex = function () {
              // the prefix '/' will have been previously scanned. Find the end of the regex.
              // search for closing '/' ignoring any that are escaped, or within brackets
              var start = position;
              var depth = 0;
              var pattern;
              var flags;
              while (position < length) {
                  var currentChar = path.charAt(position);
                  if (currentChar === '/' && path.charAt(position - 1) !== '\\' && depth === 0) {
                      // end of regex found
                      pattern = path.substring(start, position);
                      if (pattern === '') {
                          throw {
                              code: "S0301",
                              stack: (new Error()).stack,
                              position: position
                          };
                      }
                      position++;
                      currentChar = path.charAt(position);
                      // flags
                      start = position;
                      while (currentChar === 'i' || currentChar === 'm') {
                          position++;
                          currentChar = path.charAt(position);
                      }
                      flags = path.substring(start, position) + 'g';
                      return new RegExp(pattern, flags);
                  }
                  if ((currentChar === '(' || currentChar === '[' || currentChar === '{') && path.charAt(position - 1) !== '\\') {
                      depth++;
                  }
                  if ((currentChar === ')' || currentChar === ']' || currentChar === '}') && path.charAt(position - 1) !== '\\') {
                      depth--;
                  }
  
                  position++;
              }
              throw {
                  code: "S0302",
                  stack: (new Error()).stack,
                  position: position
              };
          };
  
          var next = function (prefix) {
              if (position >= length) return null;
              var currentChar = path.charAt(position);
              // skip whitespace
              while (position < length && ' \t\n\r\v'.indexOf(currentChar) > -1) {
                  position++;
                  currentChar = path.charAt(position);
              }
              // skip comments
              if (currentChar === '/' && path.charAt(position + 1) === '*') {
                  var commentStart = position;
                  position += 2;
                  currentChar = path.charAt(position);
                  while (!(currentChar === '*' && path.charAt(position + 1) === '/')) {
                      currentChar = path.charAt(++position);
                      if (position >= length) {
                          // no closing tag
                          throw {
                              code: "S0106",
                              stack: (new Error()).stack,
                              position: commentStart
                          };
                      }
                  }
                  position += 2;
                  currentChar = path.charAt(position);
                  return next(prefix); // need this to swallow any following whitespace
              }
              // test for regex
              if (prefix !== true && currentChar === '/') {
                  position++;
                  return create('regex', scanRegex());
              }
              // handle double-char operators
              if (currentChar === '.' && path.charAt(position + 1) === '.') {
                  // double-dot .. range operator
                  position += 2;
                  return create('operator', '..');
              }
              if (currentChar === ':' && path.charAt(position + 1) === '=') {
                  // := assignment
                  position += 2;
                  return create('operator', ':=');
              }
              if (currentChar === '!' && path.charAt(position + 1) === '=') {
                  // !=
                  position += 2;
                  return create('operator', '!=');
              }
              if (currentChar === '>' && path.charAt(position + 1) === '=') {
                  // >=
                  position += 2;
                  return create('operator', '>=');
              }
              if (currentChar === '<' && path.charAt(position + 1) === '=') {
                  // <=
                  position += 2;
                  return create('operator', '<=');
              }
              if (currentChar === '*' && path.charAt(position + 1) === '*') {
                  // **  descendant wildcard
                  position += 2;
                  return create('operator', '**');
              }
              if (currentChar === '~' && path.charAt(position + 1) === '>') {
                  // ~>  chain function
                  position += 2;
                  return create('operator', '~>');
              }
              // test for single char operators
              if (Object.prototype.hasOwnProperty.call(operators, currentChar)) {
                  position++;
                  return create('operator', currentChar);
              }
              // test for string literals
              if (currentChar === '"' || currentChar === "'") {
                  var quoteType = currentChar;
                  // double quoted string literal - find end of string
                  position++;
                  var qstr = "";
                  while (position < length) {
                      currentChar = path.charAt(position);
                      if (currentChar === '\\') { // escape sequence
                          position++;
                          currentChar = path.charAt(position);
                          if (Object.prototype.hasOwnProperty.call(escapes, currentChar)) {
                              qstr += escapes[currentChar];
                          } else if (currentChar === 'u') {
                              // \u should be followed by 4 hex digits
                              var octets = path.substr(position + 1, 4);
                              if (/^[0-9a-fA-F]+$/.test(octets)) {
                                  var codepoint = parseInt(octets, 16);
                                  qstr += String.fromCharCode(codepoint);
                                  position += 4;
                              } else {
                                  throw {
                                      code: "S0104",
                                      stack: (new Error()).stack,
                                      position: position
                                  };
                              }
                          } else {
                              // illegal escape sequence
                              throw {
                                  code: "S0103",
                                  stack: (new Error()).stack,
                                  position: position,
                                  token: currentChar
                              };
  
                          }
                      } else if (currentChar === quoteType) {
                          position++;
                          return create('string', qstr);
                      } else {
                          qstr += currentChar;
                      }
                      position++;
                  }
                  throw {
                      code: "S0101",
                      stack: (new Error()).stack,
                      position: position
                  };
              }
              // test for numbers
              var numregex = /^-?(0|([1-9][0-9]*))(\.[0-9]+)?([Ee][-+]?[0-9]+)?/;
              var match = numregex.exec(path.substring(position));
              if (match !== null) {
                  var num = parseFloat(match[0]);
                  if (!isNaN(num) && isFinite(num)) {
                      position += match[0].length;
                      return create('number', num);
                  } else {
                      throw {
                          code: "S0102",
                          stack: (new Error()).stack,
                          position: position,
                          token: match[0]
                      };
                  }
              }
              // test for quoted names (backticks)
              var name;
              if (currentChar === '`') {
                  // scan for closing quote
                  position++;
                  var end = path.indexOf('`', position);
                  if (end !== -1) {
                      name = path.substring(position, end);
                      position = end + 1;
                      return create('name', name);
                  }
                  position = length;
                  throw {
                      code: "S0105",
                      stack: (new Error()).stack,
                      position: position
                  };
              }
              // test for names
              var i = position;
              var ch;
              for (; ;) {
                  ch = path.charAt(i);
                  if (i === length || ' \t\n\r\v'.indexOf(ch) > -1 || Object.prototype.hasOwnProperty.call(operators, ch)) {
                      if (path.charAt(position) === '$') {
                          // variable reference
                          name = path.substring(position + 1, i);
                          position = i;
                          return create('variable', name);
                      } else {
                          name = path.substring(position, i);
                          position = i;
                          switch (name) {
                              case 'or':
                              case 'in':
                              case 'and':
                                  return create('operator', name);
                              case 'true':
                                  return create('value', true);
                              case 'false':
                                  return create('value', false);
                              case 'null':
                                  return create('value', null);
                              default:
                                  if (position === length && name === '') {
                                      // whitespace at end of input
                                      return null;
                                  }
                                  return create('name', name);
                          }
                      }
                  } else {
                      i++;
                  }
              }
          };
  
          return next;
      };
  
      // This parser implements the 'Top down operator precedence' algorithm developed by Vaughan R Pratt; http://dl.acm.org/citation.cfm?id=512931.
      // and builds on the Javascript framework described by Douglas Crockford at http://javascript.crockford.com/tdop/tdop.html
      // and in 'Beautiful Code', edited by Andy Oram and Greg Wilson, Copyright 2007 O'Reilly Media, Inc. 798-0-596-51004-6
  
      var parser = function (source, recover) {
          var node;
          var lexer;
  
          var symbol_table = {};
          var errors = [];
  
          var remainingTokens = function () {
              var remaining = [];
              if (node.id !== '(end)') {
                  remaining.push({type: node.type, value: node.value, position: node.position});
              }
              var nxt = lexer();
              while (nxt !== null) {
                  remaining.push(nxt);
                  nxt = lexer();
              }
              return remaining;
          };
  
          var base_symbol = {
              nud: function () {
                  // error - symbol has been invoked as a unary operator
                  var err = {
                      code: 'S0211',
                      token: this.value,
                      position: this.position
                  };
  
                  if (recover) {
                      err.remaining = remainingTokens();
                      err.type = 'error';
                      errors.push(err);
                      return err;
                  } else {
                      err.stack = (new Error()).stack;
                      throw err;
                  }
              }
          };
  
          var symbol = function (id, bp) {
              var s = symbol_table[id];
              bp = bp || 0;
              if (s) {
                  if (bp >= s.lbp) {
                      s.lbp = bp;
                  }
              } else {
                  s = Object.create(base_symbol);
                  s.id = s.value = id;
                  s.lbp = bp;
                  symbol_table[id] = s;
              }
              return s;
          };
  
          var handleError = function (err) {
              if (recover) {
                  // tokenize the rest of the buffer and add it to an error token
                  err.remaining = remainingTokens();
                  errors.push(err);
                  var symbol = symbol_table["(error)"];
                  node = Object.create(symbol);
                  node.error = err;
                  node.type = "(error)";
                  return node;
              } else {
                  err.stack = (new Error()).stack;
                  throw err;
              }
          };
  
          var advance = function (id, infix) {
              if (id && node.id !== id) {
                  var code;
                  if (node.id === '(end)') {
                      // unexpected end of buffer
                      code = "S0203";
                  } else {
                      code = "S0202";
                  }
                  var err = {
                      code: code,
                      position: node.position,
                      token: node.value,
                      value: id
                  };
                  return handleError(err);
              }
              var next_token = lexer(infix);
              if (next_token === null) {
                  node = symbol_table["(end)"];
                  node.position = source.length;
                  return node;
              }
              var value = next_token.value;
              var type = next_token.type;
              var symbol;
              switch (type) {
                  case 'name':
                  case 'variable':
                      symbol = symbol_table["(name)"];
                      break;
                  case 'operator':
                      symbol = symbol_table[value];
                      if (!symbol) {
                          return handleError({
                              code: "S0204",
                              stack: (new Error()).stack,
                              position: next_token.position,
                              token: value
                          });
                      }
                      break;
                  case 'string':
                  case 'number':
                  case 'value':
                      symbol = symbol_table["(literal)"];
                      break;
                  case 'regex':
                      type = "regex";
                      symbol = symbol_table["(regex)"];
                      break;
                  /* istanbul ignore next */
                  default:
                      return handleError({
                          code: "S0205",
                          stack: (new Error()).stack,
                          position: next_token.position,
                          token: value
                      });
              }
  
              node = Object.create(symbol);
              node.value = value;
              node.type = type;
              node.position = next_token.position;
              return node;
          };
  
          // Pratt's algorithm
          var expression = function (rbp) {
              var left;
              var t = node;
              advance(null, true);
              left = t.nud();
              while (rbp < node.lbp) {
                  t = node;
                  advance();
                  left = t.led(left);
              }
              return left;
          };
  
          var terminal = function (id) {
              var s = symbol(id, 0);
              s.nud = function () {
                  return this;
              };
          };
  
          // match infix operators
          // <expression> <operator> <expression>
          // left associative
          var infix = function (id, bp, led) {
              var bindingPower = bp || operators[id];
              var s = symbol(id, bindingPower);
              s.led = led || function (left) {
                  this.lhs = left;
                  this.rhs = expression(bindingPower);
                  this.type = "binary";
                  return this;
              };
              return s;
          };
  
          // match infix operators
          // <expression> <operator> <expression>
          // right associative
          var infixr = function (id, bp, led) {
              var s = symbol(id, bp);
              s.led = led;
              return s;
          };
  
          // match prefix operators
          // <operator> <expression>
          var prefix = function (id, nud) {
              var s = symbol(id);
              s.nud = nud || function () {
                  this.expression = expression(70);
                  this.type = "unary";
                  return this;
              };
              return s;
          };
  
          terminal("(end)");
          terminal("(name)");
          terminal("(literal)");
          terminal("(regex)");
          symbol(":");
          symbol(";");
          symbol(",");
          symbol(")");
          symbol("]");
          symbol("}");
          symbol(".."); // range operator
          infix("."); // map operator
          infix("+"); // numeric addition
          infix("-"); // numeric subtraction
          infix("*"); // numeric multiplication
          infix("/"); // numeric division
          infix("%"); // numeric modulus
          infix("="); // equality
          infix("<"); // less than
          infix(">"); // greater than
          infix("!="); // not equal to
          infix("<="); // less than or equal
          infix(">="); // greater than or equal
          infix("&"); // string concatenation
          infix("and"); // Boolean AND
          infix("or"); // Boolean OR
          infix("in"); // is member of array
          terminal("and"); // the 'keywords' can also be used as terminals (field names)
          terminal("or"); //
          terminal("in"); //
          prefix("-"); // unary numeric negation
          infix("~>"); // function application
  
          infixr("(error)", 10, function (left) {
              this.lhs = left;
  
              this.error = node.error;
              this.remaining = remainingTokens();
              this.type = 'error';
              return this;
          });
  
          // field wildcard (single level)
          prefix('*', function () {
              this.type = "wildcard";
              return this;
          });
  
          // descendant wildcard (multi-level)
          prefix('**', function () {
              this.type = "descendant";
              return this;
          });
  
          // parent operator
          prefix('%', function () {
              this.type = "parent";
              return this;
          });
  
          // function invocation
          infix("(", operators['('], function (left) {
              // left is is what we are trying to invoke
              this.procedure = left;
              this.type = 'function';
              this.arguments = [];
              if (node.id !== ')') {
                  for (; ;) {
                      if (node.type === 'operator' && node.id === '?') {
                          // partial function application
                          this.type = 'partial';
                          this.arguments.push(node);
                          advance('?');
                      } else {
                          this.arguments.push(expression(0));
                      }
                      if (node.id !== ',') break;
                      advance(',');
                  }
              }
              advance(")", true);
              // if the name of the function is 'function' or λ, then this is function definition (lambda function)
              if (left.type === 'name' && (left.value === 'function' || left.value === '\u03BB')) {
                  // all of the args must be VARIABLE tokens
                  this.arguments.forEach(function (arg, index) {
                      if (arg.type !== 'variable') {
                          return handleError({
                              code: "S0208",
                              stack: (new Error()).stack,
                              position: arg.position,
                              token: arg.value,
                              value: index + 1
                          });
                      }
                  });
                  this.type = 'lambda';
                  // is the next token a '<' - if so, parse the function signature
                  if (node.id === '<') {
                      var sigPos = node.position;
                      var depth = 1;
                      var sig = '<';
                      while (depth > 0 && node.id !== '{' && node.id !== '(end)') {
                          var tok = advance();
                          if (tok.id === '>') {
                              depth--;
                          } else if (tok.id === '<') {
                              depth++;
                          }
                          sig += tok.value;
                      }
                      advance('>');
                      try {
                          this.signature = parseSignature(sig);
                      } catch (err) {
                          // insert the position into this error
                          err.position = sigPos + err.offset;
                          return handleError(err);
                      }
                  }
                  // parse the function body
                  advance('{');
                  this.body = expression(0);
                  advance('}');
              }
              return this;
          });
  
          // parenthesis - block expression
          prefix("(", function () {
              var expressions = [];
              while (node.id !== ")") {
                  expressions.push(expression(0));
                  if (node.id !== ";") {
                      break;
                  }
                  advance(";");
              }
              advance(")", true);
              this.type = 'block';
              this.expressions = expressions;
              return this;
          });
  
          // array constructor
          prefix("[", function () {
              var a = [];
              if (node.id !== "]") {
                  for (; ;) {
                      var item = expression(0);
                      if (node.id === "..") {
                          // range operator
                          var range = {type: "binary", value: "..", position: node.position, lhs: item};
                          advance("..");
                          range.rhs = expression(0);
                          item = range;
                      }
                      a.push(item);
                      if (node.id !== ",") {
                          break;
                      }
                      advance(",");
                  }
              }
              advance("]", true);
              this.expressions = a;
              this.type = "unary";
              return this;
          });
  
          // filter - predicate or array index
          infix("[", operators['['], function (left) {
              if (node.id === "]") {
                  // empty predicate means maintain singleton arrays in the output
                  var step = left;
                  while (step && step.type === 'binary' && step.value === '[') {
                      step = step.lhs;
                  }
                  step.keepArray = true;
                  advance("]");
                  return left;
              } else {
                  this.lhs = left;
                  this.rhs = expression(operators[']']);
                  this.type = 'binary';
                  advance("]", true);
                  return this;
              }
          });
  
          // order-by
          infix("^", operators['^'], function (left) {
              advance("(");
              var terms = [];
              for (; ;) {
                  var term = {
                      descending: false
                  };
                  if (node.id === "<") {
                      // ascending sort
                      advance("<");
                  } else if (node.id === ">") {
                      // descending sort
                      term.descending = true;
                      advance(">");
                  } else {
                      //unspecified - default to ascending
                  }
                  term.expression = expression(0);
                  terms.push(term);
                  if (node.id !== ",") {
                      break;
                  }
                  advance(",");
              }
              advance(")");
              this.lhs = left;
              this.rhs = terms;
              this.type = 'binary';
              return this;
          });
  
          var objectParser = function (left) {
              var a = [];
              if (node.id !== "}") {
                  for (; ;) {
                      var n = expression(0);
                      advance(":");
                      var v = expression(0);
                      a.push([n, v]); // holds an array of name/value expression pairs
                      if (node.id !== ",") {
                          break;
                      }
                      advance(",");
                  }
              }
              advance("}", true);
              if (typeof left === 'undefined') {
                  // NUD - unary prefix form
                  this.lhs = a;
                  this.type = "unary";
              } else {
                  // LED - binary infix form
                  this.lhs = left;
                  this.rhs = a;
                  this.type = 'binary';
              }
              return this;
          };
  
          // object constructor
          prefix("{", objectParser);
  
          // object grouping
          infix("{", operators['{'], objectParser);
  
          // bind variable
          infixr(":=", operators[':='], function (left) {
              if (left.type !== 'variable') {
                  return handleError({
                      code: "S0212",
                      stack: (new Error()).stack,
                      position: left.position,
                      token: left.value
                  });
              }
              this.lhs = left;
              this.rhs = expression(operators[':='] - 1); // subtract 1 from bindingPower for right associative operators
              this.type = "binary";
              return this;
          });
  
          // focus variable bind
          infix("@", operators['@'], function (left) {
              this.lhs = left;
              this.rhs = expression(operators['@']);
              if(this.rhs.type !== 'variable') {
                  return handleError({
                      code: "S0214",
                      stack: (new Error()).stack,
                      position: this.rhs.position,
                      token: "@"
                  });
              }
              this.type = "binary";
              return this;
          });
  
          // index (position) variable bind
          infix("#", operators['#'], function (left) {
              this.lhs = left;
              this.rhs = expression(operators['#']);
              if(this.rhs.type !== 'variable') {
                  return handleError({
                      code: "S0214",
                      stack: (new Error()).stack,
                      position: this.rhs.position,
                      token: "#"
                  });
              }
              this.type = "binary";
              return this;
          });
  
          // if/then/else ternary operator ?:
          infix("?", operators['?'], function (left) {
              this.type = 'condition';
              this.condition = left;
              this.then = expression(0);
              if (node.id === ':') {
                  // else condition
                  advance(":");
                  this.else = expression(0);
              }
              return this;
          });
  
          // object transformer
          prefix("|", function () {
              this.type = 'transform';
              this.pattern = expression(0);
              advance('|');
              this.update = expression(0);
              if (node.id === ',') {
                  advance(',');
                  this.delete = expression(0);
              }
              advance('|');
              return this;
          });
  
          // tail call optimization
          // this is invoked by the post parser to analyse lambda functions to see
          // if they make a tail call.  If so, it is replaced by a thunk which will
          // be invoked by the trampoline loop during function application.
          // This enables tail-recursive functions to be written without growing the stack
          var tailCallOptimize = function (expr) {
              var result;
              if (expr.type === 'function' && !expr.predicate) {
                  var thunk = {type: 'lambda', thunk: true, arguments: [], position: expr.position};
                  thunk.body = expr;
                  result = thunk;
              } else if (expr.type === 'condition') {
                  // analyse both branches
                  expr.then = tailCallOptimize(expr.then);
                  if (typeof expr.else !== 'undefined') {
                      expr.else = tailCallOptimize(expr.else);
                  }
                  result = expr;
              } else if (expr.type === 'block') {
                  // only the last expression in the block
                  var length = expr.expressions.length;
                  if (length > 0) {
                      expr.expressions[length - 1] = tailCallOptimize(expr.expressions[length - 1]);
                  }
                  result = expr;
              } else {
                  result = expr;
              }
              return result;
          };
  
          var ancestorLabel = 0;
          var ancestorIndex = 0;
          var ancestry = [];
  
          var seekParent = function (node, slot) {
              switch (node.type) {
                  case 'name':
                  case 'wildcard':
                      slot.level--;
                      if(slot.level === 0) {
                          if (typeof node.ancestor === 'undefined') {
                              node.ancestor = slot;
                          } else {
                              // reuse the existing label
                              ancestry[slot.index].slot.label = node.ancestor.label;
                              node.ancestor = slot;
                          }
                          node.tuple = true;
                      }
                      break;
                  case 'parent':
                      slot.level++;
                      break;
                  case 'block':
                      // look in last expression in the block
                      if(node.expressions.length > 0) {
                          node.tuple = true;
                          slot = seekParent(node.expressions[node.expressions.length - 1], slot);
                      }
                      break;
                  case 'path':
                      // last step in path
                      node.tuple = true;
                      var index = node.steps.length - 1;
                      slot = seekParent(node.steps[index--], slot);
                      while (slot.level > 0 && index >= 0) {
                          // check previous steps
                          slot = seekParent(node.steps[index--], slot);
                      }
                      break;
                  default:
                      // error - can't derive ancestor
                      throw {
                          code: "S0217",
                          token: node.type,
                          position: node.position
                      };
              }
              return slot;
          };
  
          var pushAncestry = function(result, value) {
              if(typeof value.seekingParent !== 'undefined' || value.type === 'parent') {
                  var slots = (typeof value.seekingParent !== 'undefined') ? value.seekingParent : [];
                  if (value.type === 'parent') {
                      slots.push(value.slot);
                  }
                  if(typeof result.seekingParent === 'undefined') {
                      result.seekingParent = slots;
                  } else {
                      Array.prototype.push.apply(result.seekingParent, slots);
                  }
              }
          };
  
          var resolveAncestry = function(path) {
              var index = path.steps.length - 1;
              var laststep = path.steps[index];
              var slots = (typeof laststep.seekingParent !== 'undefined') ? laststep.seekingParent : [];
              if (laststep.type === 'parent') {
                  slots.push(laststep.slot);
              }
              for(var is = 0; is < slots.length; is++) {
                  var slot = slots[is];
                  index = path.steps.length - 2;
                  while (slot.level > 0) {
                      if (index < 0) {
                          if(typeof path.seekingParent === 'undefined') {
                              path.seekingParent = [slot];
                          } else {
                              path.seekingParent.push(slot);
                          }
                          break;
                      }
                      // try previous step
                      var step = path.steps[index--];
                      // multiple contiguous steps that bind the focus should be skipped
                      while(index >= 0 && step.focus && path.steps[index].focus) {
                          step = path.steps[index--];
                      }
                      slot = seekParent(step, slot);
                  }
              }
          };
  
          // post-parse stage
          // the purpose of this is to add as much semantic value to the parse tree as possible
          // in order to simplify the work of the evaluator.
          // This includes flattening the parts of the AST representing location paths,
          // converting them to arrays of steps which in turn may contain arrays of predicates.
          // following this, nodes containing '.' and '[' should be eliminated from the AST.
          var processAST = function (expr) {
              var result;
              switch (expr.type) {
                  case 'binary':
                      switch (expr.value) {
                          case '.':
                              var lstep = processAST(expr.lhs);
  
                              if (lstep.type === 'path') {
                                  result = lstep;
                              } else {
                                  result = {type: 'path', steps: [lstep]};
                              }
                              if(lstep.type === 'parent') {
                                  result.seekingParent = [lstep.slot];
                              }
                              var rest = processAST(expr.rhs);
                              if (rest.type === 'function' &&
                                  rest.procedure.type === 'path' &&
                                  rest.procedure.steps.length === 1 &&
                                  rest.procedure.steps[0].type === 'name' &&
                                  result.steps[result.steps.length - 1].type === 'function') {
                                  // next function in chain of functions - will override a thenable
                                  result.steps[result.steps.length - 1].nextFunction = rest.procedure.steps[0].value;
                              }
                              if (rest.type === 'path') {
                                  Array.prototype.push.apply(result.steps, rest.steps);
                              } else {
                                  if(typeof rest.predicate !== 'undefined') {
                                      rest.stages = rest.predicate;
                                      delete rest.predicate;
                                  }
                                  result.steps.push(rest);
                              }
                              // any steps within a path that are string literals, should be changed to 'name'
                              result.steps.filter(function (step) {
                                  if (step.type === 'number' || step.type === 'value') {
                                      // don't allow steps to be numbers or the values true/false/null
                                      throw {
                                          code: "S0213",
                                          stack: (new Error()).stack,
                                          position: step.position,
                                          value: step.value
                                      };
                                  }
                                  return step.type === 'string';
                              }).forEach(function (lit) {
                                  lit.type = 'name';
                              });
                              // any step that signals keeping a singleton array, should be flagged on the path
                              if (result.steps.filter(function (step) {
                                  return step.keepArray === true;
                              }).length > 0) {
                                  result.keepSingletonArray = true;
                              }
                              // if first step is a path constructor, flag it for special handling
                              var firststep = result.steps[0];
                              if (firststep.type === 'unary' && firststep.value === '[') {
                                  firststep.consarray = true;
                              }
                              // if the last step is an array constructor, flag it so it doesn't flatten
                              var laststep = result.steps[result.steps.length - 1];
                              if (laststep.type === 'unary' && laststep.value === '[') {
                                  laststep.consarray = true;
                              }
                              resolveAncestry(result);
                              break;
                          case '[':
                              // predicated step
                              // LHS is a step or a predicated step
                              // RHS is the predicate expr
                              result = processAST(expr.lhs);
                              var step = result;
                              var type = 'predicate';
                              if (result.type === 'path') {
                                  step = result.steps[result.steps.length - 1];
                                  type = 'stages';
                              }
                              if (typeof step.group !== 'undefined') {
                                  throw {
                                      code: "S0209",
                                      stack: (new Error()).stack,
                                      position: expr.position
                                  };
                              }
                              if (typeof step[type] === 'undefined') {
                                  step[type] = [];
                              }
                              var predicate = processAST(expr.rhs);
                              if(typeof predicate.seekingParent !== 'undefined') {
                                  predicate.seekingParent.forEach(slot => {
                                      if(slot.level === 1) {
                                          seekParent(step, slot);
                                      } else {
                                          slot.level--;
                                      }
                                  });
                                  pushAncestry(step, predicate);
                              }
                              step[type].push({type: 'filter', expr: predicate, position: expr.position});
                              break;
                          case '{':
                              // group-by
                              // LHS is a step or a predicated step
                              // RHS is the object constructor expr
                              result = processAST(expr.lhs);
                              if (typeof result.group !== 'undefined') {
                                  throw {
                                      code: "S0210",
                                      stack: (new Error()).stack,
                                      position: expr.position
                                  };
                              }
                              // object constructor - process each pair
                              result.group = {
                                  lhs: expr.rhs.map(function (pair) {
                                      return [processAST(pair[0]), processAST(pair[1])];
                                  }),
                                  position: expr.position
                              };
                              break;
                          case '^':
                              // order-by
                              // LHS is the array to be ordered
                              // RHS defines the terms
                              result = processAST(expr.lhs);
                              if (result.type !== 'path') {
                                  result = {type: 'path', steps: [result]};
                              }
                              var sortStep = {type: 'sort', position: expr.position};
                              sortStep.terms = expr.rhs.map(function (terms) {
                                  var expression = processAST(terms.expression);
                                  pushAncestry(sortStep, expression);
                                  return {
                                      descending: terms.descending,
                                      expression: expression
                                  };
                              });
                              result.steps.push(sortStep);
                              resolveAncestry(result);
                              break;
                          case ':=':
                              result = {type: 'bind', value: expr.value, position: expr.position};
                              result.lhs = processAST(expr.lhs);
                              result.rhs = processAST(expr.rhs);
                              pushAncestry(result, result.rhs);
                              break;
                          case '@':
                              result = processAST(expr.lhs);
                              step = result;
                              if (result.type === 'path') {
                                  step = result.steps[result.steps.length - 1];
                              }
                              // throw error if there are any predicates defined at this point
                              // at this point the only type of stages can be predicates
                              if(typeof step.stages !== 'undefined' || typeof step.predicate !== 'undefined') {
                                  throw {
                                      code: "S0215",
                                      stack: (new Error()).stack,
                                      position: expr.position
                                  };
                              }
                              // also throw if this is applied after an 'order-by' clause
                              if(step.type === 'sort') {
                                  throw {
                                      code: "S0216",
                                      stack: (new Error()).stack,
                                      position: expr.position
                                  };
                              }
                              if(expr.keepArray) {
                                  step.keepArray = true;
                              }
                              step.focus = expr.rhs.value;
                              step.tuple = true;
                              break;
                          case '#':
                              result = processAST(expr.lhs);
                              step = result;
                              if (result.type === 'path') {
                                  step = result.steps[result.steps.length - 1];
                              } else {
                                  result = {type: 'path', steps: [result]};
                                  if (typeof step.predicate !== 'undefined') {
                                      step.stages = step.predicate;
                                      delete step.predicate;
                                  }
                              }
                              if (typeof step.stages === 'undefined') {
                                  step.index = expr.rhs.value;
                              } else {
                                  step.stages.push({type: 'index', value: expr.rhs.value, position: expr.position});
                              }
                              step.tuple = true;
                              break;
                          case '~>':
                              result = {type: 'apply', value: expr.value, position: expr.position};
                              result.lhs = processAST(expr.lhs);
                              result.rhs = processAST(expr.rhs);
                              break;
                          default:
                              result = {type: expr.type, value: expr.value, position: expr.position};
                              result.lhs = processAST(expr.lhs);
                              result.rhs = processAST(expr.rhs);
                              pushAncestry(result, result.lhs);
                              pushAncestry(result, result.rhs);
                      }
                      break;
                  case 'unary':
                      result = {type: expr.type, value: expr.value, position: expr.position};
                      if (expr.value === '[') {
                          // array constructor - process each item
                          result.expressions = expr.expressions.map(function (item) {
                              var value = processAST(item);
                              pushAncestry(result, value);
                              return value;
                          });
                      } else if (expr.value === '{') {
                          // object constructor - process each pair
                          result.lhs = expr.lhs.map(function (pair) {
                              var key = processAST(pair[0]);
                              pushAncestry(result, key);
                              var value = processAST(pair[1]);
                              pushAncestry(result, value);
                              return [key, value];
                          });
                      } else {
                          // all other unary expressions - just process the expression
                          result.expression = processAST(expr.expression);
                          // if unary minus on a number, then pre-process
                          if (expr.value === '-' && result.expression.type === 'number') {
                              result = result.expression;
                              result.value = -result.value;
                          } else {
                              pushAncestry(result, result.expression);
                          }
                      }
                      break;
                  case 'function':
                  case 'partial':
                      result = {type: expr.type, name: expr.name, value: expr.value, position: expr.position};
                      result.arguments = expr.arguments.map(function (arg) {
                          var argAST = processAST(arg);
                          pushAncestry(result, argAST);
                          return argAST;
                      });
                      result.procedure = processAST(expr.procedure);
                      break;
                  case 'lambda':
                      result = {
                          type: expr.type,
                          arguments: expr.arguments,
                          signature: expr.signature,
                          position: expr.position
                      };
                      var body = processAST(expr.body);
                      result.body = tailCallOptimize(body);
                      break;
                  case 'condition':
                      result = {type: expr.type, position: expr.position};
                      result.condition = processAST(expr.condition);
                      pushAncestry(result, result.condition);
                      result.then = processAST(expr.then);
                      pushAncestry(result, result.then);
                      if (typeof expr.else !== 'undefined') {
                          result.else = processAST(expr.else);
                          pushAncestry(result, result.else);
                      }
                      break;
                  case 'transform':
                      result = {type: expr.type, position: expr.position};
                      result.pattern = processAST(expr.pattern);
                      result.update = processAST(expr.update);
                      if (typeof expr.delete !== 'undefined') {
                          result.delete = processAST(expr.delete);
                      }
                      break;
                  case 'block':
                      result = {type: expr.type, position: expr.position};
                      // array of expressions - process each one
                      result.expressions = expr.expressions.map(function (item) {
                          var part = processAST(item);
                          pushAncestry(result, part);
                          if (part.consarray || (part.type === 'path' && part.steps[0].consarray)) {
                              result.consarray = true;
                          }
                          return part;
                      });
                      // TODO scan the array of expressions to see if any of them assign variables
                      // if so, need to mark the block as one that needs to create a new frame
                      break;
                  case 'name':
                      result = {type: 'path', steps: [expr]};
                      if (expr.keepArray) {
                          result.keepSingletonArray = true;
                      }
                      break;
                  case 'parent':
                      result = {type: 'parent', slot: { label: '!' + ancestorLabel++, level: 1, index: ancestorIndex++ } };
                      ancestry.push(result);
                      break;
                  case 'string':
                  case 'number':
                  case 'value':
                  case 'wildcard':
                  case 'descendant':
                  case 'variable':
                  case 'regex':
                      result = expr;
                      break;
                  case 'operator':
                      // the tokens 'and' and 'or' might have been used as a name rather than an operator
                      if (expr.value === 'and' || expr.value === 'or' || expr.value === 'in') {
                          expr.type = 'name';
                          result = processAST(expr);
                      } else /* istanbul ignore else */ if (expr.value === '?') {
                          // partial application
                          result = expr;
                      } else {
                          throw {
                              code: "S0201",
                              stack: (new Error()).stack,
                              position: expr.position,
                              token: expr.value
                          };
                      }
                      break;
                  case 'error':
                      result = expr;
                      if (expr.lhs) {
                          result = processAST(expr.lhs);
                      }
                      break;
                  default:
                      var code = "S0206";
                      /* istanbul ignore else */
                      if (expr.id === '(end)') {
                          code = "S0207";
                      }
                      var err = {
                          code: code,
                          position: expr.position,
                          token: expr.value
                      };
                      if (recover) {
                          errors.push(err);
                          return {type: 'error', error: err};
                      } else {
                          err.stack = (new Error()).stack;
                          throw err;
                      }
              }
              if (expr.keepArray) {
                  result.keepArray = true;
              }
              return result;
          };
  
          // now invoke the tokenizer and the parser and return the syntax tree
          lexer = tokenizer(source);
          advance();
          // parse the tokens
          var expr = expression(0);
          if (node.id !== '(end)') {
              var err = {
                  code: "S0201",
                  position: node.position,
                  token: node.value
              };
              handleError(err);
          }
          expr = processAST(expr);
  
          if(expr.type === 'parent' || typeof expr.seekingParent !== 'undefined') {
              // error - trying to derive ancestor at top level
              throw {
                  code: "S0217",
                  token: expr.type,
                  position: expr.position
              };
          }
  
          if (errors.length > 0) {
              expr.errors = errors;
          }
  
          return expr;
      };
  
      return parser;
  })();
  
  module.exports = parser;
  
  },{"./signature":5}],5:[function(require,module,exports){
  /**
   * © Copyright IBM Corp. 2016, 2018 All Rights Reserved
   *   Project name: JSONata
   *   This project is licensed under the MIT License, see LICENSE
   */
  
  var utils = require('./utils');
  
  const signature = (() => {
      'use strict';
  
      // A mapping between the function signature symbols and the full plural of the type
      // Expected to be used in error messages
      var arraySignatureMapping = {
          "a": "arrays",
          "b": "booleans",
          "f": "functions",
          "n": "numbers",
          "o": "objects",
          "s": "strings"
      };
  
      /**
       * Parses a function signature definition and returns a validation function
       * @param {string} signature - the signature between the <angle brackets>
       * @returns {Function} validation function
       */
      function parseSignature(signature) {
          // create a Regex that represents this signature and return a function that when invoked,
          // returns the validated (possibly fixed-up) arguments, or throws a validation error
          // step through the signature, one symbol at a time
          var position = 1;
          var params = [];
          var param = {};
          var prevParam = param;
          while (position < signature.length) {
              var symbol = signature.charAt(position);
              if (symbol === ':') {
                  // TODO figure out what to do with the return type
                  // ignore it for now
                  break;
              }
  
              var next = function () {
                  params.push(param);
                  prevParam = param;
                  param = {};
              };
  
              var findClosingBracket = function (str, start, openSymbol, closeSymbol) {
                  // returns the position of the closing symbol (e.g. bracket) in a string
                  // that balances the opening symbol at position start
                  var depth = 1;
                  var position = start;
                  while (position < str.length) {
                      position++;
                      symbol = str.charAt(position);
                      if (symbol === closeSymbol) {
                          depth--;
                          if (depth === 0) {
                              // we're done
                              break; // out of while loop
                          }
                      } else if (symbol === openSymbol) {
                          depth++;
                      }
                  }
                  return position;
              };
  
              switch (symbol) {
                  case 's': // string
                  case 'n': // number
                  case 'b': // boolean
                  case 'l': // not so sure about expecting null?
                  case 'o': // object
                      param.regex = '[' + symbol + 'm]';
                      param.type = symbol;
                      next();
                      break;
                  case 'a': // array
                      //  normally treat any value as singleton array
                      param.regex = '[asnblfom]';
                      param.type = symbol;
                      param.array = true;
                      next();
                      break;
                  case 'f': // function
                      param.regex = 'f';
                      param.type = symbol;
                      next();
                      break;
                  case 'j': // any JSON type
                      param.regex = '[asnblom]';
                      param.type = symbol;
                      next();
                      break;
                  case 'x': // any type
                      param.regex = '[asnblfom]';
                      param.type = symbol;
                      next();
                      break;
                  case '-': // use context if param not supplied
                      prevParam.context = true;
                      prevParam.contextRegex = new RegExp(prevParam.regex); // pre-compiled to test the context type at runtime
                      prevParam.regex += '?';
                      break;
                  case '?': // optional param
                  case '+': // one or more
                      prevParam.regex += symbol;
                      break;
                  case '(': // choice of types
                      // search forward for matching ')'
                      var endParen = findClosingBracket(signature, position, '(', ')');
                      var choice = signature.substring(position + 1, endParen);
                      if (choice.indexOf('<') === -1) {
                          // no parameterized types, simple regex
                          param.regex = '[' + choice + 'm]';
                      } else {
                          // TODO harder
                          throw {
                              code: "S0402",
                              stack: (new Error()).stack,
                              value: choice,
                              offset: position
                          };
                      }
                      param.type = '(' + choice + ')';
                      position = endParen;
                      next();
                      break;
                  case '<': // type parameter - can only be applied to 'a' and 'f'
                      if (prevParam.type === 'a' || prevParam.type === 'f') {
                          // search forward for matching '>'
                          var endPos = findClosingBracket(signature, position, '<', '>');
                          prevParam.subtype = signature.substring(position + 1, endPos);
                          position = endPos;
                      } else {
                          throw {
                              code: "S0401",
                              stack: (new Error()).stack,
                              value: prevParam.type,
                              offset: position
                          };
                      }
                      break;
              }
              position++;
          }
          var regexStr = '^' +
              params.map(function (param) {
                  return '(' + param.regex + ')';
              }).join('') +
              '$';
          var regex = new RegExp(regexStr);
          var getSymbol = function (value) {
              var symbol;
              if (utils.isFunction(value)) {
                  symbol = 'f';
              } else {
                  var type = typeof value;
                  switch (type) {
                      case 'string':
                          symbol = 's';
                          break;
                      case 'number':
                          symbol = 'n';
                          break;
                      case 'boolean':
                          symbol = 'b';
                          break;
                      case 'object':
                          if (value === null) {
                              symbol = 'l';
                          } else if (Array.isArray(value)) {
                              symbol = 'a';
                          } else {
                              symbol = 'o';
                          }
                          break;
                      case 'undefined':
                      default:
                          // any value can be undefined, but should be allowed to match
                          symbol = 'm'; // m for missing
                  }
              }
              return symbol;
          };
  
          var throwValidationError = function (badArgs, badSig) {
              // to figure out where this went wrong we need apply each component of the
              // regex to each argument until we get to the one that fails to match
              var partialPattern = '^';
              var goodTo = 0;
              for (var index = 0; index < params.length; index++) {
                  partialPattern += params[index].regex;
                  var match = badSig.match(partialPattern);
                  if (match === null) {
                      // failed here
                      throw {
                          code: "T0410",
                          stack: (new Error()).stack,
                          value: badArgs[goodTo],
                          index: goodTo + 1
                      };
                  }
                  goodTo = match[0].length;
              }
              // if it got this far, it's probably because of extraneous arguments (we
              // haven't added the trailing '$' in the regex yet.
              throw {
                  code: "T0410",
                  stack: (new Error()).stack,
                  value: badArgs[goodTo],
                  index: goodTo + 1
              };
          };
  
          return {
              definition: signature,
              validate: function (args, context) {
                  var suppliedSig = '';
                  args.forEach(function (arg) {
                      suppliedSig += getSymbol(arg);
                  });
                  var isValid = regex.exec(suppliedSig);
                  if (isValid) {
                      var validatedArgs = [];
                      var argIndex = 0;
                      params.forEach(function (param, index) {
                          var arg = args[argIndex];
                          var match = isValid[index + 1];
                          if (match === '') {
                              if (param.context && param.contextRegex) {
                                  // substitute context value for missing arg
                                  // first check that the context value is the right type
                                  var contextType = getSymbol(context);
                                  // test contextType against the regex for this arg (without the trailing ?)
                                  if (param.contextRegex.test(contextType)) {
                                      validatedArgs.push(context);
                                  } else {
                                      // context value not compatible with this argument
                                      throw {
                                          code: "T0411",
                                          stack: (new Error()).stack,
                                          value: context,
                                          index: argIndex + 1
                                      };
                                  }
                              } else {
                                  validatedArgs.push(arg);
                                  argIndex++;
                              }
                          } else {
                              // may have matched multiple args (if the regex ends with a '+'
                              // split into single tokens
                              match.split('').forEach(function (single) {
                                  if (param.type === 'a') {
                                      if (single === 'm') {
                                          // missing (undefined)
                                          arg = undefined;
                                      } else {
                                          arg = args[argIndex];
                                          var arrayOK = true;
                                          // is there type information on the contents of the array?
                                          if (typeof param.subtype !== 'undefined') {
                                              if (single !== 'a' && match !== param.subtype) {
                                                  arrayOK = false;
                                              } else if (single === 'a') {
                                                  if (arg.length > 0) {
                                                      var itemType = getSymbol(arg[0]);
                                                      if (itemType !== param.subtype.charAt(0)) { // TODO recurse further
                                                          arrayOK = false;
                                                      } else {
                                                          // make sure every item in the array is this type
                                                          var differentItems = arg.filter(function (val) {
                                                              return (getSymbol(val) !== itemType);
                                                          });
                                                          arrayOK = (differentItems.length === 0);
                                                      }
                                                  }
                                              }
                                          }
                                          if (!arrayOK) {
                                              throw {
                                                  code: "T0412",
                                                  stack: (new Error()).stack,
                                                  value: arg,
                                                  index: argIndex + 1,
                                                  type: arraySignatureMapping[param.subtype]
                                              };
                                          }
                                          // the function expects an array. If it's not one, make it so
                                          if (single !== 'a') {
                                              arg = [arg];
                                          }
                                      }
                                      validatedArgs.push(arg);
                                      argIndex++;
                                  } else {
                                      validatedArgs.push(arg);
                                      argIndex++;
                                  }
                              });
                          }
                      });
                      return validatedArgs;
                  }
                  throwValidationError(args, suppliedSig);
              }
          };
      }
  
      return parseSignature;
  })();
  
  module.exports = signature;
  
  },{"./utils":6}],6:[function(require,module,exports){
  /**
   * © Copyright IBM Corp. 2016, 2018 All Rights Reserved
   *   Project name: JSONata
   *   This project is licensed under the MIT License, see LICENSE
   */
  
  const utils = (() => {
      'use strict';
  
      /**
       * Check if value is a finite number
       * @param {float} n - number to evaluate
       * @returns {boolean} True if n is a finite number
       */
      function isNumeric(n) {
          var isNum = false;
          if(typeof n === 'number') {
              isNum = !isNaN(n);
              if (isNum && !isFinite(n)) {
                  throw {
                      code: "D1001",
                      value: n,
                      stack: (new Error()).stack
                  };
              }
          }
          return isNum;
      }
  
      /**
       * Returns true if the arg is an array of strings
       * @param {*} arg - the item to test
       * @returns {boolean} True if arg is an array of strings
       */
      function isArrayOfStrings(arg) {
          var result = false;
          /* istanbul ignore else */
          if(Array.isArray(arg)) {
              result = (arg.filter(function(item){return typeof item !== 'string';}).length === 0);
          }
          return result;
      }
  
      /**
       * Returns true if the arg is an array of numbers
       * @param {*} arg - the item to test
       * @returns {boolean} True if arg is an array of numbers
       */
      function isArrayOfNumbers(arg) {
          var result = false;
          if(Array.isArray(arg)) {
              result = (arg.filter(function(item){return !isNumeric(item);}).length === 0);
          }
          return result;
      }
  
      /**
       * Create an empty sequence to contain query results
       * @returns {Array} - empty sequence
       */
      function createSequence() {
          var sequence = [];
          sequence.sequence = true;
          if (arguments.length === 1) {
              sequence.push(arguments[0]);
          }
          return sequence;
      }
  
      /**
       * Tests if a value is a sequence
       * @param {*} value the value to test
       * @returns {boolean} true if it's a sequence
       */
      function isSequence(value) {
          return value.sequence === true && Array.isArray(value);
      }
  
      /**
       *
       * @param {Object} arg - expression to test
       * @returns {boolean} - true if it is a function (lambda or built-in)
       */
      function isFunction(arg) {
          return ((arg && (arg._jsonata_function === true || arg._jsonata_lambda === true)) || typeof arg === 'function');
      }
  
      /**
       * Returns the arity (number of arguments) of the function
       * @param {*} func - the function
       * @returns {*} - the arity
       */
      function getFunctionArity(func) {
          var arity = typeof func.arity === 'number' ? func.arity :
              typeof func.implementation === 'function' ? func.implementation.length :
                  typeof func.length === 'number' ? func.length : func.arguments.length;
          return arity;
      }
  
      /**
       * Tests whether arg is a lambda function
       * @param {*} arg - the value to test
       * @returns {boolean} - true if it is a lambda function
       */
      function isLambda(arg) {
          return arg && arg._jsonata_lambda === true;
      }
  
      // istanbul ignore next
      var $Symbol = typeof Symbol === "function" ? Symbol : {};
      // istanbul ignore next
      var iteratorSymbol = $Symbol.iterator || "@@iterator";
  
      /**
       * @param {Object} arg - expression to test
       * @returns {boolean} - true if it is iterable
       */
      function isIterable(arg) {
          return (
              typeof arg === 'object' &&
              arg !== null &&
              iteratorSymbol in arg &&
              'next' in arg &&
              typeof arg.next === 'function'
          );
      }
  
      /**
       * Compares two values for equality
       * @param {*} lhs first value
       * @param {*} rhs second value
       * @returns {boolean} true if they are deep equal
       */
      function isDeepEqual(lhs, rhs) {
          if (lhs === rhs) {
              return true;
          }
          if(typeof lhs === 'object' && typeof rhs === 'object' && lhs !== null && rhs !== null) {
              if(Array.isArray(lhs) && Array.isArray(rhs)) {
                  // both arrays (or sequences)
                  // must be the same length
                  if(lhs.length !== rhs.length) {
                      return false;
                  }
                  // must contain same values in same order
                  for(var ii = 0; ii < lhs.length; ii++) {
                      if(!isDeepEqual(lhs[ii], rhs[ii])) {
                          return false;
                      }
                  }
                  return true;
              }
              // both objects
              // must have the same set of keys (in any order)
              var lkeys = Object.getOwnPropertyNames(lhs);
              var rkeys = Object.getOwnPropertyNames(rhs);
              if(lkeys.length !== rkeys.length) {
                  return false;
              }
              lkeys = lkeys.sort();
              rkeys = rkeys.sort();
              for(ii=0; ii < lkeys.length; ii++) {
                  if(lkeys[ii] !== rkeys[ii]) {
                      return false;
                  }
              }
              // must have the same values
              for(ii=0; ii < lkeys.length; ii++) {
                  var key = lkeys[ii];
                  if(!isDeepEqual(lhs[key], rhs[key])) {
                      return false;
                  }
              }
              return true;
          }
          return false;
      }
  
      /**
       * converts a string to an array of characters
       * @param {string} str - the input string
       * @returns {Array} - the array of characters
       */
      function stringToArray(str) {
          var arr = [];
          for (let char of str) {
              arr.push(char);
          }
          return arr;
      }
  
      return {
          isNumeric,
          isArrayOfStrings,
          isArrayOfNumbers,
          createSequence,
          isSequence,
          isFunction,
          isLambda,
          isIterable,
          getFunctionArity,
          isDeepEqual,
          stringToArray
      };
  })();
  
  module.exports = utils;
  
  },{}]},{},[3])(3)
  });
  
  
  /***/ }),
  
  /***/ 375:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const {PassThrough: PassThroughStream} = __webpack_require__(413);
  
  module.exports = options => {
  	options = {...options};
  
  	const {array} = options;
  	let {encoding} = options;
  	const isBuffer = encoding === 'buffer';
  	let objectMode = false;
  
  	if (array) {
  		objectMode = !(encoding || isBuffer);
  	} else {
  		encoding = encoding || 'utf8';
  	}
  
  	if (isBuffer) {
  		encoding = null;
  	}
  
  	const stream = new PassThroughStream({objectMode});
  
  	if (encoding) {
  		stream.setEncoding(encoding);
  	}
  
  	let length = 0;
  	const chunks = [];
  
  	stream.on('data', chunk => {
  		chunks.push(chunk);
  
  		if (objectMode) {
  			length = chunks.length;
  		} else {
  			length += chunk.length;
  		}
  	});
  
  	stream.getBufferedValue = () => {
  		if (array) {
  			return chunks;
  		}
  
  		return isBuffer ? Buffer.concat(chunks, length) : chunks.join('');
  	};
  
  	stream.getBufferedLength = () => length;
  
  	return stream;
  };
  
  
  /***/ }),
  
  /***/ 390:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  
  const EventEmitter = __webpack_require__(614);
  const urlLib = __webpack_require__(835);
  const normalizeUrl = __webpack_require__(53);
  const getStream = __webpack_require__(997);
  const CachePolicy = __webpack_require__(154);
  const Response = __webpack_require__(93);
  const lowercaseKeys = __webpack_require__(474);
  const cloneResponse = __webpack_require__(325);
  const Keyv = __webpack_require__(303);
  
  class CacheableRequest {
  	constructor(request, cacheAdapter) {
  		if (typeof request !== 'function') {
  			throw new TypeError('Parameter `request` must be a function');
  		}
  
  		this.cache = new Keyv({
  			uri: typeof cacheAdapter === 'string' && cacheAdapter,
  			store: typeof cacheAdapter !== 'string' && cacheAdapter,
  			namespace: 'cacheable-request'
  		});
  
  		return this.createCacheableRequest(request);
  	}
  
  	createCacheableRequest(request) {
  		return (opts, cb) => {
  			let url;
  			if (typeof opts === 'string') {
  				url = normalizeUrlObject(urlLib.parse(opts));
  				opts = {};
  			} else if (opts instanceof urlLib.URL) {
  				url = normalizeUrlObject(urlLib.parse(opts.toString()));
  				opts = {};
  			} else {
  				const [pathname, ...searchParts] = (opts.path || '').split('?');
  				const search = searchParts.length > 0 ?
  					`?${searchParts.join('?')}` :
  					'';
  				url = normalizeUrlObject({ ...opts, pathname, search });
  			}
  
  			opts = {
  				headers: {},
  				method: 'GET',
  				cache: true,
  				strictTtl: false,
  				automaticFailover: false,
  				...opts,
  				...urlObjectToRequestOptions(url)
  			};
  			opts.headers = lowercaseKeys(opts.headers);
  
  			const ee = new EventEmitter();
  			const normalizedUrlString = normalizeUrl(
  				urlLib.format(url),
  				{
  					stripWWW: false,
  					removeTrailingSlash: false,
  					stripAuthentication: false
  				}
  			);
  			const key = `${opts.method}:${normalizedUrlString}`;
  			let revalidate = false;
  			let madeRequest = false;
  
  			const makeRequest = opts => {
  				madeRequest = true;
  				let requestErrored = false;
  				let requestErrorCallback;
  
  				const requestErrorPromise = new Promise(resolve => {
  					requestErrorCallback = () => {
  						if (!requestErrored) {
  							requestErrored = true;
  							resolve();
  						}
  					};
  				});
  
  				const handler = response => {
  					if (revalidate && !opts.forceRefresh) {
  						response.status = response.statusCode;
  						const revalidatedPolicy = CachePolicy.fromObject(revalidate.cachePolicy).revalidatedPolicy(opts, response);
  						if (!revalidatedPolicy.modified) {
  							const headers = revalidatedPolicy.policy.responseHeaders();
  							response = new Response(revalidate.statusCode, headers, revalidate.body, revalidate.url);
  							response.cachePolicy = revalidatedPolicy.policy;
  							response.fromCache = true;
  						}
  					}
  
  					if (!response.fromCache) {
  						response.cachePolicy = new CachePolicy(opts, response, opts);
  						response.fromCache = false;
  					}
  
  					let clonedResponse;
  					if (opts.cache && response.cachePolicy.storable()) {
  						clonedResponse = cloneResponse(response);
  
  						(async () => {
  							try {
  								const bodyPromise = getStream.buffer(response);
  
  								await Promise.race([
  									requestErrorPromise,
  									new Promise(resolve => response.once('end', resolve))
  								]);
  
  								if (requestErrored) {
  									return;
  								}
  
  								const body = await bodyPromise;
  
  								const value = {
  									cachePolicy: response.cachePolicy.toObject(),
  									url: response.url,
  									statusCode: response.fromCache ? revalidate.statusCode : response.statusCode,
  									body
  								};
  
  								let ttl = opts.strictTtl ? response.cachePolicy.timeToLive() : undefined;
  								if (opts.maxTtl) {
  									ttl = ttl ? Math.min(ttl, opts.maxTtl) : opts.maxTtl;
  								}
  
  								await this.cache.set(key, value, ttl);
  							} catch (error) {
  								ee.emit('error', new CacheableRequest.CacheError(error));
  							}
  						})();
  					} else if (opts.cache && revalidate) {
  						(async () => {
  							try {
  								await this.cache.delete(key);
  							} catch (error) {
  								ee.emit('error', new CacheableRequest.CacheError(error));
  							}
  						})();
  					}
  
  					ee.emit('response', clonedResponse || response);
  					if (typeof cb === 'function') {
  						cb(clonedResponse || response);
  					}
  				};
  
  				try {
  					const req = request(opts, handler);
  					req.once('error', requestErrorCallback);
  					req.once('abort', requestErrorCallback);
  					ee.emit('request', req);
  				} catch (error) {
  					ee.emit('error', new CacheableRequest.RequestError(error));
  				}
  			};
  
  			(async () => {
  				const get = async opts => {
  					await Promise.resolve();
  
  					const cacheEntry = opts.cache ? await this.cache.get(key) : undefined;
  					if (typeof cacheEntry === 'undefined') {
  						return makeRequest(opts);
  					}
  
  					const policy = CachePolicy.fromObject(cacheEntry.cachePolicy);
  					if (policy.satisfiesWithoutRevalidation(opts) && !opts.forceRefresh) {
  						const headers = policy.responseHeaders();
  						const response = new Response(cacheEntry.statusCode, headers, cacheEntry.body, cacheEntry.url);
  						response.cachePolicy = policy;
  						response.fromCache = true;
  
  						ee.emit('response', response);
  						if (typeof cb === 'function') {
  							cb(response);
  						}
  					} else {
  						revalidate = cacheEntry;
  						opts.headers = policy.revalidationHeaders(opts);
  						makeRequest(opts);
  					}
  				};
  
  				const errorHandler = error => ee.emit('error', new CacheableRequest.CacheError(error));
  				this.cache.once('error', errorHandler);
  				ee.on('response', () => this.cache.removeListener('error', errorHandler));
  
  				try {
  					await get(opts);
  				} catch (error) {
  					if (opts.automaticFailover && !madeRequest) {
  						makeRequest(opts);
  					}
  
  					ee.emit('error', new CacheableRequest.CacheError(error));
  				}
  			})();
  
  			return ee;
  		};
  	}
  }
  
  function urlObjectToRequestOptions(url) {
  	const options = { ...url };
  	options.path = `${url.pathname || '/'}${url.search || ''}`;
  	delete options.pathname;
  	delete options.search;
  	return options;
  }
  
  function normalizeUrlObject(url) {
  	// If url was parsed by url.parse or new URL:
  	// - hostname will be set
  	// - host will be hostname[:port]
  	// - port will be set if it was explicit in the parsed string
  	// Otherwise, url was from request options:
  	// - hostname or host may be set
  	// - host shall not have port encoded
  	return {
  		protocol: url.protocol,
  		auth: url.auth,
  		hostname: url.hostname || url.host || 'localhost',
  		port: url.port,
  		pathname: url.pathname,
  		search: url.search
  	};
  }
  
  CacheableRequest.RequestError = class extends Error {
  	constructor(error) {
  		super(error.message);
  		this.name = 'RequestError';
  		Object.assign(this, error);
  	}
  };
  
  CacheableRequest.CacheError = class extends Error {
  	constructor(error) {
  		super(error.message);
  		this.name = 'CacheError';
  		Object.assign(this, error);
  	}
  };
  
  module.exports = CacheableRequest;
  
  
  /***/ }),
  
  /***/ 413:
  /***/ (function(module) {
  
  module.exports = require("stream");
  
  /***/ }),
  
  /***/ 422:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.isResponseOk = void 0;
  exports.isResponseOk = (response) => {
      const { statusCode } = response;
      const limitStatusCode = response.request.options.followRedirect ? 299 : 399;
      return (statusCode >= 200 && statusCode <= limitStatusCode) || statusCode === 304;
  };
  
  
  /***/ }),
  
  /***/ 431:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  var __importStar = (this && this.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
      result["default"] = mod;
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const os = __importStar(__webpack_require__(87));
  /**
   * Commands
   *
   * Command Format:
   *   ::name key=value,key=value::message
   *
   * Examples:
   *   ::warning::This is the message
   *   ::set-env name=MY_VAR::some value
   */
  function issueCommand(command, properties, message) {
      const cmd = new Command(command, properties, message);
      process.stdout.write(cmd.toString() + os.EOL);
  }
  exports.issueCommand = issueCommand;
  function issue(name, message = '') {
      issueCommand(name, {}, message);
  }
  exports.issue = issue;
  const CMD_STRING = '::';
  class Command {
      constructor(command, properties, message) {
          if (!command) {
              command = 'missing.command';
          }
          this.command = command;
          this.properties = properties;
          this.message = message;
      }
      toString() {
          let cmdStr = CMD_STRING + this.command;
          if (this.properties && Object.keys(this.properties).length > 0) {
              cmdStr += ' ';
              let first = true;
              for (const key in this.properties) {
                  if (this.properties.hasOwnProperty(key)) {
                      const val = this.properties[key];
                      if (val) {
                          if (first) {
                              first = false;
                          }
                          else {
                              cmdStr += ',';
                          }
                          cmdStr += `${key}=${escapeProperty(val)}`;
                      }
                  }
              }
          }
          cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
          return cmdStr;
      }
  }
  /**
   * Sanitizes an input into a string so it can be passed into issueCommand safely
   * @param input input to sanitize into a string
   */
  function toCommandValue(input) {
      if (input === null || input === undefined) {
          return '';
      }
      else if (typeof input === 'string' || input instanceof String) {
          return input;
      }
      return JSON.stringify(input);
  }
  exports.toCommandValue = toCommandValue;
  function escapeData(s) {
      return toCommandValue(s)
          .replace(/%/g, '%25')
          .replace(/\r/g, '%0D')
          .replace(/\n/g, '%0A');
  }
  function escapeProperty(s) {
      return toCommandValue(s)
          .replace(/%/g, '%25')
          .replace(/\r/g, '%0D')
          .replace(/\n/g, '%0A')
          .replace(/:/g, '%3A')
          .replace(/,/g, '%2C');
  }
  //# sourceMappingURL=command.js.map
  
  /***/ }),
  
  /***/ 452:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  // TODO: Update https://github.com/sindresorhus/get-stream
  const getBuffer = async (stream) => {
      const chunks = [];
      let length = 0;
      for await (const chunk of stream) {
          chunks.push(chunk);
          length += Buffer.byteLength(chunk);
      }
      if (Buffer.isBuffer(chunks[0])) {
          return Buffer.concat(chunks, length);
      }
      return Buffer.from(chunks.join(''));
  };
  exports.default = getBuffer;
  
  
  /***/ }),
  
  /***/ 453:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  var once = __webpack_require__(49)
  var eos = __webpack_require__(9)
  var fs = __webpack_require__(747) // we only need fs to get the ReadStream and WriteStream prototypes
  
  var noop = function () {}
  var ancient = /^v?\.0/.test(process.version)
  
  var isFn = function (fn) {
    return typeof fn === 'function'
  }
  
  var isFS = function (stream) {
    if (!ancient) return false // newer node version do not need to care about fs is a special way
    if (!fs) return false // browser
    return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close)
  }
  
  var isRequest = function (stream) {
    return stream.setHeader && isFn(stream.abort)
  }
  
  var destroyer = function (stream, reading, writing, callback) {
    callback = once(callback)
  
    var closed = false
    stream.on('close', function () {
      closed = true
    })
  
    eos(stream, {readable: reading, writable: writing}, function (err) {
      if (err) return callback(err)
      closed = true
      callback()
    })
  
    var destroyed = false
    return function (err) {
      if (closed) return
      if (destroyed) return
      destroyed = true
  
      if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks
      if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want
  
      if (isFn(stream.destroy)) return stream.destroy()
  
      callback(err || new Error('stream was destroyed'))
    }
  }
  
  var call = function (fn) {
    fn()
  }
  
  var pipe = function (from, to) {
    return from.pipe(to)
  }
  
  var pump = function () {
    var streams = Array.prototype.slice.call(arguments)
    var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop
  
    if (Array.isArray(streams[0])) streams = streams[0]
    if (streams.length < 2) throw new Error('pump requires two streams per minimum')
  
    var error
    var destroys = streams.map(function (stream, i) {
      var reading = i < streams.length - 1
      var writing = i > 0
      return destroyer(stream, reading, writing, function (err) {
        if (!error) error = err
        if (err) destroys.forEach(call)
        if (reading) return
        destroys.forEach(call)
        callback(error)
      })
    })
  
    return streams.reduce(pipe)
  }
  
  module.exports = pump
  
  
  /***/ }),
  
  /***/ 460:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const is_1 = __webpack_require__(534);
  exports.default = (body) => is_1.default.nodeStream(body) && is_1.default.function_(body.getBoundary);
  
  
  /***/ }),
  
  /***/ 461:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  const jsonata = __webpack_require__(350);
  
  
  /**
   * @typedef {Object} SecretRequest
   * @property {string} path
   * @property {string} selector
   */
  
  /**
   * @template {SecretRequest} TRequest
   * @typedef {Object} SecretResponse
   * @property {TRequest} request
   * @property {string} value
   * @property {boolean} cachedResponse
   */
  
   /**
    * @template TRequest
    * @param {Array<TRequest>} secretRequests
    * @param {import('got').Got} client
    * @return {Promise<SecretResponse<TRequest>[]>}
    */
  async function getSecrets(secretRequests, client) {
      const responseCache = new Map();
      const results = [];
      for (const secretRequest of secretRequests) {
          let { path, selector } = secretRequest;
  
          const requestPath = `v1/${path}`;
          let body;
          let cachedResponse = false;
          if (responseCache.has(requestPath)) {
              body = responseCache.get(requestPath);
              cachedResponse = true;
          } else {
              const result = await client.get(requestPath);
              body = result.body;
              responseCache.set(requestPath, body);
          }
  
          selector = "data." + selector
          body = JSON.parse(body)
          if (body.data["data"] != undefined) {
              selector = "data." + selector
          }
  
          const value = selectData(body, selector);
          results.push({
              request: secretRequest,
              value,
              cachedResponse
          });
      }
      return results;
  }
  
  /**
   * Uses a Jsonata selector retrieve a bit of data from the result
   * @param {object} data 
   * @param {string} selector 
   */
  function selectData(data, selector) {
      const ata = jsonata(selector);
      let result = JSON.stringify(ata.evaluate(data));
      // Compat for custom engines
      if (!result && ata.ast().type === "path" && ata.ast()['steps'].length === 1 && selector !== 'data' && 'data' in data) {
          result = JSON.stringify(jsonata(`data.${selector}`).evaluate(data));
      } else if (!result) {
          throw Error(`Unable to retrieve result for ${selector}. No match data was found. Double check your Key or Selector.`);
      }
  
      if (result.startsWith(`"`)) {
          result = result.substring(1, result.length - 1);
      }
      return result;
  }
  
  module.exports = {
      getSecrets,
      selectData
  }
  
  /***/ }),
  
  /***/ 470:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
      function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
      return new (P || (P = Promise))(function (resolve, reject) {
          function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
          function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
          function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
          step((generator = generator.apply(thisArg, _arguments || [])).next());
      });
  };
  var __importStar = (this && this.__importStar) || function (mod) {
      if (mod && mod.__esModule) return mod;
      var result = {};
      if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
      result["default"] = mod;
      return result;
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const command_1 = __webpack_require__(431);
  const os = __importStar(__webpack_require__(87));
  const path = __importStar(__webpack_require__(622));
  /**
   * The code to exit an action
   */
  var ExitCode;
  (function (ExitCode) {
      /**
       * A code indicating that the action was successful
       */
      ExitCode[ExitCode["Success"] = 0] = "Success";
      /**
       * A code indicating that the action was a failure
       */
      ExitCode[ExitCode["Failure"] = 1] = "Failure";
  })(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
  //-----------------------------------------------------------------------
  // Variables
  //-----------------------------------------------------------------------
  /**
   * Sets env variable for this action and future actions in the job
   * @param name the name of the variable to set
   * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  function exportVariable(name, val) {
      const convertedVal = command_1.toCommandValue(val);
      process.env[name] = convertedVal;
      command_1.issueCommand('set-env', { name }, convertedVal);
  }
  exports.exportVariable = exportVariable;
  /**
   * Registers a secret which will get masked from logs
   * @param secret value of the secret
   */
  function setSecret(secret) {
      command_1.issueCommand('add-mask', {}, secret);
  }
  exports.setSecret = setSecret;
  /**
   * Prepends inputPath to the PATH (for this action and future actions)
   * @param inputPath
   */
  function addPath(inputPath) {
      command_1.issueCommand('add-path', {}, inputPath);
      process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
  }
  exports.addPath = addPath;
  /**
   * Gets the value of an input.  The value is also trimmed.
   *
   * @param     name     name of the input to get
   * @param     options  optional. See InputOptions.
   * @returns   string
   */
  function getInput(name, options) {
      const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
      if (options && options.required && !val) {
          throw new Error(`Input required and not supplied: ${name}`);
      }
      return val.trim();
  }
  exports.getInput = getInput;
  /**
   * Sets the value of an output.
   *
   * @param     name     name of the output to set
   * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  function setOutput(name, value) {
      command_1.issueCommand('set-output', { name }, value);
  }
  exports.setOutput = setOutput;
  /**
   * Enables or disables the echoing of commands into stdout for the rest of the step.
   * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
   *
   */
  function setCommandEcho(enabled) {
      command_1.issue('echo', enabled ? 'on' : 'off');
  }
  exports.setCommandEcho = setCommandEcho;
  //-----------------------------------------------------------------------
  // Results
  //-----------------------------------------------------------------------
  /**
   * Sets the action status to failed.
   * When the action exits it will be with an exit code of 1
   * @param message add error issue message
   */
  function setFailed(message) {
      process.exitCode = ExitCode.Failure;
      error(message);
  }
  exports.setFailed = setFailed;
  //-----------------------------------------------------------------------
  // Logging Commands
  //-----------------------------------------------------------------------
  /**
   * Gets whether Actions Step Debug is on or not
   */
  function isDebug() {
      return process.env['RUNNER_DEBUG'] === '1';
  }
  exports.isDebug = isDebug;
  /**
   * Writes debug message to user log
   * @param message debug message
   */
  function debug(message) {
      command_1.issueCommand('debug', {}, message);
  }
  exports.debug = debug;
  /**
   * Adds an error issue
   * @param message error issue message. Errors will be converted to string via toString()
   */
  function error(message) {
      command_1.issue('error', message instanceof Error ? message.toString() : message);
  }
  exports.error = error;
  /**
   * Adds an warning issue
   * @param message warning issue message. Errors will be converted to string via toString()
   */
  function warning(message) {
      command_1.issue('warning', message instanceof Error ? message.toString() : message);
  }
  exports.warning = warning;
  /**
   * Writes info to log with console.log.
   * @param message info message
   */
  function info(message) {
      process.stdout.write(message + os.EOL);
  }
  exports.info = info;
  /**
   * Begin an output group.
   *
   * Output until the next `groupEnd` will be foldable in this group
   *
   * @param name The name of the output group
   */
  function startGroup(name) {
      command_1.issue('group', name);
  }
  exports.startGroup = startGroup;
  /**
   * End an output group.
   */
  function endGroup() {
      command_1.issue('endgroup');
  }
  exports.endGroup = endGroup;
  /**
   * Wrap an asynchronous function call in a group.
   *
   * Returns the same type as the function itself.
   *
   * @param name The name of the group
   * @param fn The function to wrap in the group
   */
  function group(name, fn) {
      return __awaiter(this, void 0, void 0, function* () {
          startGroup(name);
          let result;
          try {
              result = yield fn();
          }
          finally {
              endGroup();
          }
          return result;
      });
  }
  exports.group = group;
  //-----------------------------------------------------------------------
  // Wrapper action state
  //-----------------------------------------------------------------------
  /**
   * Saves state for current action, the state can only be retrieved by this action's post job execution.
   *
   * @param     name     name of the state to store
   * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  function saveState(name, value) {
      command_1.issueCommand('save-state', { name }, value);
  }
  exports.saveState = saveState;
  /**
   * Gets the value of an state set by this action's main execution.
   *
   * @param     name     name of the state to get
   * @returns   string
   */
  function getState(name) {
      return process.env[`STATE_${name}`] || '';
  }
  exports.getState = getState;
  //# sourceMappingURL=core.js.map
  
  /***/ }),
  
  /***/ 474:
  /***/ (function(module) {
  
  "use strict";
  
  module.exports = object => {
  	const result = {};
  
  	for (const [key, value] of Object.entries(object)) {
  		result[key.toLowerCase()] = value;
  	}
  
  	return result;
  };
  
  
  /***/ }),
  
  /***/ 490:
  /***/ (function(module, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const defer_to_connect_1 = __webpack_require__(790);
  const nodejsMajorVersion = Number(process.versions.node.split('.')[0]);
  const timer = (request) => {
      const timings = {
          start: Date.now(),
          socket: undefined,
          lookup: undefined,
          connect: undefined,
          secureConnect: undefined,
          upload: undefined,
          response: undefined,
          end: undefined,
          error: undefined,
          abort: undefined,
          phases: {
              wait: undefined,
              dns: undefined,
              tcp: undefined,
              tls: undefined,
              request: undefined,
              firstByte: undefined,
              download: undefined,
              total: undefined
          }
      };
      request.timings = timings;
      const handleError = (origin) => {
          const emit = origin.emit.bind(origin);
          origin.emit = (event, ...args) => {
              // Catches the `error` event
              if (event === 'error') {
                  timings.error = Date.now();
                  timings.phases.total = timings.error - timings.start;
                  origin.emit = emit;
              }
              // Saves the original behavior
              return emit(event, ...args);
          };
      };
      handleError(request);
      request.prependOnceListener('abort', () => {
          timings.abort = Date.now();
          // Let the `end` response event be responsible for setting the total phase,
          // unless the Node.js major version is >= 13.
          if (!timings.response || nodejsMajorVersion >= 13) {
              timings.phases.total = Date.now() - timings.start;
          }
      });
      const onSocket = (socket) => {
          timings.socket = Date.now();
          timings.phases.wait = timings.socket - timings.start;
          const lookupListener = () => {
              timings.lookup = Date.now();
              timings.phases.dns = timings.lookup - timings.socket;
          };
          socket.prependOnceListener('lookup', lookupListener);
          defer_to_connect_1.default(socket, {
              connect: () => {
                  timings.connect = Date.now();
                  if (timings.lookup === undefined) {
                      socket.removeListener('lookup', lookupListener);
                      timings.lookup = timings.connect;
                      timings.phases.dns = timings.lookup - timings.socket;
                  }
                  timings.phases.tcp = timings.connect - timings.lookup;
                  // This callback is called before flushing any data,
                  // so we don't need to set `timings.phases.request` here.
              },
              secureConnect: () => {
                  timings.secureConnect = Date.now();
                  timings.phases.tls = timings.secureConnect - timings.connect;
              }
          });
      };
      if (request.socket) {
          onSocket(request.socket);
      }
      else {
          request.prependOnceListener('socket', onSocket);
      }
      const onUpload = () => {
          var _a;
          timings.upload = Date.now();
          timings.phases.request = timings.upload - (_a = timings.secureConnect, (_a !== null && _a !== void 0 ? _a : timings.connect));
      };
      const writableFinished = () => {
          if (typeof request.writableFinished === 'boolean') {
              return request.writableFinished;
          }
          // Node.js doesn't have `request.writableFinished` property
          return request.finished && request.outputSize === 0 && (!request.socket || request.socket.writableLength === 0);
      };
      if (writableFinished()) {
          onUpload();
      }
      else {
          request.prependOnceListener('finish', onUpload);
      }
      request.prependOnceListener('response', (response) => {
          timings.response = Date.now();
          timings.phases.firstByte = timings.response - timings.upload;
          response.timings = timings;
          handleError(response);
          response.prependOnceListener('end', () => {
              timings.end = Date.now();
              timings.phases.download = timings.end - timings.response;
              timings.phases.total = timings.end - timings.start;
          });
      });
      return timings;
  };
  exports.default = timer;
  // For CommonJS default export support
  module.exports = timer;
  module.exports.default = timer;
  
  
  /***/ }),
  
  /***/ 492:
  /***/ (function(__unusedmodule, __unusedexports, __webpack_require__) {
  
  const core = __webpack_require__(470);
  const { exportSecrets } = __webpack_require__(928);
  
  (async () => {
      try {
          await core.group('Get Vault Secrets', exportSecrets);
      } catch (error) {
          core.setFailed(error.message);
      }
  })();
  
  
  /***/ }),
  
  /***/ 507:
  /***/ (function(module) {
  
  "use strict";
  
  /* istanbul ignore file: https://github.com/nodejs/node/blob/a91293d4d9ab403046ab5eb022332e4e3d249bd3/lib/internal/url.js#L1257 */
  
  module.exports = url => {
  	const options = {
  		protocol: url.protocol,
  		hostname: typeof url.hostname === 'string' && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname,
  		host: url.host,
  		hash: url.hash,
  		search: url.search,
  		pathname: url.pathname,
  		href: url.href,
  		path: `${url.pathname || ''}${url.search || ''}`
  	};
  
  	if (typeof url.port === 'string' && url.port.length !== 0) {
  		options.port = Number(url.port);
  	}
  
  	if (url.username || url.password) {
  		options.auth = `${url.username || ''}:${url.password || ''}`;
  	}
  
  	return options;
  };
  
  
  /***/ }),
  
  /***/ 524:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const tls = __webpack_require__(16);
  
  module.exports = (options = {}) => new Promise((resolve, reject) => {
  	const socket = tls.connect(options, () => {
  		if (options.resolveSocket) {
  			socket.off('error', reject);
  			resolve({alpnProtocol: socket.alpnProtocol, socket});
  		} else {
  			socket.destroy();
  			resolve({alpnProtocol: socket.alpnProtocol});
  		}
  	});
  
  	socket.on('error', reject);
  });
  
  
  /***/ }),
  
  /***/ 534:
  /***/ (function(module, exports) {
  
  "use strict";
  
  /// <reference lib="es2018"/>
  /// <reference lib="dom"/>
  /// <reference types="node"/>
  Object.defineProperty(exports, "__esModule", { value: true });
  const typedArrayTypeNames = [
      'Int8Array',
      'Uint8Array',
      'Uint8ClampedArray',
      'Int16Array',
      'Uint16Array',
      'Int32Array',
      'Uint32Array',
      'Float32Array',
      'Float64Array',
      'BigInt64Array',
      'BigUint64Array'
  ];
  function isTypedArrayName(name) {
      return typedArrayTypeNames.includes(name);
  }
  const objectTypeNames = [
      'Function',
      'Generator',
      'AsyncGenerator',
      'GeneratorFunction',
      'AsyncGeneratorFunction',
      'AsyncFunction',
      'Observable',
      'Array',
      'Buffer',
      'Object',
      'RegExp',
      'Date',
      'Error',
      'Map',
      'Set',
      'WeakMap',
      'WeakSet',
      'ArrayBuffer',
      'SharedArrayBuffer',
      'DataView',
      'Promise',
      'URL',
      'HTMLElement',
      ...typedArrayTypeNames
  ];
  function isObjectTypeName(name) {
      return objectTypeNames.includes(name);
  }
  const primitiveTypeNames = [
      'null',
      'undefined',
      'string',
      'number',
      'bigint',
      'boolean',
      'symbol'
  ];
  function isPrimitiveTypeName(name) {
      return primitiveTypeNames.includes(name);
  }
  // eslint-disable-next-line @typescript-eslint/ban-types
  function isOfType(type) {
      return (value) => typeof value === type;
  }
  const { toString } = Object.prototype;
  const getObjectType = (value) => {
      const objectTypeName = toString.call(value).slice(8, -1);
      if (/HTML\w+Element/.test(objectTypeName) && is.domElement(value)) {
          return 'HTMLElement';
      }
      if (isObjectTypeName(objectTypeName)) {
          return objectTypeName;
      }
      return undefined;
  };
  const isObjectOfType = (type) => (value) => getObjectType(value) === type;
  function is(value) {
      if (value === null) {
          return 'null';
      }
      switch (typeof value) {
          case 'undefined':
              return 'undefined';
          case 'string':
              return 'string';
          case 'number':
              return 'number';
          case 'boolean':
              return 'boolean';
          case 'function':
              return 'Function';
          case 'bigint':
              return 'bigint';
          case 'symbol':
              return 'symbol';
          default:
      }
      if (is.observable(value)) {
          return 'Observable';
      }
      if (is.array(value)) {
          return 'Array';
      }
      if (is.buffer(value)) {
          return 'Buffer';
      }
      const tagType = getObjectType(value);
      if (tagType) {
          return tagType;
      }
      if (value instanceof String || value instanceof Boolean || value instanceof Number) {
          throw new TypeError('Please don\'t use object wrappers for primitive types');
      }
      return 'Object';
  }
  is.undefined = isOfType('undefined');
  is.string = isOfType('string');
  const isNumberType = isOfType('number');
  is.number = (value) => isNumberType(value) && !is.nan(value);
  is.bigint = isOfType('bigint');
  // eslint-disable-next-line @typescript-eslint/ban-types
  is.function_ = isOfType('function');
  is.null_ = (value) => value === null;
  is.class_ = (value) => is.function_(value) && value.toString().startsWith('class ');
  is.boolean = (value) => value === true || value === false;
  is.symbol = isOfType('symbol');
  is.numericString = (value) => is.string(value) && !is.emptyStringOrWhitespace(value) && !Number.isNaN(Number(value));
  is.array = (value, assertion) => {
      if (!Array.isArray(value)) {
          return false;
      }
      if (!is.function_(assertion)) {
          return true;
      }
      return value.every(assertion);
  };
  is.buffer = (value) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = value) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.isBuffer) === null || _c === void 0 ? void 0 : _c.call(_b, value)) !== null && _d !== void 0 ? _d : false; };
  is.nullOrUndefined = (value) => is.null_(value) || is.undefined(value);
  is.object = (value) => !is.null_(value) && (typeof value === 'object' || is.function_(value));
  is.iterable = (value) => { var _a; return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a[Symbol.iterator]); };
  is.asyncIterable = (value) => { var _a; return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a[Symbol.asyncIterator]); };
  is.generator = (value) => is.iterable(value) && is.function_(value.next) && is.function_(value.throw);
  is.asyncGenerator = (value) => is.asyncIterable(value) && is.function_(value.next) && is.function_(value.throw);
  is.nativePromise = (value) => isObjectOfType('Promise')(value);
  const hasPromiseAPI = (value) => {
      var _a, _b;
      return is.function_((_a = value) === null || _a === void 0 ? void 0 : _a.then) &&
          is.function_((_b = value) === null || _b === void 0 ? void 0 : _b.catch);
  };
  is.promise = (value) => is.nativePromise(value) || hasPromiseAPI(value);
  is.generatorFunction = isObjectOfType('GeneratorFunction');
  is.asyncGeneratorFunction = (value) => getObjectType(value) === 'AsyncGeneratorFunction';
  is.asyncFunction = (value) => getObjectType(value) === 'AsyncFunction';
  // eslint-disable-next-line no-prototype-builtins, @typescript-eslint/ban-types
  is.boundFunction = (value) => is.function_(value) && !value.hasOwnProperty('prototype');
  is.regExp = isObjectOfType('RegExp');
  is.date = isObjectOfType('Date');
  is.error = isObjectOfType('Error');
  is.map = (value) => isObjectOfType('Map')(value);
  is.set = (value) => isObjectOfType('Set')(value);
  is.weakMap = (value) => isObjectOfType('WeakMap')(value);
  is.weakSet = (value) => isObjectOfType('WeakSet')(value);
  is.int8Array = isObjectOfType('Int8Array');
  is.uint8Array = isObjectOfType('Uint8Array');
  is.uint8ClampedArray = isObjectOfType('Uint8ClampedArray');
  is.int16Array = isObjectOfType('Int16Array');
  is.uint16Array = isObjectOfType('Uint16Array');
  is.int32Array = isObjectOfType('Int32Array');
  is.uint32Array = isObjectOfType('Uint32Array');
  is.float32Array = isObjectOfType('Float32Array');
  is.float64Array = isObjectOfType('Float64Array');
  is.bigInt64Array = isObjectOfType('BigInt64Array');
  is.bigUint64Array = isObjectOfType('BigUint64Array');
  is.arrayBuffer = isObjectOfType('ArrayBuffer');
  is.sharedArrayBuffer = isObjectOfType('SharedArrayBuffer');
  is.dataView = isObjectOfType('DataView');
  is.directInstanceOf = (instance, class_) => Object.getPrototypeOf(instance) === class_.prototype;
  is.urlInstance = (value) => isObjectOfType('URL')(value);
  is.urlString = (value) => {
      if (!is.string(value)) {
          return false;
      }
      try {
          new URL(value); // eslint-disable-line no-new
          return true;
      }
      catch (_a) {
          return false;
      }
  };
  // TODO: Use the `not` operator with a type guard here when it's available.
  // Example: `is.truthy = (value: unknown): value is (not false | not 0 | not '' | not undefined | not null) => Boolean(value);`
  is.truthy = (value) => Boolean(value);
  // Example: `is.falsy = (value: unknown): value is (not true | 0 | '' | undefined | null) => Boolean(value);`
  is.falsy = (value) => !value;
  is.nan = (value) => Number.isNaN(value);
  is.primitive = (value) => is.null_(value) || isPrimitiveTypeName(typeof value);
  is.integer = (value) => Number.isInteger(value);
  is.safeInteger = (value) => Number.isSafeInteger(value);
  is.plainObject = (value) => {
      // From: https://github.com/sindresorhus/is-plain-obj/blob/master/index.js
      if (toString.call(value) !== '[object Object]') {
          return false;
      }
      const prototype = Object.getPrototypeOf(value);
      return prototype === null || prototype === Object.getPrototypeOf({});
  };
  is.typedArray = (value) => isTypedArrayName(getObjectType(value));
  const isValidLength = (value) => is.safeInteger(value) && value >= 0;
  is.arrayLike = (value) => !is.nullOrUndefined(value) && !is.function_(value) && isValidLength(value.length);
  is.inRange = (value, range) => {
      if (is.number(range)) {
          return value >= Math.min(0, range) && value <= Math.max(range, 0);
      }
      if (is.array(range) && range.length === 2) {
          return value >= Math.min(...range) && value <= Math.max(...range);
      }
      throw new TypeError(`Invalid range: ${JSON.stringify(range)}`);
  };
  const NODE_TYPE_ELEMENT = 1;
  const DOM_PROPERTIES_TO_CHECK = [
      'innerHTML',
      'ownerDocument',
      'style',
      'attributes',
      'nodeValue'
  ];
  is.domElement = (value) => {
      return is.object(value) &&
          value.nodeType === NODE_TYPE_ELEMENT &&
          is.string(value.nodeName) &&
          !is.plainObject(value) &&
          DOM_PROPERTIES_TO_CHECK.every(property => property in value);
  };
  is.observable = (value) => {
      var _a, _b, _c, _d;
      if (!value) {
          return false;
      }
      // eslint-disable-next-line no-use-extend-native/no-use-extend-native
      if (value === ((_b = (_a = value)[Symbol.observable]) === null || _b === void 0 ? void 0 : _b.call(_a))) {
          return true;
      }
      if (value === ((_d = (_c = value)['@@observable']) === null || _d === void 0 ? void 0 : _d.call(_c))) {
          return true;
      }
      return false;
  };
  is.nodeStream = (value) => is.object(value) && is.function_(value.pipe) && !is.observable(value);
  is.infinite = (value) => value === Infinity || value === -Infinity;
  const isAbsoluteMod2 = (remainder) => (value) => is.integer(value) && Math.abs(value % 2) === remainder;
  is.evenInteger = isAbsoluteMod2(0);
  is.oddInteger = isAbsoluteMod2(1);
  is.emptyArray = (value) => is.array(value) && value.length === 0;
  is.nonEmptyArray = (value) => is.array(value) && value.length > 0;
  is.emptyString = (value) => is.string(value) && value.length === 0;
  // TODO: Use `not ''` when the `not` operator is available.
  is.nonEmptyString = (value) => is.string(value) && value.length > 0;
  const isWhiteSpaceString = (value) => is.string(value) && !/\S/.test(value);
  is.emptyStringOrWhitespace = (value) => is.emptyString(value) || isWhiteSpaceString(value);
  is.emptyObject = (value) => is.object(value) && !is.map(value) && !is.set(value) && Object.keys(value).length === 0;
  // TODO: Use `not` operator here to remove `Map` and `Set` from type guard:
  // - https://github.com/Microsoft/TypeScript/pull/29317
  is.nonEmptyObject = (value) => is.object(value) && !is.map(value) && !is.set(value) && Object.keys(value).length > 0;
  is.emptySet = (value) => is.set(value) && value.size === 0;
  is.nonEmptySet = (value) => is.set(value) && value.size > 0;
  is.emptyMap = (value) => is.map(value) && value.size === 0;
  is.nonEmptyMap = (value) => is.map(value) && value.size > 0;
  const predicateOnArray = (method, predicate, values) => {
      if (!is.function_(predicate)) {
          throw new TypeError(`Invalid predicate: ${JSON.stringify(predicate)}`);
      }
      if (values.length === 0) {
          throw new TypeError('Invalid number of values');
      }
      return method.call(values, predicate);
  };
  is.any = (predicate, ...values) => {
      const predicates = is.array(predicate) ? predicate : [predicate];
      return predicates.some(singlePredicate => predicateOnArray(Array.prototype.some, singlePredicate, values));
  };
  is.all = (predicate, ...values) => predicateOnArray(Array.prototype.every, predicate, values);
  const assertType = (condition, description, value) => {
      if (!condition) {
          throw new TypeError(`Expected value which is \`${description}\`, received value of type \`${is(value)}\`.`);
      }
  };
  exports.assert = {
      // Unknowns.
      undefined: (value) => assertType(is.undefined(value), 'undefined', value),
      string: (value) => assertType(is.string(value), 'string', value),
      number: (value) => assertType(is.number(value), 'number', value),
      bigint: (value) => assertType(is.bigint(value), 'bigint', value),
      // eslint-disable-next-line @typescript-eslint/ban-types
      function_: (value) => assertType(is.function_(value), 'Function', value),
      null_: (value) => assertType(is.null_(value), 'null', value),
      class_: (value) => assertType(is.class_(value), "Class" /* class_ */, value),
      boolean: (value) => assertType(is.boolean(value), 'boolean', value),
      symbol: (value) => assertType(is.symbol(value), 'symbol', value),
      numericString: (value) => assertType(is.numericString(value), "string with a number" /* numericString */, value),
      array: (value, assertion) => {
          const assert = assertType;
          assert(is.array(value), 'Array', value);
          if (assertion) {
              value.forEach(assertion);
          }
      },
      buffer: (value) => assertType(is.buffer(value), 'Buffer', value),
      nullOrUndefined: (value) => assertType(is.nullOrUndefined(value), "null or undefined" /* nullOrUndefined */, value),
      object: (value) => assertType(is.object(value), 'Object', value),
      iterable: (value) => assertType(is.iterable(value), "Iterable" /* iterable */, value),
      asyncIterable: (value) => assertType(is.asyncIterable(value), "AsyncIterable" /* asyncIterable */, value),
      generator: (value) => assertType(is.generator(value), 'Generator', value),
      asyncGenerator: (value) => assertType(is.asyncGenerator(value), 'AsyncGenerator', value),
      nativePromise: (value) => assertType(is.nativePromise(value), "native Promise" /* nativePromise */, value),
      promise: (value) => assertType(is.promise(value), 'Promise', value),
      generatorFunction: (value) => assertType(is.generatorFunction(value), 'GeneratorFunction', value),
      asyncGeneratorFunction: (value) => assertType(is.asyncGeneratorFunction(value), 'AsyncGeneratorFunction', value),
      // eslint-disable-next-line @typescript-eslint/ban-types
      asyncFunction: (value) => assertType(is.asyncFunction(value), 'AsyncFunction', value),
      // eslint-disable-next-line @typescript-eslint/ban-types
      boundFunction: (value) => assertType(is.boundFunction(value), 'Function', value),
      regExp: (value) => assertType(is.regExp(value), 'RegExp', value),
      date: (value) => assertType(is.date(value), 'Date', value),
      error: (value) => assertType(is.error(value), 'Error', value),
      map: (value) => assertType(is.map(value), 'Map', value),
      set: (value) => assertType(is.set(value), 'Set', value),
      weakMap: (value) => assertType(is.weakMap(value), 'WeakMap', value),
      weakSet: (value) => assertType(is.weakSet(value), 'WeakSet', value),
      int8Array: (value) => assertType(is.int8Array(value), 'Int8Array', value),
      uint8Array: (value) => assertType(is.uint8Array(value), 'Uint8Array', value),
      uint8ClampedArray: (value) => assertType(is.uint8ClampedArray(value), 'Uint8ClampedArray', value),
      int16Array: (value) => assertType(is.int16Array(value), 'Int16Array', value),
      uint16Array: (value) => assertType(is.uint16Array(value), 'Uint16Array', value),
      int32Array: (value) => assertType(is.int32Array(value), 'Int32Array', value),
      uint32Array: (value) => assertType(is.uint32Array(value), 'Uint32Array', value),
      float32Array: (value) => assertType(is.float32Array(value), 'Float32Array', value),
      float64Array: (value) => assertType(is.float64Array(value), 'Float64Array', value),
      bigInt64Array: (value) => assertType(is.bigInt64Array(value), 'BigInt64Array', value),
      bigUint64Array: (value) => assertType(is.bigUint64Array(value), 'BigUint64Array', value),
      arrayBuffer: (value) => assertType(is.arrayBuffer(value), 'ArrayBuffer', value),
      sharedArrayBuffer: (value) => assertType(is.sharedArrayBuffer(value), 'SharedArrayBuffer', value),
      dataView: (value) => assertType(is.dataView(value), 'DataView', value),
      urlInstance: (value) => assertType(is.urlInstance(value), 'URL', value),
      urlString: (value) => assertType(is.urlString(value), "string with a URL" /* urlString */, value),
      truthy: (value) => assertType(is.truthy(value), "truthy" /* truthy */, value),
      falsy: (value) => assertType(is.falsy(value), "falsy" /* falsy */, value),
      nan: (value) => assertType(is.nan(value), "NaN" /* nan */, value),
      primitive: (value) => assertType(is.primitive(value), "primitive" /* primitive */, value),
      integer: (value) => assertType(is.integer(value), "integer" /* integer */, value),
      safeInteger: (value) => assertType(is.safeInteger(value), "integer" /* safeInteger */, value),
      plainObject: (value) => assertType(is.plainObject(value), "plain object" /* plainObject */, value),
      typedArray: (value) => assertType(is.typedArray(value), "TypedArray" /* typedArray */, value),
      arrayLike: (value) => assertType(is.arrayLike(value), "array-like" /* arrayLike */, value),
      domElement: (value) => assertType(is.domElement(value), "HTMLElement" /* domElement */, value),
      observable: (value) => assertType(is.observable(value), 'Observable', value),
      nodeStream: (value) => assertType(is.nodeStream(value), "Node.js Stream" /* nodeStream */, value),
      infinite: (value) => assertType(is.infinite(value), "infinite number" /* infinite */, value),
      emptyArray: (value) => assertType(is.emptyArray(value), "empty array" /* emptyArray */, value),
      nonEmptyArray: (value) => assertType(is.nonEmptyArray(value), "non-empty array" /* nonEmptyArray */, value),
      emptyString: (value) => assertType(is.emptyString(value), "empty string" /* emptyString */, value),
      nonEmptyString: (value) => assertType(is.nonEmptyString(value), "non-empty string" /* nonEmptyString */, value),
      emptyStringOrWhitespace: (value) => assertType(is.emptyStringOrWhitespace(value), "empty string or whitespace" /* emptyStringOrWhitespace */, value),
      emptyObject: (value) => assertType(is.emptyObject(value), "empty object" /* emptyObject */, value),
      nonEmptyObject: (value) => assertType(is.nonEmptyObject(value), "non-empty object" /* nonEmptyObject */, value),
      emptySet: (value) => assertType(is.emptySet(value), "empty set" /* emptySet */, value),
      nonEmptySet: (value) => assertType(is.nonEmptySet(value), "non-empty set" /* nonEmptySet */, value),
      emptyMap: (value) => assertType(is.emptyMap(value), "empty map" /* emptyMap */, value),
      nonEmptyMap: (value) => assertType(is.nonEmptyMap(value), "non-empty map" /* nonEmptyMap */, value),
      // Numbers.
      evenInteger: (value) => assertType(is.evenInteger(value), "even integer" /* evenInteger */, value),
      oddInteger: (value) => assertType(is.oddInteger(value), "odd integer" /* oddInteger */, value),
      // Two arguments.
      directInstanceOf: (instance, class_) => assertType(is.directInstanceOf(instance, class_), "T" /* directInstanceOf */, instance),
      inRange: (value, range) => assertType(is.inRange(value, range), "in range" /* inRange */, value),
      // Variadic functions.
      any: (predicate, ...values) => assertType(is.any(predicate, ...values), "predicate returns truthy for any value" /* any */, values),
      all: (predicate, ...values) => assertType(is.all(predicate, ...values), "predicate returns truthy for all values" /* all */, values)
  };
  // Some few keywords are reserved, but we'll populate them for Node.js users
  // See https://github.com/Microsoft/TypeScript/issues/2536
  Object.defineProperties(is, {
      class: {
          value: is.class_
      },
      function: {
          value: is.function_
      },
      null: {
          value: is.null_
      }
  });
  Object.defineProperties(exports.assert, {
      class: {
          value: exports.assert.class_
      },
      function: {
          value: exports.assert.function_
      },
      null: {
          value: exports.assert.null_
      }
  });
  exports.default = is;
  // For CommonJS default export support
  module.exports = is;
  module.exports.default = is;
  module.exports.assert = exports.assert;
  
  
  /***/ }),
  
  /***/ 537:
  /***/ (function(module) {
  
  "use strict";
  
  
  // We define these manually to ensure they're always copied
  // even if they would move up the prototype chain
  // https://nodejs.org/api/http.html#http_class_http_incomingmessage
  const knownProperties = [
  	'aborted',
  	'complete',
  	'headers',
  	'httpVersion',
  	'httpVersionMinor',
  	'httpVersionMajor',
  	'method',
  	'rawHeaders',
  	'rawTrailers',
  	'setTimeout',
  	'socket',
  	'statusCode',
  	'statusMessage',
  	'trailers',
  	'url'
  ];
  
  module.exports = (fromStream, toStream) => {
  	if (toStream._readableState.autoDestroy) {
  		throw new Error('The second stream must have the `autoDestroy` option set to `false`');
  	}
  
  	const fromProperties = new Set(Object.keys(fromStream).concat(knownProperties));
  
  	const properties = {};
  
  	for (const property of fromProperties) {
  		// Don't overwrite existing properties.
  		if (property in toStream) {
  			continue;
  		}
  
  		properties[property] = {
  			get() {
  				const value = fromStream[property];
  				const isFunction = typeof value === 'function';
  
  				return isFunction ? value.bind(fromStream) : value;
  			},
  			set(value) {
  				fromStream[property] = value;
  			},
  			enumerable: true,
  			configurable: false
  		};
  	}
  
  	Object.defineProperties(toStream, properties);
  
  	fromStream.once('aborted', () => {
  		toStream.destroy();
  
  		toStream.emit('aborted');
  	});
  
  	fromStream.once('close', () => {
  		if (fromStream.complete) {
  			if (toStream.readable) {
  				toStream.once('end', () => {
  					toStream.emit('close');
  				});
  			} else {
  				toStream.emit('close');
  			}
  		} else {
  			toStream.emit('close');
  		}
  	});
  
  	return toStream;
  };
  
  
  /***/ }),
  
  /***/ 557:
  /***/ (function(module) {
  
  "use strict";
  
  
  class CancelError extends Error {
  	constructor(reason) {
  		super(reason || 'Promise was canceled');
  		this.name = 'CancelError';
  	}
  
  	get isCanceled() {
  		return true;
  	}
  }
  
  class PCancelable {
  	static fn(userFn) {
  		return (...arguments_) => {
  			return new PCancelable((resolve, reject, onCancel) => {
  				arguments_.push(onCancel);
  				// eslint-disable-next-line promise/prefer-await-to-then
  				userFn(...arguments_).then(resolve, reject);
  			});
  		};
  	}
  
  	constructor(executor) {
  		this._cancelHandlers = [];
  		this._isPending = true;
  		this._isCanceled = false;
  		this._rejectOnCancel = true;
  
  		this._promise = new Promise((resolve, reject) => {
  			this._reject = reject;
  
  			const onResolve = value => {
  				this._isPending = false;
  				resolve(value);
  			};
  
  			const onReject = error => {
  				this._isPending = false;
  				reject(error);
  			};
  
  			const onCancel = handler => {
  				if (!this._isPending) {
  					throw new Error('The `onCancel` handler was attached after the promise settled.');
  				}
  
  				this._cancelHandlers.push(handler);
  			};
  
  			Object.defineProperties(onCancel, {
  				shouldReject: {
  					get: () => this._rejectOnCancel,
  					set: boolean => {
  						this._rejectOnCancel = boolean;
  					}
  				}
  			});
  
  			return executor(onResolve, onReject, onCancel);
  		});
  	}
  
  	then(onFulfilled, onRejected) {
  		// eslint-disable-next-line promise/prefer-await-to-then
  		return this._promise.then(onFulfilled, onRejected);
  	}
  
  	catch(onRejected) {
  		return this._promise.catch(onRejected);
  	}
  
  	finally(onFinally) {
  		return this._promise.finally(onFinally);
  	}
  
  	cancel(reason) {
  		if (!this._isPending || this._isCanceled) {
  			return;
  		}
  
  		if (this._cancelHandlers.length > 0) {
  			try {
  				for (const handler of this._cancelHandlers) {
  					handler();
  				}
  			} catch (error) {
  				this._reject(error);
  			}
  		}
  
  		this._isCanceled = true;
  		if (this._rejectOnCancel) {
  			this._reject(new CancelError(reason));
  		}
  	}
  
  	get isCanceled() {
  		return this._isCanceled;
  	}
  }
  
  Object.setPrototypeOf(PCancelable.prototype, Promise.prototype);
  
  module.exports = PCancelable;
  module.exports.CancelError = CancelError;
  
  
  /***/ }),
  
  /***/ 565:
  /***/ (function(module) {
  
  module.exports = require("http2");
  
  /***/ }),
  
  /***/ 570:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const {
  	V4MAPPED,
  	ADDRCONFIG,
  	ALL,
  	promises: {
  		Resolver: AsyncResolver
  	},
  	lookup: dnsLookup
  } = __webpack_require__(881);
  const {promisify} = __webpack_require__(669);
  const os = __webpack_require__(87);
  
  const kCacheableLookupCreateConnection = Symbol('cacheableLookupCreateConnection');
  const kCacheableLookupInstance = Symbol('cacheableLookupInstance');
  const kExpires = Symbol('expires');
  
  const supportsALL = typeof ALL === 'number';
  
  const verifyAgent = agent => {
  	if (!(agent && typeof agent.createConnection === 'function')) {
  		throw new Error('Expected an Agent instance as the first argument');
  	}
  };
  
  const map4to6 = entries => {
  	for (const entry of entries) {
  		if (entry.family === 6) {
  			continue;
  		}
  
  		entry.address = `::ffff:${entry.address}`;
  		entry.family = 6;
  	}
  };
  
  const getIfaceInfo = () => {
  	let has4 = false;
  	let has6 = false;
  
  	for (const device of Object.values(os.networkInterfaces())) {
  		for (const iface of device) {
  			if (iface.internal) {
  				continue;
  			}
  
  			if (iface.family === 'IPv6') {
  				has6 = true;
  			} else {
  				has4 = true;
  			}
  
  			if (has4 && has6) {
  				return {has4, has6};
  			}
  		}
  	}
  
  	return {has4, has6};
  };
  
  const isIterable = map => {
  	return Symbol.iterator in map;
  };
  
  const ttl = {ttl: true};
  const all = {all: true};
  
  class CacheableLookup {
  	constructor({
  		cache = new Map(),
  		maxTtl = Infinity,
  		fallbackDuration = 3600,
  		errorTtl = 0.15,
  		resolver = new AsyncResolver(),
  		lookup = dnsLookup
  	} = {}) {
  		this.maxTtl = maxTtl;
  		this.errorTtl = errorTtl;
  
  		this._cache = cache;
  		this._resolver = resolver;
  		this._dnsLookup = promisify(lookup);
  
  		if (this._resolver instanceof AsyncResolver) {
  			this._resolve4 = this._resolver.resolve4.bind(this._resolver);
  			this._resolve6 = this._resolver.resolve6.bind(this._resolver);
  		} else {
  			this._resolve4 = promisify(this._resolver.resolve4.bind(this._resolver));
  			this._resolve6 = promisify(this._resolver.resolve6.bind(this._resolver));
  		}
  
  		this._iface = getIfaceInfo();
  
  		this._pending = {};
  		this._nextRemovalTime = false;
  		this._hostnamesToFallback = new Set();
  
  		if (fallbackDuration < 1) {
  			this._fallback = false;
  		} else {
  			this._fallback = true;
  
  			const interval = setInterval(() => {
  				this._hostnamesToFallback.clear();
  			}, fallbackDuration * 1000);
  
  			/* istanbul ignore next: There is no `interval.unref()` when running inside an Electron renderer */
  			if (interval.unref) {
  				interval.unref();
  			}
  		}
  
  		this.lookup = this.lookup.bind(this);
  		this.lookupAsync = this.lookupAsync.bind(this);
  	}
  
  	set servers(servers) {
  		this.clear();
  
  		this._resolver.setServers(servers);
  	}
  
  	get servers() {
  		return this._resolver.getServers();
  	}
  
  	lookup(hostname, options, callback) {
  		if (typeof options === 'function') {
  			callback = options;
  			options = {};
  		} else if (typeof options === 'number') {
  			options = {
  				family: options
  			};
  		}
  
  		if (!callback) {
  			throw new Error('Callback must be a function.');
  		}
  
  		// eslint-disable-next-line promise/prefer-await-to-then
  		this.lookupAsync(hostname, options).then(result => {
  			if (options.all) {
  				callback(null, result);
  			} else {
  				callback(null, result.address, result.family, result.expires, result.ttl);
  			}
  		}, callback);
  	}
  
  	async lookupAsync(hostname, options = {}) {
  		if (typeof options === 'number') {
  			options = {
  				family: options
  			};
  		}
  
  		let cached = await this.query(hostname);
  
  		if (options.family === 6) {
  			const filtered = cached.filter(entry => entry.family === 6);
  
  			if (options.hints & V4MAPPED) {
  				if ((supportsALL && options.hints & ALL) || filtered.length === 0) {
  					map4to6(cached);
  				} else {
  					cached = filtered;
  				}
  			} else {
  				cached = filtered;
  			}
  		} else if (options.family === 4) {
  			cached = cached.filter(entry => entry.family === 4);
  		}
  
  		if (options.hints & ADDRCONFIG) {
  			const {_iface} = this;
  			cached = cached.filter(entry => entry.family === 6 ? _iface.has6 : _iface.has4);
  		}
  
  		if (cached.length === 0) {
  			const error = new Error(`cacheableLookup ENOTFOUND ${hostname}`);
  			error.code = 'ENOTFOUND';
  			error.hostname = hostname;
  
  			throw error;
  		}
  
  		if (options.all) {
  			return cached;
  		}
  
  		return cached[0];
  	}
  
  	async query(hostname) {
  		let cached = await this._cache.get(hostname);
  
  		if (!cached) {
  			const pending = this._pending[hostname];
  
  			if (pending) {
  				cached = await pending;
  			} else {
  				const newPromise = this.queryAndCache(hostname);
  				this._pending[hostname] = newPromise;
  
  				cached = await newPromise;
  			}
  		}
  
  		cached = cached.map(entry => {
  			return {...entry};
  		});
  
  		return cached;
  	}
  
  	async _resolve(hostname) {
  		const wrap = async promise => {
  			try {
  				return await promise;
  			} catch (error) {
  				if (error.code === 'ENODATA' || error.code === 'ENOTFOUND') {
  					return [];
  				}
  
  				throw error;
  			}
  		};
  
  		// ANY is unsafe as it doesn't trigger new queries in the underlying server.
  		const [A, AAAA] = await Promise.all([
  			this._resolve4(hostname, ttl),
  			this._resolve6(hostname, ttl)
  		].map(promise => wrap(promise)));
  
  		let aTtl = 0;
  		let aaaaTtl = 0;
  		let cacheTtl = 0;
  
  		const now = Date.now();
  
  		for (const entry of A) {
  			entry.family = 4;
  			entry.expires = now + (entry.ttl * 1000);
  
  			aTtl = Math.max(aTtl, entry.ttl);
  		}
  
  		for (const entry of AAAA) {
  			entry.family = 6;
  			entry.expires = now + (entry.ttl * 1000);
  
  			aaaaTtl = Math.max(aaaaTtl, entry.ttl);
  		}
  
  		if (A.length > 0) {
  			if (AAAA.length > 0) {
  				cacheTtl = Math.min(aTtl, aaaaTtl);
  			} else {
  				cacheTtl = aTtl;
  			}
  		} else {
  			cacheTtl = aaaaTtl;
  		}
  
  		return {
  			entries: [
  				...A,
  				...AAAA
  			],
  			cacheTtl
  		};
  	}
  
  	async _lookup(hostname) {
  		try {
  			const entries = await this._dnsLookup(hostname, {
  				all: true
  			});
  
  			return {
  				entries,
  				cacheTtl: 0
  			};
  		} catch (_) {
  			return {
  				entries: [],
  				cacheTtl: 0
  			};
  		}
  	}
  
  	async _set(hostname, data, cacheTtl) {
  		if (this.maxTtl > 0 && cacheTtl > 0) {
  			cacheTtl = Math.min(cacheTtl, this.maxTtl) * 1000;
  			data[kExpires] = Date.now() + cacheTtl;
  
  			try {
  				await this._cache.set(hostname, data, cacheTtl);
  			} catch (error) {
  				this.lookupAsync = async () => {
  					const cacheError = new Error('Cache Error. Please recreate the CacheableLookup instance.');
  					cacheError.cause = error;
  
  					throw cacheError;
  				};
  			}
  
  			if (isIterable(this._cache)) {
  				this._tick(cacheTtl);
  			}
  		}
  	}
  
  	async queryAndCache(hostname) {
  		if (this._hostnamesToFallback.has(hostname)) {
  			return this._dnsLookup(hostname, all);
  		}
  
  		try {
  			let query = await this._resolve(hostname);
  
  			if (query.entries.length === 0 && this._fallback) {
  				query = await this._lookup(hostname);
  
  				if (query.entries.length !== 0) {
  					// Use `dns.lookup(...)` for that particular hostname
  					this._hostnamesToFallback.add(hostname);
  				}
  			}
  
  			const cacheTtl = query.entries.length === 0 ? this.errorTtl : query.cacheTtl;
  			await this._set(hostname, query.entries, cacheTtl);
  
  			delete this._pending[hostname];
  
  			return query.entries;
  		} catch (error) {
  			delete this._pending[hostname];
  
  			throw error;
  		}
  	}
  
  	_tick(ms) {
  		const nextRemovalTime = this._nextRemovalTime;
  
  		if (!nextRemovalTime || ms < nextRemovalTime) {
  			clearTimeout(this._removalTimeout);
  
  			this._nextRemovalTime = ms;
  
  			this._removalTimeout = setTimeout(() => {
  				this._nextRemovalTime = false;
  
  				let nextExpiry = Infinity;
  
  				const now = Date.now();
  
  				for (const [hostname, entries] of this._cache) {
  					const expires = entries[kExpires];
  
  					if (now >= expires) {
  						this._cache.delete(hostname);
  					} else if (expires < nextExpiry) {
  						nextExpiry = expires;
  					}
  				}
  
  				if (nextExpiry !== Infinity) {
  					this._tick(nextExpiry - now);
  				}
  			}, ms);
  
  			/* istanbul ignore next: There is no `timeout.unref()` when running inside an Electron renderer */
  			if (this._removalTimeout.unref) {
  				this._removalTimeout.unref();
  			}
  		}
  	}
  
  	install(agent) {
  		verifyAgent(agent);
  
  		if (kCacheableLookupCreateConnection in agent) {
  			throw new Error('CacheableLookup has been already installed');
  		}
  
  		agent[kCacheableLookupCreateConnection] = agent.createConnection;
  		agent[kCacheableLookupInstance] = this;
  
  		agent.createConnection = (options, callback) => {
  			if (!('lookup' in options)) {
  				options.lookup = this.lookup;
  			}
  
  			return agent[kCacheableLookupCreateConnection](options, callback);
  		};
  	}
  
  	uninstall(agent) {
  		verifyAgent(agent);
  
  		if (agent[kCacheableLookupCreateConnection]) {
  			if (agent[kCacheableLookupInstance] !== this) {
  				throw new Error('The agent is not owned by this CacheableLookup instance');
  			}
  
  			agent.createConnection = agent[kCacheableLookupCreateConnection];
  
  			delete agent[kCacheableLookupCreateConnection];
  			delete agent[kCacheableLookupInstance];
  		}
  	}
  
  	updateInterfaceInfo() {
  		const {_iface} = this;
  
  		this._iface = getIfaceInfo();
  
  		if ((_iface.has4 && !this._iface.has4) || (_iface.has6 && !this._iface.has6)) {
  			this._cache.clear();
  		}
  	}
  
  	clear(hostname) {
  		if (hostname) {
  			this._cache.delete(hostname);
  			return;
  		}
  
  		this._cache.clear();
  	}
  }
  
  module.exports = CacheableLookup;
  module.exports.default = CacheableLookup;
  
  
  /***/ }),
  
  /***/ 577:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  }) : (function(o, m, k, k2) {
      if (k2 === undefined) k2 = k;
      o[k2] = m[k];
  }));
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
      for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  };
  Object.defineProperty(exports, "__esModule", { value: true });
  const events_1 = __webpack_require__(614);
  const is_1 = __webpack_require__(534);
  const PCancelable = __webpack_require__(557);
  const types_1 = __webpack_require__(36);
  const parse_body_1 = __webpack_require__(121);
  const core_1 = __webpack_require__(946);
  const proxy_events_1 = __webpack_require__(628);
  const get_buffer_1 = __webpack_require__(452);
  const is_response_ok_1 = __webpack_require__(422);
  const proxiedRequestEvents = [
      'request',
      'response',
      'redirect',
      'uploadProgress',
      'downloadProgress'
  ];
  function asPromise(normalizedOptions) {
      let globalRequest;
      let globalResponse;
      const emitter = new events_1.EventEmitter();
      const promise = new PCancelable((resolve, reject, onCancel) => {
          const makeRequest = (retryCount) => {
              const request = new core_1.default(undefined, normalizedOptions);
              request.retryCount = retryCount;
              request._noPipe = true;
              onCancel(() => request.destroy());
              onCancel.shouldReject = false;
              onCancel(() => reject(new types_1.CancelError(request)));
              globalRequest = request;
              request.once('response', async (response) => {
                  var _a;
                  response.retryCount = retryCount;
                  if (response.request.aborted) {
                      // Canceled while downloading - will throw a `CancelError` or `TimeoutError` error
                      return;
                  }
                  // Download body
                  let rawBody;
                  try {
                      rawBody = await get_buffer_1.default(request);
                      response.rawBody = rawBody;
                  }
                  catch (_b) {
                      // The same error is caught below.
                      // See request.once('error')
                      return;
                  }
                  if (request._isAboutToError) {
                      return;
                  }
                  // Parse body
                  const contentEncoding = ((_a = response.headers['content-encoding']) !== null && _a !== void 0 ? _a : '').toLowerCase();
                  const isCompressed = ['gzip', 'deflate', 'br'].includes(contentEncoding);
                  const { options } = request;
                  if (isCompressed && !options.decompress) {
                      response.body = rawBody;
                  }
                  else {
                      try {
                          response.body = parse_body_1.default(response, options.responseType, options.parseJson, options.encoding);
                      }
                      catch (error) {
                          // Fallback to `utf8`
                          response.body = rawBody.toString();
                          if (is_response_ok_1.isResponseOk(response)) {
                              request._beforeError(error);
                              return;
                          }
                      }
                  }
                  try {
                      for (const [index, hook] of options.hooks.afterResponse.entries()) {
                          // @ts-expect-error TS doesn't notice that CancelableRequest is a Promise
                          // eslint-disable-next-line no-await-in-loop
                          response = await hook(response, async (updatedOptions) => {
                              const typedOptions = core_1.default.normalizeArguments(undefined, {
                                  ...updatedOptions,
                                  retry: {
                                      calculateDelay: () => 0
                                  },
                                  throwHttpErrors: false,
                                  resolveBodyOnly: false
                              }, options);
                              // Remove any further hooks for that request, because we'll call them anyway.
                              // The loop continues. We don't want duplicates (asPromise recursion).
                              typedOptions.hooks.afterResponse = typedOptions.hooks.afterResponse.slice(0, index);
                              for (const hook of typedOptions.hooks.beforeRetry) {
                                  // eslint-disable-next-line no-await-in-loop
                                  await hook(typedOptions);
                              }
                              const promise = asPromise(typedOptions);
                              onCancel(() => {
                                  promise.catch(() => { });
                                  promise.cancel();
                              });
                              return promise;
                          });
                      }
                  }
                  catch (error) {
                      request._beforeError(new types_1.RequestError(error.message, error, request));
                      return;
                  }
                  if (!is_response_ok_1.isResponseOk(response)) {
                      request._beforeError(new types_1.HTTPError(response));
                      return;
                  }
                  globalResponse = response;
                  resolve(request.options.resolveBodyOnly ? response.body : response);
              });
              const onError = (error) => {
                  if (promise.isCanceled) {
                      return;
                  }
                  const { options } = request;
                  if (error instanceof types_1.HTTPError && !options.throwHttpErrors) {
                      const { response } = error;
                      resolve(request.options.resolveBodyOnly ? response.body : response);
                      return;
                  }
                  reject(error);
              };
              request.once('error', onError);
              request.once('retry', (newRetryCount, error) => {
                  var _a;
                  if (is_1.default.nodeStream((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.body)) {
                      onError(error);
                      return;
                  }
                  makeRequest(newRetryCount);
              });
              proxy_events_1.default(request, emitter, proxiedRequestEvents);
          };
          makeRequest(0);
      });
      promise.on = (event, fn) => {
          emitter.on(event, fn);
          return promise;
      };
      const shortcut = (responseType) => {
          const newPromise = (async () => {
              // Wait until downloading has ended
              await promise;
              const { options } = globalResponse.request;
              return parse_body_1.default(globalResponse, responseType, options.parseJson, options.encoding);
          })();
          Object.defineProperties(newPromise, Object.getOwnPropertyDescriptors(promise));
          return newPromise;
      };
      promise.json = () => {
          const { headers } = globalRequest.options;
          if (!globalRequest.writableFinished && headers.accept === undefined) {
              headers.accept = 'application/json';
          }
          return shortcut('json');
      };
      promise.buffer = () => shortcut('buffer');
      promise.text = () => shortcut('text');
      return promise;
  }
  exports.default = asPromise;
  __exportStar(__webpack_require__(36), exports);
  
  
  /***/ }),
  
  /***/ 594:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.retryAfterStatusCodes = void 0;
  exports.retryAfterStatusCodes = new Set([413, 429, 503]);
  const calculateRetryDelay = ({ attemptCount, retryOptions, error, retryAfter }) => {
      if (attemptCount > retryOptions.limit) {
          return 0;
      }
      const hasMethod = retryOptions.methods.includes(error.options.method);
      const hasErrorCode = retryOptions.errorCodes.includes(error.code);
      const hasStatusCode = error.response && retryOptions.statusCodes.includes(error.response.statusCode);
      if (!hasMethod || (!hasErrorCode && !hasStatusCode)) {
          return 0;
      }
      if (error.response) {
          if (retryAfter) {
              if (retryOptions.maxRetryAfter === undefined || retryAfter > retryOptions.maxRetryAfter) {
                  return 0;
              }
              return retryAfter;
          }
          if (error.response.statusCode === 413) {
              return 0;
          }
      }
      const noise = Math.random() * 100;
      return ((2 ** (attemptCount - 1)) * 1000) + noise;
  };
  exports.default = calculateRetryDelay;
  
  
  /***/ }),
  
  /***/ 605:
  /***/ (function(module) {
  
  module.exports = require("http");
  
  /***/ }),
  
  /***/ 614:
  /***/ (function(module) {
  
  module.exports = require("events");
  
  /***/ }),
  
  /***/ 622:
  /***/ (function(module) {
  
  module.exports = require("path");
  
  /***/ }),
  
  /***/ 628:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  function default_1(from, to, events) {
      const fns = {};
      for (const event of events) {
          fns[event] = (...args) => {
              to.emit(event, ...args);
          };
          from.on(event, fns[event]);
      }
      return () => {
          for (const event of events) {
              from.off(event, fns[event]);
          }
      };
  }
  exports.default = default_1;
  
  
  /***/ }),
  
  /***/ 631:
  /***/ (function(module) {
  
  module.exports = require("net");
  
  /***/ }),
  
  /***/ 669:
  /***/ (function(module) {
  
  module.exports = require("util");
  
  /***/ }),
  
  /***/ 676:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  const auth = __webpack_require__(151);
  const secrets = __webpack_require__(461);
  
  module.exports = {
      auth,
      secrets
  };
  
  /***/ }),
  
  /***/ 699:
  /***/ (function(module) {
  
  "use strict";
  
  /* istanbul ignore file: https://github.com/nodejs/node/blob/master/lib/internal/errors.js */
  
  const makeError = (Base, key, getMessage) => {
  	module.exports[key] = class NodeError extends Base {
  		constructor(...args) {
  			super(typeof getMessage === 'string' ? getMessage : getMessage(args));
  			this.name = `${super.name} [${key}]`;
  			this.code = key;
  		}
  	};
  };
  
  makeError(TypeError, 'ERR_INVALID_ARG_TYPE', args => {
  	const type = args[0].includes('.') ? 'property' : 'argument';
  
  	let valid = args[1];
  	const isManyTypes = Array.isArray(valid);
  
  	if (isManyTypes) {
  		valid = `${valid.slice(0, -1).join(', ')} or ${valid.slice(-1)}`;
  	}
  
  	return `The "${args[0]}" ${type} must be ${isManyTypes ? 'one of' : 'of'} type ${valid}. Received ${typeof args[2]}`;
  });
  
  makeError(TypeError, 'ERR_INVALID_PROTOCOL', args => {
  	return `Protocol "${args[0]}" not supported. Expected "${args[1]}"`;
  });
  
  makeError(Error, 'ERR_HTTP_HEADERS_SENT', args => {
  	return `Cannot ${args[0]} headers after they are sent to the client`;
  });
  
  makeError(TypeError, 'ERR_INVALID_HTTP_TOKEN', args => {
  	return `${args[0]} must be a valid HTTP token [${args[1]}]`;
  });
  
  makeError(TypeError, 'ERR_HTTP_INVALID_HEADER_VALUE', args => {
  	return `Invalid value "${args[0]} for header "${args[1]}"`;
  });
  
  makeError(TypeError, 'ERR_INVALID_CHAR', args => {
  	return `Invalid character in ${args[0]} [${args[1]}]`;
  });
  
  
  /***/ }),
  
  /***/ 723:
  /***/ (function(module) {
  
  "use strict";
  
  
  module.exports = header => {
  	switch (header) {
  		case ':method':
  		case ':scheme':
  		case ':authority':
  		case ':path':
  			return true;
  		default:
  			return false;
  	}
  };
  
  
  /***/ }),
  
  /***/ 738:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.dnsLookupIpVersionToFamily = exports.isDnsLookupIpVersion = void 0;
  const conversionTable = {
      auto: 0,
      ipv4: 4,
      ipv6: 6
  };
  exports.isDnsLookupIpVersion = (value) => {
      return value in conversionTable;
  };
  exports.dnsLookupIpVersionToFamily = (dnsLookupIpVersion) => {
      if (exports.isDnsLookupIpVersion(dnsLookupIpVersion)) {
          return conversionTable[dnsLookupIpVersion];
      }
      throw new Error('Invalid DNS lookup IP version');
  };
  
  
  /***/ }),
  
  /***/ 747:
  /***/ (function(module) {
  
  module.exports = require("fs");
  
  /***/ }),
  
  /***/ 750:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const {Readable} = __webpack_require__(413);
  
  class IncomingMessage extends Readable {
  	constructor(socket, highWaterMark) {
  		super({
  			highWaterMark,
  			autoDestroy: false
  		});
  
  		this.statusCode = null;
  		this.statusMessage = '';
  		this.httpVersion = '2.0';
  		this.httpVersionMajor = 2;
  		this.httpVersionMinor = 0;
  		this.headers = {};
  		this.trailers = {};
  		this.req = null;
  
  		this.aborted = false;
  		this.complete = false;
  		this.upgrade = null;
  
  		this.rawHeaders = [];
  		this.rawTrailers = [];
  
  		this.socket = socket;
  		this.connection = socket;
  
  		this._dumped = false;
  	}
  
  	_destroy(error) {
  		this.req._request.destroy(error);
  	}
  
  	setTimeout(ms, callback) {
  		this.req.setTimeout(ms, callback);
  		return this;
  	}
  
  	_dump() {
  		if (!this._dumped) {
  			this._dumped = true;
  
  			this.removeAllListeners('data');
  			this.resume();
  		}
  	}
  
  	_read() {
  		if (this.req) {
  			this.req._request.resume();
  		}
  	}
  }
  
  module.exports = IncomingMessage;
  
  
  /***/ }),
  
  /***/ 751:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const net = __webpack_require__(631);
  /* istanbul ignore file: https://github.com/nodejs/node/blob/v13.0.1/lib/_http_agent.js */
  
  module.exports = options => {
  	let servername = options.host;
  	const hostHeader = options.headers && options.headers.host;
  
  	if (hostHeader) {
  		if (hostHeader.startsWith('[')) {
  			const index = hostHeader.indexOf(']');
  			if (index === -1) {
  				servername = hostHeader;
  			} else {
  				servername = hostHeader.slice(1, -1);
  			}
  		} else {
  			servername = hostHeader.split(':', 1)[0];
  		}
  	}
  
  	if (net.isIP(servername)) {
  		return '';
  	}
  
  	return servername;
  };
  
  
  /***/ }),
  
  /***/ 761:
  /***/ (function(module) {
  
  module.exports = require("zlib");
  
  /***/ }),
  
  /***/ 784:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  // When attaching listeners, it's very easy to forget about them.
  // Especially if you do error handling and set timeouts.
  // So instead of checking if it's proper to throw an error on every timeout ever,
  // use this simple tool which will remove all listeners you have attached.
  exports.default = () => {
      const handlers = [];
      return {
          once(origin, event, fn) {
              origin.once(event, fn);
              handlers.push({ origin, event, fn });
          },
          unhandleAll() {
              for (const handler of handlers) {
                  const { origin, event, fn } = handler;
                  origin.removeListener(event, fn);
              }
              handlers.length = 0;
          }
      };
  };
  
  
  /***/ }),
  
  /***/ 786:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const fs_1 = __webpack_require__(747);
  const util_1 = __webpack_require__(669);
  const is_1 = __webpack_require__(534);
  const is_form_data_1 = __webpack_require__(460);
  const statAsync = util_1.promisify(fs_1.stat);
  exports.default = async (body, headers) => {
      if (headers && 'content-length' in headers) {
          return Number(headers['content-length']);
      }
      if (!body) {
          return 0;
      }
      if (is_1.default.string(body)) {
          return Buffer.byteLength(body);
      }
      if (is_1.default.buffer(body)) {
          return body.length;
      }
      if (is_form_data_1.default(body)) {
          return util_1.promisify(body.getLength.bind(body))();
      }
      if (body instanceof fs_1.ReadStream) {
          const { size } = await statAsync(body.path);
          return size;
      }
      return undefined;
  };
  
  
  /***/ }),
  
  /***/ 790:
  /***/ (function(module, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const tls_1 = __webpack_require__(16);
  const deferToConnect = (socket, fn) => {
      let listeners;
      if (typeof fn === 'function') {
          const connect = fn;
          listeners = { connect };
      }
      else {
          listeners = fn;
      }
      const hasConnectListener = typeof listeners.connect === 'function';
      const hasSecureConnectListener = typeof listeners.secureConnect === 'function';
      const hasCloseListener = typeof listeners.close === 'function';
      const onConnect = () => {
          if (hasConnectListener) {
              listeners.connect();
          }
          if (socket instanceof tls_1.TLSSocket && hasSecureConnectListener) {
              if (socket.authorized) {
                  listeners.secureConnect();
              }
              else if (!socket.authorizationError) {
                  socket.once('secureConnect', listeners.secureConnect);
              }
          }
          if (hasCloseListener) {
              socket.once('close', listeners.close);
          }
      };
      if (socket.writable && !socket.connecting) {
          onConnect();
      }
      else if (socket.connecting) {
          socket.once('connect', onConnect);
      }
      else if (socket.destroyed && hasCloseListener) {
          listeners.close(socket._hadError);
      }
  };
  exports.default = deferToConnect;
  // For CommonJS default export support
  module.exports = deferToConnect;
  module.exports.default = deferToConnect;
  
  
  /***/ }),
  
  /***/ 811:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.TimeoutError = void 0;
  const net = __webpack_require__(631);
  const unhandle_1 = __webpack_require__(784);
  const reentry = Symbol('reentry');
  const noop = () => { };
  class TimeoutError extends Error {
      constructor(threshold, event) {
          super(`Timeout awaiting '${event}' for ${threshold}ms`);
          this.event = event;
          this.name = 'TimeoutError';
          this.code = 'ETIMEDOUT';
      }
  }
  exports.TimeoutError = TimeoutError;
  exports.default = (request, delays, options) => {
      if (reentry in request) {
          return noop;
      }
      request[reentry] = true;
      const cancelers = [];
      const { once, unhandleAll } = unhandle_1.default();
      const addTimeout = (delay, callback, event) => {
          var _a;
          const timeout = setTimeout(callback, delay, delay, event);
          (_a = timeout.unref) === null || _a === void 0 ? void 0 : _a.call(timeout);
          const cancel = () => {
              clearTimeout(timeout);
          };
          cancelers.push(cancel);
          return cancel;
      };
      const { host, hostname } = options;
      const timeoutHandler = (delay, event) => {
          request.destroy(new TimeoutError(delay, event));
      };
      const cancelTimeouts = () => {
          for (const cancel of cancelers) {
              cancel();
          }
          unhandleAll();
      };
      request.once('error', error => {
          cancelTimeouts();
          // Save original behavior
          /* istanbul ignore next */
          if (request.listenerCount('error') === 0) {
              throw error;
          }
      });
      request.once('close', cancelTimeouts);
      once(request, 'response', (response) => {
          once(response, 'end', cancelTimeouts);
      });
      if (typeof delays.request !== 'undefined') {
          addTimeout(delays.request, timeoutHandler, 'request');
      }
      if (typeof delays.socket !== 'undefined') {
          const socketTimeoutHandler = () => {
              timeoutHandler(delays.socket, 'socket');
          };
          request.setTimeout(delays.socket, socketTimeoutHandler);
          // `request.setTimeout(0)` causes a memory leak.
          // We can just remove the listener and forget about the timer - it's unreffed.
          // See https://github.com/sindresorhus/got/issues/690
          cancelers.push(() => {
              request.removeListener('timeout', socketTimeoutHandler);
          });
      }
      once(request, 'socket', (socket) => {
          var _a;
          const { socketPath } = request;
          /* istanbul ignore next: hard to test */
          if (socket.connecting) {
              const hasPath = Boolean(socketPath !== null && socketPath !== void 0 ? socketPath : net.isIP((_a = hostname !== null && hostname !== void 0 ? hostname : host) !== null && _a !== void 0 ? _a : '') !== 0);
              if (typeof delays.lookup !== 'undefined' && !hasPath && typeof socket.address().address === 'undefined') {
                  const cancelTimeout = addTimeout(delays.lookup, timeoutHandler, 'lookup');
                  once(socket, 'lookup', cancelTimeout);
              }
              if (typeof delays.connect !== 'undefined') {
                  const timeConnect = () => addTimeout(delays.connect, timeoutHandler, 'connect');
                  if (hasPath) {
                      once(socket, 'connect', timeConnect());
                  }
                  else {
                      once(socket, 'lookup', (error) => {
                          if (error === null) {
                              once(socket, 'connect', timeConnect());
                          }
                      });
                  }
              }
              if (typeof delays.secureConnect !== 'undefined' && options.protocol === 'https:') {
                  once(socket, 'connect', () => {
                      const cancelTimeout = addTimeout(delays.secureConnect, timeoutHandler, 'secureConnect');
                      once(socket, 'secureConnect', cancelTimeout);
                  });
              }
          }
          if (typeof delays.send !== 'undefined') {
              const timeRequest = () => addTimeout(delays.send, timeoutHandler, 'send');
              /* istanbul ignore next: hard to test */
              if (socket.connecting) {
                  once(socket, 'connect', () => {
                      once(request, 'upload-complete', timeRequest());
                  });
              }
              else {
                  once(request, 'upload-complete', timeRequest());
              }
          }
      });
      if (typeof delays.response !== 'undefined') {
          once(request, 'upload-complete', () => {
              const cancelTimeout = addTimeout(delays.response, timeoutHandler, 'response');
              once(request, 'response', cancelTimeout);
          });
      }
      return cancelTimeouts;
  };
  
  
  /***/ }),
  
  /***/ 835:
  /***/ (function(module) {
  
  module.exports = require("url");
  
  /***/ }),
  
  /***/ 839:
  /***/ (function(__unusedmodule, exports) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  
  
  /***/ }),
  
  /***/ 861:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const {Transform, PassThrough} = __webpack_require__(413);
  const zlib = __webpack_require__(761);
  const mimicResponse = __webpack_require__(537);
  
  module.exports = response => {
  	const contentEncoding = (response.headers['content-encoding'] || '').toLowerCase();
  
  	if (!['gzip', 'deflate', 'br'].includes(contentEncoding)) {
  		return response;
  	}
  
  	// TODO: Remove this when targeting Node.js 12.
  	const isBrotli = contentEncoding === 'br';
  	if (isBrotli && typeof zlib.createBrotliDecompress !== 'function') {
  		response.destroy(new Error('Brotli is not supported on Node.js < 12'));
  		return response;
  	}
  
  	let isEmpty = true;
  
  	const checker = new Transform({
  		transform(data, _encoding, callback) {
  			isEmpty = false;
  
  			callback(null, data);
  		},
  
  		flush(callback) {
  			callback();
  		}
  	});
  
  	const finalStream = new PassThrough({
  		autoDestroy: false,
  		destroy(error, callback) {
  			response.destroy();
  
  			callback(error);
  		}
  	});
  
  	const decompressStream = isBrotli ? zlib.createBrotliDecompress() : zlib.createUnzip();
  
  	decompressStream.once('error', error => {
  		if (isEmpty && !response.readable) {
  			finalStream.end();
  			return;
  		}
  
  		finalStream.destroy(error);
  	});
  
  	mimicResponse(response, finalStream);
  	response.pipe(checker).pipe(decompressStream).pipe(finalStream);
  
  	return finalStream;
  };
  
  
  /***/ }),
  
  /***/ 881:
  /***/ (function(module) {
  
  module.exports = require("dns");
  
  /***/ }),
  
  /***/ 899:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const EventEmitter = __webpack_require__(614);
  const tls = __webpack_require__(16);
  const http2 = __webpack_require__(565);
  const QuickLRU = __webpack_require__(904);
  
  const kCurrentStreamsCount = Symbol('currentStreamsCount');
  const kRequest = Symbol('request');
  const kOriginSet = Symbol('cachedOriginSet');
  const kGracefullyClosing = Symbol('gracefullyClosing');
  
  const nameKeys = [
  	// `http2.connect()` options
  	'maxDeflateDynamicTableSize',
  	'maxSessionMemory',
  	'maxHeaderListPairs',
  	'maxOutstandingPings',
  	'maxReservedRemoteStreams',
  	'maxSendHeaderBlockLength',
  	'paddingStrategy',
  
  	// `tls.connect()` options
  	'localAddress',
  	'path',
  	'rejectUnauthorized',
  	'minDHSize',
  
  	// `tls.createSecureContext()` options
  	'ca',
  	'cert',
  	'clientCertEngine',
  	'ciphers',
  	'key',
  	'pfx',
  	'servername',
  	'minVersion',
  	'maxVersion',
  	'secureProtocol',
  	'crl',
  	'honorCipherOrder',
  	'ecdhCurve',
  	'dhparam',
  	'secureOptions',
  	'sessionIdContext'
  ];
  
  const getSortedIndex = (array, value, compare) => {
  	let low = 0;
  	let high = array.length;
  
  	while (low < high) {
  		const mid = (low + high) >>> 1;
  
  		/* istanbul ignore next */
  		if (compare(array[mid], value)) {
  			// This never gets called because we use descending sort. Better to have this anyway.
  			low = mid + 1;
  		} else {
  			high = mid;
  		}
  	}
  
  	return low;
  };
  
  const compareSessions = (a, b) => {
  	return a.remoteSettings.maxConcurrentStreams > b.remoteSettings.maxConcurrentStreams;
  };
  
  // See https://tools.ietf.org/html/rfc8336
  const closeCoveredSessions = (where, session) => {
  	// Clients SHOULD NOT emit new requests on any connection whose Origin
  	// Set is a proper subset of another connection's Origin Set, and they
  	// SHOULD close it once all outstanding requests are satisfied.
  	for (const coveredSession of where) {
  		if (
  			// The set is a proper subset when its length is less than the other set.
  			coveredSession[kOriginSet].length < session[kOriginSet].length &&
  
  			// And the other set includes all elements of the subset.
  			coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) &&
  
  			// Makes sure that the session can handle all requests from the covered session.
  			coveredSession[kCurrentStreamsCount] + session[kCurrentStreamsCount] <= session.remoteSettings.maxConcurrentStreams
  		) {
  			// This allows pending requests to finish and prevents making new requests.
  			gracefullyClose(coveredSession);
  		}
  	}
  };
  
  // This is basically inverted `closeCoveredSessions(...)`.
  const closeSessionIfCovered = (where, coveredSession) => {
  	for (const session of where) {
  		if (
  			coveredSession[kOriginSet].length < session[kOriginSet].length &&
  			coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) &&
  			coveredSession[kCurrentStreamsCount] + session[kCurrentStreamsCount] <= session.remoteSettings.maxConcurrentStreams
  		) {
  			gracefullyClose(coveredSession);
  		}
  	}
  };
  
  const getSessions = ({agent, isFree}) => {
  	const result = {};
  
  	// eslint-disable-next-line guard-for-in
  	for (const normalizedOptions in agent.sessions) {
  		const sessions = agent.sessions[normalizedOptions];
  
  		const filtered = sessions.filter(session => {
  			const result = session[Agent.kCurrentStreamsCount] < session.remoteSettings.maxConcurrentStreams;
  
  			return isFree ? result : !result;
  		});
  
  		if (filtered.length !== 0) {
  			result[normalizedOptions] = filtered;
  		}
  	}
  
  	return result;
  };
  
  const gracefullyClose = session => {
  	session[kGracefullyClosing] = true;
  
  	if (session[kCurrentStreamsCount] === 0) {
  		session.close();
  	}
  };
  
  class Agent extends EventEmitter {
  	constructor({timeout = 60000, maxSessions = Infinity, maxFreeSessions = 10, maxCachedTlsSessions = 100} = {}) {
  		super();
  
  		// A session is considered busy when its current streams count
  		// is equal to or greater than the `maxConcurrentStreams` value.
  
  		// A session is considered free when its current streams count
  		// is less than the `maxConcurrentStreams` value.
  
  		// SESSIONS[NORMALIZED_OPTIONS] = [];
  		this.sessions = {};
  
  		// The queue for creating new sessions. It looks like this:
  		// QUEUE[NORMALIZED_OPTIONS][NORMALIZED_ORIGIN] = ENTRY_FUNCTION
  		//
  		// The entry function has `listeners`, `completed` and `destroyed` properties.
  		// `listeners` is an array of objects containing `resolve` and `reject` functions.
  		// `completed` is a boolean. It's set to true after ENTRY_FUNCTION is executed.
  		// `destroyed` is a boolean. If it's set to true, the session will be destroyed if hasn't connected yet.
  		this.queue = {};
  
  		// Each session will use this timeout value.
  		this.timeout = timeout;
  
  		// Max sessions in total
  		this.maxSessions = maxSessions;
  
  		// Max free sessions in total
  		// TODO: decreasing `maxFreeSessions` should close some sessions
  		this.maxFreeSessions = maxFreeSessions;
  
  		this._freeSessionsCount = 0;
  		this._sessionsCount = 0;
  
  		// We don't support push streams by default.
  		this.settings = {
  			enablePush: false
  		};
  
  		// Reusing TLS sessions increases performance.
  		this.tlsSessionCache = new QuickLRU({maxSize: maxCachedTlsSessions});
  	}
  
  	static normalizeOrigin(url, servername) {
  		if (typeof url === 'string') {
  			url = new URL(url);
  		}
  
  		if (servername && url.hostname !== servername) {
  			url.hostname = servername;
  		}
  
  		return url.origin;
  	}
  
  	normalizeOptions(options) {
  		let normalized = '';
  
  		if (options) {
  			for (const key of nameKeys) {
  				if (options[key]) {
  					normalized += `:${options[key]}`;
  				}
  			}
  		}
  
  		return normalized;
  	}
  
  	_tryToCreateNewSession(normalizedOptions, normalizedOrigin) {
  		if (!(normalizedOptions in this.queue) || !(normalizedOrigin in this.queue[normalizedOptions])) {
  			return;
  		}
  
  		const item = this.queue[normalizedOptions][normalizedOrigin];
  
  		// The entry function can be run only once.
  		// BUG: The session may be never created when:
  		// - the first condition is false AND
  		// - this function is never called with the same arguments in the future.
  		if (this._sessionsCount < this.maxSessions && !item.completed) {
  			item.completed = true;
  
  			item();
  		}
  	}
  
  	getSession(origin, options, listeners) {
  		return new Promise((resolve, reject) => {
  			if (Array.isArray(listeners)) {
  				listeners = [...listeners];
  
  				// Resolve the current promise ASAP, we're just moving the listeners.
  				// They will be executed at a different time.
  				resolve();
  			} else {
  				listeners = [{resolve, reject}];
  			}
  
  			const normalizedOptions = this.normalizeOptions(options);
  			const normalizedOrigin = Agent.normalizeOrigin(origin, options && options.servername);
  
  			if (normalizedOrigin === undefined) {
  				for (const {reject} of listeners) {
  					reject(new TypeError('The `origin` argument needs to be a string or an URL object'));
  				}
  
  				return;
  			}
  
  			if (normalizedOptions in this.sessions) {
  				const sessions = this.sessions[normalizedOptions];
  
  				let maxConcurrentStreams = -1;
  				let currentStreamsCount = -1;
  				let optimalSession;
  
  				// We could just do this.sessions[normalizedOptions].find(...) but that isn't optimal.
  				// Additionally, we are looking for session which has biggest current pending streams count.
  				for (const session of sessions) {
  					const sessionMaxConcurrentStreams = session.remoteSettings.maxConcurrentStreams;
  
  					if (sessionMaxConcurrentStreams < maxConcurrentStreams) {
  						break;
  					}
  
  					if (session[kOriginSet].includes(normalizedOrigin)) {
  						const sessionCurrentStreamsCount = session[kCurrentStreamsCount];
  
  						if (
  							sessionCurrentStreamsCount >= sessionMaxConcurrentStreams ||
  							session[kGracefullyClosing] ||
  							// Unfortunately the `close` event isn't called immediately,
  							// so `session.destroyed` is `true`, but `session.closed` is `false`.
  							session.destroyed
  						) {
  							continue;
  						}
  
  						// We only need set this once.
  						if (!optimalSession) {
  							maxConcurrentStreams = sessionMaxConcurrentStreams;
  						}
  
  						// We're looking for the session which has biggest current pending stream count,
  						// in order to minimalize the amount of active sessions.
  						if (sessionCurrentStreamsCount > currentStreamsCount) {
  							optimalSession = session;
  							currentStreamsCount = sessionCurrentStreamsCount;
  						}
  					}
  				}
  
  				if (optimalSession) {
  					/* istanbul ignore next: safety check */
  					if (listeners.length !== 1) {
  						for (const {reject} of listeners) {
  							const error = new Error(
  								`Expected the length of listeners to be 1, got ${listeners.length}.\n` +
  								'Please report this to https://github.com/szmarczak/http2-wrapper/'
  							);
  
  							reject(error);
  						}
  
  						return;
  					}
  
  					listeners[0].resolve(optimalSession);
  					return;
  				}
  			}
  
  			if (normalizedOptions in this.queue) {
  				if (normalizedOrigin in this.queue[normalizedOptions]) {
  					// There's already an item in the queue, just attach ourselves to it.
  					this.queue[normalizedOptions][normalizedOrigin].listeners.push(...listeners);
  
  					// This shouldn't be executed here.
  					// See the comment inside _tryToCreateNewSession.
  					this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
  					return;
  				}
  			} else {
  				this.queue[normalizedOptions] = {};
  			}
  
  			// The entry must be removed from the queue IMMEDIATELY when:
  			// 1. the session connects successfully,
  			// 2. an error occurs.
  			const removeFromQueue = () => {
  				// Our entry can be replaced. We cannot remove the new one.
  				if (normalizedOptions in this.queue && this.queue[normalizedOptions][normalizedOrigin] === entry) {
  					delete this.queue[normalizedOptions][normalizedOrigin];
  
  					if (Object.keys(this.queue[normalizedOptions]).length === 0) {
  						delete this.queue[normalizedOptions];
  					}
  				}
  			};
  
  			// The main logic is here
  			const entry = () => {
  				const name = `${normalizedOrigin}:${normalizedOptions}`;
  				let receivedSettings = false;
  
  				try {
  					const session = http2.connect(origin, {
  						createConnection: this.createConnection,
  						settings: this.settings,
  						session: this.tlsSessionCache.get(name),
  						...options
  					});
  					session[kCurrentStreamsCount] = 0;
  					session[kGracefullyClosing] = false;
  
  					const isFree = () => session[kCurrentStreamsCount] < session.remoteSettings.maxConcurrentStreams;
  					let wasFree = true;
  
  					session.socket.once('session', tlsSession => {
  						this.tlsSessionCache.set(name, tlsSession);
  					});
  
  					session.once('error', error => {
  						// Listeners are empty when the session successfully connected.
  						for (const {reject} of listeners) {
  							reject(error);
  						}
  
  						// The connection got broken, purge the cache.
  						this.tlsSessionCache.delete(name);
  					});
  
  					session.setTimeout(this.timeout, () => {
  						// Terminates all streams owned by this session.
  						// TODO: Maybe the streams should have a "Session timed out" error?
  						session.destroy();
  					});
  
  					session.once('close', () => {
  						if (receivedSettings) {
  							// 1. If it wasn't free then no need to decrease because
  							//    it has been decreased already in session.request().
  							// 2. `stream.once('close')` won't increment the count
  							//    because the session is already closed.
  							if (wasFree) {
  								this._freeSessionsCount--;
  							}
  
  							this._sessionsCount--;
  
  							// This cannot be moved to the stream logic,
  							// because there may be a session that hadn't made a single request.
  							const where = this.sessions[normalizedOptions];
  							where.splice(where.indexOf(session), 1);
  
  							if (where.length === 0) {
  								delete this.sessions[normalizedOptions];
  							}
  						} else {
  							// Broken connection
  							const error = new Error('Session closed without receiving a SETTINGS frame');
  							error.code = 'HTTP2WRAPPER_NOSETTINGS';
  
  							for (const {reject} of listeners) {
  								reject(error);
  							}
  
  							removeFromQueue();
  						}
  
  						// There may be another session awaiting.
  						this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
  					});
  
  					// Iterates over the queue and processes listeners.
  					const processListeners = () => {
  						if (!(normalizedOptions in this.queue) || !isFree()) {
  							return;
  						}
  
  						for (const origin of session[kOriginSet]) {
  							if (origin in this.queue[normalizedOptions]) {
  								const {listeners} = this.queue[normalizedOptions][origin];
  
  								// Prevents session overloading.
  								while (listeners.length !== 0 && isFree()) {
  									// We assume `resolve(...)` calls `request(...)` *directly*,
  									// otherwise the session will get overloaded.
  									listeners.shift().resolve(session);
  								}
  
  								const where = this.queue[normalizedOptions];
  								if (where[origin].listeners.length === 0) {
  									delete where[origin];
  
  									if (Object.keys(where).length === 0) {
  										delete this.queue[normalizedOptions];
  										break;
  									}
  								}
  
  								// We're no longer free, no point in continuing.
  								if (!isFree()) {
  									break;
  								}
  							}
  						}
  					};
  
  					// The Origin Set cannot shrink. No need to check if it suddenly became covered by another one.
  					session.on('origin', () => {
  						session[kOriginSet] = session.originSet;
  
  						if (!isFree()) {
  							// The session is full.
  							return;
  						}
  
  						processListeners();
  
  						// Close covered sessions (if possible).
  						closeCoveredSessions(this.sessions[normalizedOptions], session);
  					});
  
  					session.once('remoteSettings', () => {
  						// Fix Node.js bug preventing the process from exiting
  						session.ref();
  						session.unref();
  
  						this._sessionsCount++;
  
  						// The Agent could have been destroyed already.
  						if (entry.destroyed) {
  							const error = new Error('Agent has been destroyed');
  
  							for (const listener of listeners) {
  								listener.reject(error);
  							}
  
  							session.destroy();
  							return;
  						}
  
  						session[kOriginSet] = session.originSet;
  
  						{
  							const where = this.sessions;
  
  							if (normalizedOptions in where) {
  								const sessions = where[normalizedOptions];
  								sessions.splice(getSortedIndex(sessions, session, compareSessions), 0, session);
  							} else {
  								where[normalizedOptions] = [session];
  							}
  						}
  
  						this._freeSessionsCount += 1;
  						receivedSettings = true;
  
  						this.emit('session', session);
  
  						processListeners();
  						removeFromQueue();
  
  						// TODO: Close last recently used (or least used?) session
  						if (session[kCurrentStreamsCount] === 0 && this._freeSessionsCount > this.maxFreeSessions) {
  							session.close();
  						}
  
  						// Check if we haven't managed to execute all listeners.
  						if (listeners.length !== 0) {
  							// Request for a new session with predefined listeners.
  							this.getSession(normalizedOrigin, options, listeners);
  							listeners.length = 0;
  						}
  
  						// `session.remoteSettings.maxConcurrentStreams` might get increased
  						session.on('remoteSettings', () => {
  							processListeners();
  
  							// In case the Origin Set changes
  							closeCoveredSessions(this.sessions[normalizedOptions], session);
  						});
  					});
  
  					// Shim `session.request()` in order to catch all streams
  					session[kRequest] = session.request;
  					session.request = (headers, streamOptions) => {
  						if (session[kGracefullyClosing]) {
  							throw new Error('The session is gracefully closing. No new streams are allowed.');
  						}
  
  						const stream = session[kRequest](headers, streamOptions);
  
  						// The process won't exit until the session is closed or all requests are gone.
  						session.ref();
  
  						++session[kCurrentStreamsCount];
  
  						if (session[kCurrentStreamsCount] === session.remoteSettings.maxConcurrentStreams) {
  							this._freeSessionsCount--;
  						}
  
  						stream.once('close', () => {
  							wasFree = isFree();
  
  							--session[kCurrentStreamsCount];
  
  							if (!session.destroyed && !session.closed) {
  								closeSessionIfCovered(this.sessions[normalizedOptions], session);
  
  								if (isFree() && !session.closed) {
  									if (!wasFree) {
  										this._freeSessionsCount++;
  
  										wasFree = true;
  									}
  
  									const isEmpty = session[kCurrentStreamsCount] === 0;
  
  									if (isEmpty) {
  										session.unref();
  									}
  
  									if (
  										isEmpty &&
  										(
  											this._freeSessionsCount > this.maxFreeSessions ||
  											session[kGracefullyClosing]
  										)
  									) {
  										session.close();
  									} else {
  										closeCoveredSessions(this.sessions[normalizedOptions], session);
  										processListeners();
  									}
  								}
  							}
  						});
  
  						return stream;
  					};
  				} catch (error) {
  					for (const listener of listeners) {
  						listener.reject(error);
  					}
  
  					removeFromQueue();
  				}
  			};
  
  			entry.listeners = listeners;
  			entry.completed = false;
  			entry.destroyed = false;
  
  			this.queue[normalizedOptions][normalizedOrigin] = entry;
  			this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
  		});
  	}
  
  	request(origin, options, headers, streamOptions) {
  		return new Promise((resolve, reject) => {
  			this.getSession(origin, options, [{
  				reject,
  				resolve: session => {
  					try {
  						resolve(session.request(headers, streamOptions));
  					} catch (error) {
  						reject(error);
  					}
  				}
  			}]);
  		});
  	}
  
  	createConnection(origin, options) {
  		return Agent.connect(origin, options);
  	}
  
  	static connect(origin, options) {
  		options.ALPNProtocols = ['h2'];
  
  		const port = origin.port || 443;
  		const host = origin.hostname || origin.host;
  
  		if (typeof options.servername === 'undefined') {
  			options.servername = host;
  		}
  
  		return tls.connect(port, host, options);
  	}
  
  	closeFreeSessions() {
  		for (const sessions of Object.values(this.sessions)) {
  			for (const session of sessions) {
  				if (session[kCurrentStreamsCount] === 0) {
  					session.close();
  				}
  			}
  		}
  	}
  
  	destroy(reason) {
  		for (const sessions of Object.values(this.sessions)) {
  			for (const session of sessions) {
  				session.destroy(reason);
  			}
  		}
  
  		for (const entriesOfAuthority of Object.values(this.queue)) {
  			for (const entry of Object.values(entriesOfAuthority)) {
  				entry.destroyed = true;
  			}
  		}
  
  		// New requests should NOT attach to destroyed sessions
  		this.queue = {};
  	}
  
  	get freeSessions() {
  		return getSessions({agent: this, isFree: true});
  	}
  
  	get busySessions() {
  		return getSessions({agent: this, isFree: false});
  	}
  }
  
  Agent.kCurrentStreamsCount = kCurrentStreamsCount;
  Agent.kGracefullyClosing = kGracefullyClosing;
  
  module.exports = {
  	Agent,
  	globalAgent: new Agent()
  };
  
  
  /***/ }),
  
  /***/ 904:
  /***/ (function(module) {
  
  "use strict";
  
  
  class QuickLRU {
  	constructor(options = {}) {
  		if (!(options.maxSize && options.maxSize > 0)) {
  			throw new TypeError('`maxSize` must be a number greater than 0');
  		}
  
  		this.maxSize = options.maxSize;
  		this.onEviction = options.onEviction;
  		this.cache = new Map();
  		this.oldCache = new Map();
  		this._size = 0;
  	}
  
  	_set(key, value) {
  		this.cache.set(key, value);
  		this._size++;
  
  		if (this._size >= this.maxSize) {
  			this._size = 0;
  
  			if (typeof this.onEviction === 'function') {
  				for (const [key, value] of this.oldCache.entries()) {
  					this.onEviction(key, value);
  				}
  			}
  
  			this.oldCache = this.cache;
  			this.cache = new Map();
  		}
  	}
  
  	get(key) {
  		if (this.cache.has(key)) {
  			return this.cache.get(key);
  		}
  
  		if (this.oldCache.has(key)) {
  			const value = this.oldCache.get(key);
  			this.oldCache.delete(key);
  			this._set(key, value);
  			return value;
  		}
  	}
  
  	set(key, value) {
  		if (this.cache.has(key)) {
  			this.cache.set(key, value);
  		} else {
  			this._set(key, value);
  		}
  
  		return this;
  	}
  
  	has(key) {
  		return this.cache.has(key) || this.oldCache.has(key);
  	}
  
  	peek(key) {
  		if (this.cache.has(key)) {
  			return this.cache.get(key);
  		}
  
  		if (this.oldCache.has(key)) {
  			return this.oldCache.get(key);
  		}
  	}
  
  	delete(key) {
  		const deleted = this.cache.delete(key);
  		if (deleted) {
  			this._size--;
  		}
  
  		return this.oldCache.delete(key) || deleted;
  	}
  
  	clear() {
  		this.cache.clear();
  		this.oldCache.clear();
  		this._size = 0;
  	}
  
  	* keys() {
  		for (const [key] of this) {
  			yield key;
  		}
  	}
  
  	* values() {
  		for (const [, value] of this) {
  			yield value;
  		}
  	}
  
  	* [Symbol.iterator]() {
  		for (const item of this.cache) {
  			yield item;
  		}
  
  		for (const item of this.oldCache) {
  			const [key] = item;
  			if (!this.cache.has(key)) {
  				yield item;
  			}
  		}
  	}
  
  	get size() {
  		let oldCacheSize = 0;
  		for (const key of this.oldCache.keys()) {
  			if (!this.cache.has(key)) {
  				oldCacheSize++;
  			}
  		}
  
  		return Math.min(this._size + oldCacheSize, this.maxSize);
  	}
  }
  
  module.exports = QuickLRU;
  
  
  /***/ }),
  
  /***/ 907:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  /* istanbul ignore file: deprecated */
  const url_1 = __webpack_require__(835);
  const keys = [
      'protocol',
      'host',
      'hostname',
      'port',
      'pathname',
      'search'
  ];
  exports.default = (origin, options) => {
      var _a, _b;
      if (options.path) {
          if (options.pathname) {
              throw new TypeError('Parameters `path` and `pathname` are mutually exclusive.');
          }
          if (options.search) {
              throw new TypeError('Parameters `path` and `search` are mutually exclusive.');
          }
          if (options.searchParams) {
              throw new TypeError('Parameters `path` and `searchParams` are mutually exclusive.');
          }
      }
      if (options.search && options.searchParams) {
          throw new TypeError('Parameters `search` and `searchParams` are mutually exclusive.');
      }
      if (!origin) {
          if (!options.protocol) {
              throw new TypeError('No URL protocol specified');
          }
          origin = `${options.protocol}//${(_b = (_a = options.hostname) !== null && _a !== void 0 ? _a : options.host) !== null && _b !== void 0 ? _b : ''}`;
      }
      const url = new url_1.URL(origin);
      if (options.path) {
          const searchIndex = options.path.indexOf('?');
          if (searchIndex === -1) {
              options.pathname = options.path;
          }
          else {
              options.pathname = options.path.slice(0, searchIndex);
              options.search = options.path.slice(searchIndex + 1);
          }
          delete options.path;
      }
      for (const key of keys) {
          if (options[key]) {
              url[key] = options[key].toString();
          }
      }
      return url;
  };
  
  
  /***/ }),
  
  /***/ 910:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const types_1 = __webpack_require__(36);
  function createRejection(error, ...beforeErrorGroups) {
      const promise = (async () => {
          if (error instanceof types_1.RequestError) {
              try {
                  for (const hooks of beforeErrorGroups) {
                      if (hooks) {
                          for (const hook of hooks) {
                              // eslint-disable-next-line no-await-in-loop
                              error = await hook(error);
                          }
                      }
                  }
              }
              catch (error_) {
                  error = error_;
              }
          }
          throw error;
      })();
      const returnPromise = () => promise;
      promise.json = returnPromise;
      promise.text = returnPromise;
      promise.buffer = returnPromise;
      promise.on = returnPromise;
      return promise;
  }
  exports.default = createRejection;
  
  
  /***/ }),
  
  /***/ 928:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  // @ts-check
  const core = __webpack_require__(470);
  const command = __webpack_require__(431);
  const got = __webpack_require__(77).default;
  const jsonata = __webpack_require__(350);
  const { auth: { retrieveToken }, secrets: { getSecrets } } = __webpack_require__(676);
  
  const AUTH_METHODS = ['approle', 'token', 'github'];
  
  async function exportSecrets() {
      const vaultUrl = core.getInput('url', { required: true });
      const vaultNamespace = core.getInput('namespace', { required: false });
      const extraHeaders = parseHeadersInput('extraHeaders', { required: false });
      const exportEnv = core.getInput('exportEnv', { required: false }) != 'false';
  
      const secretsInput = core.getInput('secrets', { required: true });
      const secretRequests = parseSecretsInput(secretsInput);
  
      const vaultMethod = (core.getInput('method', { required: false }) || 'token').toLowerCase();
      const authPayload = core.getInput('authPayload', { required: false });
      if (!AUTH_METHODS.includes(vaultMethod) && !authPayload) {
          throw Error(`Sorry, the provided authentication method ${vaultMethod} is not currently supported and no custom authPayload was provided.`);
      }
  
      const defaultOptions = {
          prefixUrl: vaultUrl,
          headers: {},
          https: {}
      }
  
      const tlsSkipVerify = (core.getInput('tlsSkipVerify', { required: false }) || 'false').toLowerCase() != 'false';
      if (tlsSkipVerify === true) {
          defaultOptions.https.rejectUnauthorized = false;
      }
  
      const caCertificateRaw = core.getInput('caCertificate', { required: false });
      if (caCertificateRaw != null) {
          defaultOptions.https.certificateAuthority = Buffer.from(caCertificateRaw, 'base64').toString();
      }
  
      const clientCertificateRaw = core.getInput('clientCertificate', { required: false });
      if (clientCertificateRaw != null) {
  	    defaultOptions.https.certificate = Buffer.from(clientCertificateRaw, 'base64').toString();
      }
  
      const clientKeyRaw = core.getInput('clientKey', { required: false });
      if (clientKeyRaw != null) {
  	    defaultOptions.https.key = Buffer.from(clientKeyRaw, 'base64').toString();
      }
  
      for (const [headerName, headerValue] of extraHeaders) {
          defaultOptions.headers[headerName] = headerValue;
      }
  
      if (vaultNamespace != null) {
          defaultOptions.headers["X-Vault-Namespace"] = vaultNamespace;
      }
  
      const vaultToken = await retrieveToken(vaultMethod, got.extend(defaultOptions));
      defaultOptions.headers['X-Vault-Token'] = vaultToken;
      const client = got.extend(defaultOptions);
  
      const requests = secretRequests.map(request => {
          const { path, selector } = request;
          return request;
      });
  
      const results = await getSecrets(requests, client);
  
      for (const result of results) {
          const { value, request, cachedResponse } = result;
          if (cachedResponse) {
              core.debug('ℹ using cached response');
          }        
          command.issue('add-mask', value);
          if (exportEnv) {
              core.exportVariable(request.envVarName, `${value}`);
          }
          core.setOutput(request.outputVarName, `${value}`);
          core.debug(`✔ ${request.path} => outputs.${request.outputVarName}${exportEnv ? ` | env.${request.envVarName}` : ''}`);
      }
  };
  
  /** @typedef {Object} SecretRequest 
   * @property {string} path
   * @property {string} envVarName
   * @property {string} outputVarName
   * @property {string} selector
  */
  
  /**
   * Parses a secrets input string into key paths and their resulting environment variable name.
   * @param {string} secretsInput
   */
  function parseSecretsInput(secretsInput) {
      const secrets = secretsInput
          .split(';')
          .filter(key => !!key)
          .map(key => key.trim())
          .filter(key => key.length !== 0);
  
      /** @type {SecretRequest[]} */
      const output = [];
      for (const secret of secrets) {
          let pathSpec = secret;
          let outputVarName = null;
  
          const renameSigilIndex = secret.lastIndexOf('|');
          if (renameSigilIndex > -1) {
              pathSpec = secret.substring(0, renameSigilIndex).trim();
              outputVarName = secret.substring(renameSigilIndex + 1).trim();
  
              if (outputVarName.length < 1) {
                  throw Error(`You must provide a value when mapping a secret to a name. Input: "${secret}"`);
              }
          }
  
          const pathParts = pathSpec
              .split(/\s+/)
              .map(part => part.trim())
              .filter(part => part.length !== 0);
  
          if (pathParts.length !== 2) {
              throw Error(`You must provide a valid path and key. Input: "${secret}"`);
          }
  
          const [path, selector] = pathParts;
  
          /** @type {any} */
          const selectorAst = jsonata(selector).ast();
  
          if ((selectorAst.type !== "path" || selectorAst.steps[0].stages) && !outputVarName) {
              throw Error(`You must provide a name for the output key when using json selectors. Input: "${secret}"`);
          }
  
          let envVarName = outputVarName;
          if (!outputVarName) {
              outputVarName = normalizeOutputKey(selector);
              envVarName = normalizeOutputKey(selector, true);
          }
  
          output.push({
              path,
              envVarName,
              outputVarName,
              selector
          });
      }
      return output;
  }
  
  /**
   * Replaces any dot chars to __ and removes non-ascii charts
   * @param {string} dataKey
   * @param {boolean=} isEnvVar
   */
  function normalizeOutputKey(dataKey, isEnvVar = false) {
      let outputKey = dataKey
          .replace('.', '__').replace(/[^\p{L}\p{N}_-]/gu, '');
      if (isEnvVar) {
          outputKey = outputKey.toUpperCase();
      }
      return outputKey;
  }
  
  /**
   * @param {string} inputKey
   * @param {any} inputOptions
   */
  function parseHeadersInput(inputKey, inputOptions) {
      /** @type {string}*/
      const rawHeadersString = core.getInput(inputKey, inputOptions) || '';
      const headerStrings = rawHeadersString
          .split('\n')
          .map(line => line.trim())
          .filter(line => line !== '');
      return headerStrings
          .reduce((map, line) => {
              const seperator = line.indexOf(':');
              const key = line.substring(0, seperator).trim().toLowerCase();
              const value = line.substring(seperator + 1).trim();
              if (map.has(key)) {
                  map.set(key, [map.get(key), value].join(', '));
              } else {
                  map.set(key, value);
              }
              return map;
          }, new Map());
  }
  
  module.exports = {
      exportSecrets,
      parseSecretsInput,
      normalizeOutputKey,
      parseHeadersInput
  };
  
  
  /***/ }),
  
  /***/ 946:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.UnsupportedProtocolError = exports.ReadError = exports.TimeoutError = exports.UploadError = exports.CacheError = exports.HTTPError = exports.MaxRedirectsError = exports.RequestError = exports.setNonEnumerableProperties = exports.knownHookEvents = exports.withoutBody = exports.kIsNormalizedAlready = void 0;
  const util_1 = __webpack_require__(669);
  const stream_1 = __webpack_require__(413);
  const fs_1 = __webpack_require__(747);
  const url_1 = __webpack_require__(835);
  const http = __webpack_require__(605);
  const http_1 = __webpack_require__(605);
  const https = __webpack_require__(211);
  const http_timer_1 = __webpack_require__(490);
  const cacheable_lookup_1 = __webpack_require__(570);
  const CacheableRequest = __webpack_require__(390);
  const decompressResponse = __webpack_require__(861);
  // @ts-expect-error Missing types
  const http2wrapper = __webpack_require__(157);
  const lowercaseKeys = __webpack_require__(474);
  const is_1 = __webpack_require__(534);
  const get_body_size_1 = __webpack_require__(786);
  const is_form_data_1 = __webpack_require__(460);
  const proxy_events_1 = __webpack_require__(628);
  const timed_out_1 = __webpack_require__(811);
  const url_to_options_1 = __webpack_require__(10);
  const options_to_url_1 = __webpack_require__(907);
  const weakable_map_1 = __webpack_require__(48);
  const get_buffer_1 = __webpack_require__(452);
  const dns_ip_version_1 = __webpack_require__(738);
  const is_response_ok_1 = __webpack_require__(422);
  const deprecation_warning_1 = __webpack_require__(189);
  const normalize_arguments_1 = __webpack_require__(992);
  const calculate_retry_delay_1 = __webpack_require__(594);
  const globalDnsCache = new cacheable_lookup_1.default();
  const kRequest = Symbol('request');
  const kResponse = Symbol('response');
  const kResponseSize = Symbol('responseSize');
  const kDownloadedSize = Symbol('downloadedSize');
  const kBodySize = Symbol('bodySize');
  const kUploadedSize = Symbol('uploadedSize');
  const kServerResponsesPiped = Symbol('serverResponsesPiped');
  const kUnproxyEvents = Symbol('unproxyEvents');
  const kIsFromCache = Symbol('isFromCache');
  const kCancelTimeouts = Symbol('cancelTimeouts');
  const kStartedReading = Symbol('startedReading');
  const kStopReading = Symbol('stopReading');
  const kTriggerRead = Symbol('triggerRead');
  const kBody = Symbol('body');
  const kJobs = Symbol('jobs');
  const kOriginalResponse = Symbol('originalResponse');
  const kRetryTimeout = Symbol('retryTimeout');
  exports.kIsNormalizedAlready = Symbol('isNormalizedAlready');
  const supportsBrotli = is_1.default.string(process.versions.brotli);
  exports.withoutBody = new Set(['GET', 'HEAD']);
  exports.knownHookEvents = [
      'init',
      'beforeRequest',
      'beforeRedirect',
      'beforeError',
      'beforeRetry',
      // Promise-Only
      'afterResponse'
  ];
  function validateSearchParameters(searchParameters) {
      // eslint-disable-next-line guard-for-in
      for (const key in searchParameters) {
          const value = searchParameters[key];
          if (!is_1.default.string(value) && !is_1.default.number(value) && !is_1.default.boolean(value) && !is_1.default.null_(value) && !is_1.default.undefined(value)) {
              throw new TypeError(`The \`searchParams\` value '${String(value)}' must be a string, number, boolean or null`);
          }
      }
  }
  function isClientRequest(clientRequest) {
      return is_1.default.object(clientRequest) && !('statusCode' in clientRequest);
  }
  const cacheableStore = new weakable_map_1.default();
  const waitForOpenFile = async (file) => new Promise((resolve, reject) => {
      const onError = (error) => {
          reject(error);
      };
      // Node.js 12 has incomplete types
      if (!file.pending) {
          resolve();
      }
      file.once('error', onError);
      file.once('ready', () => {
          file.off('error', onError);
          resolve();
      });
  });
  const redirectCodes = new Set([300, 301, 302, 303, 304, 307, 308]);
  const nonEnumerableProperties = [
      'context',
      'body',
      'json',
      'form'
  ];
  exports.setNonEnumerableProperties = (sources, to) => {
      // Non enumerable properties shall not be merged
      const properties = {};
      for (const source of sources) {
          if (!source) {
              continue;
          }
          for (const name of nonEnumerableProperties) {
              if (!(name in source)) {
                  continue;
              }
              properties[name] = {
                  writable: true,
                  configurable: true,
                  enumerable: false,
                  // @ts-expect-error TS doesn't see the check above
                  value: source[name]
              };
          }
      }
      Object.defineProperties(to, properties);
  };
  /**
  An error to be thrown when a request fails.
  Contains a `code` property with error class code, like `ECONNREFUSED`.
  */
  class RequestError extends Error {
      constructor(message, error, self) {
          var _a;
          super(message);
          Error.captureStackTrace(this, this.constructor);
          this.name = 'RequestError';
          this.code = error.code;
          if (self instanceof Request) {
              Object.defineProperty(this, 'request', {
                  enumerable: false,
                  value: self
              });
              Object.defineProperty(this, 'response', {
                  enumerable: false,
                  value: self[kResponse]
              });
              Object.defineProperty(this, 'options', {
                  // This fails because of TS 3.7.2 useDefineForClassFields
                  // Ref: https://github.com/microsoft/TypeScript/issues/34972
                  enumerable: false,
                  value: self.options
              });
          }
          else {
              Object.defineProperty(this, 'options', {
                  // This fails because of TS 3.7.2 useDefineForClassFields
                  // Ref: https://github.com/microsoft/TypeScript/issues/34972
                  enumerable: false,
                  value: self
              });
          }
          this.timings = (_a = this.request) === null || _a === void 0 ? void 0 : _a.timings;
          // Recover the original stacktrace
          if (!is_1.default.undefined(error.stack)) {
              const indexOfMessage = this.stack.indexOf(this.message) + this.message.length;
              const thisStackTrace = this.stack.slice(indexOfMessage).split('\n').reverse();
              const errorStackTrace = error.stack.slice(error.stack.indexOf(error.message) + error.message.length).split('\n').reverse();
              // Remove duplicated traces
              while (errorStackTrace.length !== 0 && errorStackTrace[0] === thisStackTrace[0]) {
                  thisStackTrace.shift();
              }
              this.stack = `${this.stack.slice(0, indexOfMessage)}${thisStackTrace.reverse().join('\n')}${errorStackTrace.reverse().join('\n')}`;
          }
      }
  }
  exports.RequestError = RequestError;
  /**
  An error to be thrown when the server redirects you more than ten times.
  Includes a `response` property.
  */
  class MaxRedirectsError extends RequestError {
      constructor(request) {
          super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request);
          this.name = 'MaxRedirectsError';
      }
  }
  exports.MaxRedirectsError = MaxRedirectsError;
  /**
  An error to be thrown when the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304.
  Includes a `response` property.
  */
  class HTTPError extends RequestError {
      constructor(response) {
          super(`Response code ${response.statusCode} (${response.statusMessage})`, {}, response.request);
          this.name = 'HTTPError';
      }
  }
  exports.HTTPError = HTTPError;
  /**
  An error to be thrown when a cache method fails.
  For example, if the database goes down or there's a filesystem error.
  */
  class CacheError extends RequestError {
      constructor(error, request) {
          super(error.message, error, request);
          this.name = 'CacheError';
      }
  }
  exports.CacheError = CacheError;
  /**
  An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
  */
  class UploadError extends RequestError {
      constructor(error, request) {
          super(error.message, error, request);
          this.name = 'UploadError';
      }
  }
  exports.UploadError = UploadError;
  /**
  An error to be thrown when the request is aborted due to a timeout.
  Includes an `event` and `timings` property.
  */
  class TimeoutError extends RequestError {
      constructor(error, timings, request) {
          super(error.message, error, request);
          this.name = 'TimeoutError';
          this.event = error.event;
          this.timings = timings;
      }
  }
  exports.TimeoutError = TimeoutError;
  /**
  An error to be thrown when reading from response stream fails.
  */
  class ReadError extends RequestError {
      constructor(error, request) {
          super(error.message, error, request);
          this.name = 'ReadError';
      }
  }
  exports.ReadError = ReadError;
  /**
  An error to be thrown when given an unsupported protocol.
  */
  class UnsupportedProtocolError extends RequestError {
      constructor(options) {
          super(`Unsupported protocol "${options.url.protocol}"`, {}, options);
          this.name = 'UnsupportedProtocolError';
      }
  }
  exports.UnsupportedProtocolError = UnsupportedProtocolError;
  const proxiedRequestEvents = [
      'socket',
      'connect',
      'continue',
      'information',
      'upgrade',
      'timeout'
  ];
  class Request extends stream_1.Duplex {
      constructor(url, options = {}, defaults) {
          super({
              // This must be false, to enable throwing after destroy
              // It is used for retry logic in Promise API
              autoDestroy: false,
              // It needs to be zero because we're just proxying the data to another stream
              highWaterMark: 0
          });
          this[kDownloadedSize] = 0;
          this[kUploadedSize] = 0;
          this.requestInitialized = false;
          this[kServerResponsesPiped] = new Set();
          this.redirects = [];
          this[kStopReading] = false;
          this[kTriggerRead] = false;
          this[kJobs] = [];
          this.retryCount = 0;
          // TODO: Remove this when targeting Node.js >= 12
          this._progressCallbacks = [];
          const unlockWrite = () => this._unlockWrite();
          const lockWrite = () => this._lockWrite();
          this.on('pipe', (source) => {
              source.prependListener('data', unlockWrite);
              source.on('data', lockWrite);
              source.prependListener('end', unlockWrite);
              source.on('end', lockWrite);
          });
          this.on('unpipe', (source) => {
              source.off('data', unlockWrite);
              source.off('data', lockWrite);
              source.off('end', unlockWrite);
              source.off('end', lockWrite);
          });
          this.on('pipe', source => {
              if (source instanceof http_1.IncomingMessage) {
                  this.options.headers = {
                      ...source.headers,
                      ...this.options.headers
                  };
              }
          });
          const { json, body, form } = options;
          if (json || body || form) {
              this._lockWrite();
          }
          (async (nonNormalizedOptions) => {
              var _a;
              try {
                  if (nonNormalizedOptions.body instanceof fs_1.ReadStream) {
                      await waitForOpenFile(nonNormalizedOptions.body);
                  }
                  if (exports.kIsNormalizedAlready in nonNormalizedOptions) {
                      this.options = nonNormalizedOptions;
                  }
                  else {
                      // @ts-expect-error Common TypeScript bug saying that `this.constructor` is not accessible
                      this.options = this.constructor.normalizeArguments(url, nonNormalizedOptions, defaults);
                  }
                  const { url: normalizedURL } = this.options;
                  if (!normalizedURL) {
                      throw new TypeError('Missing `url` property');
                  }
                  this.requestUrl = normalizedURL.toString();
                  decodeURI(this.requestUrl);
                  await this._finalizeBody();
                  await this._makeRequest();
                  if (this.destroyed) {
                      (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.destroy();
                      return;
                  }
                  // Queued writes etc.
                  for (const job of this[kJobs]) {
                      job();
                  }
                  // Prevent memory leak
                  this[kJobs].length = 0;
                  this.requestInitialized = true;
              }
              catch (error) {
                  if (error instanceof RequestError) {
                      this._beforeError(error);
                      return;
                  }
                  // This is a workaround for https://github.com/nodejs/node/issues/33335
                  if (!this.destroyed) {
                      this.destroy(error);
                  }
              }
          })(options);
      }
      static normalizeArguments(url, options, defaults) {
          var _a, _b, _c, _d, _e;
          const rawOptions = options;
          if (is_1.default.object(url) && !is_1.default.urlInstance(url)) {
              options = { ...defaults, ...url, ...options };
          }
          else {
              if (url && options && options.url !== undefined) {
                  throw new TypeError('The `url` option is mutually exclusive with the `input` argument');
              }
              options = { ...defaults, ...options };
              if (url !== undefined) {
                  options.url = url;
              }
              if (is_1.default.urlInstance(options.url)) {
                  options.url = new url_1.URL(options.url.toString());
              }
          }
          // TODO: Deprecate URL options in Got 12.
          // Support extend-specific options
          if (options.cache === false) {
              options.cache = undefined;
          }
          if (options.dnsCache === false) {
              options.dnsCache = undefined;
          }
          // Nice type assertions
          is_1.assert.any([is_1.default.string, is_1.default.undefined], options.method);
          is_1.assert.any([is_1.default.object, is_1.default.undefined], options.headers);
          is_1.assert.any([is_1.default.string, is_1.default.urlInstance, is_1.default.undefined], options.prefixUrl);
          is_1.assert.any([is_1.default.object, is_1.default.undefined], options.cookieJar);
          is_1.assert.any([is_1.default.object, is_1.default.string, is_1.default.undefined], options.searchParams);
          is_1.assert.any([is_1.default.object, is_1.default.string, is_1.default.undefined], options.cache);
          is_1.assert.any([is_1.default.object, is_1.default.number, is_1.default.undefined], options.timeout);
          is_1.assert.any([is_1.default.object, is_1.default.undefined], options.context);
          is_1.assert.any([is_1.default.object, is_1.default.undefined], options.hooks);
          is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.decompress);
          is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.ignoreInvalidCookies);
          is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.followRedirect);
          is_1.assert.any([is_1.default.number, is_1.default.undefined], options.maxRedirects);
          is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.throwHttpErrors);
          is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.http2);
          is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.allowGetBody);
          is_1.assert.any([is_1.default.string, is_1.default.undefined], options.localAddress);
          is_1.assert.any([dns_ip_version_1.isDnsLookupIpVersion, is_1.default.undefined], options.dnsLookupIpVersion);
          is_1.assert.any([is_1.default.object, is_1.default.undefined], options.https);
          is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.rejectUnauthorized);
          if (options.https) {
              is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.https.rejectUnauthorized);
              is_1.assert.any([is_1.default.function_, is_1.default.undefined], options.https.checkServerIdentity);
              is_1.assert.any([is_1.default.string, is_1.default.object, is_1.default.array, is_1.default.undefined], options.https.certificateAuthority);
              is_1.assert.any([is_1.default.string, is_1.default.object, is_1.default.array, is_1.default.undefined], options.https.key);
              is_1.assert.any([is_1.default.string, is_1.default.object, is_1.default.array, is_1.default.undefined], options.https.certificate);
              is_1.assert.any([is_1.default.string, is_1.default.undefined], options.https.passphrase);
          }
          is_1.assert.any([is_1.default.object, is_1.default.undefined], options.cacheOptions);
          // `options.method`
          if (is_1.default.string(options.method)) {
              options.method = options.method.toUpperCase();
          }
          else {
              options.method = 'GET';
          }
          // `options.headers`
          if (options.headers === (defaults === null || defaults === void 0 ? void 0 : defaults.headers)) {
              options.headers = { ...options.headers };
          }
          else {
              options.headers = lowercaseKeys({ ...(defaults === null || defaults === void 0 ? void 0 : defaults.headers), ...options.headers });
          }
          // Disallow legacy `url.Url`
          if ('slashes' in options) {
              throw new TypeError('The legacy `url.Url` has been deprecated. Use `URL` instead.');
          }
          // `options.auth`
          if ('auth' in options) {
              throw new TypeError('Parameter `auth` is deprecated. Use `username` / `password` instead.');
          }
          // `options.searchParams`
          if ('searchParams' in options) {
              if (options.searchParams && options.searchParams !== (defaults === null || defaults === void 0 ? void 0 : defaults.searchParams)) {
                  let searchParameters;
                  if (is_1.default.string(options.searchParams) || (options.searchParams instanceof url_1.URLSearchParams)) {
                      searchParameters = new url_1.URLSearchParams(options.searchParams);
                  }
                  else {
                      validateSearchParameters(options.searchParams);
                      searchParameters = new url_1.URLSearchParams();
                      // eslint-disable-next-line guard-for-in
                      for (const key in options.searchParams) {
                          const value = options.searchParams[key];
                          if (value === null) {
                              searchParameters.append(key, '');
                          }
                          else if (value !== undefined) {
                              searchParameters.append(key, value);
                          }
                      }
                  }
                  // `normalizeArguments()` is also used to merge options
                  (_a = defaults === null || defaults === void 0 ? void 0 : defaults.searchParams) === null || _a === void 0 ? void 0 : _a.forEach((value, key) => {
                      // Only use default if one isn't already defined
                      if (!searchParameters.has(key)) {
                          searchParameters.append(key, value);
                      }
                  });
                  options.searchParams = searchParameters;
              }
          }
          // `options.username` & `options.password`
          options.username = (_b = options.username) !== null && _b !== void 0 ? _b : '';
          options.password = (_c = options.password) !== null && _c !== void 0 ? _c : '';
          // `options.prefixUrl` & `options.url`
          if (is_1.default.undefined(options.prefixUrl)) {
              options.prefixUrl = (_d = defaults === null || defaults === void 0 ? void 0 : defaults.prefixUrl) !== null && _d !== void 0 ? _d : '';
          }
          else {
              options.prefixUrl = options.prefixUrl.toString();
              if (options.prefixUrl !== '' && !options.prefixUrl.endsWith('/')) {
                  options.prefixUrl += '/';
              }
          }
          if (is_1.default.string(options.url)) {
              if (options.url.startsWith('/')) {
                  throw new Error('`input` must not start with a slash when using `prefixUrl`');
              }
              options.url = options_to_url_1.default(options.prefixUrl + options.url, options);
          }
          else if ((is_1.default.undefined(options.url) && options.prefixUrl !== '') || options.protocol) {
              options.url = options_to_url_1.default(options.prefixUrl, options);
          }
          if (options.url) {
              // Make it possible to change `options.prefixUrl`
              let { prefixUrl } = options;
              Object.defineProperty(options, 'prefixUrl', {
                  set: (value) => {
                      const url = options.url;
                      if (!url.href.startsWith(value)) {
                          throw new Error(`Cannot change \`prefixUrl\` from ${prefixUrl} to ${value}: ${url.href}`);
                      }
                      options.url = new url_1.URL(value + url.href.slice(prefixUrl.length));
                      prefixUrl = value;
                  },
                  get: () => prefixUrl
              });
              // Support UNIX sockets
              let { protocol } = options.url;
              if (protocol === 'unix:') {
                  protocol = 'http:';
                  options.url = new url_1.URL(`http://unix${options.url.pathname}${options.url.search}`);
              }
              // Set search params
              if (options.searchParams) {
                  // eslint-disable-next-line @typescript-eslint/no-base-to-string
                  options.url.search = options.searchParams.toString();
              }
              // Protocol check
              if (protocol !== 'http:' && protocol !== 'https:') {
                  throw new UnsupportedProtocolError(options);
              }
              // Update `username`
              if (options.username === '') {
                  options.username = options.url.username;
              }
              else {
                  options.url.username = options.username;
              }
              // Update `password`
              if (options.password === '') {
                  options.password = options.url.password;
              }
              else {
                  options.url.password = options.password;
              }
          }
          // `options.cookieJar`
          const { cookieJar } = options;
          if (cookieJar) {
              let { setCookie, getCookieString } = cookieJar;
              is_1.assert.function_(setCookie);
              is_1.assert.function_(getCookieString);
              /* istanbul ignore next: Horrible `tough-cookie` v3 check */
              if (setCookie.length === 4 && getCookieString.length === 0) {
                  setCookie = util_1.promisify(setCookie.bind(options.cookieJar));
                  getCookieString = util_1.promisify(getCookieString.bind(options.cookieJar));
                  options.cookieJar = {
                      setCookie,
                      getCookieString: getCookieString
                  };
              }
          }
          // `options.cache`
          const { cache } = options;
          if (cache) {
              if (!cacheableStore.has(cache)) {
                  cacheableStore.set(cache, new CacheableRequest(((requestOptions, handler) => {
                      const result = requestOptions[kRequest](requestOptions, handler);
                      // TODO: remove this when `cacheable-request` supports async request functions.
                      if (is_1.default.promise(result)) {
                          // @ts-expect-error
                          // We only need to implement the error handler in order to support HTTP2 caching.
                          // The result will be a promise anyway.
                          result.once = (event, handler) => {
                              if (event === 'error') {
                                  result.catch(handler);
                              }
                              else if (event === 'abort') {
                                  // The empty catch is needed here in case when
                                  // it rejects before it's `await`ed in `_makeRequest`.
                                  (async () => {
                                      try {
                                          const request = (await result);
                                          request.once('abort', handler);
                                      }
                                      catch (_a) { }
                                  })();
                              }
                              else {
                                  /* istanbul ignore next: safety check */
                                  throw new Error(`Unknown HTTP2 promise event: ${event}`);
                              }
                              return result;
                          };
                      }
                      return result;
                  }), cache));
              }
          }
          // `options.cacheOptions`
          options.cacheOptions = { ...options.cacheOptions };
          // `options.dnsCache`
          if (options.dnsCache === true) {
              options.dnsCache = globalDnsCache;
          }
          else if (!is_1.default.undefined(options.dnsCache) && !options.dnsCache.lookup) {
              throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${is_1.default(options.dnsCache)}`);
          }
          // `options.timeout`
          if (is_1.default.number(options.timeout)) {
              options.timeout = { request: options.timeout };
          }
          else if (defaults && options.timeout !== defaults.timeout) {
              options.timeout = {
                  ...defaults.timeout,
                  ...options.timeout
              };
          }
          else {
              options.timeout = { ...options.timeout };
          }
          // `options.context`
          if (!options.context) {
              options.context = {};
          }
          // `options.hooks`
          const areHooksDefault = options.hooks === (defaults === null || defaults === void 0 ? void 0 : defaults.hooks);
          options.hooks = { ...options.hooks };
          for (const event of exports.knownHookEvents) {
              if (event in options.hooks) {
                  if (is_1.default.array(options.hooks[event])) {
                      // See https://github.com/microsoft/TypeScript/issues/31445#issuecomment-576929044
                      options.hooks[event] = [...options.hooks[event]];
                  }
                  else {
                      throw new TypeError(`Parameter \`${event}\` must be an Array, got ${is_1.default(options.hooks[event])}`);
                  }
              }
              else {
                  options.hooks[event] = [];
              }
          }
          if (defaults && !areHooksDefault) {
              for (const event of exports.knownHookEvents) {
                  const defaultHooks = defaults.hooks[event];
                  if (defaultHooks.length !== 0) {
                      // See https://github.com/microsoft/TypeScript/issues/31445#issuecomment-576929044
                      options.hooks[event] = [
                          ...defaults.hooks[event],
                          ...options.hooks[event]
                      ];
                  }
              }
          }
          // DNS options
          if ('family' in options) {
              deprecation_warning_1.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"');
          }
          // HTTPS options
          if (defaults === null || defaults === void 0 ? void 0 : defaults.https) {
              options.https = { ...defaults.https, ...options.https };
          }
          if ('rejectUnauthorized' in options) {
              deprecation_warning_1.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"');
          }
          if ('checkServerIdentity' in options) {
              deprecation_warning_1.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"');
          }
          if ('ca' in options) {
              deprecation_warning_1.default('"options.ca" was never documented, please use "options.https.certificateAuthority"');
          }
          if ('key' in options) {
              deprecation_warning_1.default('"options.key" was never documented, please use "options.https.key"');
          }
          if ('cert' in options) {
              deprecation_warning_1.default('"options.cert" was never documented, please use "options.https.certificate"');
          }
          if ('passphrase' in options) {
              deprecation_warning_1.default('"options.passphrase" was never documented, please use "options.https.passphrase"');
          }
          // Other options
          if ('followRedirects' in options) {
              throw new TypeError('The `followRedirects` option does not exist. Use `followRedirect` instead.');
          }
          if (options.agent) {
              for (const key in options.agent) {
                  if (key !== 'http' && key !== 'https' && key !== 'http2') {
                      throw new TypeError(`Expected the \`options.agent\` properties to be \`http\`, \`https\` or \`http2\`, got \`${key}\``);
                  }
              }
          }
          options.maxRedirects = (_e = options.maxRedirects) !== null && _e !== void 0 ? _e : 0;
          // Set non-enumerable properties
          exports.setNonEnumerableProperties([defaults, rawOptions], options);
          return normalize_arguments_1.default(options, defaults);
      }
      _lockWrite() {
          const onLockedWrite = () => {
              throw new TypeError('The payload has been already provided');
          };
          this.write = onLockedWrite;
          this.end = onLockedWrite;
      }
      _unlockWrite() {
          this.write = super.write;
          this.end = super.end;
      }
      async _finalizeBody() {
          const { options } = this;
          const { headers } = options;
          const isForm = !is_1.default.undefined(options.form);
          const isJSON = !is_1.default.undefined(options.json);
          const isBody = !is_1.default.undefined(options.body);
          const hasPayload = isForm || isJSON || isBody;
          const cannotHaveBody = exports.withoutBody.has(options.method) && !(options.method === 'GET' && options.allowGetBody);
          this._cannotHaveBody = cannotHaveBody;
          if (hasPayload) {
              if (cannotHaveBody) {
                  throw new TypeError(`The \`${options.method}\` method cannot be used with a body`);
              }
              if ([isBody, isForm, isJSON].filter(isTrue => isTrue).length > 1) {
                  throw new TypeError('The `body`, `json` and `form` options are mutually exclusive');
              }
              if (isBody &&
                  !(options.body instanceof stream_1.Readable) &&
                  !is_1.default.string(options.body) &&
                  !is_1.default.buffer(options.body) &&
                  !is_form_data_1.default(options.body)) {
                  throw new TypeError('The `body` option must be a stream.Readable, string or Buffer');
              }
              if (isForm && !is_1.default.object(options.form)) {
                  throw new TypeError('The `form` option must be an Object');
              }
              {
                  // Serialize body
                  const noContentType = !is_1.default.string(headers['content-type']);
                  if (isBody) {
                      // Special case for https://github.com/form-data/form-data
                      if (is_form_data_1.default(options.body) && noContentType) {
                          headers['content-type'] = `multipart/form-data; boundary=${options.body.getBoundary()}`;
                      }
                      this[kBody] = options.body;
                  }
                  else if (isForm) {
                      if (noContentType) {
                          headers['content-type'] = 'application/x-www-form-urlencoded';
                      }
                      this[kBody] = (new url_1.URLSearchParams(options.form)).toString();
                  }
                  else {
                      if (noContentType) {
                          headers['content-type'] = 'application/json';
                      }
                      this[kBody] = options.stringifyJson(options.json);
                  }
                  const uploadBodySize = await get_body_size_1.default(this[kBody], options.headers);
                  // See https://tools.ietf.org/html/rfc7230#section-3.3.2
                  // A user agent SHOULD send a Content-Length in a request message when
                  // no Transfer-Encoding is sent and the request method defines a meaning
                  // for an enclosed payload body.  For example, a Content-Length header
                  // field is normally sent in a POST request even when the value is 0
                  // (indicating an empty payload body).  A user agent SHOULD NOT send a
                  // Content-Length header field when the request message does not contain
                  // a payload body and the method semantics do not anticipate such a
                  // body.
                  if (is_1.default.undefined(headers['content-length']) && is_1.default.undefined(headers['transfer-encoding'])) {
                      if (!cannotHaveBody && !is_1.default.undefined(uploadBodySize)) {
                          headers['content-length'] = String(uploadBodySize);
                      }
                  }
              }
          }
          else if (cannotHaveBody) {
              this._lockWrite();
          }
          else {
              this._unlockWrite();
          }
          this[kBodySize] = Number(headers['content-length']) || undefined;
      }
      async _onResponseBase(response) {
          const { options } = this;
          const { url } = options;
          this[kOriginalResponse] = response;
          if (options.decompress) {
              response = decompressResponse(response);
          }
          const statusCode = response.statusCode;
          const typedResponse = response;
          typedResponse.statusMessage = typedResponse.statusMessage ? typedResponse.statusMessage : http.STATUS_CODES[statusCode];
          typedResponse.url = options.url.toString();
          typedResponse.requestUrl = this.requestUrl;
          typedResponse.redirectUrls = this.redirects;
          typedResponse.request = this;
          typedResponse.isFromCache = response.fromCache || false;
          typedResponse.ip = this.ip;
          typedResponse.retryCount = this.retryCount;
          this[kIsFromCache] = typedResponse.isFromCache;
          this[kResponseSize] = Number(response.headers['content-length']) || undefined;
          this[kResponse] = response;
          response.once('end', () => {
              this[kResponseSize] = this[kDownloadedSize];
              this.emit('downloadProgress', this.downloadProgress);
          });
          response.once('error', (error) => {
              // Force clean-up, because some packages don't do this.
              // TODO: Fix decompress-response
              response.destroy();
              this._beforeError(new ReadError(error, this));
          });
          response.once('aborted', () => {
              this._beforeError(new ReadError({
                  name: 'Error',
                  message: 'The server aborted pending request',
                  code: 'ECONNRESET'
              }, this));
          });
          this.emit('downloadProgress', this.downloadProgress);
          const rawCookies = response.headers['set-cookie'];
          if (is_1.default.object(options.cookieJar) && rawCookies) {
              let promises = rawCookies.map(async (rawCookie) => options.cookieJar.setCookie(rawCookie, url.toString()));
              if (options.ignoreInvalidCookies) {
                  promises = promises.map(async (p) => p.catch(() => { }));
              }
              try {
                  await Promise.all(promises);
              }
              catch (error) {
                  this._beforeError(error);
                  return;
              }
          }
          if (options.followRedirect && response.headers.location && redirectCodes.has(statusCode)) {
              // We're being redirected, we don't care about the response.
              // It'd be best to abort the request, but we can't because
              // we would have to sacrifice the TCP connection. We don't want that.
              response.resume();
              if (this[kRequest]) {
                  this[kCancelTimeouts]();
                  // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
                  delete this[kRequest];
                  this[kUnproxyEvents]();
              }
              const shouldBeGet = statusCode === 303 && options.method !== 'GET' && options.method !== 'HEAD';
              if (shouldBeGet || !options.methodRewriting) {
                  // Server responded with "see other", indicating that the resource exists at another location,
                  // and the client should request it from that location via GET or HEAD.
                  options.method = 'GET';
                  if ('body' in options) {
                      delete options.body;
                  }
                  if ('json' in options) {
                      delete options.json;
                  }
                  if ('form' in options) {
                      delete options.form;
                  }
              }
              if (this.redirects.length >= options.maxRedirects) {
                  this._beforeError(new MaxRedirectsError(this));
                  return;
              }
              try {
                  // Do not remove. See https://github.com/sindresorhus/got/pull/214
                  const redirectBuffer = Buffer.from(response.headers.location, 'binary').toString();
                  // Handles invalid URLs. See https://github.com/sindresorhus/got/issues/604
                  const redirectUrl = new url_1.URL(redirectBuffer, url);
                  const redirectString = redirectUrl.toString();
                  decodeURI(redirectString);
                  // Redirecting to a different site, clear sensitive data.
                  if (redirectUrl.hostname !== url.hostname || redirectUrl.port !== url.port) {
                      if ('host' in options.headers) {
                          delete options.headers.host;
                      }
                      if ('cookie' in options.headers) {
                          delete options.headers.cookie;
                      }
                      if ('authorization' in options.headers) {
                          delete options.headers.authorization;
                      }
                      if (options.username || options.password) {
                          // TODO: Fix this ignore.
                          // @ts-expect-error
                          delete options.username;
                          // @ts-expect-error
                          delete options.password;
                      }
                      if ('port' in options) {
                          delete options.port;
                      }
                  }
                  this.redirects.push(redirectString);
                  options.url = redirectUrl;
                  for (const hook of options.hooks.beforeRedirect) {
                      // eslint-disable-next-line no-await-in-loop
                      await hook(options, typedResponse);
                  }
                  this.emit('redirect', typedResponse, options);
                  await this._makeRequest();
              }
              catch (error) {
                  this._beforeError(error);
                  return;
              }
              return;
          }
          if (options.isStream && options.throwHttpErrors && !is_response_ok_1.isResponseOk(typedResponse)) {
              this._beforeError(new HTTPError(typedResponse));
              return;
          }
          response.on('readable', () => {
              if (this[kTriggerRead]) {
                  this._read();
              }
          });
          this.on('resume', () => {
              response.resume();
          });
          this.on('pause', () => {
              response.pause();
          });
          response.once('end', () => {
              this.push(null);
          });
          this.emit('response', response);
          for (const destination of this[kServerResponsesPiped]) {
              if (destination.headersSent) {
                  continue;
              }
              // eslint-disable-next-line guard-for-in
              for (const key in response.headers) {
                  const isAllowed = options.decompress ? key !== 'content-encoding' : true;
                  const value = response.headers[key];
                  if (isAllowed) {
                      destination.setHeader(key, value);
                  }
              }
              destination.statusCode = statusCode;
          }
      }
      async _onResponse(response) {
          try {
              await this._onResponseBase(response);
          }
          catch (error) {
              /* istanbul ignore next: better safe than sorry */
              this._beforeError(error);
          }
      }
      _onRequest(request) {
          const { options } = this;
          const { timeout, url } = options;
          http_timer_1.default(request);
          this[kCancelTimeouts] = timed_out_1.default(request, timeout, url);
          const responseEventName = options.cache ? 'cacheableResponse' : 'response';
          request.once(responseEventName, (response) => {
              void this._onResponse(response);
          });
          request.once('error', (error) => {
              var _a;
              // Force clean-up, because some packages (e.g. nock) don't do this.
              request.destroy();
              // Node.js <= 12.18.2 mistakenly emits the response `end` first.
              (_a = request.res) === null || _a === void 0 ? void 0 : _a.removeAllListeners('end');
              if (error instanceof timed_out_1.TimeoutError) {
                  error = new TimeoutError(error, this.timings, this);
              }
              else {
                  error = new RequestError(error.message, error, this);
              }
              this._beforeError(error);
          });
          this[kUnproxyEvents] = proxy_events_1.default(request, this, proxiedRequestEvents);
          this[kRequest] = request;
          this.emit('uploadProgress', this.uploadProgress);
          // Send body
          const body = this[kBody];
          const currentRequest = this.redirects.length === 0 ? this : request;
          if (is_1.default.nodeStream(body)) {
              body.pipe(currentRequest);
              body.once('error', (error) => {
                  this._beforeError(new UploadError(error, this));
              });
          }
          else {
              this._unlockWrite();
              if (!is_1.default.undefined(body)) {
                  this._writeRequest(body, undefined, () => { });
                  currentRequest.end();
                  this._lockWrite();
              }
              else if (this._cannotHaveBody || this._noPipe) {
                  currentRequest.end();
                  this._lockWrite();
              }
          }
          this.emit('request', request);
      }
      async _createCacheableRequest(url, options) {
          return new Promise((resolve, reject) => {
              // TODO: Remove `utils/url-to-options.ts` when `cacheable-request` is fixed
              Object.assign(options, url_to_options_1.default(url));
              // `http-cache-semantics` checks this
              // TODO: Fix this ignore.
              // @ts-expect-error
              delete options.url;
              let request;
              // This is ugly
              const cacheRequest = cacheableStore.get(options.cache)(options, async (response) => {
                  // TODO: Fix `cacheable-response`
                  response._readableState.autoDestroy = false;
                  if (request) {
                      (await request).emit('cacheableResponse', response);
                  }
                  resolve(response);
              });
              // Restore options
              options.url = url;
              cacheRequest.once('error', reject);
              cacheRequest.once('request', async (requestOrPromise) => {
                  request = requestOrPromise;
                  resolve(request);
              });
          });
      }
      async _makeRequest() {
          var _a, _b, _c, _d, _e;
          const { options } = this;
          const { headers } = options;
          for (const key in headers) {
              if (is_1.default.undefined(headers[key])) {
                  // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
                  delete headers[key];
              }
              else if (is_1.default.null_(headers[key])) {
                  throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${key}\` header`);
              }
          }
          if (options.decompress && is_1.default.undefined(headers['accept-encoding'])) {
              headers['accept-encoding'] = supportsBrotli ? 'gzip, deflate, br' : 'gzip, deflate';
          }
          // Set cookies
          if (options.cookieJar) {
              const cookieString = await options.cookieJar.getCookieString(options.url.toString());
              if (is_1.default.nonEmptyString(cookieString)) {
                  options.headers.cookie = cookieString;
              }
          }
          for (const hook of options.hooks.beforeRequest) {
              // eslint-disable-next-line no-await-in-loop
              const result = await hook(options);
              if (!is_1.default.undefined(result)) {
                  // @ts-expect-error Skip the type mismatch to support abstract responses
                  options.request = () => result;
                  break;
              }
          }
          const { agent, request, timeout, url } = options;
          if (options.dnsCache && !('lookup' in options)) {
              options.lookup = options.dnsCache.lookup;
          }
          // UNIX sockets
          if (url.hostname === 'unix') {
              const matches = /(?<socketPath>.+?):(?<path>.+)/.exec(`${url.pathname}${url.search}`);
              if (matches === null || matches === void 0 ? void 0 : matches.groups) {
                  const { socketPath, path } = matches.groups;
                  Object.assign(options, {
                      socketPath,
                      path,
                      host: ''
                  });
              }
          }
          const isHttps = url.protocol === 'https:';
          // Fallback function
          let fallbackFn;
          if (options.http2) {
              fallbackFn = http2wrapper.auto;
          }
          else {
              fallbackFn = isHttps ? https.request : http.request;
          }
          const realFn = (_a = options.request) !== null && _a !== void 0 ? _a : fallbackFn;
          // Cache support
          const fn = options.cache ? this._createCacheableRequest : realFn;
          // Pass an agent directly when HTTP2 is disabled
          if (agent && !options.http2) {
              options.agent = agent[isHttps ? 'https' : 'http'];
          }
          // Prepare plain HTTP request options
          options[kRequest] = realFn;
          delete options.request;
          // TODO: Fix this ignore.
          // @ts-expect-error
          delete options.timeout;
          const requestOptions = options;
          requestOptions.shared = (_b = options.cacheOptions) === null || _b === void 0 ? void 0 : _b.shared;
          requestOptions.cacheHeuristic = (_c = options.cacheOptions) === null || _c === void 0 ? void 0 : _c.cacheHeuristic;
          requestOptions.immutableMinTimeToLive = (_d = options.cacheOptions) === null || _d === void 0 ? void 0 : _d.immutableMinTimeToLive;
          requestOptions.ignoreCargoCult = (_e = options.cacheOptions) === null || _e === void 0 ? void 0 : _e.ignoreCargoCult;
          // If `dnsLookupIpVersion` is not present do not override `family`
          if (options.dnsLookupIpVersion !== undefined) {
              try {
                  requestOptions.family = dns_ip_version_1.dnsLookupIpVersionToFamily(options.dnsLookupIpVersion);
              }
              catch (_f) {
                  throw new Error('Invalid `dnsLookupIpVersion` option value');
              }
          }
          // HTTPS options remapping
          if (options.https) {
              if ('rejectUnauthorized' in options.https) {
                  requestOptions.rejectUnauthorized = options.https.rejectUnauthorized;
              }
              if (options.https.checkServerIdentity) {
                  requestOptions.checkServerIdentity = options.https.checkServerIdentity;
              }
              if (options.https.certificateAuthority) {
                  requestOptions.ca = options.https.certificateAuthority;
              }
              if (options.https.certificate) {
                  requestOptions.cert = options.https.certificate;
              }
              if (options.https.key) {
                  requestOptions.key = options.https.key;
              }
              if (options.https.passphrase) {
                  requestOptions.passphrase = options.https.passphrase;
              }
          }
          try {
              let requestOrResponse = await fn(url, requestOptions);
              if (is_1.default.undefined(requestOrResponse)) {
                  requestOrResponse = fallbackFn(url, requestOptions);
              }
              // Restore options
              options.request = request;
              options.timeout = timeout;
              options.agent = agent;
              // HTTPS options restore
              if (options.https) {
                  if ('rejectUnauthorized' in options.https) {
                      delete requestOptions.rejectUnauthorized;
                  }
                  if (options.https.checkServerIdentity) {
                      // @ts-expect-error - This one will be removed when we remove the alias.
                      delete requestOptions.checkServerIdentity;
                  }
                  if (options.https.certificateAuthority) {
                      delete requestOptions.ca;
                  }
                  if (options.https.certificate) {
                      delete requestOptions.cert;
                  }
                  if (options.https.key) {
                      delete requestOptions.key;
                  }
                  if (options.https.passphrase) {
                      delete requestOptions.passphrase;
                  }
              }
              if (isClientRequest(requestOrResponse)) {
                  this._onRequest(requestOrResponse);
                  // Emit the response after the stream has been ended
              }
              else if (this.writable) {
                  this.once('finish', () => {
                      void this._onResponse(requestOrResponse);
                  });
                  this._unlockWrite();
                  this.end();
                  this._lockWrite();
              }
              else {
                  void this._onResponse(requestOrResponse);
              }
          }
          catch (error) {
              if (error instanceof CacheableRequest.CacheError) {
                  throw new CacheError(error, this);
              }
              throw new RequestError(error.message, error, this);
          }
      }
      async _error(error) {
          try {
              for (const hook of this.options.hooks.beforeError) {
                  // eslint-disable-next-line no-await-in-loop
                  error = await hook(error);
              }
          }
          catch (error_) {
              error = new RequestError(error_.message, error_, this);
          }
          this.destroy(error);
      }
      _beforeError(error) {
          if (this[kStopReading]) {
              return;
          }
          const { options } = this;
          const retryCount = this.retryCount + 1;
          this[kStopReading] = true;
          if (!(error instanceof RequestError)) {
              error = new RequestError(error.message, error, this);
          }
          const typedError = error;
          const { response } = typedError;
          void (async () => {
              if (response && !response.body) {
                  response.setEncoding(this._readableState.encoding);
                  try {
                      response.rawBody = await get_buffer_1.default(response);
                      response.body = response.rawBody.toString();
                  }
                  catch (_a) { }
              }
              if (this.listenerCount('retry') !== 0) {
                  let backoff;
                  try {
                      let retryAfter;
                      if (response && 'retry-after' in response.headers) {
                          retryAfter = Number(response.headers['retry-after']);
                          if (Number.isNaN(retryAfter)) {
                              retryAfter = Date.parse(response.headers['retry-after']) - Date.now();
                              if (retryAfter <= 0) {
                                  retryAfter = 1;
                              }
                          }
                          else {
                              retryAfter *= 1000;
                          }
                      }
                      backoff = await options.retry.calculateDelay({
                          attemptCount: retryCount,
                          retryOptions: options.retry,
                          error: typedError,
                          retryAfter,
                          computedValue: calculate_retry_delay_1.default({
                              attemptCount: retryCount,
                              retryOptions: options.retry,
                              error: typedError,
                              retryAfter,
                              computedValue: 0
                          })
                      });
                  }
                  catch (error_) {
                      void this._error(new RequestError(error_.message, error_, this));
                      return;
                  }
                  if (backoff) {
                      const retry = async () => {
                          try {
                              for (const hook of this.options.hooks.beforeRetry) {
                                  // eslint-disable-next-line no-await-in-loop
                                  await hook(this.options, typedError, retryCount);
                              }
                          }
                          catch (error_) {
                              void this._error(new RequestError(error_.message, error, this));
                              return;
                          }
                          // Something forced us to abort the retry
                          if (this.destroyed) {
                              return;
                          }
                          this.destroy();
                          this.emit('retry', retryCount, error);
                      };
                      this[kRetryTimeout] = setTimeout(retry, backoff);
                      return;
                  }
              }
              void this._error(typedError);
          })();
      }
      _read() {
          this[kTriggerRead] = true;
          const response = this[kResponse];
          if (response && !this[kStopReading]) {
              // We cannot put this in the `if` above
              // because `.read()` also triggers the `end` event
              if (response.readableLength) {
                  this[kTriggerRead] = false;
              }
              let data;
              while ((data = response.read()) !== null) {
                  this[kDownloadedSize] += data.length;
                  this[kStartedReading] = true;
                  const progress = this.downloadProgress;
                  if (progress.percent < 1) {
                      this.emit('downloadProgress', progress);
                  }
                  this.push(data);
              }
          }
      }
      // Node.js 12 has incorrect types, so the encoding must be a string
      _write(chunk, encoding, callback) {
          const write = () => {
              this._writeRequest(chunk, encoding, callback);
          };
          if (this.requestInitialized) {
              write();
          }
          else {
              this[kJobs].push(write);
          }
      }
      _writeRequest(chunk, encoding, callback) {
          if (this[kRequest].destroyed) {
              // Probably the `ClientRequest` instance will throw
              return;
          }
          this._progressCallbacks.push(() => {
              this[kUploadedSize] += Buffer.byteLength(chunk, encoding);
              const progress = this.uploadProgress;
              if (progress.percent < 1) {
                  this.emit('uploadProgress', progress);
              }
          });
          // TODO: What happens if it's from cache? Then this[kRequest] won't be defined.
          this[kRequest].write(chunk, encoding, (error) => {
              if (!error && this._progressCallbacks.length !== 0) {
                  this._progressCallbacks.shift()();
              }
              callback(error);
          });
      }
      _final(callback) {
          const endRequest = () => {
              // FIX: Node.js 10 calls the write callback AFTER the end callback!
              while (this._progressCallbacks.length !== 0) {
                  this._progressCallbacks.shift()();
              }
              // We need to check if `this[kRequest]` is present,
              // because it isn't when we use cache.
              if (!(kRequest in this)) {
                  callback();
                  return;
              }
              if (this[kRequest].destroyed) {
                  callback();
                  return;
              }
              this[kRequest].end((error) => {
                  if (!error) {
                      this[kBodySize] = this[kUploadedSize];
                      this.emit('uploadProgress', this.uploadProgress);
                      this[kRequest].emit('upload-complete');
                  }
                  callback(error);
              });
          };
          if (this.requestInitialized) {
              endRequest();
          }
          else {
              this[kJobs].push(endRequest);
          }
      }
      _destroy(error, callback) {
          var _a;
          this[kStopReading] = true;
          // Prevent further retries
          clearTimeout(this[kRetryTimeout]);
          if (kRequest in this) {
              this[kCancelTimeouts]();
              // TODO: Remove the next `if` when these get fixed:
              // - https://github.com/nodejs/node/issues/32851
              if (!((_a = this[kResponse]) === null || _a === void 0 ? void 0 : _a.complete)) {
                  this[kRequest].destroy();
              }
          }
          if (error !== null && !is_1.default.undefined(error) && !(error instanceof RequestError)) {
              error = new RequestError(error.message, error, this);
          }
          callback(error);
      }
      get _isAboutToError() {
          return this[kStopReading];
      }
      /**
      The remote IP address.
      */
      get ip() {
          var _a;
          return (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.socket.remoteAddress;
      }
      /**
      Indicates whether the request has been aborted or not.
      */
      get aborted() {
          var _a, _b, _c;
          return ((_b = (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.destroyed) !== null && _b !== void 0 ? _b : this.destroyed) && !((_c = this[kOriginalResponse]) === null || _c === void 0 ? void 0 : _c.complete);
      }
      get socket() {
          var _a;
          return (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.socket;
      }
      /**
      Progress event for downloading (receiving a response).
      */
      get downloadProgress() {
          let percent;
          if (this[kResponseSize]) {
              percent = this[kDownloadedSize] / this[kResponseSize];
          }
          else if (this[kResponseSize] === this[kDownloadedSize]) {
              percent = 1;
          }
          else {
              percent = 0;
          }
          return {
              percent,
              transferred: this[kDownloadedSize],
              total: this[kResponseSize]
          };
      }
      /**
      Progress event for uploading (sending a request).
      */
      get uploadProgress() {
          let percent;
          if (this[kBodySize]) {
              percent = this[kUploadedSize] / this[kBodySize];
          }
          else if (this[kBodySize] === this[kUploadedSize]) {
              percent = 1;
          }
          else {
              percent = 0;
          }
          return {
              percent,
              transferred: this[kUploadedSize],
              total: this[kBodySize]
          };
      }
      /**
      The object contains the following properties:
  
      - `start` - Time when the request started.
      - `socket` - Time when a socket was assigned to the request.
      - `lookup` - Time when the DNS lookup finished.
      - `connect` - Time when the socket successfully connected.
      - `secureConnect` - Time when the socket securely connected.
      - `upload` - Time when the request finished uploading.
      - `response` - Time when the request fired `response` event.
      - `end` - Time when the response fired `end` event.
      - `error` - Time when the request fired `error` event.
      - `abort` - Time when the request fired `abort` event.
      - `phases`
          - `wait` - `timings.socket - timings.start`
          - `dns` - `timings.lookup - timings.socket`
          - `tcp` - `timings.connect - timings.lookup`
          - `tls` - `timings.secureConnect - timings.connect`
          - `request` - `timings.upload - (timings.secureConnect || timings.connect)`
          - `firstByte` - `timings.response - timings.upload`
          - `download` - `timings.end - timings.response`
          - `total` - `(timings.end || timings.error || timings.abort) - timings.start`
  
      If something has not been measured yet, it will be `undefined`.
  
      __Note__: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
      */
      get timings() {
          var _a;
          return (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.timings;
      }
      /**
      Whether the response was retrieved from the cache.
      */
      get isFromCache() {
          return this[kIsFromCache];
      }
      pipe(destination, options) {
          if (this[kStartedReading]) {
              throw new Error('Failed to pipe. The response has been emitted already.');
          }
          if (destination instanceof http_1.ServerResponse) {
              this[kServerResponsesPiped].add(destination);
          }
          return super.pipe(destination, options);
      }
      unpipe(destination) {
          if (destination instanceof http_1.ServerResponse) {
              this[kServerResponsesPiped].delete(destination);
          }
          super.unpipe(destination);
          return this;
      }
  }
  exports.default = Request;
  
  
  /***/ }),
  
  /***/ 988:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const http = __webpack_require__(605);
  const https = __webpack_require__(211);
  const resolveALPN = __webpack_require__(524);
  const QuickLRU = __webpack_require__(904);
  const Http2ClientRequest = __webpack_require__(181);
  const calculateServerName = __webpack_require__(751);
  const urlToOptions = __webpack_require__(507);
  
  const cache = new QuickLRU({maxSize: 100});
  const queue = new Map();
  
  const installSocket = (agent, socket, options) => {
  	socket._httpMessage = {shouldKeepAlive: true};
  
  	const onFree = () => {
  		agent.emit('free', socket, options);
  	};
  
  	socket.on('free', onFree);
  
  	const onClose = () => {
  		agent.removeSocket(socket, options);
  	};
  
  	socket.on('close', onClose);
  
  	const onRemove = () => {
  		agent.removeSocket(socket, options);
  		socket.off('close', onClose);
  		socket.off('free', onFree);
  		socket.off('agentRemove', onRemove);
  	};
  
  	socket.on('agentRemove', onRemove);
  
  	agent.emit('free', socket, options);
  };
  
  const resolveProtocol = async options => {
  	const name = `${options.host}:${options.port}:${options.ALPNProtocols.sort()}`;
  
  	if (!cache.has(name)) {
  		if (queue.has(name)) {
  			const result = await queue.get(name);
  			return result.alpnProtocol;
  		}
  
  		const {path, agent} = options;
  		options.path = options.socketPath;
  
  		const resultPromise = resolveALPN(options);
  		queue.set(name, resultPromise);
  
  		try {
  			const {socket, alpnProtocol} = await resultPromise;
  			cache.set(name, alpnProtocol);
  
  			options.path = path;
  
  			if (alpnProtocol === 'h2') {
  				// https://github.com/nodejs/node/issues/33343
  				socket.destroy();
  			} else {
  				const {globalAgent} = https;
  				const defaultCreateConnection = https.Agent.prototype.createConnection;
  
  				if (agent) {
  					if (agent.createConnection === defaultCreateConnection) {
  						installSocket(agent, socket, options);
  					} else {
  						socket.destroy();
  					}
  				} else if (globalAgent.createConnection === defaultCreateConnection) {
  					installSocket(globalAgent, socket, options);
  				} else {
  					socket.destroy();
  				}
  			}
  
  			queue.delete(name);
  
  			return alpnProtocol;
  		} catch (error) {
  			queue.delete(name);
  
  			throw error;
  		}
  	}
  
  	return cache.get(name);
  };
  
  module.exports = async (input, options, callback) => {
  	if (typeof input === 'string' || input instanceof URL) {
  		input = urlToOptions(new URL(input));
  	}
  
  	if (typeof options === 'function') {
  		callback = options;
  		options = undefined;
  	}
  
  	options = {
  		ALPNProtocols: ['h2', 'http/1.1'],
  		...input,
  		...options,
  		resolveSocket: true
  	};
  
  	if (!Array.isArray(options.ALPNProtocols) || options.ALPNProtocols.length === 0) {
  		throw new Error('The `ALPNProtocols` option must be an Array with at least one entry');
  	}
  
  	options.protocol = options.protocol || 'https:';
  	const isHttps = options.protocol === 'https:';
  
  	options.host = options.hostname || options.host || 'localhost';
  	options.session = options.tlsSession;
  	options.servername = options.servername || calculateServerName(options);
  	options.port = options.port || (isHttps ? 443 : 80);
  	options._defaultAgent = isHttps ? https.globalAgent : http.globalAgent;
  
  	const agents = options.agent;
  
  	if (agents) {
  		if (agents.addRequest) {
  			throw new Error('The `options.agent` object can contain only `http`, `https` or `http2` properties');
  		}
  
  		options.agent = agents[isHttps ? 'https' : 'http'];
  	}
  
  	if (isHttps) {
  		const protocol = await resolveProtocol(options);
  
  		if (protocol === 'h2') {
  			if (agents) {
  				options.agent = agents.http2;
  			}
  
  			return new Http2ClientRequest(options, callback);
  		}
  	}
  
  	return http.request(options, callback);
  };
  
  module.exports.protocolCache = cache;
  
  
  /***/ }),
  
  /***/ 992:
  /***/ (function(__unusedmodule, exports, __webpack_require__) {
  
  "use strict";
  
  Object.defineProperty(exports, "__esModule", { value: true });
  const is_1 = __webpack_require__(534);
  const normalizeArguments = (options, defaults) => {
      if (is_1.default.null_(options.encoding)) {
          throw new TypeError('To get a Buffer, set `options.responseType` to `buffer` instead');
      }
      is_1.assert.any([is_1.default.string, is_1.default.undefined], options.encoding);
      is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.resolveBodyOnly);
      is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.methodRewriting);
      is_1.assert.any([is_1.default.boolean, is_1.default.undefined], options.isStream);
      is_1.assert.any([is_1.default.string, is_1.default.undefined], options.responseType);
      // `options.responseType`
      if (options.responseType === undefined) {
          options.responseType = 'text';
      }
      // `options.retry`
      const { retry } = options;
      if (defaults) {
          options.retry = { ...defaults.retry };
      }
      else {
          options.retry = {
              calculateDelay: retryObject => retryObject.computedValue,
              limit: 0,
              methods: [],
              statusCodes: [],
              errorCodes: [],
              maxRetryAfter: undefined
          };
      }
      if (is_1.default.object(retry)) {
          options.retry = {
              ...options.retry,
              ...retry
          };
          options.retry.methods = [...new Set(options.retry.methods.map(method => method.toUpperCase()))];
          options.retry.statusCodes = [...new Set(options.retry.statusCodes)];
          options.retry.errorCodes = [...new Set(options.retry.errorCodes)];
      }
      else if (is_1.default.number(retry)) {
          options.retry.limit = retry;
      }
      if (is_1.default.undefined(options.retry.maxRetryAfter)) {
          options.retry.maxRetryAfter = Math.min(
          // TypeScript is not smart enough to handle `.filter(x => is.number(x))`.
          // eslint-disable-next-line unicorn/no-fn-reference-in-iterator
          ...[options.timeout.request, options.timeout.connect].filter(is_1.default.number));
      }
      // `options.pagination`
      if (is_1.default.object(options.pagination)) {
          if (defaults) {
              options.pagination = {
                  ...defaults.pagination,
                  ...options.pagination
              };
          }
          const { pagination } = options;
          if (!is_1.default.function_(pagination.transform)) {
              throw new Error('`options.pagination.transform` must be implemented');
          }
          if (!is_1.default.function_(pagination.shouldContinue)) {
              throw new Error('`options.pagination.shouldContinue` must be implemented');
          }
          if (!is_1.default.function_(pagination.filter)) {
              throw new TypeError('`options.pagination.filter` must be implemented');
          }
          if (!is_1.default.function_(pagination.paginate)) {
              throw new Error('`options.pagination.paginate` must be implemented');
          }
      }
      // JSON mode
      if (options.responseType === 'json' && options.headers.accept === undefined) {
          options.headers.accept = 'application/json';
      }
      return options;
  };
  exports.default = normalizeArguments;
  
  
  /***/ }),
  
  /***/ 997:
  /***/ (function(module, __unusedexports, __webpack_require__) {
  
  "use strict";
  
  const {constants: BufferConstants} = __webpack_require__(293);
  const pump = __webpack_require__(453);
  const bufferStream = __webpack_require__(375);
  
  class MaxBufferError extends Error {
  	constructor() {
  		super('maxBuffer exceeded');
  		this.name = 'MaxBufferError';
  	}
  }
  
  async function getStream(inputStream, options) {
  	if (!inputStream) {
  		return Promise.reject(new Error('Expected a stream'));
  	}
  
  	options = {
  		maxBuffer: Infinity,
  		...options
  	};
  
  	const {maxBuffer} = options;
  
  	let stream;
  	await new Promise((resolve, reject) => {
  		const rejectPromise = error => {
  			// Don't retrieve an oversized buffer.
  			if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
  				error.bufferedData = stream.getBufferedValue();
  			}
  
  			reject(error);
  		};
  
  		stream = pump(inputStream, bufferStream(options), error => {
  			if (error) {
  				rejectPromise(error);
  				return;
  			}
  
  			resolve();
  		});
  
  		stream.on('data', () => {
  			if (stream.getBufferedLength() > maxBuffer) {
  				rejectPromise(new MaxBufferError());
  			}
  		});
  	});
  
  	return stream.getBufferedValue();
  }
  
  module.exports = getStream;
  // TODO: Remove this for the next major release
  module.exports.default = getStream;
  module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'});
  module.exports.array = (stream, options) => getStream(stream, {...options, array: true});
  module.exports.MaxBufferError = MaxBufferError;
  
  
  /***/ })
  
  /******/ });