diff --git a/.gitignore b/.gitignore index 4cc30ee..839cf4e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,7 @@ node_modules/ dump.rdb Vagrantfile orbit-db-cache.json -examples/browser/bundle.js \ No newline at end of file +examples/browser/bundle.js +examples/browser/*.map +dist/*.map +dist/orbitdb.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a2c211a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +# Changelog + +## v0.12.0 +- IPFS pubsub diff --git a/README.md b/README.md index f81101f..8ef8c2e 100644 --- a/README.md +++ b/README.md @@ -16,22 +16,15 @@ This is the Javascript implementation and it works both in **Node.js** and **Bro - Aggregation happens on client side and data is eventually consistent - Designed to work offline first -Check out a visualization of the data flow at https://github.com/haadcode/proto2 +**Node.js** -Live demo: http://celebdil.benet.ai:8080/ipfs/Qmezm7g8mBpWyuPk6D84CNcfLKJwU6mpXuEN5GJZNkX3XK/ + -![Screenshot](https://raw.githubusercontent.com/haadcode/proto2/master/screenshot.png) +**Browser** -**NOTE: the README can be out of date, I'm working to get up to date. If you find a problem, please open an issue or a PR.** + -_Currently requires [orbit-server](https://github.com/haadcode/orbit-server) for pubsub communication. This will change in the future as soon as IPFS provides pubsub._ - -## Install -``` -npm install orbit-db -``` - -## Data stores +### Data stores Currently available data stores: @@ -40,177 +33,145 @@ Currently available data stores: - [orbit-db-feedstore](https://github.com/haadcode/orbit-db-feedstore) - [orbit-db-counterstore](https://github.com/haadcode/orbit-db-counterstore) +## Install + +From npm: +``` +npm install orbit-db +``` + +From git: +``` +git clone https://github.com/haadcode/orbit-db.git +cd orbit-db +npm install +``` + ## Usage ```javascript +'use strict' + +const IpfsApi = require('ipfs-api') const OrbitDB = require('orbit-db') -const IPFS = require('ipfs') -OrbitDB.connect('178.62.241.75:3333', 'tester', null, new IPFS(), { allowOffline: true }) - .then((orbitdb) => { - const kvstore = orbitdb.kvstore('db name') - const events = orbitdb.eventlog('db name') - const feed = orbitdb.feed('db name') - const counters = orbitdb.counter('db name') +const ipfs = IpfsApi('localhost', '5001') +const orbitdb = new OrbitDB(ipfs) - kvstore.put('key1', 'hello1') - .then(() => kvstore.get('key1')) - .then((value) => console.log(value)) // 'hello!' +const db = orbitdb.eventlog("feed name") + +db.add("hello world") + .then(() => { + const latest = db.iterator({ limit: 5 }).collect() + console.log(latest.join("\n")) }) ``` -Documentation for individual stores are WIP, please see each store's source code for available public methods. - ## Examples -*To run the examples below, make sure to run a local [orbit-server](https://github.com/haadcode/orbit-server)* +### Browser example -### Browser examples -Build the examples: ```bash npm install npm run build:examples +npm run examples:browser ``` -Then open `examples/browser.html` or `examples/index.html`. See the full example [here](https://github.com/haadcode/orbit-db/blob/master/examples/browser/browser.html). +### Node.js example -```html - - - - - - - - - - - - -``` - -### Node.js examples - -Before running the examples, install dependencies with: -``` -npm install -``` - -Key-Value store [example](https://github.com/haadcode/orbit-db/blob/master/examples/keyvalue.js): -``` -node examples/keyvalue.js -``` - -Event log [example](https://github.com/haadcode/orbit-db/blob/master/examples/eventlog.js) (run several in separate shells): -``` -node examples/eventlog.js -``` - -Benchmark writes: ```bash -node examples/benchmark.js ; +npm install +npm run examples:node +``` + +See detailed [example](https://github.com/haadcode/orbit-db/blob/master/examples/eventlog.js) and run it with: +```bash +node examples/eventlog.js +``` + +```javascript +'use strict' + +const IpfsDaemon = require('ipfs-daemon') +const OrbitDB = require('orbit-db') + +IpfsDaemon() + .then((res) => { + const orbitdb = new OrbitDB(res.ipfs) + const db = orbitdb.eventlog("|orbit-db|examples|eventlog-example") + + const creatures = ['🐙', '🐷', 'đŸŦ', '🐞', '🐈', '🙉', '🐸', '🐓'] + + const query = () => { + const index = Math.floor(Math.random() * creatures.length) + db.add(creatures[index]) + .then(() => { + const latest = db.iterator({ limit: 5 }).collect() + let output = `` + output += `---------------------------------------------------\n` + output += `Latest Visitors\n` + output += `---------------------------------------------------\n` + output += latest.reverse().map((e) => e.payload.value).join('\n') + `\n` + console.log(output) + }) + .catch((e) => { + console.error(e.stack) + }) + } + + setInterval(query, 1000) + }) + .catch((err) => console.error(err)) ``` ## API -**NOTE: the API documentation is currently out of date. It will be updated soon!** -_See usage example below_ +**TODO** -_OrbitDB calls its namespaces channels. A channel is similar to "table", "keyspace", "topic", "feed" or "collection" in other db systems._ +- [orbit-db-kvstore](https://github.com/haadcode/orbit-db-kvstore) + - put(key, value) + - set(key, value) + - get(key) +- [orbit-db-eventstore](https://github.com/haadcode/orbit-db-eventstore) + - add(value) + - get(hash) + - iterator(options) +- [orbit-db-feedstore](https://github.com/haadcode/orbit-db-feedstore) + - add(value) + - del(hash) + - get(hash) + - iterator(options) +- [orbit-db-counterstore](https://github.com/haadcode/orbit-db-counterstore) + - inc([value]) - connect(, username, password) - - channel(name, password) - - .add(data: String) // Insert an event to a channel, returns of the event - - .iterator([options]) // Returns an iterator of events - - // options : { - // gt: , // Return events newer than - // gte: , // Return events newer then (inclusive) - // lt: , // Return events older than - // lte: , // Return events older than (inclusive) - // limit: -1, // Number of events to return, -1 returns all, default 1 - // reverse: true // Return items oldest first, default latest first - // } - - .put(key, data: String) // Insert (key,value) to a channel - - .get(key) // Retrieve value - - .del({ key: }) // Remove entry - - .delete() // Deletes the channel, all data will be "removed" (unassociated with the channel, actual data is not deleted from ipfs) - -## Usage -```javascript -const async = require('asyncawait/async'); -const ipfsAPI = require('ipfs-api'); -const OrbitDB = require('orbit-db'); - -// local ipfs daemon -const ipfs = ipfsAPI(); - -async(() => { - // Connect - const orbit = await(OrbitClient.connect('localhost:3333', 'usernamne', '', ipfs)); - - /* Event Log */ - const eventlog = orbit.eventlog('eventlog test'); - const hash = await(eventlog.add('hello')); // - - // Remove event - await(eventlog.remove(hash)); - - // Iterator options - const options = { limit: -1 }; // fetch all messages - - // Get events - const iter = eventlog.iterator(options); // Symbol.iterator - const next = iter.next(); // { value: , done: false|true} - - // OR: - // var all = iter.collect(); // returns all elements as an array - - // OR: - // for(let i of iter) - // console.log(i.hash, i.item); - - /* Delete database locally */ - eventlog.delete(); - - /* KV Store */ - const kvstore = orbit.kvstore('kv test'); - await(kvstore.put('key1', 'hello world')); - kvstore.get('key1'); // returns "hello world" - await(kvstore.del('key1')); -})(); -``` - -### Development +## Development #### Run Tests ```bash npm test ``` -Keep tests running while development: -```bash -mocha -w -``` - #### Build distributables ```bash -npm install npm run build ``` + +## Background + +**TODO** + +Check out a visualization of the data flow at https://github.com/haadcode/proto2 + +Live demo: http://celebdil.benet.ai:8080/ipfs/Qmezm7g8mBpWyuPk6D84CNcfLKJwU6mpXuEN5GJZNkX3XK/ + +![Screenshot](https://raw.githubusercontent.com/haadcode/proto2/master/screenshot.png) + +**TODO: list of modules used, orbit-db-pubsub, etc.** + +## Contributing + +**TODO** + +## License + +MIT ÂŠī¸ 2016, Haadcode diff --git a/circle.yml b/circle.yml index 09ae5e9..ee1c24b 100644 --- a/circle.yml +++ b/circle.yml @@ -1,8 +1,3 @@ machine: node: - version: 4.3.1 - services: - - redis -dependencies: - pre: - - npm install -g npm@3.x.x + version: 6.1.0 diff --git a/dist/orbitdb.js b/dist/orbitdb.js deleted file mode 100644 index 4e99baf..0000000 --- a/dist/orbitdb.js +++ /dev/null @@ -1,42646 +0,0 @@ -var OrbitDB = -/******/ (function(modules) { // webpackBootstrap -/******/ // 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 -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - -/******/ // Flag the module as loaded -/******/ module.l = true; - -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } - - -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; - -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; - -/******/ // identity function for calling harmory imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; - -/******/ // define getter function for harmory exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ }; - -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; - -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; - -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 160); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { return this; })(); - -try { - // This works if eval is allowed (see CSP) - g = g || Function("return this")() || (1,eval)("this"); -} catch(e) { - // This works if the window reference is available - if(typeof window === "object") - g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }, -/* 1 */ -/***/ function(module, exports, __webpack_require__) { - -var store = __webpack_require__(52)('wks') - , uid = __webpack_require__(56) - , Symbol = __webpack_require__(2).Symbol - , USE_SYMBOL = typeof Symbol == 'function'; - -var $exports = module.exports = function(name){ - return store[name] || (store[name] = - USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); -}; - -$exports.store = store; - -/***/ }, -/* 2 */ -/***/ function(module, exports) { - -// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 -var global = module.exports = typeof window != 'undefined' && window.Math == Math - ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); -if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef - -/***/ }, -/* 3 */ -/***/ function(module, exports) { - -var core = module.exports = {version: '2.4.0'}; -if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef - -/***/ }, -/* 4 */ -/***/ function(module, exports, __webpack_require__) { - - -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = __webpack_require__(122); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); - -/** - * Colors. - */ - -exports.colors = [ - 'lightseagreen', - 'forestgreen', - 'goldenrod', - 'dodgerblue', - 'darkorchid', - 'crimson' -]; - -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - -function useColors() { - // is webkit? http://stackoverflow.com/a/16459606/376773 - return ('WebkitAppearance' in document.documentElement.style) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (window.console && (console.firebug || (console.exception && console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - -exports.formatters.j = function(v) { - return JSON.stringify(v); -}; - - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs() { - var args = arguments; - var useColors = this.useColors; - - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); - - if (!useColors) return args; - - var c = 'color: ' + this.color; - args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); - - // the final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - var index = 0; - var lastC = 0; - args[0].replace(/%[a-z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); - return args; -} - -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; - } - } catch(e) {} -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} - return r; -} - -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ - -exports.enable(load()); - -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - -function localstorage(){ - try { - return window.localStorage; - } catch (e) {} -} - - -/***/ }, -/* 5 */ -/***/ function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(17); -module.exports = function(it){ - if(!isObject(it))throw TypeError(it + ' is not an object!'); - return it; -}; - -/***/ }, -/* 6 */ -/***/ function(module, exports, __webpack_require__) { - -// Thank's IE8 for his funny defineProperty -module.exports = !__webpack_require__(23)(function(){ - return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; -}); - -/***/ }, -/* 7 */ -/***/ function(module, exports, __webpack_require__) { - -var dP = __webpack_require__(10) - , createDesc = __webpack_require__(51); -module.exports = __webpack_require__(6) ? function(object, key, value){ - return dP.f(object, key, createDesc(1, value)); -} : function(object, key, value){ - object[key] = value; - return object; -}; - -/***/ }, -/* 8 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/** - * Module dependencies. - */ - -var keys = __webpack_require__(129); -var hasBinary = __webpack_require__(130); -var sliceBuffer = __webpack_require__(76); -var base64encoder = __webpack_require__(79); -var after = __webpack_require__(75); -var utf8 = __webpack_require__(155); - -/** - * Check if we are running an android browser. That requires us to use - * ArrayBuffer with polling transports... - * - * http://ghinda.net/jpeg-blob-ajax-android/ - */ - -var isAndroid = navigator.userAgent.match(/Android/i); - -/** - * Check if we are running in PhantomJS. - * Uploading a Blob with PhantomJS does not work correctly, as reported here: - * https://github.com/ariya/phantomjs/issues/11395 - * @type boolean - */ -var isPhantomJS = /PhantomJS/i.test(navigator.userAgent); - -/** - * When true, avoids using Blobs to encode payloads. - * @type boolean - */ -var dontSendBlobs = isAndroid || isPhantomJS; - -/** - * Current protocol version. - */ - -exports.protocol = 3; - -/** - * Packet types. - */ - -var packets = exports.packets = { - open: 0 // non-ws - , close: 1 // non-ws - , ping: 2 - , pong: 3 - , message: 4 - , upgrade: 5 - , noop: 6 -}; - -var packetslist = keys(packets); - -/** - * Premade error packet. - */ - -var err = { type: 'error', data: 'parser error' }; - -/** - * Create a blob api even for blob builder when vendor prefixes exist - */ - -var Blob = __webpack_require__(81); - -/** - * Encodes a packet. - * - * [ ] - * - * Example: - * - * 5hello world - * 3 - * 4 - * - * Binary is encoded in an identical principle - * - * @api private - */ - -exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) { - if ('function' == typeof supportsBinary) { - callback = supportsBinary; - supportsBinary = false; - } - - if ('function' == typeof utf8encode) { - callback = utf8encode; - utf8encode = null; - } - - var data = (packet.data === undefined) - ? undefined - : packet.data.buffer || packet.data; - - if (global.ArrayBuffer && data instanceof ArrayBuffer) { - return encodeArrayBuffer(packet, supportsBinary, callback); - } else if (Blob && data instanceof global.Blob) { - return encodeBlob(packet, supportsBinary, callback); - } - - // might be an object with { base64: true, data: dataAsBase64String } - if (data && data.base64) { - return encodeBase64Object(packet, callback); - } - - // Sending data as a utf-8 string - var encoded = packets[packet.type]; - - // data fragment is optional - if (undefined !== packet.data) { - encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data); - } - - return callback('' + encoded); - -}; - -function encodeBase64Object(packet, callback) { - // packet data is an object { base64: true, data: dataAsBase64String } - var message = 'b' + exports.packets[packet.type] + packet.data.data; - return callback(message); -} - -/** - * Encode packet helpers for binary types - */ - -function encodeArrayBuffer(packet, supportsBinary, callback) { - if (!supportsBinary) { - return exports.encodeBase64Packet(packet, callback); - } - - var data = packet.data; - var contentArray = new Uint8Array(data); - var resultBuffer = new Uint8Array(1 + data.byteLength); - - resultBuffer[0] = packets[packet.type]; - for (var i = 0; i < contentArray.length; i++) { - resultBuffer[i+1] = contentArray[i]; - } - - return callback(resultBuffer.buffer); -} - -function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) { - if (!supportsBinary) { - return exports.encodeBase64Packet(packet, callback); - } - - var fr = new FileReader(); - fr.onload = function() { - packet.data = fr.result; - exports.encodePacket(packet, supportsBinary, true, callback); - }; - return fr.readAsArrayBuffer(packet.data); -} - -function encodeBlob(packet, supportsBinary, callback) { - if (!supportsBinary) { - return exports.encodeBase64Packet(packet, callback); - } - - if (dontSendBlobs) { - return encodeBlobAsArrayBuffer(packet, supportsBinary, callback); - } - - var length = new Uint8Array(1); - length[0] = packets[packet.type]; - var blob = new Blob([length.buffer, packet.data]); - - return callback(blob); -} - -/** - * Encodes a packet with binary data in a base64 string - * - * @param {Object} packet, has `type` and `data` - * @return {String} base64 encoded message - */ - -exports.encodeBase64Packet = function(packet, callback) { - var message = 'b' + exports.packets[packet.type]; - if (Blob && packet.data instanceof global.Blob) { - var fr = new FileReader(); - fr.onload = function() { - var b64 = fr.result.split(',')[1]; - callback(message + b64); - }; - return fr.readAsDataURL(packet.data); - } - - var b64data; - try { - b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data)); - } catch (e) { - // iPhone Safari doesn't let you apply with typed arrays - var typed = new Uint8Array(packet.data); - var basic = new Array(typed.length); - for (var i = 0; i < typed.length; i++) { - basic[i] = typed[i]; - } - b64data = String.fromCharCode.apply(null, basic); - } - message += global.btoa(b64data); - return callback(message); -}; - -/** - * Decodes a packet. Changes format to Blob if requested. - * - * @return {Object} with `type` and `data` (if any) - * @api private - */ - -exports.decodePacket = function (data, binaryType, utf8decode) { - // String data - if (typeof data == 'string' || data === undefined) { - if (data.charAt(0) == 'b') { - return exports.decodeBase64Packet(data.substr(1), binaryType); - } - - if (utf8decode) { - try { - data = utf8.decode(data); - } catch (e) { - return err; - } - } - var type = data.charAt(0); - - if (Number(type) != type || !packetslist[type]) { - return err; - } - - if (data.length > 1) { - return { type: packetslist[type], data: data.substring(1) }; - } else { - return { type: packetslist[type] }; - } - } - - var asArray = new Uint8Array(data); - var type = asArray[0]; - var rest = sliceBuffer(data, 1); - if (Blob && binaryType === 'blob') { - rest = new Blob([rest]); - } - return { type: packetslist[type], data: rest }; -}; - -/** - * Decodes a packet encoded in a base64 string - * - * @param {String} base64 encoded message - * @return {Object} with `type` and `data` (if any) - */ - -exports.decodeBase64Packet = function(msg, binaryType) { - var type = packetslist[msg.charAt(0)]; - if (!global.ArrayBuffer) { - return { type: type, data: { base64: true, data: msg.substr(1) } }; - } - - var data = base64encoder.decode(msg.substr(1)); - - if (binaryType === 'blob' && Blob) { - data = new Blob([data]); - } - - return { type: type, data: data }; -}; - -/** - * Encodes multiple messages (payload). - * - * :data - * - * Example: - * - * 11:hello world2:hi - * - * If any contents are binary, they will be encoded as base64 strings. Base64 - * encoded strings are marked with a b before the length specifier - * - * @param {Array} packets - * @api private - */ - -exports.encodePayload = function (packets, supportsBinary, callback) { - if (typeof supportsBinary == 'function') { - callback = supportsBinary; - supportsBinary = null; - } - - var isBinary = hasBinary(packets); - - if (supportsBinary && isBinary) { - if (Blob && !dontSendBlobs) { - return exports.encodePayloadAsBlob(packets, callback); - } - - return exports.encodePayloadAsArrayBuffer(packets, callback); - } - - if (!packets.length) { - return callback('0:'); - } - - function setLengthHeader(message) { - return message.length + ':' + message; - } - - function encodeOne(packet, doneCallback) { - exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) { - doneCallback(null, setLengthHeader(message)); - }); - } - - map(packets, encodeOne, function(err, results) { - return callback(results.join('')); - }); -}; - -/** - * Async array map using after - */ - -function map(ary, each, done) { - var result = new Array(ary.length); - var next = after(ary.length, done); - - var eachWithIndex = function(i, el, cb) { - each(el, function(error, msg) { - result[i] = msg; - cb(error, result); - }); - }; - - for (var i = 0; i < ary.length; i++) { - eachWithIndex(i, ary[i], next); - } -} - -/* - * Decodes data when a payload is maybe expected. Possible binary contents are - * decoded from their base64 representation - * - * @param {String} data, callback method - * @api public - */ - -exports.decodePayload = function (data, binaryType, callback) { - if (typeof data != 'string') { - return exports.decodePayloadAsBinary(data, binaryType, callback); - } - - if (typeof binaryType === 'function') { - callback = binaryType; - binaryType = null; - } - - var packet; - if (data == '') { - // parser error - ignoring payload - return callback(err, 0, 1); - } - - var length = '' - , n, msg; - - for (var i = 0, l = data.length; i < l; i++) { - var chr = data.charAt(i); - - if (':' != chr) { - length += chr; - } else { - if ('' == length || (length != (n = Number(length)))) { - // parser error - ignoring payload - return callback(err, 0, 1); - } - - msg = data.substr(i + 1, n); - - if (length != msg.length) { - // parser error - ignoring payload - return callback(err, 0, 1); - } - - if (msg.length) { - packet = exports.decodePacket(msg, binaryType, true); - - if (err.type == packet.type && err.data == packet.data) { - // parser error in individual packet - ignoring payload - return callback(err, 0, 1); - } - - var ret = callback(packet, i + n, l); - if (false === ret) return; - } - - // advance cursor - i += n; - length = ''; - } - } - - if (length != '') { - // parser error - ignoring payload - return callback(err, 0, 1); - } - -}; - -/** - * Encodes multiple messages (payload) as binary. - * - * <1 = binary, 0 = string>[...] - * - * Example: - * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers - * - * @param {Array} packets - * @return {ArrayBuffer} encoded payload - * @api private - */ - -exports.encodePayloadAsArrayBuffer = function(packets, callback) { - if (!packets.length) { - return callback(new ArrayBuffer(0)); - } - - function encodeOne(packet, doneCallback) { - exports.encodePacket(packet, true, true, function(data) { - return doneCallback(null, data); - }); - } - - map(packets, encodeOne, function(err, encodedPackets) { - var totalLength = encodedPackets.reduce(function(acc, p) { - var len; - if (typeof p === 'string'){ - len = p.length; - } else { - len = p.byteLength; - } - return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2 - }, 0); - - var resultArray = new Uint8Array(totalLength); - - var bufferIndex = 0; - encodedPackets.forEach(function(p) { - var isString = typeof p === 'string'; - var ab = p; - if (isString) { - var view = new Uint8Array(p.length); - for (var i = 0; i < p.length; i++) { - view[i] = p.charCodeAt(i); - } - ab = view.buffer; - } - - if (isString) { // not true binary - resultArray[bufferIndex++] = 0; - } else { // true binary - resultArray[bufferIndex++] = 1; - } - - var lenStr = ab.byteLength.toString(); - for (var i = 0; i < lenStr.length; i++) { - resultArray[bufferIndex++] = parseInt(lenStr[i]); - } - resultArray[bufferIndex++] = 255; - - var view = new Uint8Array(ab); - for (var i = 0; i < view.length; i++) { - resultArray[bufferIndex++] = view[i]; - } - }); - - return callback(resultArray.buffer); - }); -}; - -/** - * Encode as Blob - */ - -exports.encodePayloadAsBlob = function(packets, callback) { - function encodeOne(packet, doneCallback) { - exports.encodePacket(packet, true, true, function(encoded) { - var binaryIdentifier = new Uint8Array(1); - binaryIdentifier[0] = 1; - if (typeof encoded === 'string') { - var view = new Uint8Array(encoded.length); - for (var i = 0; i < encoded.length; i++) { - view[i] = encoded.charCodeAt(i); - } - encoded = view.buffer; - binaryIdentifier[0] = 0; - } - - var len = (encoded instanceof ArrayBuffer) - ? encoded.byteLength - : encoded.size; - - var lenStr = len.toString(); - var lengthAry = new Uint8Array(lenStr.length + 1); - for (var i = 0; i < lenStr.length; i++) { - lengthAry[i] = parseInt(lenStr[i]); - } - lengthAry[lenStr.length] = 255; - - if (Blob) { - var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]); - doneCallback(null, blob); - } - }); - } - - map(packets, encodeOne, function(err, results) { - return callback(new Blob(results)); - }); -}; - -/* - * Decodes data when a payload is maybe expected. Strings are decoded by - * interpreting each byte as a key code for entries marked to start with 0. See - * description of encodePayloadAsBinary - * - * @param {ArrayBuffer} data, callback method - * @api public - */ - -exports.decodePayloadAsBinary = function (data, binaryType, callback) { - if (typeof binaryType === 'function') { - callback = binaryType; - binaryType = null; - } - - var bufferTail = data; - var buffers = []; - - var numberTooLong = false; - while (bufferTail.byteLength > 0) { - var tailArray = new Uint8Array(bufferTail); - var isString = tailArray[0] === 0; - var msgLength = ''; - - for (var i = 1; ; i++) { - if (tailArray[i] == 255) break; - - if (msgLength.length > 310) { - numberTooLong = true; - break; - } - - msgLength += tailArray[i]; - } - - if(numberTooLong) return callback(err, 0, 1); - - bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length); - msgLength = parseInt(msgLength); - - var msg = sliceBuffer(bufferTail, 0, msgLength); - if (isString) { - try { - msg = String.fromCharCode.apply(null, new Uint8Array(msg)); - } catch (e) { - // iPhone Safari doesn't let you apply to typed arrays - var typed = new Uint8Array(msg); - msg = ''; - for (var i = 0; i < typed.length; i++) { - msg += String.fromCharCode(typed[i]); - } - } - } - - buffers.push(msg); - bufferTail = sliceBuffer(bufferTail, msgLength); - } - - var total = buffers.length; - buffers.forEach(function(buffer, i) { - callback(exports.decodePacket(buffer, binaryType, true), i, total); - }); -}; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }, -/* 9 */ -/***/ function(module, exports) { - -module.exports = {}; - -/***/ }, -/* 10 */ -/***/ function(module, exports, __webpack_require__) { - -var anObject = __webpack_require__(5) - , IE8_DOM_DEFINE = __webpack_require__(91) - , toPrimitive = __webpack_require__(111) - , dP = Object.defineProperty; - -exports.f = __webpack_require__(6) ? Object.defineProperty : function defineProperty(O, P, Attributes){ - anObject(O); - P = toPrimitive(P, true); - anObject(Attributes); - if(IE8_DOM_DEFINE)try { - return dP(O, P, Attributes); - } catch(e){ /* empty */ } - if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!'); - if('value' in Attributes)O[P] = Attributes.value; - return O; -}; - -/***/ }, -/* 11 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(setImmediate, clearImmediate) {var nextTick = __webpack_require__(149).nextTick; -var apply = Function.prototype.apply; -var slice = Array.prototype.slice; -var immediateIds = {}; -var nextImmediateId = 0; - -// DOM APIs, for completeness - -exports.setTimeout = function() { - return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); -}; -exports.setInterval = function() { - return new Timeout(apply.call(setInterval, window, arguments), clearInterval); -}; -exports.clearTimeout = -exports.clearInterval = function(timeout) { timeout.close(); }; - -function Timeout(id, clearFn) { - this._id = id; - this._clearFn = clearFn; -} -Timeout.prototype.unref = Timeout.prototype.ref = function() {}; -Timeout.prototype.close = function() { - this._clearFn.call(window, this._id); -}; - -// Does not start the time, just sets up the members needed. -exports.enroll = function(item, msecs) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = msecs; -}; - -exports.unenroll = function(item) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = -1; -}; - -exports._unrefActive = exports.active = function(item) { - clearTimeout(item._idleTimeoutId); - - var msecs = item._idleTimeout; - if (msecs >= 0) { - item._idleTimeoutId = setTimeout(function onTimeout() { - if (item._onTimeout) - item._onTimeout(); - }, msecs); - } -}; - -// That's not how node.js implements it but the exposed api is the same. -exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { - var id = nextImmediateId++; - var args = arguments.length < 2 ? false : slice.call(arguments, 1); - - immediateIds[id] = true; - - nextTick(function onNextTick() { - if (immediateIds[id]) { - // fn.call() is faster so we optimize for the common use-case - // @see http://jsperf.com/call-apply-segu - if (args) { - fn.apply(null, args); - } else { - fn.call(null); - } - // Prevent ids from leaking - exports.clearImmediate(id); - } - }); - - return id; -}; - -exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) { - delete immediateIds[id]; -}; -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11).setImmediate, __webpack_require__(11).clearImmediate)) - -/***/ }, -/* 12 */ -/***/ function(module, exports) { - - -module.exports = function(a, b){ - var fn = function(){}; - fn.prototype = b.prototype; - a.prototype = new fn; - a.prototype.constructor = a; -}; - -/***/ }, -/* 13 */ -/***/ function(module, exports) { - -var toString = {}.toString; - -module.exports = function(it){ - return toString.call(it).slice(8, -1); -}; - -/***/ }, -/* 14 */ -/***/ function(module, exports, __webpack_require__) { - -// optional / simple context binding -var aFunction = __webpack_require__(20); -module.exports = function(fn, that, length){ - aFunction(fn); - if(that === undefined)return fn; - switch(length){ - case 1: return function(a){ - return fn.call(that, a); - }; - case 2: return function(a, b){ - return fn.call(that, a, b); - }; - case 3: return function(a, b, c){ - return fn.call(that, a, b, c); - }; - } - return function(/* ...args */){ - return fn.apply(that, arguments); - }; -}; - -/***/ }, -/* 15 */ -/***/ function(module, exports, __webpack_require__) { - -var global = __webpack_require__(2) - , core = __webpack_require__(3) - , ctx = __webpack_require__(14) - , hide = __webpack_require__(7) - , PROTOTYPE = 'prototype'; - -var $export = function(type, name, source){ - var IS_FORCED = type & $export.F - , IS_GLOBAL = type & $export.G - , IS_STATIC = type & $export.S - , IS_PROTO = type & $export.P - , IS_BIND = type & $export.B - , IS_WRAP = type & $export.W - , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) - , expProto = exports[PROTOTYPE] - , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] - , key, own, out; - if(IS_GLOBAL)source = name; - for(key in source){ - // contains in native - own = !IS_FORCED && target && target[key] !== undefined; - if(own && key in exports)continue; - // export native or passed - out = own ? target[key] : source[key]; - // prevent global pollution for namespaces - exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] - // bind timers to global for call from export context - : IS_BIND && own ? ctx(out, global) - // wrap global constructors for prevent change them in library - : IS_WRAP && target[key] == out ? (function(C){ - var F = function(a, b, c){ - if(this instanceof C){ - switch(arguments.length){ - case 0: return new C; - case 1: return new C(a); - case 2: return new C(a, b); - } return new C(a, b, c); - } return C.apply(this, arguments); - }; - F[PROTOTYPE] = C[PROTOTYPE]; - return F; - // make static versions for prototype methods - })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; - // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% - if(IS_PROTO){ - (exports.virtual || (exports.virtual = {}))[key] = out; - // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% - if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); - } - } -}; -// type bitmap -$export.F = 1; // forced -$export.G = 2; // global -$export.S = 4; // static -$export.P = 8; // proto -$export.B = 16; // bind -$export.W = 32; // wrap -$export.U = 64; // safe -$export.R = 128; // real proto method for `library` -module.exports = $export; - -/***/ }, -/* 16 */ -/***/ function(module, exports) { - -var hasOwnProperty = {}.hasOwnProperty; -module.exports = function(it, key){ - return hasOwnProperty.call(it, key); -}; - -/***/ }, -/* 17 */ -/***/ function(module, exports) { - -module.exports = function(it){ - return typeof it === 'object' ? it !== null : typeof it === 'function'; -}; - -/***/ }, -/* 18 */ -/***/ function(module, exports, __webpack_require__) { - -exports.nextTick = function nextTick(fn) { - setTimeout(fn, 0); -}; - -exports.platform = exports.arch = -exports.execPath = exports.title = 'browser'; -exports.pid = 1; -exports.browser = true; -exports.env = {}; -exports.argv = []; - -exports.binding = function (name) { - throw new Error('No such module. (Possibly not yet loaded)') -}; - -(function () { - var cwd = '/'; - var path; - exports.cwd = function () { return cwd }; - exports.chdir = function (dir) { - if (!path) path = __webpack_require__(63); - cwd = path.resolve(dir, cwd); - }; -})(); - -exports.exit = exports.kill = -exports.umask = exports.dlopen = -exports.uptime = exports.memoryUsage = -exports.uvCounters = function() {}; -exports.features = {}; - - -/***/ }, -/* 19 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(Buffer, global) {/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -/* eslint-disable no-proto */ - -'use strict' - -var base64 = __webpack_require__(80) -var ieee754 = __webpack_require__(135) -var isArray = __webpack_require__(139) - -exports.Buffer = Buffer -exports.SlowBuffer = SlowBuffer -exports.INSPECT_MAX_BYTES = 50 - -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * Due to various browser bugs, sometimes the Object implementation will be used even - * when the browser supports typed arrays. - * - * Note: - * - * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. - * - * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. - * - * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of - * incorrect length in some situations. - - * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they - * get the Object implementation, which is slower but behaves correctly. - */ -Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined - ? global.TYPED_ARRAY_SUPPORT - : typedArraySupport() - -/* - * Export kMaxLength after typed array support is determined. - */ -exports.kMaxLength = kMaxLength() - -function typedArraySupport () { - try { - var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} - return arr.foo() === 42 && // typed array instances can be augmented - typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` - arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` - } catch (e) { - return false - } -} - -function kMaxLength () { - return Buffer.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff -} - -function createBuffer (that, length) { - if (kMaxLength() < length) { - throw new RangeError('Invalid typed array length') - } - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = new Uint8Array(length) - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - if (that === null) { - that = new Buffer(length) - } - that.length = length - } - - return that -} - -/** - * The Buffer constructor returns instances of `Uint8Array` that have their - * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of - * `Uint8Array`, so the returned instances will have all the node `Buffer` methods - * and the `Uint8Array` methods. Square bracket notation works as expected -- it - * returns a single octet. - * - * The `Uint8Array` prototype remains unmodified. - */ - -function Buffer (arg, encodingOrOffset, length) { - if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { - return new Buffer(arg, encodingOrOffset, length) - } - - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ) - } - return allocUnsafe(this, arg) - } - return from(this, arg, encodingOrOffset, length) -} - -Buffer.poolSize = 8192 // not used by this implementation - -// TODO: Legacy, not needed anymore. Remove in next major version. -Buffer._augment = function (arr) { - arr.__proto__ = Buffer.prototype - return arr -} - -function from (that, value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } - - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - return fromArrayBuffer(that, value, encodingOrOffset, length) - } - - if (typeof value === 'string') { - return fromString(that, value, encodingOrOffset) - } - - return fromObject(that, value) -} - -/** - * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError - * if value is a number. - * Buffer.from(str[, encoding]) - * Buffer.from(array) - * Buffer.from(buffer) - * Buffer.from(arrayBuffer[, byteOffset[, length]]) - **/ -Buffer.from = function (value, encodingOrOffset, length) { - return from(null, value, encodingOrOffset, length) -} - -if (Buffer.TYPED_ARRAY_SUPPORT) { - Buffer.prototype.__proto__ = Uint8Array.prototype - Buffer.__proto__ = Uint8Array - if (typeof Symbol !== 'undefined' && Symbol.species && - Buffer[Symbol.species] === Buffer) { - // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true - }) - } -} - -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be a number') - } -} - -function alloc (that, size, fill, encoding) { - assertSize(size) - if (size <= 0) { - return createBuffer(that, size) - } - if (fill !== undefined) { - // Only pay attention to encoding if it's a string. This - // prevents accidentally sending in a number that would - // be interpretted as a start offset. - return typeof encoding === 'string' - ? createBuffer(that, size).fill(fill, encoding) - : createBuffer(that, size).fill(fill) - } - return createBuffer(that, size) -} - -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(null, size, fill, encoding) -} - -function allocUnsafe (that, size) { - assertSize(size) - that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < size; ++i) { - that[i] = 0 - } - } - return that -} - -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(null, size) -} -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(null, size) -} - -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } - - var length = byteLength(string, encoding) | 0 - that = createBuffer(that, length) - - that.write(string, encoding) - return that -} - -function fromArrayLike (that, array) { - var length = checked(array.length) | 0 - that = createBuffer(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that -} - -function fromArrayBuffer (that, array, byteOffset, length) { - array.byteLength // this throws if `array` is not a valid ArrayBuffer - - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('\'offset\' is out of bounds') - } - - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('\'length\' is out of bounds') - } - - if (byteOffset === undefined && length === undefined) { - array = new Uint8Array(array) - } else if (length === undefined) { - array = new Uint8Array(array, byteOffset) - } else { - array = new Uint8Array(array, byteOffset, length) - } - - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = array - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - that = fromArrayLike(that, array) - } - return that -} - -function fromObject (that, obj) { - if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - that = createBuffer(that, len) - - if (that.length === 0) { - return that - } - - obj.copy(that, 0, 0, len) - return that - } - - if (obj) { - if ((typeof ArrayBuffer !== 'undefined' && - obj.buffer instanceof ArrayBuffer) || 'length' in obj) { - if (typeof obj.length !== 'number' || isnan(obj.length)) { - return createBuffer(that, 0) - } - return fromArrayLike(that, obj) - } - - if (obj.type === 'Buffer' && isArray(obj.data)) { - return fromArrayLike(that, obj.data) - } - } - - throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') -} - -function checked (length) { - // Note: cannot use `length < kMaxLength` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + kMaxLength().toString(16) + ' bytes') - } - return length | 0 -} - -function SlowBuffer (length) { - if (+length != length) { // eslint-disable-line eqeqeq - length = 0 - } - return Buffer.alloc(+length) -} - -Buffer.isBuffer = function isBuffer (b) { - return !!(b != null && b._isBuffer) -} - -Buffer.compare = function compare (a, b) { - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError('Arguments must be Buffers') - } - - if (a === b) return 0 - - var x = a.length - var y = b.length - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i] - y = b[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'binary': - case 'base64': - case 'raw': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} - -Buffer.concat = function concat (list, length) { - if (!isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer.alloc(0) - } - - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; ++i) { - length += list[i].length - } - } - - var buffer = Buffer.allocUnsafe(length) - var pos = 0 - for (i = 0; i < list.length; ++i) { - var buf = list[i] - if (!Buffer.isBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - buf.copy(buffer, pos) - pos += buf.length - } - return buffer -} - -function byteLength (string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length - } - if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && - (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { - return string.byteLength - } - if (typeof string !== 'string') { - string = '' + string - } - - var len = string.length - if (len === 0) return 0 - - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'binary': - case 'raw': - case 'raws': - return len - case 'utf8': - case 'utf-8': - case undefined: - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) return utf8ToBytes(string).length // assume utf8 - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} -Buffer.byteLength = byteLength - -function slowToString (encoding, start, end) { - var loweredCase = false - - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. - - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0 - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } - - if (end === undefined || end > this.length) { - end = this.length - } - - if (end <= 0) { - return '' - } - - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0 - start >>>= 0 - - if (end <= start) { - return '' - } - - if (!encoding) encoding = 'utf8' - - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) - - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) - - case 'ascii': - return asciiSlice(this, start, end) - - case 'binary': - return binarySlice(this, start, end) - - case 'base64': - return base64Slice(this, start, end) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true - } - } -} - -// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect -// Buffer instances. -Buffer.prototype._isBuffer = true - -function swap (b, n, m) { - var i = b[n] - b[n] = b[m] - b[m] = i -} - -Buffer.prototype.swap16 = function swap16 () { - var len = this.length - if (len % 2 !== 0) { - throw new RangeError('Buffer size must be a multiple of 16-bits') - } - for (var i = 0; i < len; i += 2) { - swap(this, i, i + 1) - } - return this -} - -Buffer.prototype.swap32 = function swap32 () { - var len = this.length - if (len % 4 !== 0) { - throw new RangeError('Buffer size must be a multiple of 32-bits') - } - for (var i = 0; i < len; i += 4) { - swap(this, i, i + 3) - swap(this, i + 1, i + 2) - } - return this -} - -Buffer.prototype.toString = function toString () { - var length = this.length | 0 - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) -} - -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 -} - -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') - if (this.length > max) str += ' ... ' - } - return '' -} - -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (!Buffer.isBuffer(target)) { - throw new TypeError('Argument must be a Buffer') - } - - if (start === undefined) { - start = 0 - } - if (end === undefined) { - end = target ? target.length : 0 - } - if (thisStart === undefined) { - thisStart = 0 - } - if (thisEnd === undefined) { - thisEnd = this.length - } - - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } - - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 - } - - start >>>= 0 - end >>>= 0 - thisStart >>>= 0 - thisEnd >>>= 0 - - if (this === target) return 0 - - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) - - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) - - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i] - y = targetCopy[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -function arrayIndexOf (arr, val, byteOffset, encoding) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length - - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase() - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 - } - indexSize = 2 - arrLength /= 2 - valLength /= 2 - byteOffset /= 2 - } - } - - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) - } - } - - var foundIndex = -1 - for (var i = byteOffset; i < arrLength; ++i) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize - } else { - if (foundIndex !== -1) i -= i - foundIndex - foundIndex = -1 - } - } - - return -1 -} - -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - if (typeof byteOffset === 'string') { - encoding = byteOffset - byteOffset = 0 - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000 - } - byteOffset >>= 0 - - if (this.length === 0) return -1 - if (byteOffset >= this.length) return -1 - - // Negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) - - if (typeof val === 'string') { - val = Buffer.from(val, encoding) - } - - if (Buffer.isBuffer(val)) { - // special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1 - } - return arrayIndexOf(this, val, byteOffset, encoding) - } - if (typeof val === 'number') { - if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { - return Uint8Array.prototype.indexOf.call(this, val, byteOffset) - } - return arrayIndexOf(this, [ val ], byteOffset, encoding) - } - - throw new TypeError('val must be string, number or Buffer') -} - -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -} - -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } - - // must be an even number of digits - var strLen = string.length - if (strLen % 2 !== 0) throw new Error('Invalid hex string') - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (isNaN(parsed)) return i - buf[offset + i] = parsed - } - return i -} - -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} - -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} - -function binaryWrite (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} - -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) -} - -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} - -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8' - length = this.length - offset = 0 - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset - length = this.length - offset = 0 - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset | 0 - if (isFinite(length)) { - length = length | 0 - if (encoding === undefined) encoding = 'utf8' - } else { - encoding = length - length = undefined - } - // legacy write(string, encoding, offset, length) - remove in v0.13 - } else { - throw new Error( - 'Buffer.write(string, encoding, offset[, length]) is no longer supported' - ) - } - - var remaining = this.length - offset - if (length === undefined || length > remaining) length = remaining - - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('Attempt to write outside buffer bounds') - } - - if (!encoding) encoding = 'utf8' - - var loweredCase = false - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) - - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) - - case 'ascii': - return asciiWrite(this, string, offset, length) - - case 'binary': - return binaryWrite(this, string, offset, length) - - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} - -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} - -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} - -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end) - var res = [] - - var i = start - while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 - - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint - - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte - } - break - case 2: - secondByte = buf[i + 1] - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint - } - } - break - case 3: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint - } - } - break - case 4: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - fourthByte = buf[i + 3] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint - } - } - } - } - - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD - bytesPerSequence = 1 - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000 - res.push(codePoint >>> 10 & 0x3FF | 0xD800) - codePoint = 0xDC00 | codePoint & 0x3FF - } - - res.push(codePoint) - i += bytesPerSequence - } - - return decodeCodePointsArray(res) -} - -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 - -function decodeCodePointsArray (codePoints) { - var len = codePoints.length - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() - } - - // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ) - } - return res -} - -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i] & 0x7F) - } - return ret -} - -function binarySlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i]) - } - return ret -} - -function hexSlice (buf, start, end) { - var len = buf.length - - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len - - var out = '' - for (var i = start; i < end; ++i) { - out += toHex(buf[i]) - } - return out -} - -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) - } - return res -} - -Buffer.prototype.slice = function slice (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end - - if (start < 0) { - start += len - if (start < 0) start = 0 - } else if (start > len) { - start = len - } - - if (end < 0) { - end += len - if (end < 0) end = 0 - } else if (end > len) { - end = len - } - - if (end < start) end = start - - var newBuf - if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = this.subarray(start, end) - newBuf.__proto__ = Buffer.prototype - } else { - var sliceLen = end - start - newBuf = new Buffer(sliceLen, undefined) - for (var i = 0; i < sliceLen; ++i) { - newBuf[i] = this[i + start] - } - } - - return newBuf -} - -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') -} - -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - - return val -} - -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) - } - - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul - } - - return val -} - -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} - -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} - -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} - -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} - -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} - -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} - -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} - -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} - -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} - -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} - -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} - -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} - -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') - if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') - if (offset + ext > buf.length) throw new RangeError('Index out of range') -} - -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var mul = 1 - var i = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var i = byteLength - 1 - var mul = 1 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - this[offset] = (value & 0xff) - return offset + 1 -} - -function objectWriteUInt16 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { - buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } -} - -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} - -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} - -function objectWriteUInt32 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffffffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { - buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff - } -} - -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} - -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} - -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = 0 - var mul = 1 - var sub = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = byteLength - 1 - var mul = 1 - var sub = 0 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} - -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} - -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} - -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - } else { - objectWriteUInt32(this, value, offset, true) - } - return offset + 4 -} - -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) - } - return offset + 4 -} - -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) throw new RangeError('Index out of range') - if (offset < 0) throw new RangeError('Index out of range') -} - -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} - -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} - -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) - } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} - -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start - - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 - - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') - if (end < 0) throw new RangeError('sourceEnd out of bounds') - - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start - } - - var len = end - start - var i - - if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } - } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { - // ascending copy from start - for (i = 0; i < len; ++i) { - target[i + targetStart] = this[i + start] - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, start + len), - targetStart - ) - } - - return len -} - -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start - start = 0 - end = this.length - } else if (typeof end === 'string') { - encoding = end - end = this.length - } - if (val.length === 1) { - var code = val.charCodeAt(0) - if (code < 256) { - val = code - } - } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - } else if (typeof val === 'number') { - val = val & 255 - } - - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this - } - - start = start >>> 0 - end = end === undefined ? this.length : end >>> 0 - - if (!val) val = 0 - - var i - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val - } - } else { - var bytes = Buffer.isBuffer(val) - ? val - : utf8ToBytes(new Buffer(val, encoding).toString()) - var len = bytes.length - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len] - } - } - - return this -} - -// HELPER FUNCTIONS -// ================ - -var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g - -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} - -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} - -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} - -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] - - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i) - - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } - - // valid lead - leadSurrogate = codePoint - - continue - } - - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } - - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - } - - leadSurrogate = null - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') - } - } - - return bytes -} - -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} - -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break - - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } - - return byteArray -} - -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} - -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} - -function isnan (val) { - return val !== val // eslint-disable-line no-self-compare -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(19).Buffer, __webpack_require__(0))) - -/***/ }, -/* 20 */ -/***/ function(module, exports) { - -module.exports = function(it){ - if(typeof it != 'function')throw TypeError(it + ' is not a function!'); - return it; -}; - -/***/ }, -/* 21 */ -/***/ function(module, exports) { - -// 7.2.1 RequireObjectCoercible(argument) -module.exports = function(it){ - if(it == undefined)throw TypeError("Can't call method on " + it); - return it; -}; - -/***/ }, -/* 22 */ -/***/ function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(17) - , document = __webpack_require__(2).document - // in old IE typeof document.createElement is 'object' - , is = isObject(document) && isObject(document.createElement); -module.exports = function(it){ - return is ? document.createElement(it) : {}; -}; - -/***/ }, -/* 23 */ -/***/ function(module, exports) { - -module.exports = function(exec){ - try { - return !!exec(); - } catch(e){ - return true; - } -}; - -/***/ }, -/* 24 */ -/***/ function(module, exports, __webpack_require__) { - -var def = __webpack_require__(10).f - , has = __webpack_require__(16) - , TAG = __webpack_require__(1)('toStringTag'); - -module.exports = function(it, tag, stat){ - if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag}); -}; - -/***/ }, -/* 25 */ -/***/ function(module, exports, __webpack_require__) { - -var shared = __webpack_require__(52)('keys') - , uid = __webpack_require__(56); -module.exports = function(key){ - return shared[key] || (shared[key] = uid(key)); -}; - -/***/ }, -/* 26 */ -/***/ function(module, exports) { - -// 7.1.4 ToInteger -var ceil = Math.ceil - , floor = Math.floor; -module.exports = function(it){ - return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); -}; - -/***/ }, -/* 27 */ -/***/ function(module, exports, __webpack_require__) { - -// to indexed object, toObject with fallback for non-array-like ES3 strings -var IObject = __webpack_require__(93) - , defined = __webpack_require__(21); -module.exports = function(it){ - return IObject(defined(it)); -}; - -/***/ }, -/* 28 */ -/***/ function(module, exports, __webpack_require__) { - -/** - * Module dependencies. - */ - -var parser = __webpack_require__(8); -var Emitter = __webpack_require__(30); - -/** - * Module exports. - */ - -module.exports = Transport; - -/** - * Transport abstract constructor. - * - * @param {Object} options. - * @api private - */ - -function Transport (opts) { - this.path = opts.path; - this.hostname = opts.hostname; - this.port = opts.port; - this.secure = opts.secure; - this.query = opts.query; - this.timestampParam = opts.timestampParam; - this.timestampRequests = opts.timestampRequests; - this.readyState = ''; - this.agent = opts.agent || false; - this.socket = opts.socket; - this.enablesXDR = opts.enablesXDR; - - // SSL options for Node.js client - this.pfx = opts.pfx; - this.key = opts.key; - this.passphrase = opts.passphrase; - this.cert = opts.cert; - this.ca = opts.ca; - this.ciphers = opts.ciphers; - this.rejectUnauthorized = opts.rejectUnauthorized; - - // other options for Node.js client - this.extraHeaders = opts.extraHeaders; -} - -/** - * Mix in `Emitter`. - */ - -Emitter(Transport.prototype); - -/** - * Emits an error. - * - * @param {String} str - * @return {Transport} for chaining - * @api public - */ - -Transport.prototype.onError = function (msg, desc) { - var err = new Error(msg); - err.type = 'TransportError'; - err.description = desc; - this.emit('error', err); - return this; -}; - -/** - * Opens the transport. - * - * @api public - */ - -Transport.prototype.open = function () { - if ('closed' == this.readyState || '' == this.readyState) { - this.readyState = 'opening'; - this.doOpen(); - } - - return this; -}; - -/** - * Closes the transport. - * - * @api private - */ - -Transport.prototype.close = function () { - if ('opening' == this.readyState || 'open' == this.readyState) { - this.doClose(); - this.onClose(); - } - - return this; -}; - -/** - * Sends multiple packets. - * - * @param {Array} packets - * @api private - */ - -Transport.prototype.send = function(packets){ - if ('open' == this.readyState) { - this.write(packets); - } else { - throw new Error('Transport not open'); - } -}; - -/** - * Called upon open - * - * @api private - */ - -Transport.prototype.onOpen = function () { - this.readyState = 'open'; - this.writable = true; - this.emit('open'); -}; - -/** - * Called with data. - * - * @param {String} data - * @api private - */ - -Transport.prototype.onData = function(data){ - var packet = parser.decodePacket(data, this.socket.binaryType); - this.onPacket(packet); -}; - -/** - * Called with a decoded packet. - */ - -Transport.prototype.onPacket = function (packet) { - this.emit('packet', packet); -}; - -/** - * Called upon close. - * - * @api private - */ - -Transport.prototype.onClose = function () { - this.readyState = 'closed'; - this.emit('close'); -}; - - -/***/ }, -/* 29 */ -/***/ function(module, exports, __webpack_require__) { - -// browser shim for xmlhttprequest module -var hasCORS = __webpack_require__(134); - -module.exports = function(opts) { - var xdomain = opts.xdomain; - - // scheme must be same when usign XDomainRequest - // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx - var xscheme = opts.xscheme; - - // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default. - // https://github.com/Automattic/engine.io-client/pull/217 - var enablesXDR = opts.enablesXDR; - - // XMLHttpRequest can be disabled on IE - try { - if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) { - return new XMLHttpRequest(); - } - } catch (e) { } - - // Use XDomainRequest for IE8 if enablesXDR is true - // because loading bar keeps flashing when using jsonp-polling - // https://github.com/yujiosaka/socke.io-ie8-loading-example - try { - if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) { - return new XDomainRequest(); - } - } catch (e) { } - - if (!xdomain) { - try { - return new ActiveXObject('Microsoft.XMLHTTP'); - } catch(e) { } - } -} - - -/***/ }, -/* 30 */ -/***/ function(module, exports) { - - -/** - * Expose `Emitter`. - */ - -module.exports = Emitter; - -/** - * Initialize a new `Emitter`. - * - * @api public - */ - -function Emitter(obj) { - if (obj) return mixin(obj); -}; - -/** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; - } - return obj; -} - -/** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.on = -Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks[event] = this._callbacks[event] || []) - .push(fn); - return this; -}; - -/** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.once = function(event, fn){ - var self = this; - this._callbacks = this._callbacks || {}; - - function on() { - self.off(event, on); - fn.apply(this, arguments); - } - - on.fn = fn; - this.on(event, on); - return this; -}; - -/** - * Remove the given callback for `event` or all - * registered callbacks. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.off = -Emitter.prototype.removeListener = -Emitter.prototype.removeAllListeners = -Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; - } - - // specific event - var callbacks = this._callbacks[event]; - if (!callbacks) return this; - - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks[event]; - return this; - } - - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; - } - } - return this; -}; - -/** - * Emit `event` with the given args. - * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} - */ - -Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks[event]; - - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); - } - } - - return this; -}; - -/** - * Return array of callbacks for `event`. - * - * @param {String} event - * @return {Array} - * @api public - */ - -Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks[event] || []; -}; - -/** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ - -Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; -}; - - -/***/ }, -/* 31 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(setImmediate, clearImmediate) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/* - * @name Lazy.js - * - * @fileOverview - * Lazy.js is a lazy evaluation library for JavaScript. - * - * This has been done before. For examples see: - * - * - [wu.js](http://fitzgen.github.io/wu.js/) - * - [Linq.js](http://linqjs.codeplex.com/) - * - [from.js](https://github.com/suckgamoni/fromjs/) - * - [IxJS](http://rx.codeplex.com/) - * - [sloth.js](http://rfw.name/sloth.js/) - * - * However, at least at present, Lazy.js is faster (on average) than any of - * those libraries. It is also more complete, with nearly all of the - * functionality of [Underscore](http://underscorejs.org/) and - * [Lo-Dash](http://lodash.com/). - * - * Finding your way around the code - * -------------------------------- - * - * At the heart of Lazy.js is the {@link Sequence} object. You create an initial - * sequence using {@link Lazy}, which can accept an array, object, or string. - * You can then "chain" together methods from this sequence, creating a new - * sequence with each call. - * - * Here's an example: - * - * var data = getReallyBigArray(); - * - * var statistics = Lazy(data) - * .map(transform) - * .filter(validate) - * .reduce(aggregate); - * - * {@link Sequence} is the foundation of other, more specific sequence types. - * - * An {@link ArrayLikeSequence} provides indexed access to its elements. - * - * An {@link ObjectLikeSequence} consists of key/value pairs. - * - * A {@link StringLikeSequence} is like a string (duh): actually, it is an - * {@link ArrayLikeSequence} whose elements happen to be characters. - * - * An {@link AsyncSequence} is special: it iterates over its elements - * asynchronously (so calling `each` generally begins an asynchronous loop and - * returns immediately). - * - * For more information - * -------------------- - * - * I wrote a blog post that explains a little bit more about Lazy.js, which you - * can read [here](http://philosopherdeveloper.com/posts/introducing-lazy-js.html). - * - * You can also [create an issue on GitHub](https://github.com/dtao/lazy.js/issues) - * if you have any issues with the library. I work through them eventually. - * - * [@dtao](https://github.com/dtao) - */ - -(function(root, factory) { - if (true) { - !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else if (typeof exports === 'object') { - module.exports = factory(); - } else { - root.Lazy = factory(); - } -})(this, function(context) { - /** - * Wraps an object and returns a {@link Sequence}. For `null` or `undefined`, - * simply returns an empty sequence (see {@link Lazy.strict} for a stricter - * implementation). - * - * - For **arrays**, Lazy will create a sequence comprising the elements in - * the array (an {@link ArrayLikeSequence}). - * - For **objects**, Lazy will create a sequence of key/value pairs - * (an {@link ObjectLikeSequence}). - * - For **strings**, Lazy will create a sequence of characters (a - * {@link StringLikeSequence}). - * - * @public - * @param {Array|Object|string} source An array, object, or string to wrap. - * @returns {Sequence} The wrapped lazy object. - * - * @exampleHelpers - * // Utility functions to provide to all examples - * function increment(x) { return x + 1; } - * function isEven(x) { return x % 2 === 0; } - * function isPositive(x) { return x > 0; } - * function isNegative(x) { return x < 0; } - * - * @examples - * Lazy([1, 2, 4]) // instanceof Lazy.ArrayLikeSequence - * Lazy({ foo: "bar" }) // instanceof Lazy.ObjectLikeSequence - * Lazy("hello, world!") // instanceof Lazy.StringLikeSequence - * Lazy() // sequence: [] - * Lazy(null) // sequence: [] - */ - function Lazy(source) { - if (source instanceof Array) { - return new ArrayWrapper(source); - - } else if (typeof source === "string") { - return new StringWrapper(source); - - } else if (source instanceof Sequence) { - return source; - } - - if (Lazy.extensions) { - var extensions = Lazy.extensions, length = extensions.length, result; - while (!result && length--) { - result = extensions[length](source); - } - if (result) { - return result; - } - } - - return new ObjectWrapper(source); - } - - Lazy.VERSION = '0.4.2'; - - /*** Utility methods of questionable value ***/ - - Lazy.noop = function noop() {}; - Lazy.identity = function identity(x) { return x; }; - - /** - * Provides a stricter version of {@link Lazy} which throws an error when - * attempting to wrap `null`, `undefined`, or numeric or boolean values as a - * sequence. - * - * @public - * @returns {Function} A stricter version of the {@link Lazy} helper function. - * - * @examples - * var Strict = Lazy.strict(); - * - * Strict() // throws - * Strict(null) // throws - * Strict(true) // throws - * Strict(5) // throws - * Strict([1, 2, 3]) // instanceof Lazy.ArrayLikeSequence - * Strict({ foo: "bar" }) // instanceof Lazy.ObjectLikeSequence - * Strict("hello, world!") // instanceof Lazy.StringLikeSequence - * - * // Let's also ensure the static functions are still there. - * Strict.range(3) // sequence: [0, 1, 2] - * Strict.generate(Date.now) // instanceof Lazy.GeneratedSequence - */ - Lazy.strict = function strict() { - function StrictLazy(source) { - if (source == null) { - throw new Error("You cannot wrap null or undefined using Lazy."); - } - - if (typeof source === "number" || typeof source === "boolean") { - throw new Error("You cannot wrap primitive values using Lazy."); - } - - return Lazy(source); - }; - - Lazy(Lazy).each(function(property, name) { - StrictLazy[name] = property; - }); - - return StrictLazy; - }; - - /** - * The `Sequence` object provides a unified API encapsulating the notion of - * zero or more consecutive elements in a collection, stream, etc. - * - * Lazy evaluation - * --------------- - * - * Generally speaking, creating a sequence should not be an expensive operation, - * and should not iterate over an underlying source or trigger any side effects. - * This means that chaining together methods that return sequences incurs only - * the cost of creating the `Sequence` objects themselves and not the cost of - * iterating an underlying data source multiple times. - * - * The following code, for example, creates 4 sequences and does nothing with - * `source`: - * - * var seq = Lazy(source) // 1st sequence - * .map(func) // 2nd - * .filter(pred) // 3rd - * .reverse(); // 4th - * - * Lazy's convention is to hold off on iterating or otherwise *doing* anything - * (aside from creating `Sequence` objects) until you call `each`: - * - * seq.each(function(x) { console.log(x); }); - * - * Defining custom sequences - * ------------------------- - * - * Defining your own type of sequence is relatively simple: - * - * 1. Pass a *method name* and an object containing *function overrides* to - * {@link Sequence.define}. If the object includes a function called `init`, - * this function will be called upon initialization. - * 2. The object should include at least either a `getIterator` method or an - * `each` method. The former supports both asynchronous and synchronous - * iteration, but is slightly more cumbersome to implement. The latter - * supports synchronous iteration and can be automatically implemented in - * terms of the former. You can also implement both if you want, e.g. to - * optimize performance. For more info, see {@link Iterator} and - * {@link AsyncSequence}. - * - * As a trivial example, the following code defines a new method, `sample`, - * which randomly may or may not include each element from its parent. - * - * Lazy.Sequence.define("sample", { - * each: function(fn) { - * return this.parent.each(function(e) { - * // 50/50 chance of including this element. - * if (Math.random() > 0.5) { - * return fn(e); - * } - * }); - * } - * }); - * - * (Of course, the above could also easily have been implemented using - * {@link #filter} instead of creating a custom sequence. But I *did* say this - * was a trivial example, to be fair.) - * - * Now it will be possible to create this type of sequence from any parent - * sequence by calling the method name you specified. In other words, you can - * now do this: - * - * Lazy(arr).sample(); - * Lazy(arr).map(func).sample(); - * Lazy(arr).map(func).filter(pred).sample(); - * - * Etc., etc. - * - * @public - * @constructor - */ - function Sequence() {} - - /** - * Create a new constructor function for a type inheriting from `Sequence`. - * - * @public - * @param {string|Array.} methodName The name(s) of the method(s) to be - * used for constructing the new sequence. The method will be attached to - * the `Sequence` prototype so that it can be chained with any other - * sequence methods, like {@link #map}, {@link #filter}, etc. - * @param {Object} overrides An object containing function overrides for this - * new sequence type. **Must** include either `getIterator` or `each` (or - * both). *May* include an `init` method as well. For these overrides, - * `this` will be the new sequence, and `this.parent` will be the base - * sequence from which the new sequence was constructed. - * @returns {Function} A constructor for a new type inheriting from `Sequence`. - * - * @examples - * // This sequence type logs every element to the specified logger as it - * // iterates over it. - * Lazy.Sequence.define("verbose", { - * init: function(logger) { - * this.logger = logger; - * }, - * - * each: function(fn) { - * var logger = this.logger; - * return this.parent.each(function(e, i) { - * logger(e); - * return fn(e, i); - * }); - * } - * }); - * - * Lazy([1, 2, 3]).verbose(logger).each(Lazy.noop) // calls logger 3 times - */ - Sequence.define = function define(methodName, overrides) { - if (!overrides || (!overrides.getIterator && !overrides.each)) { - throw new Error("A custom sequence must implement *at least* getIterator or each!"); - } - - return defineSequenceType(Sequence, methodName, overrides); - }; - - /** - * Gets the number of elements in the sequence. In some cases, this may - * require eagerly evaluating the sequence. - * - * @public - * @returns {number} The number of elements in the sequence. - * - * @examples - * Lazy([1, 2, 3]).size(); // => 3 - * Lazy([1, 2]).map(Lazy.identity).size(); // => 2 - * Lazy([1, 2, 3]).reject(isEven).size(); // => 2 - * Lazy([1, 2, 3]).take(1).size(); // => 1 - * Lazy({ foo: 1, bar: 2 }).size(); // => 2 - * Lazy('hello').size(); // => 5 - */ - Sequence.prototype.size = function size() { - return this.getIndex().length(); - }; - - /** - * Creates an {@link Iterator} object with two methods, `moveNext` -- returning - * true or false -- and `current` -- returning the current value. - * - * This method is used when asynchronously iterating over sequences. Any type - * inheriting from `Sequence` must implement this method or it can't support - * asynchronous iteration. - * - * Note that **this method is not intended to be used directly by application - * code.** Rather, it is intended as a means for implementors to potentially - * define custom sequence types that support either synchronous or - * asynchronous iteration. - * - * @public - * @returns {Iterator} An iterator object. - * - * @examples - * var iterator = Lazy([1, 2]).getIterator(); - * - * iterator.moveNext(); // => true - * iterator.current(); // => 1 - * iterator.moveNext(); // => true - * iterator.current(); // => 2 - * iterator.moveNext(); // => false - */ - Sequence.prototype.getIterator = function getIterator() { - return new Iterator(this); - }; - - /** - * Gets the root sequence underlying the current chain of sequences. - */ - Sequence.prototype.root = function root() { - return this.parent.root(); - }; - - /** - * Whether or not the current sequence is an asynchronous one. This is more - * accurate than checking `instanceof {@link AsyncSequence}` because, for - * example, `Lazy([1, 2, 3]).async().map(Lazy.identity)` returns a sequence - * that iterates asynchronously even though it's not an instance of - * `AsyncSequence`. - * - * @returns {boolean} Whether or not the current sequence is an asynchronous one. - */ - Sequence.prototype.isAsync = function isAsync() { - return this.parent ? this.parent.isAsync() : false; - }; - - /** - * Evaluates the sequence and produces the appropriate value (an array in most - * cases, an object for {@link ObjectLikeSequence}s or a string for - * {@link StringLikeSequence}s). - * - * @returns {Array|string|Object} The value resulting from fully evaluating - * the sequence. - */ - Sequence.prototype.value = function value() { - return this.toArray(); - }; - - /** - * Applies the current transformation chain to a given source, returning the - * resulting value. - * - * @examples - * var sequence = Lazy([]) - * .map(function(x) { return x * -1; }) - * .filter(function(x) { return x % 2 === 0; }); - * - * sequence.apply([1, 2, 3, 4]); // => [-2, -4] - */ - Sequence.prototype.apply = function apply(source) { - var root = this.root(), - previousSource = root.source, - result; - - try { - root.source = source; - result = this.value(); - } finally { - root.source = previousSource; - } - - return result; - }; - - /** - * The Iterator object provides an API for iterating over a sequence. - * - * The purpose of the `Iterator` type is mainly to offer an agnostic way of - * iterating over a sequence -- either synchronous (i.e. with a `while` loop) - * or asynchronously (with recursive calls to either `setTimeout` or --- if - * available --- `setImmediate`). It is not intended to be used directly by - * application code. - * - * @public - * @constructor - * @param {Sequence} sequence The sequence to iterate over. - */ - function Iterator(sequence) { - this.sequence = sequence; - this.index = -1; - } - - /** - * Gets the current item this iterator is pointing to. - * - * @public - * @returns {*} The current item. - */ - Iterator.prototype.current = function current() { - return this.cachedIndex && this.cachedIndex.get(this.index); - }; - - /** - * Moves the iterator to the next item in a sequence, if possible. - * - * @public - * @returns {boolean} True if the iterator is able to move to a new item, or else - * false. - */ - Iterator.prototype.moveNext = function moveNext() { - var cachedIndex = this.cachedIndex; - - if (!cachedIndex) { - cachedIndex = this.cachedIndex = this.sequence.getIndex(); - } - - if (this.index >= cachedIndex.length() - 1) { - return false; - } - - ++this.index; - return true; - }; - - /** - * Creates an array snapshot of a sequence. - * - * Note that for indefinite sequences, this method may raise an exception or - * (worse) cause the environment to hang. - * - * @public - * @returns {Array} An array containing the current contents of the sequence. - * - * @examples - * Lazy([1, 2, 3]).toArray() // => [1, 2, 3] - */ - Sequence.prototype.toArray = function toArray() { - return this.reduce(function(arr, element) { - arr.push(element); - return arr; - }, []); - }; - - /** - * Provides an indexed view into the sequence. - * - * For sequences that are already indexed, this will simply return the - * sequence. For non-indexed sequences, this will eagerly evaluate the - * sequence. - * - * @returns {ArrayLikeSequence} A sequence containing the current contents of - * the sequence. - * - * @examples - * Lazy([1, 2, 3]).filter(isEven) // instanceof Lazy.Sequence - * Lazy([1, 2, 3]).filter(isEven).getIndex() // instanceof Lazy.ArrayLikeSequence - */ - Sequence.prototype.getIndex = function getIndex() { - return new ArrayWrapper(this.toArray()); - }; - - /** - * Returns the element at the specified index. Note that, for sequences that - * are not {@link ArrayLikeSequence}s, this may require partially evaluating - * the sequence, iterating to reach the result. (In other words for such - * sequences this method is not O(1).) - * - * @public - * @param {number} i The index to access. - * @returns {*} The element. - * - */ - Sequence.prototype.get = function get(i) { - var element; - this.each(function(e, index) { - if (index === i) { - element = e; - return false; - } - }); - return element; - }; - - /** - * Provides an indexed, memoized view into the sequence. This will cache the - * result whenever the sequence is first iterated, so that subsequent - * iterations will access the same element objects. - * - * @public - * @returns {ArrayLikeSequence} An indexed, memoized sequence containing this - * sequence's elements, cached after the first iteration. - * - * @example - * function createObject() { return new Object(); } - * - * var plain = Lazy.generate(createObject, 10), - * memoized = Lazy.generate(createObject, 10).memoize(); - * - * plain.toArray()[0] === plain.toArray()[0]; // => false - * memoized.toArray()[0] === memoized.toArray()[0]; // => true - */ - Sequence.prototype.memoize = function memoize() { - return new MemoizedSequence(this); - }; - - /** - * @constructor - */ - function MemoizedSequence(parent) { - this.parent = parent; - } - - // MemoizedSequence needs to have its prototype set up after ArrayLikeSequence - - /** - * Creates an object from a sequence of key/value pairs. - * - * @public - * @returns {Object} An object with keys and values corresponding to the pairs - * of elements in the sequence. - * - * @examples - * var details = [ - * ["first", "Dan"], - * ["last", "Tao"], - * ["age", 29] - * ]; - * - * Lazy(details).toObject() // => { first: "Dan", last: "Tao", age: 29 } - */ - Sequence.prototype.toObject = function toObject() { - return this.reduce(function(object, pair) { - object[pair[0]] = pair[1]; - return object; - }, {}); - }; - - /** - * Iterates over this sequence and executes a function for every element. - * - * @public - * @aka forEach - * @param {Function} fn The function to call on each element in the sequence. - * Return false from the function to end the iteration. - * @returns {boolean} `true` if the iteration evaluated the entire sequence, - * or `false` if iteration was ended early. - * - * @examples - * Lazy([1, 2, 3, 4]).each(fn) // calls fn 4 times - */ - Sequence.prototype.each = function each(fn) { - var iterator = this.getIterator(), - i = -1; - - while (iterator.moveNext()) { - if (fn(iterator.current(), ++i) === false) { - return false; - } - } - - return true; - }; - - Sequence.prototype.forEach = function forEach(fn) { - return this.each(fn); - }; - - /** - * Creates a new sequence whose values are calculated by passing this sequence's - * elements through some mapping function. - * - * @public - * @aka collect - * @param {Function} mapFn The mapping function used to project this sequence's - * elements onto a new sequence. This function takes up to two arguments: - * the element, and the current index. - * @returns {Sequence} The new sequence. - * - * @examples - * function addIndexToValue(e, i) { return e + i; } - * - * Lazy([]).map(increment) // sequence: [] - * Lazy([1, 2, 3]).map(increment) // sequence: [2, 3, 4] - * Lazy([1, 2, 3]).map(addIndexToValue) // sequence: [1, 3, 5] - * - * @benchmarks - * function increment(x) { return x + 1; } - * - * var smArr = Lazy.range(10).toArray(), - * lgArr = Lazy.range(100).toArray(); - * - * Lazy(smArr).map(increment).each(Lazy.noop) // lazy - 10 elements - * Lazy(lgArr).map(increment).each(Lazy.noop) // lazy - 100 elements - * _.each(_.map(smArr, increment), _.noop) // lodash - 10 elements - * _.each(_.map(lgArr, increment), _.noop) // lodash - 100 elements - */ - Sequence.prototype.map = function map(mapFn) { - return new MappedSequence(this, createCallback(mapFn)); - }; - - Sequence.prototype.collect = function collect(mapFn) { - return this.map(mapFn); - }; - - /** - * @constructor - */ - function MappedSequence(parent, mapFn) { - this.parent = parent; - this.mapFn = mapFn; - } - - MappedSequence.prototype = new Sequence(); - - MappedSequence.prototype.getIterator = function getIterator() { - return new MappingIterator(this.parent, this.mapFn); - }; - - MappedSequence.prototype.each = function each(fn) { - var mapFn = this.mapFn; - return this.parent.each(function(e, i) { - return fn(mapFn(e, i), i); - }); - }; - - /** - * @constructor - */ - function MappingIterator(sequence, mapFn) { - this.iterator = sequence.getIterator(); - this.mapFn = mapFn; - this.index = -1; - } - - MappingIterator.prototype.current = function current() { - return this.mapFn(this.iterator.current(), this.index); - }; - - MappingIterator.prototype.moveNext = function moveNext() { - if (this.iterator.moveNext()) { - ++this.index; - return true; - } - - return false; - }; - - /** - * Creates a new sequence whose values are calculated by accessing the specified - * property from each element in this sequence. - * - * @public - * @param {string} propertyName The name of the property to access for every - * element in this sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * var people = [ - * { first: "Dan", last: "Tao" }, - * { first: "Bob", last: "Smith" } - * ]; - * - * Lazy(people).pluck("last") // sequence: ["Tao", "Smith"] - */ - Sequence.prototype.pluck = function pluck(property) { - return this.map(property); - }; - - /** - * Creates a new sequence whose values are calculated by invoking the specified - * function on each element in this sequence. - * - * @public - * @param {string} methodName The name of the method to invoke for every element - * in this sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * function Person(first, last) { - * this.fullName = function fullName() { - * return first + " " + last; - * }; - * } - * - * var people = [ - * new Person("Dan", "Tao"), - * new Person("Bob", "Smith") - * ]; - * - * Lazy(people).invoke("fullName") // sequence: ["Dan Tao", "Bob Smith"] - */ - Sequence.prototype.invoke = function invoke(methodName) { - return this.map(function(e) { - return e[methodName](); - }); - }; - - /** - * Creates a new sequence whose values are the elements of this sequence which - * satisfy the specified predicate. - * - * @public - * @aka select - * @param {Function} filterFn The predicate to call on each element in this - * sequence, which returns true if the element should be included. - * @returns {Sequence} The new sequence. - * - * @examples - * var numbers = [1, 2, 3, 4, 5, 6]; - * - * Lazy(numbers).filter(isEven) // sequence: [2, 4, 6] - * - * @benchmarks - * function isEven(x) { return x % 2 === 0; } - * - * var smArr = Lazy.range(10).toArray(), - * lgArr = Lazy.range(100).toArray(); - * - * Lazy(smArr).filter(isEven).each(Lazy.noop) // lazy - 10 elements - * Lazy(lgArr).filter(isEven).each(Lazy.noop) // lazy - 100 elements - * _.each(_.filter(smArr, isEven), _.noop) // lodash - 10 elements - * _.each(_.filter(lgArr, isEven), _.noop) // lodash - 100 elements - */ - Sequence.prototype.filter = function filter(filterFn) { - return new FilteredSequence(this, createCallback(filterFn)); - }; - - Sequence.prototype.select = function select(filterFn) { - return this.filter(filterFn); - }; - - /** - * @constructor - */ - function FilteredSequence(parent, filterFn) { - this.parent = parent; - this.filterFn = filterFn; - } - - FilteredSequence.prototype = new Sequence(); - - FilteredSequence.prototype.getIterator = function getIterator() { - return new FilteringIterator(this.parent, this.filterFn); - }; - - FilteredSequence.prototype.each = function each(fn) { - var filterFn = this.filterFn, - j = 0; - - return this.parent.each(function(e, i) { - if (filterFn(e, i)) { - return fn(e, j++); - } - }); - }; - - FilteredSequence.prototype.reverse = function reverse() { - return this.parent.reverse().filter(this.filterFn); - }; - - /** - * @constructor - */ - function FilteringIterator(sequence, filterFn) { - this.iterator = sequence.getIterator(); - this.filterFn = filterFn; - this.index = 0; - } - - FilteringIterator.prototype.current = function current() { - return this.value; - }; - - FilteringIterator.prototype.moveNext = function moveNext() { - var iterator = this.iterator, - filterFn = this.filterFn, - value; - - while (iterator.moveNext()) { - value = iterator.current(); - if (filterFn(value, this.index++)) { - this.value = value; - return true; - } - } - - this.value = undefined; - return false; - }; - - /** - * Creates a new sequence whose values exclude the elements of this sequence - * identified by the specified predicate. - * - * @public - * @param {Function} rejectFn The predicate to call on each element in this - * sequence, which returns true if the element should be omitted. - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, 2, 3, 4, 5]).reject(isEven) // sequence: [1, 3, 5] - * Lazy([{ foo: 1 }, { bar: 2 }]).reject('foo') // sequence: [{ bar: 2 }] - * Lazy([{ foo: 1 }, { foo: 2 }]).reject({ foo: 2 }) // sequence: [{ foo: 1 }] - */ - Sequence.prototype.reject = function reject(rejectFn) { - rejectFn = createCallback(rejectFn); - return this.filter(function(e) { return !rejectFn(e); }); - }; - - /** - * Creates a new sequence whose values have the specified type, as determined - * by the `typeof` operator. - * - * @public - * @param {string} type The type of elements to include from the underlying - * sequence, i.e. where `typeof [element] === [type]`. - * @returns {Sequence} The new sequence, comprising elements of the specified - * type. - * - * @examples - * Lazy([1, 2, 'foo', 'bar']).ofType('number') // sequence: [1, 2] - * Lazy([1, 2, 'foo', 'bar']).ofType('string') // sequence: ['foo', 'bar'] - * Lazy([1, 2, 'foo', 'bar']).ofType('boolean') // sequence: [] - */ - Sequence.prototype.ofType = function ofType(type) { - return this.filter(function(e) { return typeof e === type; }); - }; - - /** - * Creates a new sequence whose values are the elements of this sequence with - * property names and values matching those of the specified object. - * - * @public - * @param {Object} properties The properties that should be found on every - * element that is to be included in this sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * var people = [ - * { first: "Dan", last: "Tao" }, - * { first: "Bob", last: "Smith" } - * ]; - * - * Lazy(people).where({ first: "Dan" }) // sequence: [{ first: "Dan", last: "Tao" }] - * - * @benchmarks - * var animals = ["dog", "cat", "mouse", "horse", "pig", "snake"]; - * - * Lazy(animals).where({ length: 3 }).each(Lazy.noop) // lazy - * _.each(_.where(animals, { length: 3 }), _.noop) // lodash - */ - Sequence.prototype.where = function where(properties) { - return this.filter(properties); - }; - - /** - * Creates a new sequence with the same elements as this one, but to be iterated - * in the opposite order. - * - * Note that in some (but not all) cases, the only way to create such a sequence - * may require iterating the entire underlying source when `each` is called. - * - * @public - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, 2, 3]).reverse() // sequence: [3, 2, 1] - * Lazy([]).reverse() // sequence: [] - */ - Sequence.prototype.reverse = function reverse() { - return new ReversedSequence(this); - }; - - /** - * @constructor - */ - function ReversedSequence(parent) { - this.parent = parent; - } - - ReversedSequence.prototype = new Sequence(); - - ReversedSequence.prototype.getIterator = function getIterator() { - return new ReversedIterator(this.parent); - }; - - /** - * @constuctor - */ - function ReversedIterator(sequence) { - this.sequence = sequence; - } - - ReversedIterator.prototype.current = function current() { - return this.getIndex().get(this.index); - }; - - ReversedIterator.prototype.moveNext = function moveNext() { - var index = this.getIndex(), - length = index.length(); - - if (typeof this.index === "undefined") { - this.index = length; - } - - return (--this.index >= 0); - }; - - ReversedIterator.prototype.getIndex = function getIndex() { - if (!this.cachedIndex) { - this.cachedIndex = this.sequence.getIndex(); - } - - return this.cachedIndex; - }; - - /** - * Creates a new sequence with all of the elements of this one, plus those of - * the given array(s). - * - * @public - * @param {...*} var_args One or more values (or arrays of values) to use for - * additional items after this sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * var left = [1, 2, 3]; - * var right = [4, 5, 6]; - * - * Lazy(left).concat(right) // sequence: [1, 2, 3, 4, 5, 6] - * Lazy(left).concat(Lazy(right)) // sequence: [1, 2, 3, 4, 5, 6] - * Lazy(left).concat(right, [7, 8]) // sequence: [1, 2, 3, 4, 5, 6, 7, 8] - */ - Sequence.prototype.concat = function concat(var_args) { - return new ConcatenatedSequence(this, arraySlice.call(arguments, 0)); - }; - - /** - * @constructor - */ - function ConcatenatedSequence(parent, arrays) { - this.parent = parent; - this.arrays = arrays; - } - - ConcatenatedSequence.prototype = new Sequence(); - - ConcatenatedSequence.prototype.each = function each(fn) { - var done = false, - i = 0; - - this.parent.each(function(e) { - if (fn(e, i++) === false) { - done = true; - return false; - } - }); - - if (!done) { - Lazy(this.arrays).flatten().each(function(e) { - if (fn(e, i++) === false) { - return false; - } - }); - } - }; - - /** - * Creates a new sequence comprising the first N elements from this sequence, OR - * (if N is `undefined`) simply returns the first element of this sequence. - * - * @public - * @aka head, take - * @param {number=} count The number of elements to take from this sequence. If - * this value exceeds the length of the sequence, the resulting sequence - * will be essentially the same as this one. - * @returns {*} The new sequence (or the first element from this sequence if - * no count was given). - * - * @examples - * function powerOfTwo(exp) { - * return Math.pow(2, exp); - * } - * - * Lazy.generate(powerOfTwo).first() // => 1 - * Lazy.generate(powerOfTwo).first(5) // sequence: [1, 2, 4, 8, 16] - * Lazy.generate(powerOfTwo).skip(2).first() // => 4 - * Lazy.generate(powerOfTwo).skip(2).first(2) // sequence: [4, 8] - */ - Sequence.prototype.first = function first(count) { - if (typeof count === "undefined") { - return getFirst(this); - } - return new TakeSequence(this, count); - }; - - Sequence.prototype.head = - Sequence.prototype.take = function (count) { - return this.first(count); - }; - - /** - * @constructor - */ - function TakeSequence(parent, count) { - this.parent = parent; - this.count = count; - } - - TakeSequence.prototype = new Sequence(); - - TakeSequence.prototype.getIterator = function getIterator() { - return new TakeIterator(this.parent, this.count); - }; - - TakeSequence.prototype.each = function each(fn) { - var count = this.count, - i = 0; - - var result; - var handle = this.parent.each(function(e) { - if (i < count) { result = fn(e, i++); } - if (i >= count) { return false; } - return result; - }); - - if (handle instanceof AsyncHandle) { - return handle; - } - - return i === count && result !== false; - }; - - /** - * @constructor - */ - function TakeIterator(sequence, count) { - this.iterator = sequence.getIterator(); - this.count = count; - } - - TakeIterator.prototype.current = function current() { - return this.iterator.current(); - }; - - TakeIterator.prototype.moveNext = function moveNext() { - return ((--this.count >= 0) && this.iterator.moveNext()); - }; - - /** - * Creates a new sequence comprising the elements from the head of this sequence - * that satisfy some predicate. Once an element is encountered that doesn't - * satisfy the predicate, iteration will stop. - * - * @public - * @param {Function} predicate - * @returns {Sequence} The new sequence - * - * @examples - * function lessThan(x) { - * return function(y) { - * return y < x; - * }; - * } - * - * Lazy([1, 2, 3, 4]).takeWhile(lessThan(3)) // sequence: [1, 2] - * Lazy([1, 2, 3, 4]).takeWhile(lessThan(0)) // sequence: [] - */ - Sequence.prototype.takeWhile = function takeWhile(predicate) { - return new TakeWhileSequence(this, predicate); - }; - - /** - * @constructor - */ - function TakeWhileSequence(parent, predicate) { - this.parent = parent; - this.predicate = predicate; - } - - TakeWhileSequence.prototype = new Sequence(); - - TakeWhileSequence.prototype.each = function each(fn) { - var predicate = this.predicate, - finished = false, - j = 0; - - var result = this.parent.each(function(e, i) { - if (!predicate(e, i)) { - finished = true; - return false; - } - - return fn(e, j++); - }); - - if (result instanceof AsyncHandle) { - return result; - } - - return finished; - }; - - /** - * Creates a new sequence comprising all but the last N elements of this - * sequence. - * - * @public - * @param {number=} count The number of items to omit from the end of the - * sequence (defaults to 1). - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, 2, 3, 4]).initial() // sequence: [1, 2, 3] - * Lazy([1, 2, 3, 4]).initial(2) // sequence: [1, 2] - * Lazy([1, 2, 3]).filter(Lazy.identity).initial() // sequence: [1, 2] - */ - Sequence.prototype.initial = function initial(count) { - return new InitialSequence(this, count); - }; - - function InitialSequence(parent, count) { - this.parent = parent; - this.count = typeof count === "number" ? count : 1; - } - - InitialSequence.prototype = new Sequence(); - - InitialSequence.prototype.each = function each(fn) { - var index = this.parent.getIndex(); - return index.take(index.length() - this.count).each(fn); - }; - - /** - * Creates a new sequence comprising the last N elements of this sequence, OR - * (if N is `undefined`) simply returns the last element of this sequence. - * - * @public - * @param {number=} count The number of items to take from the end of the - * sequence. - * @returns {*} The new sequence (or the last element from this sequence - * if no count was given). - * - * @examples - * Lazy([1, 2, 3]).last() // => 3 - * Lazy([1, 2, 3]).last(2) // sequence: [2, 3] - * Lazy([1, 2, 3]).filter(isEven).last(2) // sequence: [2] - */ - Sequence.prototype.last = function last(count) { - if (typeof count === "undefined") { - return this.reverse().first(); - } - return this.reverse().take(count).reverse(); - }; - - /** - * Returns the first element in this sequence with property names and values - * matching those of the specified object. - * - * @public - * @param {Object} properties The properties that should be found on some - * element in this sequence. - * @returns {*} The found element, or `undefined` if none exists in this - * sequence. - * - * @examples - * var words = ["foo", "bar"]; - * - * Lazy(words).findWhere({ 0: "f" }); // => "foo" - * Lazy(words).findWhere({ 0: "z" }); // => undefined - */ - Sequence.prototype.findWhere = function findWhere(properties) { - return this.where(properties).first(); - }; - - /** - * Creates a new sequence comprising all but the first N elements of this - * sequence. - * - * @public - * @aka skip, tail, rest - * @param {number=} count The number of items to omit from the beginning of the - * sequence (defaults to 1). - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, 2, 3, 4]).rest() // sequence: [2, 3, 4] - * Lazy([1, 2, 3, 4]).rest(0) // sequence: [1, 2, 3, 4] - * Lazy([1, 2, 3, 4]).rest(2) // sequence: [3, 4] - * Lazy([1, 2, 3, 4]).rest(5) // sequence: [] - */ - Sequence.prototype.rest = function rest(count) { - return new DropSequence(this, count); - }; - - Sequence.prototype.skip = - Sequence.prototype.tail = - Sequence.prototype.drop = function drop(count) { - return this.rest(count); - }; - - /** - * @constructor - */ - function DropSequence(parent, count) { - this.parent = parent; - this.count = typeof count === "number" ? count : 1; - } - - DropSequence.prototype = new Sequence(); - - DropSequence.prototype.each = function each(fn) { - var count = this.count, - dropped = 0, - i = 0; - - return this.parent.each(function(e) { - if (dropped++ < count) { return; } - return fn(e, i++); - }); - }; - - /** - * Creates a new sequence comprising the elements from this sequence *after* - * those that satisfy some predicate. The sequence starts with the first - * element that does not match the predicate. - * - * @public - * @aka skipWhile - * @param {Function} predicate - * @returns {Sequence} The new sequence - */ - Sequence.prototype.dropWhile = function dropWhile(predicate) { - return new DropWhileSequence(this, predicate); - }; - - Sequence.prototype.skipWhile = function skipWhile(predicate) { - return this.dropWhile(predicate); - }; - - /** - * @constructor - */ - function DropWhileSequence(parent, predicate) { - this.parent = parent; - this.predicate = predicate; - } - - DropWhileSequence.prototype = new Sequence(); - - DropWhileSequence.prototype.each = function each(fn) { - var predicate = this.predicate, - done = false; - - return this.parent.each(function(e) { - if (!done) { - if (predicate(e)) { - return; - } - - done = true; - } - - return fn(e); - }); - }; - - /** - * Creates a new sequence with the same elements as this one, but ordered - * using the specified comparison function. - * - * This has essentially the same behavior as calling - * [`Array#sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort), - * but obviously instead of modifying the collection it returns a new - * {@link Sequence} object. - * - * @public - * @param {Function=} sortFn The function used to compare elements in the - * sequence. The function will be passed two elements and should return: - * - 1 if the first is greater - * - -1 if the second is greater - * - 0 if the two values are the same - * @param {boolean} descending Whether or not the resulting sequence should be - * in descending order (defaults to `false`). - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([5, 10, 1]).sort() // sequence: [1, 5, 10] - * Lazy(['foo', 'bar']).sort() // sequence: ['bar', 'foo'] - * Lazy(['b', 'c', 'a']).sort(null, true) // sequence: ['c', 'b', 'a'] - * Lazy([5, 10, 1]).sort(null, true) // sequence: [10, 5, 1] - * - * // Sorting w/ custom comparison function - * Lazy(['a', 'ab', 'aa', 'ba', 'b', 'abc']).sort(function compare(x, y) { - * if (x.length && (x.length !== y.length)) { return compare(x.length, y.length); } - * if (x === y) { return 0; } - * return x > y ? 1 : -1; - * }); - * // => sequence: ['a', 'b', 'aa', 'ab', 'ba', 'abc'] - */ - Sequence.prototype.sort = function sort(sortFn, descending) { - sortFn || (sortFn = compare); - if (descending) { sortFn = reverseArguments(sortFn); } - return new SortedSequence(this, sortFn); - }; - - /** - * Creates a new sequence with the same elements as this one, but ordered by - * the results of the given function. - * - * You can pass: - * - * - a *string*, to sort by the named property - * - a function, to sort by the result of calling the function on each element - * - * @public - * @param {Function} sortFn The function to call on the elements in this - * sequence, in order to sort them. - * @param {boolean} descending Whether or not the resulting sequence should be - * in descending order (defaults to `false`). - * @returns {Sequence} The new sequence. - * - * @examples - * function population(country) { - * return country.pop; - * } - * - * function area(country) { - * return country.sqkm; - * } - * - * var countries = [ - * { name: "USA", pop: 320000000, sqkm: 9600000 }, - * { name: "Brazil", pop: 194000000, sqkm: 8500000 }, - * { name: "Nigeria", pop: 174000000, sqkm: 924000 }, - * { name: "China", pop: 1350000000, sqkm: 9700000 }, - * { name: "Russia", pop: 143000000, sqkm: 17000000 }, - * { name: "Australia", pop: 23000000, sqkm: 7700000 } - * ]; - * - * Lazy(countries).sortBy(population).last(3).pluck('name') // sequence: ["Brazil", "USA", "China"] - * Lazy(countries).sortBy(area).last(3).pluck('name') // sequence: ["USA", "China", "Russia"] - * Lazy(countries).sortBy(area, true).first(3).pluck('name') // sequence: ["Russia", "China", "USA"] - * - * @benchmarks - * var randoms = Lazy.generate(Math.random).take(100).toArray(); - * - * Lazy(randoms).sortBy(Lazy.identity).each(Lazy.noop) // lazy - * _.each(_.sortBy(randoms, Lazy.identity), _.noop) // lodash - */ - Sequence.prototype.sortBy = function sortBy(sortFn, descending) { - sortFn = createComparator(sortFn); - if (descending) { sortFn = reverseArguments(sortFn); } - return new SortedSequence(this, sortFn); - }; - - /** - * @constructor - */ - function SortedSequence(parent, sortFn) { - this.parent = parent; - this.sortFn = sortFn; - } - - SortedSequence.prototype = new Sequence(); - - SortedSequence.prototype.each = function each(fn) { - var sortFn = this.sortFn, - result = this.parent.toArray(); - - result.sort(sortFn); - - return forEach(result, fn); - }; - - /** - * @examples - * var items = [{ a: 4 }, { a: 3 }, { a: 5 }]; - * - * Lazy(items).sortBy('a').reverse(); - * // => sequence: [{ a: 5 }, { a: 4 }, { a: 3 }] - * - * Lazy(items).sortBy('a').reverse().reverse(); - * // => sequence: [{ a: 3 }, { a: 4 }, { a: 5 }] - */ - SortedSequence.prototype.reverse = function reverse() { - return new SortedSequence(this.parent, reverseArguments(this.sortFn)); - }; - - /** - * Creates a new {@link ObjectLikeSequence} comprising the elements in this - * one, grouped together according to some key. The value associated with each - * key in the resulting object-like sequence is an array containing all of - * the elements in this sequence with that key. - * - * @public - * @param {Function|string} keyFn The function to call on the elements in this - * sequence to obtain a key by which to group them, or a string representing - * a parameter to read from all the elements in this sequence. - * @param {Function|string} valFn (Optional) The function to call on the elements - * in this sequence to assign to the value for each instance to appear in the - * group, or a string representing a parameter to read from all the elements - * in this sequence. - * @returns {ObjectLikeSequence} The new sequence. - * - * @examples - * function oddOrEven(x) { - * return x % 2 === 0 ? 'even' : 'odd'; - * } - * function square(x) { - * return x*x; - * } - * - * var numbers = [1, 2, 3, 4, 5]; - * - * Lazy(numbers).groupBy(oddOrEven) // sequence: { odd: [1, 3, 5], even: [2, 4] } - * Lazy(numbers).groupBy(oddOrEven).get("odd") // => [1, 3, 5] - * Lazy(numbers).groupBy(oddOrEven).get("foo") // => undefined - * Lazy(numbers).groupBy(oddOrEven, square).get("even") // => [4, 16] - * - * Lazy([ - * { name: 'toString' }, - * { name: 'toString' } - * ]).groupBy('name'); - * // => sequence: { - * 'toString': [ - * { name: 'toString' }, - * { name: 'toString' } - * ] - * } - */ - Sequence.prototype.groupBy = function groupBy(keyFn, valFn) { - return new GroupedSequence(this, keyFn, valFn); - }; - - /** - * @constructor - */ - function GroupedSequence(parent, keyFn, valFn) { - this.parent = parent; - this.keyFn = keyFn; - this.valFn = valFn; - } - - // GroupedSequence must have its prototype set after ObjectLikeSequence has - // been fully initialized. - - /** - * Creates a new {@link ObjectLikeSequence} comprising the elements in this - * one, indexed according to some key. - * - * @public - * @param {Function|string} keyFn The function to call on the elements in this - * sequence to obtain a key by which to index them, or a string - * representing a property to read from all the elements in this sequence. - * @param {Function|string} valFn (Optional) The function to call on the elements - * in this sequence to assign to the value of the indexed object, or a string - * representing a parameter to read from all the elements in this sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * var people = [ - * { name: 'Bob', age: 25 }, - * { name: 'Fred', age: 34 } - * ]; - * - * var bob = people[0], - * fred = people[1]; - * - * Lazy(people).indexBy('name') // sequence: { 'Bob': bob, 'Fred': fred } - * Lazy(people).indexBy('name', 'age') // sequence: { 'Bob': 25, 'Fred': 34 } - */ - Sequence.prototype.indexBy = function(keyFn, valFn) { - return new IndexedSequence(this, keyFn, valFn); - }; - - /** - * @constructor - */ - function IndexedSequence(parent, keyFn, valFn) { - this.parent = parent; - this.keyFn = keyFn; - this.valFn = valFn; - } - - // IndexedSequence must have its prototype set after ObjectLikeSequence has - // been fully initialized. - - /** - * Creates a new {@link ObjectLikeSequence} containing the unique keys of all - * the elements in this sequence, each paired with the number of elements - * in this sequence having that key. - * - * @public - * @param {Function|string} keyFn The function to call on the elements in this - * sequence to obtain a key by which to count them, or a string representing - * a parameter to read from all the elements in this sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * function oddOrEven(x) { - * return x % 2 === 0 ? 'even' : 'odd'; - * } - * - * var numbers = [1, 2, 3, 4, 5]; - * - * Lazy(numbers).countBy(oddOrEven) // sequence: { odd: 3, even: 2 } - * Lazy(numbers).countBy(oddOrEven).get("odd") // => 3 - * Lazy(numbers).countBy(oddOrEven).get("foo") // => undefined - */ - Sequence.prototype.countBy = function countBy(keyFn) { - return new CountedSequence(this, keyFn); - }; - - /** - * @constructor - */ - function CountedSequence(parent, keyFn) { - this.parent = parent; - this.keyFn = keyFn; - } - - // CountedSequence, like GroupedSequence, must have its prototype set after - // ObjectLikeSequence has been fully initialized. - - /** - * Creates a new sequence with every unique element from this one appearing - * exactly once (i.e., with duplicates removed). - * - * @public - * @aka unique - * @param {Function} keyFn An optional function to produce the key for each - * object. This key is then tested for uniqueness as opposed to the - * object reference. - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, 2, 2, 3, 3, 3]).uniq() // sequence: [1, 2, 3] - * Lazy([{ name: 'mike' }, - * { name: 'sarah' }, - * { name: 'mike' } - * ]).uniq('name') - * // sequence: [{ name: 'mike' }, { name: 'sarah' }] - * - * @benchmarks - * function randomOf(array) { - * return function() { - * return array[Math.floor(Math.random() * array.length)]; - * }; - * } - * - * var mostUnique = Lazy.generate(randomOf(_.range(100)), 100).toArray(), - * someUnique = Lazy.generate(randomOf(_.range(50)), 100).toArray(), - * mostDupes = Lazy.generate(randomOf(_.range(5)), 100).toArray(); - * - * Lazy(mostUnique).uniq().each(Lazy.noop) // lazy - mostly unique elements - * Lazy(someUnique).uniq().each(Lazy.noop) // lazy - some unique elements - * Lazy(mostDupes).uniq().each(Lazy.noop) // lazy - mostly duplicate elements - * _.each(_.uniq(mostUnique), _.noop) // lodash - mostly unique elements - * _.each(_.uniq(someUnique), _.noop) // lodash - some unique elements - * _.each(_.uniq(mostDupes), _.noop) // lodash - mostly duplicate elements - */ - Sequence.prototype.uniq = function uniq(keyFn) { - return new UniqueSequence(this, keyFn); - }; - - Sequence.prototype.unique = function unique(keyFn) { - return this.uniq(keyFn); - }; - - /** - * @constructor - */ - function UniqueSequence(parent, keyFn) { - this.parent = parent; - this.keyFn = keyFn; - } - - UniqueSequence.prototype = new Sequence(); - - UniqueSequence.prototype.each = function each(fn) { - var cache = new Set(), - keyFn = this.keyFn, - i = 0; - - if (keyFn) { - keyFn = createCallback(keyFn); - return this.parent.each(function(e) { - if (cache.add(keyFn(e))) { - return fn(e, i++); - } - }); - - } else { - return this.parent.each(function(e) { - if (cache.add(e)) { - return fn(e, i++); - } - }); - } - }; - - /** - * Creates a new sequence by combining the elements from this sequence with - * corresponding elements from the specified array(s). - * - * @public - * @param {...Array} var_args One or more arrays of elements to combine with - * those of this sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, 2]).zip([3, 4]) // sequence: [[1, 3], [2, 4]] - * - * @benchmarks - * var smArrL = Lazy.range(10).toArray(), - * smArrR = Lazy.range(10, 20).toArray(), - * lgArrL = Lazy.range(100).toArray(), - * lgArrR = Lazy.range(100, 200).toArray(); - * - * Lazy(smArrL).zip(smArrR).each(Lazy.noop) // lazy - zipping 10-element arrays - * Lazy(lgArrL).zip(lgArrR).each(Lazy.noop) // lazy - zipping 100-element arrays - * _.each(_.zip(smArrL, smArrR), _.noop) // lodash - zipping 10-element arrays - * _.each(_.zip(lgArrL, lgArrR), _.noop) // lodash - zipping 100-element arrays - */ - Sequence.prototype.zip = function zip(var_args) { - if (arguments.length === 1) { - return new SimpleZippedSequence(this, (/** @type {Array} */ var_args)); - } else { - return new ZippedSequence(this, arraySlice.call(arguments, 0)); - } - }; - - /** - * @constructor - */ - function ZippedSequence(parent, arrays) { - this.parent = parent; - this.arrays = arrays; - } - - ZippedSequence.prototype = new Sequence(); - - ZippedSequence.prototype.each = function each(fn) { - var arrays = this.arrays, - i = 0; - this.parent.each(function(e) { - var group = [e]; - for (var j = 0; j < arrays.length; ++j) { - if (arrays[j].length > i) { - group.push(arrays[j][i]); - } - } - return fn(group, i++); - }); - }; - - /** - * Creates a new sequence with the same elements as this one, in a randomized - * order. - * - * @public - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, 2, 3, 4, 5]).shuffle().value() // =~ [1, 2, 3, 4, 5] - */ - Sequence.prototype.shuffle = function shuffle() { - return new ShuffledSequence(this); - }; - - /** - * @constructor - */ - function ShuffledSequence(parent) { - this.parent = parent; - } - - ShuffledSequence.prototype = new Sequence(); - - ShuffledSequence.prototype.each = function each(fn) { - var shuffled = this.parent.toArray(), - floor = Math.floor, - random = Math.random, - j = 0; - - for (var i = shuffled.length - 1; i > 0; --i) { - swap(shuffled, i, floor(random() * (i + 1))); - if (fn(shuffled[i], j++) === false) { - return; - } - } - fn(shuffled[0], j); - }; - - /** - * Creates a new sequence with every element from this sequence, and with arrays - * exploded so that a sequence of arrays (of arrays) becomes a flat sequence of - * values. - * - * @public - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, [2, 3], [4, [5]]]).flatten() // sequence: [1, 2, 3, 4, 5] - * Lazy([1, Lazy([2, 3])]).flatten() // sequence: [1, 2, 3] - */ - Sequence.prototype.flatten = function flatten() { - return new FlattenedSequence(this); - }; - - /** - * @constructor - */ - function FlattenedSequence(parent) { - this.parent = parent; - } - - FlattenedSequence.prototype = new Sequence(); - - FlattenedSequence.prototype.each = function each(fn) { - var index = 0; - - return this.parent.each(function recurseVisitor(e) { - if (e instanceof Array) { - return forEach(e, recurseVisitor); - } - - if (e instanceof Sequence) { - return e.each(recurseVisitor); - } - - return fn(e, index++); - }); - }; - - /** - * Creates a new sequence with the same elements as this one, except for all - * falsy values (`false`, `0`, `""`, `null`, and `undefined`). - * - * @public - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy(["foo", null, "bar", undefined]).compact() // sequence: ["foo", "bar"] - */ - Sequence.prototype.compact = function compact() { - return this.filter(function(e) { return !!e; }); - }; - - /** - * Creates a new sequence with all the elements of this sequence that are not - * also among the specified arguments. - * - * @public - * @aka difference - * @param {...*} var_args The values, or array(s) of values, to be excluded from the - * resulting sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy([1, 2, 3, 4, 5]).without(2, 3) // sequence: [1, 4, 5] - * Lazy([1, 2, 3, 4, 5]).without([4, 5]) // sequence: [1, 2, 3] - */ - Sequence.prototype.without = function without(var_args) { - return new WithoutSequence(this, arraySlice.call(arguments, 0)); - }; - - Sequence.prototype.difference = function difference(var_args) { - return this.without.apply(this, arguments); - }; - - /** - * @constructor - */ - function WithoutSequence(parent, values) { - this.parent = parent; - this.values = values; - } - - WithoutSequence.prototype = new Sequence(); - - WithoutSequence.prototype.each = function each(fn) { - var set = createSet(this.values), - i = 0; - return this.parent.each(function(e) { - if (!set.contains(e)) { - return fn(e, i++); - } - }); - }; - - /** - * Creates a new sequence with all the unique elements either in this sequence - * or among the specified arguments. - * - * @public - * @param {...*} var_args The values, or array(s) of values, to be additionally - * included in the resulting sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy(["foo", "bar"]).union([]) // sequence: ["foo", "bar"] - * Lazy(["foo", "bar"]).union(["bar", "baz"]) // sequence: ["foo", "bar", "baz"] - */ - Sequence.prototype.union = function union(var_args) { - return this.concat(var_args).uniq(); - }; - - /** - * Creates a new sequence with all the elements of this sequence that also - * appear among the specified arguments. - * - * @public - * @param {...*} var_args The values, or array(s) of values, in which elements - * from this sequence must also be included to end up in the resulting sequence. - * @returns {Sequence} The new sequence. - * - * @examples - * Lazy(["foo", "bar"]).intersection([]) // sequence: [] - * Lazy(["foo", "bar"]).intersection(["bar", "baz"]) // sequence: ["bar"] - */ - Sequence.prototype.intersection = function intersection(var_args) { - if (arguments.length === 1 && arguments[0] instanceof Array) { - return new SimpleIntersectionSequence(this, (/** @type {Array} */ var_args)); - } else { - return new IntersectionSequence(this, arraySlice.call(arguments, 0)); - } - }; - - /** - * @constructor - */ - function IntersectionSequence(parent, arrays) { - this.parent = parent; - this.arrays = arrays; - } - - IntersectionSequence.prototype = new Sequence(); - - IntersectionSequence.prototype.each = function each(fn) { - var sets = Lazy(this.arrays).map(function(values) { - return new UniqueMemoizer(Lazy(values).getIterator()); - }); - - var setIterator = new UniqueMemoizer(sets.getIterator()), - i = 0; - - return this.parent.each(function(e) { - var includedInAll = true; - setIterator.each(function(set) { - if (!set.contains(e)) { - includedInAll = false; - return false; - } - }); - - if (includedInAll) { - return fn(e, i++); - } - }); - }; - - /** - * @constructor - */ - function UniqueMemoizer(iterator) { - this.iterator = iterator; - this.set = new Set(); - this.memo = []; - this.currentValue = undefined; - } - - UniqueMemoizer.prototype.current = function current() { - return this.currentValue; - }; - - UniqueMemoizer.prototype.moveNext = function moveNext() { - var iterator = this.iterator, - set = this.set, - memo = this.memo, - current; - - while (iterator.moveNext()) { - current = iterator.current(); - if (set.add(current)) { - memo.push(current); - this.currentValue = current; - return true; - } - } - return false; - }; - - UniqueMemoizer.prototype.each = function each(fn) { - var memo = this.memo, - length = memo.length, - i = -1; - - while (++i < length) { - if (fn(memo[i], i) === false) { - return false; - } - } - - while (this.moveNext()) { - if (fn(this.currentValue, i++) === false) { - break; - } - } - }; - - UniqueMemoizer.prototype.contains = function contains(e) { - if (this.set.contains(e)) { - return true; - } - - while (this.moveNext()) { - if (this.currentValue === e) { - return true; - } - } - - return false; - }; - - /** - * Checks whether every element in this sequence satisfies a given predicate. - * - * @public - * @aka all - * @param {Function} predicate A function to call on (potentially) every element - * in this sequence. - * @returns {boolean} True if `predicate` returns true for every element in the - * sequence (or the sequence is empty). False if `predicate` returns false - * for at least one element. - * - * @examples - * var numbers = [1, 2, 3, 4, 5]; - * - * var objects = [{ foo: true }, { foo: false, bar: true }]; - * - * Lazy(numbers).every(isEven) // => false - * Lazy(numbers).every(isPositive) // => true - * Lazy(objects).all('foo') // => false - * Lazy(objects).all('bar') // => false - */ - Sequence.prototype.every = function every(predicate) { - predicate = createCallback(predicate); - - return this.each(function(e, i) { - return !!predicate(e, i); - }); - }; - - Sequence.prototype.all = function all(predicate) { - return this.every(predicate); - }; - - /** - * Checks whether at least one element in this sequence satisfies a given - * predicate (or, if no predicate is specified, whether the sequence contains at - * least one element). - * - * @public - * @aka any - * @param {Function=} predicate A function to call on (potentially) every element - * in this sequence. - * @returns {boolean} True if `predicate` returns true for at least one element - * in the sequence. False if `predicate` returns false for every element (or - * the sequence is empty). - * - * @examples - * var numbers = [1, 2, 3, 4, 5]; - * - * Lazy(numbers).some() // => true - * Lazy(numbers).some(isEven) // => true - * Lazy(numbers).some(isNegative) // => false - * Lazy([]).some() // => false - */ - Sequence.prototype.some = function some(predicate) { - predicate = createCallback(predicate, true); - - var success = false; - this.each(function(e) { - if (predicate(e)) { - success = true; - return false; - } - }); - return success; - }; - - Sequence.prototype.any = function any(predicate) { - return this.some(predicate); - }; - - /** - * Checks whether NO elements in this sequence satisfy the given predicate - * (the opposite of {@link Sequence#all}, basically). - * - * @public - * @param {Function=} predicate A function to call on (potentially) every element - * in this sequence. - * @returns {boolean} True if `predicate` does not return true for any element - * in the sequence. False if `predicate` returns true for at least one - * element. - * - * @examples - * var numbers = [1, 2, 3, 4, 5]; - * - * Lazy(numbers).none() // => false - * Lazy(numbers).none(isEven) // => false - * Lazy(numbers).none(isNegative) // => true - * Lazy([]).none(isEven) // => true - * Lazy([]).none(isNegative) // => true - * Lazy([]).none() // => true - */ - Sequence.prototype.none = function none(predicate) { - return !this.any(predicate); - }; - - /** - * Checks whether the sequence has no elements. - * - * @public - * @returns {boolean} True if the sequence is empty, false if it contains at - * least one element. - * - * @examples - * Lazy([]).isEmpty() // => true - * Lazy([1, 2, 3]).isEmpty() // => false - */ - Sequence.prototype.isEmpty = function isEmpty() { - return !this.any(); - }; - - /** - * Performs (at worst) a linear search from the head of this sequence, - * returning the first index at which the specified value is found. - * - * @public - * @param {*} value The element to search for in the sequence. - * @returns {number} The index within this sequence where the given value is - * located, or -1 if the sequence doesn't contain the value. - * - * @examples - * function reciprocal(x) { return 1 / x; } - * - * Lazy(["foo", "bar", "baz"]).indexOf("bar") // => 1 - * Lazy([1, 2, 3]).indexOf(4) // => -1 - * Lazy([1, 2, 3]).map(reciprocal).indexOf(0.5) // => 1 - */ - Sequence.prototype.indexOf = function indexOf(value) { - var foundIndex = -1; - this.each(function(e, i) { - if (e === value) { - foundIndex = i; - return false; - } - }); - return foundIndex; - }; - - /** - * Performs (at worst) a linear search from the tail of this sequence, - * returning the last index at which the specified value is found. - * - * @public - * @param {*} value The element to search for in the sequence. - * @returns {number} The last index within this sequence where the given value - * is located, or -1 if the sequence doesn't contain the value. - * - * @examples - * Lazy(["a", "b", "c", "b", "a"]).lastIndexOf("b") // => 3 - * Lazy([1, 2, 3]).lastIndexOf(0) // => -1 - * Lazy([2, 2, 1, 2, 4]).filter(isEven).lastIndexOf(2) // 2 - */ - Sequence.prototype.lastIndexOf = function lastIndexOf(value) { - var reversed = this.getIndex().reverse(), - index = reversed.indexOf(value); - if (index !== -1) { - index = reversed.length() - index - 1; - } - return index; - }; - - /** - * Performs a binary search of this sequence, returning the lowest index where - * the given value is either found, or where it belongs (if it is not already - * in the sequence). - * - * This method assumes the sequence is in sorted order and will fail otherwise. - * - * @public - * @param {*} value The element to search for in the sequence. - * @returns {number} An index within this sequence where the given value is - * located, or where it belongs in sorted order. - * - * @examples - * Lazy([1, 3, 6, 9]).sortedIndex(3) // => 1 - * Lazy([1, 3, 6, 9]).sortedIndex(7) // => 3 - * Lazy([5, 10, 15, 20]).filter(isEven).sortedIndex(10) // => 0 - * Lazy([5, 10, 15, 20]).filter(isEven).sortedIndex(12) // => 1 - */ - Sequence.prototype.sortedIndex = function sortedIndex(value) { - var indexed = this.getIndex(), - lower = 0, - upper = indexed.length(), - i; - - while (lower < upper) { - i = (lower + upper) >>> 1; - if (compare(indexed.get(i), value) === -1) { - lower = i + 1; - } else { - upper = i; - } - } - return lower; - }; - - /** - * Checks whether the given value is in this sequence. - * - * @public - * @param {*} value The element to search for in the sequence. - * @returns {boolean} True if the sequence contains the value, false if not. - * - * @examples - * var numbers = [5, 10, 15, 20]; - * - * Lazy(numbers).contains(15) // => true - * Lazy(numbers).contains(13) // => false - */ - Sequence.prototype.contains = function contains(value) { - return this.indexOf(value) !== -1; - }; - - /** - * Aggregates a sequence into a single value according to some accumulator - * function. - * - * For an asynchronous sequence, instead of immediately returning a result - * (which it can't, obviously), this method returns an {@link AsyncHandle} - * whose `onComplete` method can be called to supply a callback to handle the - * final result once iteration has completed. - * - * @public - * @aka inject, foldl - * @param {Function} aggregator The function through which to pass every element - * in the sequence. For every element, the function will be passed the total - * aggregated result thus far and the element itself, and should return a - * new aggregated result. - * @param {*=} memo The starting value to use for the aggregated result - * (defaults to the first element in the sequence). - * @returns {*} The result of the aggregation, or, for asynchronous sequences, - * an {@link AsyncHandle} whose `onComplete` method accepts a callback to - * handle the final result. - * - * @examples - * function multiply(x, y) { return x * y; } - * - * var numbers = [1, 2, 3, 4]; - * - * Lazy(numbers).reduce(multiply) // => 24 - * Lazy(numbers).reduce(multiply, 5) // => 120 - */ - Sequence.prototype.reduce = function reduce(aggregator, memo) { - if (arguments.length < 2) { - return this.tail().reduce(aggregator, this.head()); - } - - var eachResult = this.each(function(e, i) { - memo = aggregator(memo, e, i); - }); - - // TODO: Think of a way more efficient solution to this problem. - if (eachResult instanceof AsyncHandle) { - return eachResult.then(function() { return memo; }); - } - - return memo; - }; - - Sequence.prototype.inject = - Sequence.prototype.foldl = function foldl(aggregator, memo) { - return this.reduce(aggregator, memo); - }; - - /** - * Aggregates a sequence, from the tail, into a single value according to some - * accumulator function. - * - * @public - * @aka foldr - * @param {Function} aggregator The function through which to pass every element - * in the sequence. For every element, the function will be passed the total - * aggregated result thus far and the element itself, and should return a - * new aggregated result. - * @param {*} memo The starting value to use for the aggregated result. - * @returns {*} The result of the aggregation. - * - * @examples - * function append(s1, s2) { - * return s1 + s2; - * } - * - * function isVowel(str) { - * return "aeiou".indexOf(str) !== -1; - * } - * - * Lazy("abcde").reduceRight(append) // => "edcba" - * Lazy("abcde").filter(isVowel).reduceRight(append) // => "ea" - */ - Sequence.prototype.reduceRight = function reduceRight(aggregator, memo) { - if (arguments.length < 2) { - return this.initial(1).reduceRight(aggregator, this.last()); - } - - // This bothers me... but frankly, calling reverse().reduce() is potentially - // going to eagerly evaluate the sequence anyway; so it's really not an issue. - var indexed = this.getIndex(), - i = indexed.length() - 1; - return indexed.reverse().reduce(function(m, e) { - return aggregator(m, e, i--); - }, memo); - }; - - Sequence.prototype.foldr = function foldr(aggregator, memo) { - return this.reduceRight(aggregator, memo); - }; - - /** - * Groups this sequence into consecutive (overlapping) segments of a specified - * length. If the underlying sequence has fewer elements than the specfied - * length, then this sequence will be empty. - * - * @public - * @param {number} length The length of each consecutive segment. - * @returns {Sequence} The resulting sequence of consecutive segments. - * - * @examples - * Lazy([]).consecutive(2) // => sequence: [] - * Lazy([1]).consecutive(2) // => sequence: [] - * Lazy([1, 2]).consecutive(2) // => sequence: [[1, 2]] - * Lazy([1, 2, 3]).consecutive(2) // => sequence: [[1, 2], [2, 3]] - * Lazy([1, 2, 3]).consecutive(0) // => sequence: [[]] - * Lazy([1, 2, 3]).consecutive(1) // => sequence: [[1], [2], [3]] - */ - Sequence.prototype.consecutive = function consecutive(count) { - var queue = new Queue(count); - var segments = this.map(function(element) { - if (queue.add(element).count === count) { - return queue.toArray(); - } - }); - return segments.compact(); - }; - - /** - * Breaks this sequence into chunks (arrays) of a specified length. - * - * @public - * @param {number} size The size of each chunk. - * @returns {Sequence} The resulting sequence of chunks. - * - * @examples - * Lazy([]).chunk(2) // sequence: [] - * Lazy([1, 2, 3]).chunk(2) // sequence: [[1, 2], [3]] - * Lazy([1, 2, 3]).chunk(1) // sequence: [[1], [2], [3]] - * Lazy([1, 2, 3]).chunk(4) // sequence: [[1, 2, 3]] - * Lazy([1, 2, 3]).chunk(0) // throws - */ - Sequence.prototype.chunk = function chunk(size) { - if (size < 1) { - throw new Error("You must specify a positive chunk size."); - } - - return new ChunkedSequence(this, size); - }; - - /** - * @constructor - */ - function ChunkedSequence(parent, size) { - this.parent = parent; - this.chunkSize = size; - } - - ChunkedSequence.prototype = new Sequence(); - - ChunkedSequence.prototype.getIterator = function getIterator() { - return new ChunkedIterator(this.parent, this.chunkSize); - }; - - /** - * @constructor - */ - function ChunkedIterator(sequence, size) { - this.iterator = sequence.getIterator(); - this.size = size; - } - - ChunkedIterator.prototype.current = function current() { - return this.currentChunk; - }; - - ChunkedIterator.prototype.moveNext = function moveNext() { - var iterator = this.iterator, - chunkSize = this.size, - chunk = []; - - while (chunk.length < chunkSize && iterator.moveNext()) { - chunk.push(iterator.current()); - } - - if (chunk.length === 0) { - return false; - } - - this.currentChunk = chunk; - return true; - }; - - /** - * Passes each element in the sequence to the specified callback during - * iteration. This is like {@link Sequence#each}, except that it can be - * inserted anywhere in the middle of a chain of methods to "intercept" the - * values in the sequence at that point. - * - * @public - * @param {Function} callback A function to call on every element in the - * sequence during iteration. The return value of this function does not - * matter. - * @returns {Sequence} A sequence comprising the same elements as this one. - * - * @examples - * Lazy([1, 2, 3]).tap(fn).each(Lazy.noop); // calls fn 3 times - */ - Sequence.prototype.tap = function tap(callback) { - return new TappedSequence(this, callback); - }; - - /** - * @constructor - */ - function TappedSequence(parent, callback) { - this.parent = parent; - this.callback = callback; - } - - TappedSequence.prototype = new Sequence(); - - TappedSequence.prototype.each = function each(fn) { - var callback = this.callback; - return this.parent.each(function(e, i) { - callback(e, i); - return fn(e, i); - }); - }; - - /** - * Seaches for the first element in the sequence satisfying a given predicate. - * - * @public - * @aka detect - * @param {Function} predicate A function to call on (potentially) every element - * in the sequence. - * @returns {*} The first element in the sequence for which `predicate` returns - * `true`, or `undefined` if no such element is found. - * - * @examples - * function divisibleBy3(x) { - * return x % 3 === 0; - * } - * - * var numbers = [5, 6, 7, 8, 9, 10]; - * - * Lazy(numbers).find(divisibleBy3) // => 6 - * Lazy(numbers).find(isNegative) // => undefined - */ - Sequence.prototype.find = function find(predicate) { - return this.filter(predicate).first(); - }; - - Sequence.prototype.detect = function detect(predicate) { - return this.find(predicate); - }; - - /** - * Gets the minimum value in the sequence. - * - * @public - * @param {Function=} valueFn The function by which the value for comparison is - * calculated for each element in the sequence. - * @returns {*} The element with the lowest value in the sequence, or - * `Infinity` if the sequence is empty. - * - * @examples - * function negate(x) { return x * -1; } - * - * Lazy([]).min() // => Infinity - * Lazy([6, 18, 2, 49, 34]).min() // => 2 - * Lazy([6, 18, 2, 49, 34]).min(negate) // => 49 - */ - Sequence.prototype.min = function min(valueFn) { - if (typeof valueFn !== "undefined") { - return this.minBy(valueFn); - } - - return this.reduce(function(x, y) { return y < x ? y : x; }, Infinity); - }; - - Sequence.prototype.minBy = function minBy(valueFn) { - valueFn = createCallback(valueFn); - return this.reduce(function(x, y) { return valueFn(y) < valueFn(x) ? y : x; }); - }; - - /** - * Gets the maximum value in the sequence. - * - * @public - * @param {Function=} valueFn The function by which the value for comparison is - * calculated for each element in the sequence. - * @returns {*} The element with the highest value in the sequence, or - * `-Infinity` if the sequence is empty. - * - * @examples - * function reverseDigits(x) { - * return Number(String(x).split('').reverse().join('')); - * } - * - * Lazy([]).max() // => -Infinity - * Lazy([6, 18, 2, 48, 29]).max() // => 48 - * Lazy([6, 18, 2, 48, 29]).max(reverseDigits) // => 29 - */ - Sequence.prototype.max = function max(valueFn) { - if (typeof valueFn !== "undefined") { - return this.maxBy(valueFn); - } - - return this.reduce(function(x, y) { return y > x ? y : x; }, -Infinity); - }; - - Sequence.prototype.maxBy = function maxBy(valueFn) { - valueFn = createCallback(valueFn); - return this.reduce(function(x, y) { return valueFn(y) > valueFn(x) ? y : x; }); - }; - - /** - * Gets the sum of the values in the sequence. - * - * @public - * @param {Function=} valueFn The function used to select the values that will - * be summed up. - * @returns {*} The sum. - * - * @examples - * Lazy([]).sum() // => 0 - * Lazy([1, 2, 3, 4]).sum() // => 10 - * Lazy([1.2, 3.4]).sum(Math.floor) // => 4 - * Lazy(['foo', 'bar']).sum('length') // => 6 - */ - Sequence.prototype.sum = function sum(valueFn) { - if (typeof valueFn !== "undefined") { - return this.sumBy(valueFn); - } - - return this.reduce(function(x, y) { return x + y; }, 0); - }; - - Sequence.prototype.sumBy = function sumBy(valueFn) { - valueFn = createCallback(valueFn); - return this.reduce(function(x, y) { return x + valueFn(y); }, 0); - }; - - /** - * Creates a string from joining together all of the elements in this sequence, - * separated by the given delimiter. - * - * @public - * @aka toString - * @param {string=} delimiter The separator to insert between every element from - * this sequence in the resulting string (defaults to `","`). - * @returns {string} The delimited string. - * - * @examples - * Lazy([6, 29, 1984]).join("/") // => "6/29/1984" - * Lazy(["a", "b", "c"]).join() // => "a,b,c" - * Lazy(["a", "b", "c"]).join("") // => "abc" - * Lazy([1, 2, 3]).join() // => "1,2,3" - * Lazy([1, 2, 3]).join("") // => "123" - * Lazy(["", "", ""]).join(",") // => ",," - */ - Sequence.prototype.join = function join(delimiter) { - delimiter = typeof delimiter === "string" ? delimiter : ","; - - return this.reduce(function(str, e, i) { - if (i > 0) { - str += delimiter; - } - return str + e; - }, ""); - }; - - Sequence.prototype.toString = function toString(delimiter) { - return this.join(delimiter); - }; - - /** - * Creates a sequence, with the same elements as this one, that will be iterated - * over asynchronously when calling `each`. - * - * @public - * @param {number=} interval The approximate period, in milliseconds, that - * should elapse between each element in the resulting sequence. Omitting - * this argument will result in the fastest possible asynchronous iteration. - * @returns {AsyncSequence} The new asynchronous sequence. - * - * @examples - * Lazy([1, 2, 3]).async(100).each(fn) // calls fn 3 times asynchronously - */ - Sequence.prototype.async = function async(interval) { - return new AsyncSequence(this, interval); - }; - - /** - * @constructor - */ - function SimpleIntersectionSequence(parent, array) { - this.parent = parent; - this.array = array; - this.each = getEachForIntersection(array); - } - - SimpleIntersectionSequence.prototype = new Sequence(); - - SimpleIntersectionSequence.prototype.eachMemoizerCache = function eachMemoizerCache(fn) { - var iterator = new UniqueMemoizer(Lazy(this.array).getIterator()), - i = 0; - - return this.parent.each(function(e) { - if (iterator.contains(e)) { - return fn(e, i++); - } - }); - }; - - SimpleIntersectionSequence.prototype.eachArrayCache = function eachArrayCache(fn) { - var array = this.array, - find = arrayContains, - i = 0; - - return this.parent.each(function(e) { - if (find(array, e)) { - return fn(e, i++); - } - }); - }; - - function getEachForIntersection(source) { - if (source.length < 40) { - return SimpleIntersectionSequence.prototype.eachArrayCache; - } else { - return SimpleIntersectionSequence.prototype.eachMemoizerCache; - } - } - - /** - * An optimized version of {@link ZippedSequence}, when zipping a sequence with - * only one array. - * - * @param {Sequence} parent The underlying sequence. - * @param {Array} array The array with which to zip the sequence. - * @constructor - */ - function SimpleZippedSequence(parent, array) { - this.parent = parent; - this.array = array; - } - - SimpleZippedSequence.prototype = new Sequence(); - - SimpleZippedSequence.prototype.each = function each(fn) { - var array = this.array; - return this.parent.each(function(e, i) { - return fn([e, array[i]], i); - }); - }; - - /** - * An `ArrayLikeSequence` is a {@link Sequence} that provides random access to - * its elements. This extends the API for iterating with the additional methods - * {@link #get} and {@link #length}, allowing a sequence to act as a "view" into - * a collection or other indexed data source. - * - * The initial sequence created by wrapping an array with `Lazy(array)` is an - * `ArrayLikeSequence`. - * - * All methods of `ArrayLikeSequence` that conceptually should return - * something like a array (with indexed access) return another - * `ArrayLikeSequence`, for example: - * - * - {@link Sequence#map} - * - {@link ArrayLikeSequence#slice} - * - {@link Sequence#take} and {@link Sequence#drop} - * - {@link Sequence#reverse} - * - * The above is not an exhaustive list. There are also certain other cases - * where it might be possible to return an `ArrayLikeSequence` (e.g., calling - * {@link Sequence#concat} with a single array argument), but this is not - * guaranteed by the API. - * - * Note that in many cases, it is not possible to provide indexed access - * without first performing at least a partial iteration of the underlying - * sequence. In these cases an `ArrayLikeSequence` will not be returned: - * - * - {@link Sequence#filter} - * - {@link Sequence#uniq} - * - {@link Sequence#union} - * - {@link Sequence#intersect} - * - * etc. The above methods only return ordinary {@link Sequence} objects. - * - * Defining custom array-like sequences - * ------------------------------------ - * - * Creating a custom `ArrayLikeSequence` is essentially the same as creating a - * custom {@link Sequence}. You just have a couple more methods you need to - * implement: `get` and (optionally) `length`. - * - * Here's an example. Let's define a sequence type called `OffsetSequence` that - * offsets each of its parent's elements by a set distance, and circles back to - * the beginning after reaching the end. **Remember**: the initialization - * function you pass to {@link #define} should always accept a `parent` as its - * first parameter. - * - * ArrayLikeSequence.define("offset", { - * init: function(parent, offset) { - * this.offset = offset; - * }, - * - * get: function(i) { - * return this.parent.get((i + this.offset) % this.parent.length()); - * } - * }); - * - * It's worth noting a couple of things here. - * - * First, Lazy's default implementation of `length` simply returns the parent's - * length. In this case, since an `OffsetSequence` will always have the same - * number of elements as its parent, that implementation is fine; so we don't - * need to override it. - * - * Second, the default implementation of `each` uses `get` and `length` to - * essentially create a `for` loop, which is fine here. If you want to implement - * `each` your own way, you can do that; but in most cases (as here), you can - * probably just stick with the default. - * - * So we're already done, after only implementing `get`! Pretty easy, huh? - * - * Now the `offset` method will be chainable from any `ArrayLikeSequence`. So - * for example: - * - * Lazy([1, 2, 3]).map(mapFn).offset(3); - * - * ...will work, but: - * - * Lazy([1, 2, 3]).filter(mapFn).offset(3); - * - * ...will not (because `filter` does not return an `ArrayLikeSequence`). - * - * (Also, as with the example provided for defining custom {@link Sequence} - * types, this example really could have been implemented using a function - * already available as part of Lazy.js: in this case, {@link Sequence#map}.) - * - * @public - * @constructor - * - * @examples - * Lazy([1, 2, 3]) // instanceof Lazy.ArrayLikeSequence - * Lazy([1, 2, 3]).map(Lazy.identity) // instanceof Lazy.ArrayLikeSequence - * Lazy([1, 2, 3]).take(2) // instanceof Lazy.ArrayLikeSequence - * Lazy([1, 2, 3]).drop(2) // instanceof Lazy.ArrayLikeSequence - * Lazy([1, 2, 3]).reverse() // instanceof Lazy.ArrayLikeSequence - * Lazy([1, 2, 3]).slice(1, 2) // instanceof Lazy.ArrayLikeSequence - */ - function ArrayLikeSequence() {} - - ArrayLikeSequence.prototype = new Sequence(); - - /** - * Create a new constructor function for a type inheriting from - * `ArrayLikeSequence`. - * - * @public - * @param {string|Array.} methodName The name(s) of the method(s) to be - * used for constructing the new sequence. The method will be attached to - * the `ArrayLikeSequence` prototype so that it can be chained with any other - * methods that return array-like sequences. - * @param {Object} overrides An object containing function overrides for this - * new sequence type. **Must** include `get`. *May* include `init`, - * `length`, `getIterator`, and `each`. For each function, `this` will be - * the new sequence and `this.parent` will be the source sequence. - * @returns {Function} A constructor for a new type inheriting from - * `ArrayLikeSequence`. - * - * @examples - * Lazy.ArrayLikeSequence.define("offset", { - * init: function(offset) { - * this.offset = offset; - * }, - * - * get: function(i) { - * return this.parent.get((i + this.offset) % this.parent.length()); - * } - * }); - * - * Lazy([1, 2, 3]).offset(1) // sequence: [2, 3, 1] - */ - ArrayLikeSequence.define = function define(methodName, overrides) { - if (!overrides || typeof overrides.get !== 'function') { - throw new Error("A custom array-like sequence must implement *at least* get!"); - } - - return defineSequenceType(ArrayLikeSequence, methodName, overrides); - }; - - /** - * Returns the element at the specified index. - * - * @public - * @param {number} i The index to access. - * @returns {*} The element. - * - * @examples - * function increment(x) { return x + 1; } - * - * Lazy([1, 2, 3]).get(1) // => 2 - * Lazy([1, 2, 3]).get(-1) // => undefined - * Lazy([1, 2, 3]).map(increment).get(1) // => 3 - */ - ArrayLikeSequence.prototype.get = function get(i) { - return this.parent.get(i); - }; - - /** - * Returns the length of the sequence. - * - * @public - * @returns {number} The length. - * - * @examples - * function increment(x) { return x + 1; } - * - * Lazy([]).length() // => 0 - * Lazy([1, 2, 3]).length() // => 3 - * Lazy([1, 2, 3]).map(increment).length() // => 3 - */ - ArrayLikeSequence.prototype.length = function length() { - return this.parent.length(); - }; - - /** - * Returns the current sequence (since it is already indexed). - */ - ArrayLikeSequence.prototype.getIndex = function getIndex() { - return this; - }; - - /** - * An optimized version of {@link Sequence#getIterator}. - */ - ArrayLikeSequence.prototype.getIterator = function getIterator() { - return new IndexedIterator(this); - }; - - /** - * An optimized version of {@link Iterator} meant to work with already-indexed - * sequences. - * - * @param {ArrayLikeSequence} sequence The sequence to iterate over. - * @constructor - */ - function IndexedIterator(sequence) { - this.sequence = sequence; - this.index = -1; - } - - IndexedIterator.prototype.current = function current() { - return this.sequence.get(this.index); - }; - - IndexedIterator.prototype.moveNext = function moveNext() { - if (this.index >= this.sequence.length() - 1) { - return false; - } - - ++this.index; - return true; - }; - - /** - * An optimized version of {@link Sequence#each}. - */ - ArrayLikeSequence.prototype.each = function each(fn) { - var length = this.length(), - i = -1; - - while (++i < length) { - if (fn(this.get(i), i) === false) { - return false; - } - } - - return true; - }; - - /** - * Returns a new sequence with the same elements as this one, minus the last - * element. - * - * @public - * @returns {ArrayLikeSequence} The new array-like sequence. - * - * @examples - * Lazy([1, 2, 3]).pop() // sequence: [1, 2] - * Lazy([]).pop() // sequence: [] - */ - ArrayLikeSequence.prototype.pop = function pop() { - return this.initial(); - }; - - /** - * Returns a new sequence with the same elements as this one, minus the first - * element. - * - * @public - * @returns {ArrayLikeSequence} The new array-like sequence. - * - * @examples - * Lazy([1, 2, 3]).shift() // sequence: [2, 3] - * Lazy([]).shift() // sequence: [] - */ - ArrayLikeSequence.prototype.shift = function shift() { - return this.drop(); - }; - - /** - * Returns a new sequence comprising the portion of this sequence starting - * from the specified starting index and continuing until the specified ending - * index or to the end of the sequence. - * - * @public - * @param {number} begin The index at which the new sequence should start. - * @param {number=} end The index at which the new sequence should end. - * @returns {ArrayLikeSequence} The new array-like sequence. - * - * @examples - * Lazy([1, 2, 3, 4, 5]).slice(0) // sequence: [1, 2, 3, 4, 5] - * Lazy([1, 2, 3, 4, 5]).slice(2) // sequence: [3, 4, 5] - * Lazy([1, 2, 3, 4, 5]).slice(2, 4) // sequence: [3, 4] - * Lazy([1, 2, 3, 4, 5]).slice(-1) // sequence: [5] - * Lazy([1, 2, 3, 4, 5]).slice(1, -1) // sequence: [2, 3, 4] - * Lazy([1, 2, 3, 4, 5]).slice(0, 10) // sequence: [1, 2, 3, 4, 5] - */ - ArrayLikeSequence.prototype.slice = function slice(begin, end) { - var length = this.length(); - - if (begin < 0) { - begin = length + begin; - } - - var result = this.drop(begin); - - if (typeof end === "number") { - if (end < 0) { - end = length + end; - } - result = result.take(end - begin); - } - - return result; - }; - - /** - * An optimized version of {@link Sequence#map}, which creates an - * {@link ArrayLikeSequence} so that the result still provides random access. - * - * @public - * - * @examples - * Lazy([1, 2, 3]).map(Lazy.identity) // instanceof Lazy.ArrayLikeSequence - */ - ArrayLikeSequence.prototype.map = function map(mapFn) { - return new IndexedMappedSequence(this, createCallback(mapFn)); - }; - - /** - * @constructor - */ - function IndexedMappedSequence(parent, mapFn) { - this.parent = parent; - this.mapFn = mapFn; - } - - IndexedMappedSequence.prototype = new ArrayLikeSequence(); - - IndexedMappedSequence.prototype.get = function get(i) { - if (i < 0 || i >= this.parent.length()) { - return undefined; - } - - return this.mapFn(this.parent.get(i), i); - }; - - /** - * An optimized version of {@link Sequence#filter}. - */ - ArrayLikeSequence.prototype.filter = function filter(filterFn) { - return new IndexedFilteredSequence(this, createCallback(filterFn)); - }; - - /** - * @constructor - */ - function IndexedFilteredSequence(parent, filterFn) { - this.parent = parent; - this.filterFn = filterFn; - } - - IndexedFilteredSequence.prototype = new FilteredSequence(); - - IndexedFilteredSequence.prototype.each = function each(fn) { - var parent = this.parent, - filterFn = this.filterFn, - length = this.parent.length(), - i = -1, - j = 0, - e; - - while (++i < length) { - e = parent.get(i); - if (filterFn(e, i) && fn(e, j++) === false) { - return false; - } - } - - return true; - }; - - /** - * An optimized version of {@link Sequence#reverse}, which creates an - * {@link ArrayLikeSequence} so that the result still provides random access. - * - * @public - * - * @examples - * Lazy([1, 2, 3]).reverse() // instanceof Lazy.ArrayLikeSequence - */ - ArrayLikeSequence.prototype.reverse = function reverse() { - return new IndexedReversedSequence(this); - }; - - /** - * @constructor - */ - function IndexedReversedSequence(parent) { - this.parent = parent; - } - - IndexedReversedSequence.prototype = new ArrayLikeSequence(); - - IndexedReversedSequence.prototype.get = function get(i) { - return this.parent.get(this.length() - i - 1); - }; - - /** - * An optimized version of {@link Sequence#first}, which creates an - * {@link ArrayLikeSequence} so that the result still provides random access. - * - * @public - * - * @examples - * Lazy([1, 2, 3]).first(2) // instanceof Lazy.ArrayLikeSequence - */ - ArrayLikeSequence.prototype.first = function first(count) { - if (typeof count === "undefined") { - return this.get(0); - } - - return new IndexedTakeSequence(this, count); - }; - - /** - * @constructor - */ - function IndexedTakeSequence(parent, count) { - this.parent = parent; - this.count = count; - } - - IndexedTakeSequence.prototype = new ArrayLikeSequence(); - - IndexedTakeSequence.prototype.length = function length() { - var parentLength = this.parent.length(); - return this.count <= parentLength ? this.count : parentLength; - }; - - /** - * An optimized version of {@link Sequence#rest}, which creates an - * {@link ArrayLikeSequence} so that the result still provides random access. - * - * @public - * - * @examples - * Lazy([1, 2, 3]).rest() // instanceof Lazy.ArrayLikeSequence - */ - ArrayLikeSequence.prototype.rest = function rest(count) { - return new IndexedDropSequence(this, count); - }; - - /** - * @constructor - */ - function IndexedDropSequence(parent, count) { - this.parent = parent; - this.count = typeof count === "number" ? count : 1; - } - - IndexedDropSequence.prototype = new ArrayLikeSequence(); - - IndexedDropSequence.prototype.get = function get(i) { - return this.parent.get(this.count + i); - }; - - IndexedDropSequence.prototype.length = function length() { - var parentLength = this.parent.length(); - return this.count <= parentLength ? parentLength - this.count : 0; - }; - - /** - * An optimized version of {@link Sequence#concat} that returns another - * {@link ArrayLikeSequence} *if* the argument is an array. - * - * @public - * @param {...*} var_args - * - * @examples - * Lazy([1, 2]).concat([3, 4]) // instanceof Lazy.ArrayLikeSequence - * Lazy([1, 2]).concat([3, 4]) // sequence: [1, 2, 3, 4] - */ - ArrayLikeSequence.prototype.concat = function concat(var_args) { - if (arguments.length === 1 && arguments[0] instanceof Array) { - return new IndexedConcatenatedSequence(this, (/** @type {Array} */ var_args)); - } else { - return Sequence.prototype.concat.apply(this, arguments); - } - }; - - /** - * @constructor - */ - function IndexedConcatenatedSequence(parent, other) { - this.parent = parent; - this.other = other; - } - - IndexedConcatenatedSequence.prototype = new ArrayLikeSequence(); - - IndexedConcatenatedSequence.prototype.get = function get(i) { - var parentLength = this.parent.length(); - if (i < parentLength) { - return this.parent.get(i); - } else { - return this.other[i - parentLength]; - } - }; - - IndexedConcatenatedSequence.prototype.length = function length() { - return this.parent.length() + this.other.length; - }; - - /** - * An optimized version of {@link Sequence#uniq}. - */ - ArrayLikeSequence.prototype.uniq = function uniq(keyFn) { - return new IndexedUniqueSequence(this, createCallback(keyFn)); - }; - - /** - * @param {ArrayLikeSequence} parent - * @constructor - */ - function IndexedUniqueSequence(parent, keyFn) { - this.parent = parent; - this.each = getEachForParent(parent); - this.keyFn = keyFn; - } - - IndexedUniqueSequence.prototype = new Sequence(); - - IndexedUniqueSequence.prototype.eachArrayCache = function eachArrayCache(fn) { - // Basically the same implementation as w/ the set, but using an array because - // it's cheaper for smaller sequences. - var parent = this.parent, - keyFn = this.keyFn, - length = parent.length(), - cache = [], - find = arrayContains, - key, value, - i = -1, - j = 0; - - while (++i < length) { - value = parent.get(i); - key = keyFn(value); - if (!find(cache, key)) { - cache.push(key); - if (fn(value, j++) === false) { - return false; - } - } - } - }; - - IndexedUniqueSequence.prototype.eachSetCache = UniqueSequence.prototype.each; - - function getEachForParent(parent) { - if (parent.length() < 100) { - return IndexedUniqueSequence.prototype.eachArrayCache; - } else { - return UniqueSequence.prototype.each; - } - } - - // Now that we've fully initialized the ArrayLikeSequence prototype, we can - // set the prototype for MemoizedSequence. - - MemoizedSequence.prototype = new ArrayLikeSequence(); - - MemoizedSequence.prototype.cache = function cache() { - return this.cachedResult || (this.cachedResult = this.parent.toArray()); - }; - - MemoizedSequence.prototype.get = function get(i) { - return this.cache()[i]; - }; - - MemoizedSequence.prototype.length = function length() { - return this.cache().length; - }; - - MemoizedSequence.prototype.slice = function slice(begin, end) { - return this.cache().slice(begin, end); - }; - - MemoizedSequence.prototype.toArray = function toArray() { - return this.cache().slice(0); - }; - - /** - * ArrayWrapper is the most basic {@link Sequence}. It directly wraps an array - * and implements the same methods as {@link ArrayLikeSequence}, but more - * efficiently. - * - * @constructor - */ - function ArrayWrapper(source) { - this.source = source; - } - - ArrayWrapper.prototype = new ArrayLikeSequence(); - - ArrayWrapper.prototype.root = function root() { - return this; - }; - - ArrayWrapper.prototype.isAsync = function isAsync() { - return false; - }; - - /** - * Returns the element at the specified index in the source array. - * - * @param {number} i The index to access. - * @returns {*} The element. - */ - ArrayWrapper.prototype.get = function get(i) { - return this.source[i]; - }; - - /** - * Returns the length of the source array. - * - * @returns {number} The length. - */ - ArrayWrapper.prototype.length = function length() { - return this.source.length; - }; - - /** - * An optimized version of {@link Sequence#each}. - */ - ArrayWrapper.prototype.each = function each(fn) { - return forEach(this.source, fn); - }; - - /** - * An optimized version of {@link Sequence#map}. - */ - ArrayWrapper.prototype.map = function map(mapFn) { - return new MappedArrayWrapper(this, createCallback(mapFn)); - }; - - /** - * An optimized version of {@link Sequence#filter}. - */ - ArrayWrapper.prototype.filter = function filter(filterFn) { - return new FilteredArrayWrapper(this, createCallback(filterFn)); - }; - - /** - * An optimized version of {@link Sequence#uniq}. - */ - ArrayWrapper.prototype.uniq = function uniq(keyFn) { - return new UniqueArrayWrapper(this, keyFn); - }; - - /** - * An optimized version of {@link ArrayLikeSequence#concat}. - * - * @param {...*} var_args - */ - ArrayWrapper.prototype.concat = function concat(var_args) { - if (arguments.length === 1 && arguments[0] instanceof Array) { - return new ConcatArrayWrapper(this, (/** @type {Array} */ var_args)); - } else { - return ArrayLikeSequence.prototype.concat.apply(this, arguments); - } - }; - - /** - * An optimized version of {@link Sequence#toArray}. - */ - ArrayWrapper.prototype.toArray = function toArray() { - return this.source.slice(0); - }; - - /** - * @constructor - */ - function MappedArrayWrapper(parent, mapFn) { - this.parent = parent; - this.mapFn = mapFn; - } - - MappedArrayWrapper.prototype = new ArrayLikeSequence(); - - MappedArrayWrapper.prototype.get = function get(i) { - var source = this.parent.source; - - if (i < 0 || i >= source.length) { - return undefined; - } - - return this.mapFn(source[i]); - }; - - MappedArrayWrapper.prototype.length = function length() { - return this.parent.source.length; - }; - - MappedArrayWrapper.prototype.each = function each(fn) { - var source = this.parent.source, - length = source.length, - mapFn = this.mapFn, - i = -1; - - while (++i < length) { - if (fn(mapFn(source[i], i), i) === false) { - return false; - } - } - - return true; - }; - - /** - * @constructor - */ - function FilteredArrayWrapper(parent, filterFn) { - this.parent = parent; - this.filterFn = filterFn; - } - - FilteredArrayWrapper.prototype = new FilteredSequence(); - - FilteredArrayWrapper.prototype.each = function each(fn) { - var source = this.parent.source, - filterFn = this.filterFn, - length = source.length, - i = -1, - j = 0, - e; - - while (++i < length) { - e = source[i]; - if (filterFn(e, i) && fn(e, j++) === false) { - return false; - } - } - - return true; - }; - - /** - * @constructor - */ - function UniqueArrayWrapper(parent, keyFn) { - this.parent = parent; - this.each = getEachForSource(parent.source); - this.keyFn = keyFn; - } - - UniqueArrayWrapper.prototype = new Sequence(); - - UniqueArrayWrapper.prototype.eachNoCache = function eachNoCache(fn) { - var source = this.parent.source, - keyFn = this.keyFn, - length = source.length, - find = arrayContainsBefore, - value, - - // Yes, this is hideous. - // Trying to get performance first, will refactor next! - i = -1, - k = 0; - - while (++i < length) { - value = source[i]; - if (!find(source, value, i, keyFn) && fn(value, k++) === false) { - return false; - } - } - - return true; - }; - - UniqueArrayWrapper.prototype.eachArrayCache = function eachArrayCache(fn) { - // Basically the same implementation as w/ the set, but using an array because - // it's cheaper for smaller sequences. - var source = this.parent.source, - keyFn = this.keyFn, - length = source.length, - cache = [], - find = arrayContains, - key, value, - i = -1, - j = 0; - - if (keyFn) { - keyFn = createCallback(keyFn); - while (++i < length) { - value = source[i]; - key = keyFn(value); - if (!find(cache, key)) { - cache.push(key); - if (fn(value, j++) === false) { - return false; - } - } - } - - } else { - while (++i < length) { - value = source[i]; - if (!find(cache, value)) { - cache.push(value); - if (fn(value, j++) === false) { - return false; - } - } - } - } - - return true; - }; - - UniqueArrayWrapper.prototype.eachSetCache = UniqueSequence.prototype.each; - - /** - * My latest findings here... - * - * So I hadn't really given the set-based approach enough credit. The main issue - * was that my Set implementation was totally not optimized at all. After pretty - * heavily optimizing it (just take a look; it's a monstrosity now!), it now - * becomes the fastest option for much smaller values of N. - */ - function getEachForSource(source) { - if (source.length < 40) { - return UniqueArrayWrapper.prototype.eachNoCache; - } else if (source.length < 100) { - return UniqueArrayWrapper.prototype.eachArrayCache; - } else { - return UniqueArrayWrapper.prototype.eachSetCache; - } - } - - /** - * @constructor - */ - function ConcatArrayWrapper(parent, other) { - this.parent = parent; - this.other = other; - } - - ConcatArrayWrapper.prototype = new ArrayLikeSequence(); - - ConcatArrayWrapper.prototype.get = function get(i) { - var source = this.parent.source, - sourceLength = source.length; - - if (i < sourceLength) { - return source[i]; - } else { - return this.other[i - sourceLength]; - } - }; - - ConcatArrayWrapper.prototype.length = function length() { - return this.parent.source.length + this.other.length; - }; - - ConcatArrayWrapper.prototype.each = function each(fn) { - var source = this.parent.source, - sourceLength = source.length, - other = this.other, - otherLength = other.length, - i = 0, - j = -1; - - while (++j < sourceLength) { - if (fn(source[j], i++) === false) { - return false; - } - } - - j = -1; - while (++j < otherLength) { - if (fn(other[j], i++) === false) { - return false; - } - } - - return true; - }; - - /** - * An `ObjectLikeSequence` object represents a sequence of key/value pairs. - * - * The initial sequence you get by wrapping an object with `Lazy(object)` is - * an `ObjectLikeSequence`. - * - * All methods of `ObjectLikeSequence` that conceptually should return - * something like an object return another `ObjectLikeSequence`. - * - * @public - * @constructor - * - * @examples - * var obj = { foo: 'bar' }; - * - * Lazy(obj).assign({ bar: 'baz' }) // instanceof Lazy.ObjectLikeSequence - * Lazy(obj).defaults({ bar: 'baz' }) // instanceof Lazy.ObjectLikeSequence - * Lazy(obj).invert() // instanceof Lazy.ObjectLikeSequence - */ - function ObjectLikeSequence() {} - - ObjectLikeSequence.prototype = new Sequence(); - - /** - * Create a new constructor function for a type inheriting from - * `ObjectLikeSequence`. - * - * @public - * @param {string|Array.} methodName The name(s) of the method(s) to be - * used for constructing the new sequence. The method will be attached to - * the `ObjectLikeSequence` prototype so that it can be chained with any other - * methods that return object-like sequences. - * @param {Object} overrides An object containing function overrides for this - * new sequence type. **Must** include `each`. *May* include `init` and - * `get` (for looking up an element by key). - * @returns {Function} A constructor for a new type inheriting from - * `ObjectLikeSequence`. - * - * @examples - * function downcaseKey(value, key) { - * return [key.toLowerCase(), value]; - * } - * - * Lazy.ObjectLikeSequence.define("caseInsensitive", { - * init: function() { - * var downcased = this.parent - * .map(downcaseKey) - * .toObject(); - * this.downcased = Lazy(downcased); - * }, - * - * get: function(key) { - * return this.downcased.get(key.toLowerCase()); - * }, - * - * each: function(fn) { - * return this.downcased.each(fn); - * } - * }); - * - * Lazy({ Foo: 'bar' }).caseInsensitive() // sequence: { foo: 'bar' } - * Lazy({ FOO: 'bar' }).caseInsensitive().get('foo') // => 'bar' - * Lazy({ FOO: 'bar' }).caseInsensitive().get('FOO') // => 'bar' - */ - ObjectLikeSequence.define = function define(methodName, overrides) { - if (!overrides || typeof overrides.each !== 'function') { - throw new Error("A custom object-like sequence must implement *at least* each!"); - } - - return defineSequenceType(ObjectLikeSequence, methodName, overrides); - }; - - ObjectLikeSequence.prototype.value = function value() { - return this.toObject(); - }; - - /** - * Gets the element at the specified key in this sequence. - * - * @public - * @param {string} key The key. - * @returns {*} The element. - * - * @examples - * Lazy({ foo: "bar" }).get("foo") // => "bar" - * Lazy({ foo: "bar" }).extend({ foo: "baz" }).get("foo") // => "baz" - * Lazy({ foo: "bar" }).defaults({ bar: "baz" }).get("bar") // => "baz" - * Lazy({ foo: "bar" }).invert().get("bar") // => "foo" - * Lazy({ foo: 1, bar: 2 }).pick(["foo"]).get("foo") // => 1 - * Lazy({ foo: 1, bar: 2 }).pick(["foo"]).get("bar") // => undefined - * Lazy({ foo: 1, bar: 2 }).omit(["foo"]).get("bar") // => 2 - * Lazy({ foo: 1, bar: 2 }).omit(["foo"]).get("foo") // => undefined - */ - ObjectLikeSequence.prototype.get = function get(key) { - var pair = this.pairs().find(function(pair) { - return pair[0] === key; - }); - - return pair ? pair[1] : undefined; - }; - - /** - * Returns a {@link Sequence} whose elements are the keys of this object-like - * sequence. - * - * @public - * @returns {Sequence} The sequence based on this sequence's keys. - * - * @examples - * Lazy({ hello: "hola", goodbye: "hasta luego" }).keys() // sequence: ["hello", "goodbye"] - */ - ObjectLikeSequence.prototype.keys = function keys() { - return this.map(function(v, k) { return k; }); - }; - - /** - * Returns a {@link Sequence} whose elements are the values of this object-like - * sequence. - * - * @public - * @returns {Sequence} The sequence based on this sequence's values. - * - * @examples - * Lazy({ hello: "hola", goodbye: "hasta luego" }).values() // sequence: ["hola", "hasta luego"] - */ - ObjectLikeSequence.prototype.values = function values() { - return this.map(function(v, k) { return v; }); - }; - - /** - * Throws an exception. Asynchronous iteration over object-like sequences is - * not supported. - * - * @public - * @examples - * Lazy({ foo: 'bar' }).async() // throws - */ - ObjectLikeSequence.prototype.async = function async() { - throw new Error('An ObjectLikeSequence does not support asynchronous iteration.'); - }; - - ObjectLikeSequence.prototype.filter = function filter(filterFn) { - return new FilteredObjectLikeSequence(this, createCallback(filterFn)); - }; - - function FilteredObjectLikeSequence(parent, filterFn) { - this.parent = parent; - this.filterFn = filterFn; - } - - FilteredObjectLikeSequence.prototype = new ObjectLikeSequence(); - - FilteredObjectLikeSequence.prototype.each = function each(fn) { - var filterFn = this.filterFn; - - return this.parent.each(function(v, k) { - if (filterFn(v, k)) { - return fn(v, k); - } - }); - }; - - /** - * Returns this same sequence. (Reversing an object-like sequence doesn't make - * any sense.) - */ - ObjectLikeSequence.prototype.reverse = function reverse() { - return this; - }; - - /** - * Returns an {@link ObjectLikeSequence} whose elements are the combination of - * this sequence and another object. In the case of a key appearing in both this - * sequence and the given object, the other object's value will override the - * one in this sequence. - * - * @public - * @aka extend - * @param {Object} other The other object to assign to this sequence. - * @returns {ObjectLikeSequence} A new sequence comprising elements from this - * sequence plus the contents of `other`. - * - * @examples - * Lazy({ "uno": 1, "dos": 2 }).assign({ "tres": 3 }) // sequence: { uno: 1, dos: 2, tres: 3 } - * Lazy({ foo: "bar" }).assign({ foo: "baz" }); // sequence: { foo: "baz" } - */ - ObjectLikeSequence.prototype.assign = function assign(other) { - return new AssignSequence(this, other); - }; - - ObjectLikeSequence.prototype.extend = function extend(other) { - return this.assign(other); - }; - - /** - * @constructor - */ - function AssignSequence(parent, other) { - this.parent = parent; - this.other = other; - } - - AssignSequence.prototype = new ObjectLikeSequence(); - - AssignSequence.prototype.get = function get(key) { - return this.other[key] || this.parent.get(key); - }; - - AssignSequence.prototype.each = function each(fn) { - var merged = new Set(), - done = false; - - Lazy(this.other).each(function(value, key) { - if (fn(value, key) === false) { - done = true; - return false; - } - - merged.add(key); - }); - - if (!done) { - return this.parent.each(function(value, key) { - if (!merged.contains(key) && fn(value, key) === false) { - return false; - } - }); - } - }; - - /** - * Returns an {@link ObjectLikeSequence} whose elements are the combination of - * this sequence and a 'default' object. In the case of a key appearing in both - * this sequence and the given object, this sequence's value will override the - * default object's. - * - * @public - * @param {Object} defaults The 'default' object to use for missing keys in this - * sequence. - * @returns {ObjectLikeSequence} A new sequence comprising elements from this - * sequence supplemented by the contents of `defaults`. - * - * @examples - * Lazy({ name: "Dan" }).defaults({ name: "User", password: "passw0rd" }) // sequence: { name: "Dan", password: "passw0rd" } - */ - ObjectLikeSequence.prototype.defaults = function defaults(defaults) { - return new DefaultsSequence(this, defaults); - }; - - /** - * @constructor - */ - function DefaultsSequence(parent, defaults) { - this.parent = parent; - this.defaults = defaults; - } - - DefaultsSequence.prototype = new ObjectLikeSequence(); - - DefaultsSequence.prototype.get = function get(key) { - return this.parent.get(key) || this.defaults[key]; - }; - - DefaultsSequence.prototype.each = function each(fn) { - var merged = new Set(), - done = false; - - this.parent.each(function(value, key) { - if (fn(value, key) === false) { - done = true; - return false; - } - - if (typeof value !== "undefined") { - merged.add(key); - } - }); - - if (!done) { - Lazy(this.defaults).each(function(value, key) { - if (!merged.contains(key) && fn(value, key) === false) { - return false; - } - }); - } - }; - - /** - * Returns an {@link ObjectLikeSequence} whose values are this sequence's keys, - * and whose keys are this sequence's values. - * - * @public - * @returns {ObjectLikeSequence} A new sequence comprising the inverted keys and - * values from this sequence. - * - * @examples - * Lazy({ first: "Dan", last: "Tao" }).invert() // sequence: { Dan: "first", Tao: "last" } - */ - ObjectLikeSequence.prototype.invert = function invert() { - return new InvertedSequence(this); - }; - - /** - * @constructor - */ - function InvertedSequence(parent) { - this.parent = parent; - } - - InvertedSequence.prototype = new ObjectLikeSequence(); - - InvertedSequence.prototype.each = function each(fn) { - this.parent.each(function(value, key) { - return fn(key, value); - }); - }; - - /** - * Produces an {@link ObjectLikeSequence} consisting of all the recursively - * merged values from this and the given object(s) or sequence(s). - * - * Note that by default this method only merges "vanilla" objects (bags of - * key/value pairs), not arrays or any other custom object types. To customize - * how merging works, you can provide the mergeFn argument, e.g. to handling - * merging arrays, strings, or other types of objects. - * - * @public - * @param {...Object|ObjectLikeSequence} others The other object(s) or - * sequence(s) whose values will be merged into this one. - * @param {Function=} mergeFn An optional function used to customize merging - * behavior. The function should take two values as parameters and return - * whatever the "merged" form of those values is. If the function returns - * undefined then the new value will simply replace the old one in the - * final result. - * @returns {ObjectLikeSequence} The new sequence consisting of merged values. - * - * @examples - * // These examples are completely stolen from Lo-Dash's documentation: - * // lodash.com/docs#merge - * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] - * }; - * - * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] - * }; - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * function mergeArrays(a, b) { - * return Array.isArray(a) ? a.concat(b) : undefined; - * } - * - * Lazy(names).merge(ages); // => sequence: { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } - * Lazy(food).merge(otherFood, mergeArrays); // => sequence: { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } - * - * // ----- Now for my own tests: ----- - * - * // merges objects - * Lazy({ foo: 1 }).merge({ foo: 2 }); // => sequence: { foo: 2 } - * Lazy({ foo: 1 }).merge({ bar: 2 }); // => sequence: { foo: 1, bar: 2 } - * - * // goes deep - * Lazy({ foo: { bar: 1 } }).merge({ foo: { bar: 2 } }); // => sequence: { foo: { bar: 2 } } - * Lazy({ foo: { bar: 1 } }).merge({ foo: { baz: 2 } }); // => sequence: { foo: { bar: 1, baz: 2 } } - * Lazy({ foo: { bar: 1 } }).merge({ foo: { baz: 2 } }); // => sequence: { foo: { bar: 1, baz: 2 } } - * - * // gives precedence to later sources - * Lazy({ foo: 1 }).merge({ bar: 2 }, { bar: 3 }); // => sequence: { foo: 1, bar: 3 } - * - * // undefined gets passed over - * Lazy({ foo: 1 }).merge({ foo: undefined }); // => sequence: { foo: 1 } - * - * // null doesn't get passed over - * Lazy({ foo: 1 }).merge({ foo: null }); // => sequence: { foo: null } - * - * // array contents get merged as well - * Lazy({ foo: [{ bar: 1 }] }).merge({ foo: [{ baz: 2 }] }); // => sequence: { foo: [{ bar: 1, baz: 2}] } - */ - ObjectLikeSequence.prototype.merge = function merge(var_args) { - var mergeFn = arguments.length > 1 && typeof arguments[arguments.length - 1] === "function" ? - arrayPop.call(arguments) : null; - return new MergedSequence(this, arraySlice.call(arguments, 0), mergeFn); - }; - - /** - * @constructor - */ - function MergedSequence(parent, others, mergeFn) { - this.parent = parent; - this.others = others; - this.mergeFn = mergeFn; - } - - MergedSequence.prototype = new ObjectLikeSequence(); - - MergedSequence.prototype.each = function each(fn) { - var others = this.others, - mergeFn = this.mergeFn || mergeObjects, - keys = {}; - - var iteratedFullSource = this.parent.each(function(value, key) { - var merged = value; - - forEach(others, function(other) { - if (key in other) { - merged = mergeFn(merged, other[key]); - } - }); - - keys[key] = true; - - return fn(merged, key); - }); - - if (iteratedFullSource === false) { - return false; - } - - var remaining = {}; - - forEach(others, function(other) { - for (var k in other) { - if (!keys[k]) { - remaining[k] = mergeFn(remaining[k], other[k]); - } - } - }); - - return Lazy(remaining).each(fn); - }; - - /** - * @private - * @examples - * mergeObjects({ foo: 1 }, { bar: 2 }); // => { foo: 1, bar: 2 } - * mergeObjects({ foo: { bar: 1 } }, { foo: { baz: 2 } }); // => { foo: { bar: 1, baz: 2 } } - * mergeObjects({ foo: { bar: 1 } }, { foo: undefined }); // => { foo: { bar: 1 } } - * mergeObjects({ foo: { bar: 1 } }, { foo: null }); // => { foo: null } - * mergeObjects({ array: [0, 1, 2] }, { array: [3, 4, 5] }).array; // instanceof Array - * mergeObjects({ date: new Date() }, { date: new Date() }).date; // instanceof Date - * mergeObjects([{ foo: 1 }], [{ bar: 2 }]); // => [{ foo: 1, bar: 2 }] - */ - function mergeObjects(a, b) { - var merged, prop; - - if (typeof b === 'undefined') { - return a; - } - - // Check that we're dealing with two objects or two arrays. - if (isVanillaObject(a) && isVanillaObject(b)) { - merged = {}; - } else if (a instanceof Array && b instanceof Array) { - merged = []; - } else { - // Otherwise there's no merging to do -- just replace a w/ b. - return b; - } - - for (prop in a) { - merged[prop] = mergeObjects(a[prop], b[prop]); - } - for (prop in b) { - if (!merged[prop]) { - merged[prop] = b[prop]; - } - } - return merged; - } - - /** - * Checks whether an object is a "vanilla" object, i.e. {'foo': 'bar'} as - * opposed to an array, date, etc. - * - * @private - * @examples - * isVanillaObject({foo: 'bar'}); // => true - * isVanillaObject(new Date()); // => false - * isVanillaObject([1, 2, 3]); // => false - */ - function isVanillaObject(object) { - return object && object.constructor === Object; - } - - /** - * Creates a {@link Sequence} consisting of the keys from this sequence whose - * values are functions. - * - * @public - * @aka methods - * @returns {Sequence} The new sequence. - * - * @examples - * var dog = { - * name: "Fido", - * breed: "Golden Retriever", - * bark: function() { console.log("Woof!"); }, - * wagTail: function() { console.log("TODO: implement robotic dog interface"); } - * }; - * - * Lazy(dog).functions() // sequence: ["bark", "wagTail"] - */ - ObjectLikeSequence.prototype.functions = function functions() { - return this - .filter(function(v, k) { return typeof(v) === "function"; }) - .map(function(v, k) { return k; }); - }; - - ObjectLikeSequence.prototype.methods = function methods() { - return this.functions(); - }; - - /** - * Creates an {@link ObjectLikeSequence} consisting of the key/value pairs from - * this sequence whose keys are included in the given array of property names. - * - * @public - * @param {Array} properties An array of the properties to "pick" from this - * sequence. - * @returns {ObjectLikeSequence} The new sequence. - * - * @examples - * var players = { - * "who": "first", - * "what": "second", - * "i don't know": "third" - * }; - * - * Lazy(players).pick(["who", "what"]) // sequence: { who: "first", what: "second" } - */ - ObjectLikeSequence.prototype.pick = function pick(properties) { - return new PickSequence(this, properties); - }; - - /** - * @constructor - */ - function PickSequence(parent, properties) { - this.parent = parent; - this.properties = properties; - } - - PickSequence.prototype = new ObjectLikeSequence(); - - PickSequence.prototype.get = function get(key) { - return arrayContains(this.properties, key) ? this.parent.get(key) : undefined; - }; - - PickSequence.prototype.each = function each(fn) { - var inArray = arrayContains, - properties = this.properties; - - return this.parent.each(function(value, key) { - if (inArray(properties, key)) { - return fn(value, key); - } - }); - }; - - /** - * Creates an {@link ObjectLikeSequence} consisting of the key/value pairs from - * this sequence excluding those with the specified keys. - * - * @public - * @param {Array} properties An array of the properties to *omit* from this - * sequence. - * @returns {ObjectLikeSequence} The new sequence. - * - * @examples - * var players = { - * "who": "first", - * "what": "second", - * "i don't know": "third" - * }; - * - * Lazy(players).omit(["who", "what"]) // sequence: { "i don't know": "third" } - */ - ObjectLikeSequence.prototype.omit = function omit(properties) { - return new OmitSequence(this, properties); - }; - - /** - * @constructor - */ - function OmitSequence(parent, properties) { - this.parent = parent; - this.properties = properties; - } - - OmitSequence.prototype = new ObjectLikeSequence(); - - OmitSequence.prototype.get = function get(key) { - return arrayContains(this.properties, key) ? undefined : this.parent.get(key); - }; - - OmitSequence.prototype.each = function each(fn) { - var inArray = arrayContains, - properties = this.properties; - - return this.parent.each(function(value, key) { - if (!inArray(properties, key)) { - return fn(value, key); - } - }); - }; - - /** - * Maps the key/value pairs in this sequence to arrays. - * - * @public - * @aka toArray - * @returns {Sequence} An sequence of `[key, value]` pairs. - * - * @examples - * var colorCodes = { - * red: "#f00", - * green: "#0f0", - * blue: "#00f" - * }; - * - * Lazy(colorCodes).pairs() // sequence: [["red", "#f00"], ["green", "#0f0"], ["blue", "#00f"]] - */ - ObjectLikeSequence.prototype.pairs = function pairs() { - return this.map(function(v, k) { return [k, v]; }); - }; - - /** - * Creates an array from the key/value pairs in this sequence. - * - * @public - * @returns {Array} An array of `[key, value]` elements. - * - * @examples - * var colorCodes = { - * red: "#f00", - * green: "#0f0", - * blue: "#00f" - * }; - * - * Lazy(colorCodes).toArray() // => [["red", "#f00"], ["green", "#0f0"], ["blue", "#00f"]] - */ - ObjectLikeSequence.prototype.toArray = function toArray() { - return this.pairs().toArray(); - }; - - /** - * Creates an object with the key/value pairs from this sequence. - * - * @public - * @returns {Object} An object with the same key/value pairs as this sequence. - * - * @examples - * var colorCodes = { - * red: "#f00", - * green: "#0f0", - * blue: "#00f" - * }; - * - * Lazy(colorCodes).toObject() // => { red: "#f00", green: "#0f0", blue: "#00f" } - */ - ObjectLikeSequence.prototype.toObject = function toObject() { - return this.reduce(function(object, value, key) { - object[key] = value; - return object; - }, {}); - }; - - // Now that we've fully initialized the ObjectLikeSequence prototype, we can - // actually set the prototypes for GroupedSequence, IndexedSequence, and - // CountedSequence. - - GroupedSequence.prototype = new ObjectLikeSequence(); - - GroupedSequence.prototype.each = function each(fn) { - var keyFn = createCallback(this.keyFn), - valFn = createCallback(this.valFn), - result; - - result = this.parent.reduce(function(grouped,e) { - var key = keyFn(e), - val = valFn(e); - if (!(grouped[key] instanceof Array)) { - grouped[key] = [val]; - } else { - grouped[key].push(val); - } - return grouped; - },{}); - - return transform(function(grouped) { - for (var key in grouped) { - if (fn(grouped[key], key) === false) { - return false; - } - } - }, result); - }; - - IndexedSequence.prototype = new ObjectLikeSequence(); - - IndexedSequence.prototype.each = function each(fn) { - var keyFn = createCallback(this.keyFn), - valFn = createCallback(this.valFn), - indexed = {}; - - return this.parent.each(function(e) { - var key = keyFn(e), - val = valFn(e); - - if (!indexed[key]) { - indexed[key] = val; - return fn(val, key); - } - }); - }; - - CountedSequence.prototype = new ObjectLikeSequence(); - - CountedSequence.prototype.each = function each(fn) { - var keyFn = createCallback(this.keyFn), - counted = {}; - - this.parent.each(function(e) { - var key = keyFn(e); - if (!counted[key]) { - counted[key] = 1; - } else { - counted[key] += 1; - } - }); - - for (var key in counted) { - if (fn(counted[key], key) === false) { - return false; - } - } - - return true; - }; - - /** - * Watches for all changes to a specified property (or properties) of an - * object and produces a sequence whose elements have the properties - * `{ property, value }` indicating which property changed and what it was - * changed to. - * - * Note that this method **only works on directly wrapped objects**; it will - * *not* work on any arbitrary {@link ObjectLikeSequence}. - * - * @public - * @param {(string|Array)=} propertyNames A property name or array of property - * names to watch. If this parameter is `undefined`, all of the object's - * current (enumerable) properties will be watched. - * @returns {Sequence} A sequence comprising `{ property, value }` objects - * describing each change to the specified property/properties. - * - * @examples - * var obj = {}, - * changes = []; - * - * Lazy(obj).watch('foo').each(function(change) { - * changes.push(change); - * }); - * - * obj.foo = 1; - * obj.bar = 2; - * obj.foo = 3; - * - * obj.foo; // => 3 - * changes; // => [{ property: 'foo', value: 1 }, { property: 'foo', value: 3 }] - */ - ObjectLikeSequence.prototype.watch = function watch(propertyNames) { - throw new Error('You can only call #watch on a directly wrapped object.'); - }; - - /** - * @constructor - */ - function ObjectWrapper(source) { - this.source = source; - } - - ObjectWrapper.prototype = new ObjectLikeSequence(); - - ObjectWrapper.prototype.root = function root() { - return this; - }; - - ObjectWrapper.prototype.isAsync = function isAsync() { - return false; - }; - - ObjectWrapper.prototype.get = function get(key) { - return this.source[key]; - }; - - ObjectWrapper.prototype.each = function each(fn) { - var source = this.source, - key; - - for (key in source) { - if (fn(source[key], key) === false) { - return false; - } - } - - return true; - }; - - /** - * A `StringLikeSequence` represents a sequence of characters. - * - * The initial sequence you get by wrapping a string with `Lazy(string)` is a - * `StringLikeSequence`. - * - * All methods of `StringLikeSequence` that conceptually should return - * something like a string return another `StringLikeSequence`. - * - * @public - * @constructor - * - * @examples - * function upcase(str) { return str.toUpperCase(); } - * - * Lazy('foo') // instanceof Lazy.StringLikeSequence - * Lazy('foo').toUpperCase() // instanceof Lazy.StringLikeSequence - * Lazy('foo').reverse() // instanceof Lazy.StringLikeSequence - * Lazy('foo').take(2) // instanceof Lazy.StringLikeSequence - * Lazy('foo').drop(1) // instanceof Lazy.StringLikeSequence - * Lazy('foo').substring(1) // instanceof Lazy.StringLikeSequence - * - * // Note that `map` does not create a `StringLikeSequence` because there's - * // no guarantee the mapping function will return characters. In the event - * // you do want to map a string onto a string-like sequence, use - * // `mapString`: - * Lazy('foo').map(Lazy.identity) // instanceof Lazy.ArrayLikeSequence - * Lazy('foo').mapString(Lazy.identity) // instanceof Lazy.StringLikeSequence - */ - function StringLikeSequence() {} - - StringLikeSequence.prototype = new ArrayLikeSequence(); - - /** - * Create a new constructor function for a type inheriting from - * `StringLikeSequence`. - * - * @public - * @param {string|Array.} methodName The name(s) of the method(s) to be - * used for constructing the new sequence. The method will be attached to - * the `StringLikeSequence` prototype so that it can be chained with any other - * methods that return string-like sequences. - * @param {Object} overrides An object containing function overrides for this - * new sequence type. Has the same requirements as - * {@link ArrayLikeSequence.define}. - * @returns {Function} A constructor for a new type inheriting from - * `StringLikeSequence`. - * - * @examples - * Lazy.StringLikeSequence.define("zomg", { - * length: function() { - * return this.parent.length() + "!!ZOMG!!!1".length; - * }, - * - * get: function(i) { - * if (i < this.parent.length()) { - * return this.parent.get(i); - * } - * return "!!ZOMG!!!1".charAt(i - this.parent.length()); - * } - * }); - * - * Lazy('foo').zomg() // sequence: "foo!!ZOMG!!!1" - */ - StringLikeSequence.define = function define(methodName, overrides) { - if (!overrides || typeof overrides.get !== 'function') { - throw new Error("A custom string-like sequence must implement *at least* get!"); - } - - return defineSequenceType(StringLikeSequence, methodName, overrides); - }; - - StringLikeSequence.prototype.value = function value() { - return this.toString(); - }; - - /** - * Returns an {@link IndexedIterator} that will step over each character in this - * sequence one by one. - * - * @returns {IndexedIterator} The iterator. - */ - StringLikeSequence.prototype.getIterator = function getIterator() { - return new CharIterator(this); - }; - - /** - * @constructor - */ - function CharIterator(source) { - this.source = Lazy(source); - this.index = -1; - } - - CharIterator.prototype.current = function current() { - return this.source.charAt(this.index); - }; - - CharIterator.prototype.moveNext = function moveNext() { - return (++this.index < this.source.length()); - }; - - /** - * Returns the character at the given index of this sequence, or the empty - * string if the specified index lies outside the bounds of the sequence. - * - * @public - * @param {number} i The index of this sequence. - * @returns {string} The character at the specified index. - * - * @examples - * Lazy("foo").charAt(0) // => "f" - * Lazy("foo").charAt(-1) // => "" - * Lazy("foo").charAt(10) // => "" - */ - StringLikeSequence.prototype.charAt = function charAt(i) { - return this.get(i); - }; - - /** - * Returns the character code at the given index of this sequence, or `NaN` if - * the index lies outside the bounds of the sequence. - * - * @public - * @param {number} i The index of the character whose character code you want. - * @returns {number} The character code. - * - * @examples - * Lazy("abc").charCodeAt(0) // => 97 - * Lazy("abc").charCodeAt(-1) // => NaN - * Lazy("abc").charCodeAt(10) // => NaN - */ - StringLikeSequence.prototype.charCodeAt = function charCodeAt(i) { - var char = this.charAt(i); - if (!char) { return NaN; } - - return char.charCodeAt(0); - }; - - /** - * Returns a {@link StringLikeSequence} comprising the characters from *this* - * sequence starting at `start` and ending at `stop` (exclusive), or---if - * `stop` is `undefined`, including the rest of the sequence. - * - * @public - * @param {number} start The index where this sequence should begin. - * @param {number=} stop The index (exclusive) where this sequence should end. - * @returns {StringLikeSequence} The new sequence. - * - * @examples - * Lazy("foo").substring(1) // sequence: "oo" - * Lazy("foo").substring(-1) // sequence: "foo" - * Lazy("hello").substring(1, 3) // sequence: "el" - * Lazy("hello").substring(1, 9) // sequence: "ello" - */ - StringLikeSequence.prototype.substring = function substring(start, stop) { - return new StringSegment(this, start, stop); - }; - - /** - * @constructor - */ - function StringSegment(parent, start, stop) { - this.parent = parent; - this.start = Math.max(0, start); - this.stop = stop; - } - - StringSegment.prototype = new StringLikeSequence(); - - StringSegment.prototype.get = function get(i) { - return this.parent.get(i + this.start); - }; - - StringSegment.prototype.length = function length() { - return (typeof this.stop === "number" ? this.stop : this.parent.length()) - this.start; - }; - - /** - * An optimized version of {@link Sequence#first} that returns another - * {@link StringLikeSequence} (or just the first character, if `count` is - * undefined). - * - * @public - * @examples - * Lazy('foo').first() // => 'f' - * Lazy('fo').first(2) // sequence: 'fo' - * Lazy('foo').first(10) // sequence: 'foo' - * Lazy('foo').toUpperCase().first() // => 'F' - * Lazy('foo').toUpperCase().first(2) // sequence: 'FO' - */ - StringLikeSequence.prototype.first = function first(count) { - if (typeof count === "undefined") { - return this.charAt(0); - } - - return this.substring(0, count); - }; - - /** - * An optimized version of {@link Sequence#last} that returns another - * {@link StringLikeSequence} (or just the last character, if `count` is - * undefined). - * - * @public - * @examples - * Lazy('foo').last() // => 'o' - * Lazy('foo').last(2) // sequence: 'oo' - * Lazy('foo').last(10) // sequence: 'foo' - * Lazy('foo').toUpperCase().last() // => 'O' - * Lazy('foo').toUpperCase().last(2) // sequence: 'OO' - */ - StringLikeSequence.prototype.last = function last(count) { - if (typeof count === "undefined") { - return this.charAt(this.length() - 1); - } - - return this.substring(this.length() - count); - }; - - StringLikeSequence.prototype.drop = function drop(count) { - return this.substring(count); - }; - - /** - * Finds the index of the first occurrence of the given substring within this - * sequence, starting from the specified index (or the beginning of the - * sequence). - * - * @public - * @param {string} substring The substring to search for. - * @param {number=} startIndex The index from which to start the search. - * @returns {number} The first index where the given substring is found, or - * -1 if it isn't in the sequence. - * - * @examples - * Lazy('canal').indexOf('a') // => 1 - * Lazy('canal').indexOf('a', 2) // => 3 - * Lazy('canal').indexOf('ana') // => 1 - * Lazy('canal').indexOf('andy') // => -1 - * Lazy('canal').indexOf('x') // => -1 - */ - StringLikeSequence.prototype.indexOf = function indexOf(substring, startIndex) { - return this.toString().indexOf(substring, startIndex); - }; - - /** - * Finds the index of the last occurrence of the given substring within this - * sequence, starting from the specified index (or the end of the sequence) - * and working backwards. - * - * @public - * @param {string} substring The substring to search for. - * @param {number=} startIndex The index from which to start the search. - * @returns {number} The last index where the given substring is found, or - * -1 if it isn't in the sequence. - * - * @examples - * Lazy('canal').lastIndexOf('a') // => 3 - * Lazy('canal').lastIndexOf('a', 2) // => 1 - * Lazy('canal').lastIndexOf('ana') // => 1 - * Lazy('canal').lastIndexOf('andy') // => -1 - * Lazy('canal').lastIndexOf('x') // => -1 - */ - StringLikeSequence.prototype.lastIndexOf = function lastIndexOf(substring, startIndex) { - return this.toString().lastIndexOf(substring, startIndex); - }; - - /** - * Checks if this sequence contains a given substring. - * - * @public - * @param {string} substring The substring to check for. - * @returns {boolean} Whether or not this sequence contains `substring`. - * - * @examples - * Lazy('hello').contains('ell') // => true - * Lazy('hello').contains('') // => true - * Lazy('hello').contains('abc') // => false - */ - StringLikeSequence.prototype.contains = function contains(substring) { - return this.indexOf(substring) !== -1; - }; - - /** - * Checks if this sequence ends with a given suffix. - * - * @public - * @param {string} suffix The suffix to check for. - * @returns {boolean} Whether or not this sequence ends with `suffix`. - * - * @examples - * Lazy('foo').endsWith('oo') // => true - * Lazy('foo').endsWith('') // => true - * Lazy('foo').endsWith('abc') // => false - */ - StringLikeSequence.prototype.endsWith = function endsWith(suffix) { - return this.substring(this.length() - suffix.length).toString() === suffix; - }; - - /** - * Checks if this sequence starts with a given prefix. - * - * @public - * @param {string} prefix The prefix to check for. - * @returns {boolean} Whether or not this sequence starts with `prefix`. - * - * @examples - * Lazy('foo').startsWith('fo') // => true - * Lazy('foo').startsWith('') // => true - * Lazy('foo').startsWith('abc') // => false - */ - StringLikeSequence.prototype.startsWith = function startsWith(prefix) { - return this.substring(0, prefix.length).toString() === prefix; - }; - - /** - * Converts all of the characters in this string to uppercase. - * - * @public - * @returns {StringLikeSequence} A new sequence with the same characters as - * this sequence, all uppercase. - * - * @examples - * function nextLetter(a) { - * return String.fromCharCode(a.charCodeAt(0) + 1); - * } - * - * Lazy('foo').toUpperCase() // sequence: 'FOO' - * Lazy('foo').substring(1).toUpperCase() // sequence: 'OO' - * Lazy('abc').mapString(nextLetter).toUpperCase() // sequence: 'BCD' - */ - StringLikeSequence.prototype.toUpperCase = function toUpperCase() { - return this.mapString(function(char) { return char.toUpperCase(); }); - }; - - /** - * Converts all of the characters in this string to lowercase. - * - * @public - * @returns {StringLikeSequence} A new sequence with the same characters as - * this sequence, all lowercase. - * - * @examples - * function nextLetter(a) { - * return String.fromCharCode(a.charCodeAt(0) + 1); - * } - * - * Lazy('FOO').toLowerCase() // sequence: 'foo' - * Lazy('FOO').substring(1).toLowerCase() // sequence: 'oo' - * Lazy('ABC').mapString(nextLetter).toLowerCase() // sequence: 'bcd' - */ - StringLikeSequence.prototype.toLowerCase = function toLowerCase() { - return this.mapString(function(char) { return char.toLowerCase(); }); - }; - - /** - * Maps the characters of this sequence onto a new {@link StringLikeSequence}. - * - * @public - * @param {Function} mapFn The function used to map characters from this - * sequence onto the new sequence. - * @returns {StringLikeSequence} The new sequence. - * - * @examples - * function upcase(char) { return char.toUpperCase(); } - * - * Lazy("foo").mapString(upcase) // sequence: "FOO" - * Lazy("foo").mapString(upcase).charAt(0) // => "F" - * Lazy("foo").mapString(upcase).charCodeAt(0) // => 70 - * Lazy("foo").mapString(upcase).substring(1) // sequence: "OO" - */ - StringLikeSequence.prototype.mapString = function mapString(mapFn) { - return new MappedStringLikeSequence(this, mapFn); - }; - - /** - * @constructor - */ - function MappedStringLikeSequence(parent, mapFn) { - this.parent = parent; - this.mapFn = mapFn; - } - - MappedStringLikeSequence.prototype = new StringLikeSequence(); - MappedStringLikeSequence.prototype.get = IndexedMappedSequence.prototype.get; - MappedStringLikeSequence.prototype.length = IndexedMappedSequence.prototype.length; - - /** - * Returns a copy of this sequence that reads back to front. - * - * @public - * - * @examples - * Lazy("abcdefg").reverse() // sequence: "gfedcba" - */ - StringLikeSequence.prototype.reverse = function reverse() { - return new ReversedStringLikeSequence(this); - }; - - /** - * @constructor - */ - function ReversedStringLikeSequence(parent) { - this.parent = parent; - } - - ReversedStringLikeSequence.prototype = new StringLikeSequence(); - ReversedStringLikeSequence.prototype.get = IndexedReversedSequence.prototype.get; - ReversedStringLikeSequence.prototype.length = IndexedReversedSequence.prototype.length; - - StringLikeSequence.prototype.toString = function toString() { - return this.join(""); - }; - - /** - * Creates a {@link Sequence} comprising all of the matches for the specified - * pattern in the underlying string. - * - * @public - * @param {RegExp} pattern The pattern to match. - * @returns {Sequence} A sequence of all the matches. - * - * @examples - * Lazy("abracadabra").match(/a[bcd]/) // sequence: ["ab", "ac", "ad", "ab"] - * Lazy("fee fi fo fum").match(/\w+/) // sequence: ["fee", "fi", "fo", "fum"] - * Lazy("hello").match(/xyz/) // sequence: [] - */ - StringLikeSequence.prototype.match = function match(pattern) { - return new StringMatchSequence(this, pattern); - }; - - /** - * @constructor - */ - function StringMatchSequence(parent, pattern) { - this.parent = parent; - this.pattern = pattern; - } - - StringMatchSequence.prototype = new Sequence(); - - StringMatchSequence.prototype.getIterator = function getIterator() { - return new StringMatchIterator(this.parent.toString(), this.pattern); - }; - - /** - * @constructor - */ - function StringMatchIterator(source, pattern) { - this.source = source; - this.pattern = cloneRegex(pattern); - } - - StringMatchIterator.prototype.current = function current() { - return this.match[0]; - }; - - StringMatchIterator.prototype.moveNext = function moveNext() { - return !!(this.match = this.pattern.exec(this.source)); - }; - - /** - * Creates a {@link Sequence} comprising all of the substrings of this string - * separated by the given delimiter, which can be either a string or a regular - * expression. - * - * @public - * @param {string|RegExp} delimiter The delimiter to use for recognizing - * substrings. - * @returns {Sequence} A sequence of all the substrings separated by the given - * delimiter. - * - * @examples - * Lazy("foo").split("") // sequence: ["f", "o", "o"] - * Lazy("yo dawg").split(" ") // sequence: ["yo", "dawg"] - * Lazy("bah bah\tblack sheep").split(/\s+/) // sequence: ["bah", "bah", "black", "sheep"] - */ - StringLikeSequence.prototype.split = function split(delimiter) { - return new SplitStringSequence(this, delimiter); - }; - - /** - * @constructor - */ - function SplitStringSequence(parent, pattern) { - this.parent = parent; - this.pattern = pattern; - } - - SplitStringSequence.prototype = new Sequence(); - - SplitStringSequence.prototype.getIterator = function getIterator() { - var source = this.parent.toString(); - - if (this.pattern instanceof RegExp) { - if (this.pattern.source === "" || this.pattern.source === "(?:)") { - return new CharIterator(source); - } else { - return new SplitWithRegExpIterator(source, this.pattern); - } - } else if (this.pattern === "") { - return new CharIterator(source); - } else { - return new SplitWithStringIterator(source, this.pattern); - } - }; - - /** - * @constructor - */ - function SplitWithRegExpIterator(source, pattern) { - this.source = source; - this.pattern = cloneRegex(pattern); - } - - SplitWithRegExpIterator.prototype.current = function current() { - return this.source.substring(this.start, this.end); - }; - - SplitWithRegExpIterator.prototype.moveNext = function moveNext() { - if (!this.pattern) { - return false; - } - - var match = this.pattern.exec(this.source); - - if (match) { - this.start = this.nextStart ? this.nextStart : 0; - this.end = match.index; - this.nextStart = match.index + match[0].length; - return true; - - } else if (this.pattern) { - this.start = this.nextStart; - this.end = undefined; - this.nextStart = undefined; - this.pattern = undefined; - return true; - } - - return false; - }; - - /** - * @constructor - */ - function SplitWithStringIterator(source, delimiter) { - this.source = source; - this.delimiter = delimiter; - } - - SplitWithStringIterator.prototype.current = function current() { - return this.source.substring(this.leftIndex, this.rightIndex); - }; - - SplitWithStringIterator.prototype.moveNext = function moveNext() { - if (!this.finished) { - this.leftIndex = typeof this.leftIndex !== "undefined" ? - this.rightIndex + this.delimiter.length : - 0; - this.rightIndex = this.source.indexOf(this.delimiter, this.leftIndex); - } - - if (this.rightIndex === -1) { - this.finished = true; - this.rightIndex = undefined; - return true; - } - - return !this.finished; - }; - - /** - * Wraps a string exposing {@link #match} and {@link #split} methods that return - * {@link Sequence} objects instead of arrays, improving on the efficiency of - * JavaScript's built-in `String#split` and `String.match` methods and - * supporting asynchronous iteration. - * - * @param {string} source The string to wrap. - * @constructor - */ - function StringWrapper(source) { - this.source = source; - } - - StringWrapper.prototype = new StringLikeSequence(); - - StringWrapper.prototype.root = function root() { - return this; - }; - - StringWrapper.prototype.isAsync = function isAsync() { - return false; - }; - - StringWrapper.prototype.get = function get(i) { - return this.source.charAt(i); - }; - - StringWrapper.prototype.length = function length() { - return this.source.length; - }; - - StringWrapper.prototype.toString = function toString() { - return this.source; - }; - - /** - * A `GeneratedSequence` does not wrap an in-memory colllection but rather - * determines its elements on-the-fly during iteration according to a generator - * function. - * - * You create a `GeneratedSequence` by calling {@link Lazy.generate}. - * - * @public - * @constructor - * @param {function(number):*} generatorFn A function which accepts an index - * and returns a value for the element at that position in the sequence. - * @param {number=} length The length of the sequence. If this argument is - * omitted, the sequence will go on forever. - */ - function GeneratedSequence(generatorFn, length) { - this.get = generatorFn; - this.fixedLength = length; - } - - GeneratedSequence.prototype = new Sequence(); - - GeneratedSequence.prototype.isAsync = function isAsync() { - return false; - }; - - /** - * Returns the length of this sequence. - * - * @public - * @returns {number} The length, or `undefined` if this is an indefinite - * sequence. - */ - GeneratedSequence.prototype.length = function length() { - return this.fixedLength; - }; - - /** - * Iterates over the sequence produced by invoking this sequence's generator - * function up to its specified length, or, if length is `undefined`, - * indefinitely (in which case the sequence will go on forever--you would need - * to call, e.g., {@link Sequence#take} to limit iteration). - * - * @public - * @param {Function} fn The function to call on each output from the generator - * function. - */ - GeneratedSequence.prototype.each = function each(fn) { - var generatorFn = this.get, - length = this.fixedLength, - i = 0; - - while (typeof length === "undefined" || i < length) { - if (fn(generatorFn(i), i++) === false) { - return false; - } - } - - return true; - }; - - GeneratedSequence.prototype.getIterator = function getIterator() { - return new GeneratedIterator(this); - }; - - /** - * Iterates over a generated sequence. (This allows generated sequences to be - * iterated asynchronously.) - * - * @param {GeneratedSequence} sequence The generated sequence to iterate over. - * @constructor - */ - function GeneratedIterator(sequence) { - this.sequence = sequence; - this.index = 0; - this.currentValue = null; - } - - GeneratedIterator.prototype.current = function current() { - return this.currentValue; - }; - - GeneratedIterator.prototype.moveNext = function moveNext() { - var sequence = this.sequence; - - if (typeof sequence.fixedLength === "number" && this.index >= sequence.fixedLength) { - return false; - } - - this.currentValue = sequence.get(this.index++); - return true; - }; - - /** - * An `AsyncSequence` iterates over its elements asynchronously when - * {@link #each} is called. - * - * You get an `AsyncSequence` by calling {@link Sequence#async} on any - * sequence. Note that some sequence types may not support asynchronous - * iteration. - * - * Returning values - * ---------------- - * - * Because of its asynchronous nature, an `AsyncSequence` cannot be used in the - * same way as other sequences for functions that return values directly (e.g., - * `reduce`, `max`, `any`, even `toArray`). - * - * Instead, these methods return an `AsyncHandle` whose `onComplete` method - * accepts a callback that will be called with the final result once iteration - * has finished. - * - * Defining custom asynchronous sequences - * -------------------------------------- - * - * There are plenty of ways to define an asynchronous sequence. Here's one. - * - * 1. First, implement an {@link Iterator}. This is an object whose prototype - * has the methods {@link Iterator#moveNext} (which returns a `boolean`) and - * {@link current} (which returns the current value). - * 2. Next, create a simple wrapper that inherits from `AsyncSequence`, whose - * `getIterator` function returns an instance of the iterator type you just - * defined. - * - * The default implementation for {@link #each} on an `AsyncSequence` is to - * create an iterator and then asynchronously call {@link Iterator#moveNext} - * (using `setImmediate`, if available, otherwise `setTimeout`) until the iterator - * can't move ahead any more. - * - * @public - * @constructor - * @param {Sequence} parent A {@link Sequence} to wrap, to expose asynchronous - * iteration. - * @param {number=} interval How many milliseconds should elapse between each - * element when iterating over this sequence. If this argument is omitted, - * asynchronous iteration will be executed as fast as possible. - */ - function AsyncSequence(parent, interval) { - if (parent instanceof AsyncSequence) { - throw new Error("Sequence is already asynchronous!"); - } - - this.parent = parent; - this.interval = interval; - this.onNextCallback = getOnNextCallback(interval); - this.cancelCallback = getCancelCallback(interval); - } - - AsyncSequence.prototype = new Sequence(); - - AsyncSequence.prototype.isAsync = function isAsync() { - return true; - }; - - /** - * Throws an exception. You cannot manually iterate over an asynchronous - * sequence. - * - * @public - * @example - * Lazy([1, 2, 3]).async().getIterator() // throws - */ - AsyncSequence.prototype.getIterator = function getIterator() { - throw new Error('An AsyncSequence does not support synchronous iteration.'); - }; - - /** - * An asynchronous version of {@link Sequence#each}. - * - * @public - * @param {Function} fn The function to invoke asynchronously on each element in - * the sequence one by one. - * @returns {AsyncHandle} An {@link AsyncHandle} providing the ability to - * cancel the asynchronous iteration (by calling `cancel()`) as well as - * supply callback(s) for when an error is encountered (`onError`) or when - * iteration is complete (`onComplete`). - */ - AsyncSequence.prototype.each = function each(fn) { - var iterator = this.parent.getIterator(), - onNextCallback = this.onNextCallback, - cancelCallback = this.cancelCallback, - i = 0; - - var handle = new AsyncHandle(function cancel() { - if (cancellationId) { - cancelCallback(cancellationId); - } - }); - - var cancellationId = onNextCallback(function iterate() { - cancellationId = null; - - try { - if (iterator.moveNext() && fn(iterator.current(), i++) !== false) { - cancellationId = onNextCallback(iterate); - - } else { - handle._resolve(); - } - - } catch (e) { - handle._reject(e); - } - }); - - return handle; - }; - - /** - * An `AsyncHandle` provides a [Promises/A+](http://promises-aplus.github.io/promises-spec/) - * compliant interface for an {@link AsyncSequence} that is currently (or was) - * iterating over its elements. - * - * In addition to behaving as a promise, an `AsyncHandle` provides the ability - * to {@link AsyncHandle#cancel} iteration (if `cancelFn` is provided) - * and also offers convenient {@link AsyncHandle#onComplete} and - * {@link AsyncHandle#onError} methods to attach listeners for when iteration - * is complete or an error is thrown during iteration. - * - * @public - * @param {Function} cancelFn A function to cancel asynchronous iteration. - * This is passed in to support different cancellation mechanisms for - * different forms of asynchronous sequences (e.g., timeout-based - * sequences, sequences based on I/O, etc.). - * @constructor - * - * @example - * // Create a sequence of 100,000 random numbers, in chunks of 100. - * var sequence = Lazy.generate(Math.random) - * .chunk(100) - * .async() - * .take(1000); - * - * // Reduce-style operations -- i.e., operations that return a *value* (as - * // opposed to a *sequence*) -- return an AsyncHandle for async sequences. - * var handle = sequence.toArray(); - * - * handle.onComplete(function(array) { - * // Do something w/ 1,000-element array. - * }); - * - * // Since an AsyncHandle is a promise, you can also use it to create - * // subsequent promises using `then` (see the Promises/A+ spec for more - * // info). - * var flattened = handle.then(function(array) { - * return Lazy(array).flatten(); - * }); - */ - function AsyncHandle(cancelFn) { - this.resolveListeners = []; - this.rejectListeners = []; - this.state = PENDING; - this.cancelFn = cancelFn; - } - - // Async handle states - var PENDING = 1, - RESOLVED = 2, - REJECTED = 3; - - AsyncHandle.prototype.then = function then(onFulfilled, onRejected) { - var promise = new AsyncHandle(this.cancelFn); - - this.resolveListeners.push(function(value) { - try { - if (typeof onFulfilled !== 'function') { - resolve(promise, value); - return; - } - - resolve(promise, onFulfilled(value)); - - } catch (e) { - promise._reject(e); - } - }); - - this.rejectListeners.push(function(reason) { - try { - if (typeof onRejected !== 'function') { - promise._reject(reason); - return; - } - - resolve(promise, onRejected(reason)); - - } catch (e) { - promise._reject(e); - } - }); - - if (this.state === RESOLVED) { - this._resolve(this.value); - } - - if (this.state === REJECTED) { - this._reject(this.reason); - } - - return promise; - }; - - AsyncHandle.prototype._resolve = function _resolve(value) { - if (this.state === REJECTED) { - return; - } - - if (this.state === PENDING) { - this.state = RESOLVED; - this.value = value; - } - - consumeListeners(this.resolveListeners, this.value); - }; - - AsyncHandle.prototype._reject = function _reject(reason) { - if (this.state === RESOLVED) { - return; - } - - if (this.state === PENDING) { - this.state = REJECTED; - this.reason = reason; - } - - consumeListeners(this.rejectListeners, this.reason); - }; - - /** - * Cancels asynchronous iteration. - * - * @public - */ - AsyncHandle.prototype.cancel = function cancel() { - if (this.cancelFn) { - this.cancelFn(); - this.cancelFn = null; - this._resolve(false); - } - }; - - /** - * Updates the handle with a callback to execute when iteration is completed. - * - * @public - * @param {Function} callback The function to call when the asynchronous - * iteration is completed. - * @return {AsyncHandle} A reference to the handle (for chaining). - */ - AsyncHandle.prototype.onComplete = function onComplete(callback) { - this.resolveListeners.push(callback); - return this; - }; - - /** - * Updates the handle with a callback to execute if/when any error is - * encountered during asynchronous iteration. - * - * @public - * @param {Function} callback The function to call, with any associated error - * object, when an error occurs. - * @return {AsyncHandle} A reference to the handle (for chaining). - */ - AsyncHandle.prototype.onError = function onError(callback) { - this.rejectListeners.push(callback); - return this; - }; - - /** - * Promise resolution procedure: - * http://promises-aplus.github.io/promises-spec/#the_promise_resolution_procedure - */ - function resolve(promise, x) { - if (promise === x) { - promise._reject(new TypeError('Cannot resolve a promise to itself')); - return; - } - - if (x instanceof AsyncHandle) { - x.then( - function(value) { resolve(promise, value); }, - function(reason) { promise._reject(reason); } - ); - return; - } - - var then; - try { - then = (/function|object/).test(typeof x) && x != null && x.then; - } catch (e) { - promise._reject(e); - return; - } - - var thenableState = PENDING; - if (typeof then === 'function') { - try { - then.call( - x, - function resolvePromise(value) { - if (thenableState !== PENDING) { - return; - } - thenableState = RESOLVED; - resolve(promise, value); - }, - function rejectPromise(reason) { - if (thenableState !== PENDING) { - return; - } - thenableState = REJECTED; - promise._reject(reason); - } - ); - } catch (e) { - if (thenableState !== PENDING) { - return; - } - - promise._reject(e); - } - - return; - } - - promise._resolve(x); - } - - function consumeListeners(listeners, value, callback) { - callback || (callback = getOnNextCallback()); - - callback(function() { - if (listeners.length > 0) { - listeners.shift()(value); - consumeListeners(listeners, value, callback); - } - }); - } - - function getOnNextCallback(interval) { - if (typeof interval === "undefined") { - if (typeof setImmediate === "function") { - return setImmediate; - } - } - - interval = interval || 0; - return function(fn) { - return setTimeout(fn, interval); - }; - } - - function getCancelCallback(interval) { - if (typeof interval === "undefined") { - if (typeof clearImmediate === "function") { - return clearImmediate; - } - } - - return clearTimeout; - } - - /** - * Transform a value, whether the value is retrieved asynchronously or directly. - * - * @private - * @param {Function} fn The function that transforms the value. - * @param {*} value The value to be transformed. This can be an {@link AsyncHandle} when the value - * is retrieved asynchronously, otherwise it can be anything. - * @returns {*} An {@link AsyncHandle} when `value` is also an {@link AsyncHandle}, otherwise - * whatever `fn` resulted in. - */ - function transform(fn, value) { - if (value instanceof AsyncHandle) { - return value.then(function() { fn(value); }); - } - return fn(value); - } - - /** - * An async version of {@link Sequence#reverse}. - */ - AsyncSequence.prototype.reverse = function reverse() { - return this.parent.reverse().async(); - }; - - /** - * A version of {@link Sequence#find} which returns an {@link AsyncHandle}. - * - * @public - * @param {Function} predicate A function to call on (potentially) every element - * in the sequence. - * @returns {AsyncHandle} An {@link AsyncHandle} (promise) which resolves to - * the found element, once it is detected, or else `undefined`. - */ - AsyncSequence.prototype.find = function find(predicate) { - var found; - - var handle = this.each(function(e, i) { - if (predicate(e, i)) { - found = e; - return false; - } - }); - - return handle.then(function() { return found; }); - }; - - /** - * A version of {@link Sequence#indexOf} which returns an {@link AsyncHandle}. - * - * @public - * @param {*} value The element to search for in the sequence. - * @returns {AsyncHandle} An {@link AsyncHandle} (promise) which resolves to - * the found index, once it is detected, or -1. - */ - AsyncSequence.prototype.indexOf = function indexOf(value) { - var foundIndex = -1; - - var handle = this.each(function(e, i) { - if (e === value) { - foundIndex = i; - return false; - } - }); - - return handle.then(function() { - return foundIndex; - }); - }; - - /** - * A version of {@link Sequence#contains} which returns an {@link AsyncHandle}. - * - * @public - * @param {*} value The element to search for in the sequence. - * @returns {AsyncHandle} An {@link AsyncHandle} (promise) which resolves to - * either `true` or `false` to indicate whether the element was found. - */ - AsyncSequence.prototype.contains = function contains(value) { - var found = false; - - var handle = this.each(function(e) { - if (e === value) { - found = true; - return false; - } - }); - - return handle.then(function() { - return found; - }); - }; - - /** - * Just return the same sequence for `AsyncSequence#async` (I see no harm in this). - */ - AsyncSequence.prototype.async = function async() { - return this; - }; - - /** - * See {@link ObjectLikeSequence#watch} for docs. - */ - ObjectWrapper.prototype.watch = function watch(propertyNames) { - return new WatchedPropertySequence(this.source, propertyNames); - }; - - function WatchedPropertySequence(object, propertyNames) { - this.listeners = []; - - if (!propertyNames) { - propertyNames = Lazy(object).keys().toArray(); - } else if (!(propertyNames instanceof Array)) { - propertyNames = [propertyNames]; - } - - var listeners = this.listeners, - index = 0; - - Lazy(propertyNames).each(function(propertyName) { - var propertyValue = object[propertyName]; - - Object.defineProperty(object, propertyName, { - get: function() { - return propertyValue; - }, - - set: function(value) { - for (var i = listeners.length - 1; i >= 0; --i) { - if (listeners[i]({ property: propertyName, value: value }, index) === false) { - listeners.splice(i, 1); - } - } - propertyValue = value; - ++index; - } - }); - }); - } - - WatchedPropertySequence.prototype = new AsyncSequence(); - - WatchedPropertySequence.prototype.each = function each(fn) { - this.listeners.push(fn); - }; - - /** - * A StreamLikeSequence comprises a sequence of 'chunks' of data, which are - * typically multiline strings. - * - * @constructor - */ - function StreamLikeSequence() {} - - StreamLikeSequence.prototype = new AsyncSequence(); - - StreamLikeSequence.prototype.isAsync = function isAsync() { - return true; - }; - - StreamLikeSequence.prototype.split = function split(delimiter) { - return new SplitStreamSequence(this, delimiter); - }; - - /** - * @constructor - */ - function SplitStreamSequence(parent, delimiter) { - this.parent = parent; - this.delimiter = delimiter; - this.each = this.getEachForDelimiter(delimiter); - } - - SplitStreamSequence.prototype = new Sequence(); - - SplitStreamSequence.prototype.getEachForDelimiter = function getEachForDelimiter(delimiter) { - if (delimiter instanceof RegExp) { - return this.regexEach; - } - - return this.stringEach; - }; - - SplitStreamSequence.prototype.regexEach = function each(fn) { - var delimiter = cloneRegex(this.delimiter), - buffer = '', - start = 0, end, - index = 0; - - var handle = this.parent.each(function(chunk) { - buffer += chunk; - - var match; - while (match = delimiter.exec(buffer)) { - end = match.index; - if (fn(buffer.substring(start, end), index++) === false) { - return false; - } - start = end + match[0].length; - } - - buffer = buffer.substring(start); - start = 0; - }); - - handle.onComplete(function() { - if (buffer.length > 0) { - fn(buffer, index++); - } - }); - - return handle; - }; - - SplitStreamSequence.prototype.stringEach = function each(fn) { - var delimiter = this.delimiter, - pieceIndex = 0, - buffer = '', - bufferIndex = 0; - - var handle = this.parent.each(function(chunk) { - buffer += chunk; - var delimiterIndex; - while ((delimiterIndex = buffer.indexOf(delimiter)) >= 0) { - var piece = buffer.substr(0,delimiterIndex); - buffer = buffer.substr(delimiterIndex+delimiter.length); - if (fn(piece,pieceIndex++) === false) { - return false; - } - } - return true; - }); - - handle.onComplete(function() { - fn(buffer, pieceIndex++); - }); - - return handle; - }; - - StreamLikeSequence.prototype.lines = function lines() { - return this.split("\n"); - }; - - StreamLikeSequence.prototype.match = function match(pattern) { - return new MatchedStreamSequence(this, pattern); - }; - - /** - * @constructor - */ - function MatchedStreamSequence(parent, pattern) { - this.parent = parent; - this.pattern = cloneRegex(pattern); - } - - MatchedStreamSequence.prototype = new AsyncSequence(); - - MatchedStreamSequence.prototype.each = function each(fn) { - var pattern = this.pattern, - done = false, - i = 0; - - return this.parent.each(function(chunk) { - Lazy(chunk).match(pattern).each(function(match) { - if (fn(match, i++) === false) { - done = true; - return false; - } - }); - - return !done; - }); - }; - - /** - * Defines a wrapper for custom {@link StreamLikeSequence}s. This is useful - * if you want a way to handle a stream of events as a sequence, but you can't - * use Lazy's existing interface (i.e., you're wrapping an object from a - * library with its own custom events). - * - * This method defines a *factory*: that is, it produces a function that can - * be used to wrap objects and return a {@link Sequence}. Hopefully the - * example will make this clear. - * - * @public - * @param {Function} initializer An initialization function called on objects - * created by this factory. `this` will be bound to the created object, - * which is an instance of {@link StreamLikeSequence}. Use `emit` to - * generate data for the sequence. - * @returns {Function} A function that creates a new {@link StreamLikeSequence}, - * initializes it using the specified function, and returns it. - * - * @example - * var factory = Lazy.createWrapper(function(eventSource) { - * var sequence = this; - * - * eventSource.handleEvent(function(data) { - * sequence.emit(data); - * }); - * }); - * - * var eventEmitter = { - * triggerEvent: function(data) { - * eventEmitter.eventHandler(data); - * }, - * handleEvent: function(handler) { - * eventEmitter.eventHandler = handler; - * }, - * eventHandler: function() {} - * }; - * - * var events = []; - * - * factory(eventEmitter).each(function(e) { - * events.push(e); - * }); - * - * eventEmitter.triggerEvent('foo'); - * eventEmitter.triggerEvent('bar'); - * - * events // => ['foo', 'bar'] - */ - Lazy.createWrapper = function createWrapper(initializer) { - var ctor = function() { - this.listeners = []; - }; - - ctor.prototype = new StreamLikeSequence(); - - ctor.prototype.each = function(listener) { - this.listeners.push(listener); - }; - - ctor.prototype.emit = function(data) { - var listeners = this.listeners; - - for (var len = listeners.length, i = len - 1; i >= 0; --i) { - if (listeners[i](data) === false) { - listeners.splice(i, 1); - } - } - }; - - return function() { - var sequence = new ctor(); - initializer.apply(sequence, arguments); - return sequence; - }; - }; - - /** - * Creates a {@link GeneratedSequence} using the specified generator function - * and (optionally) length. - * - * @public - * @param {function(number):*} generatorFn The function used to generate the - * sequence. This function accepts an index as a parameter and should return - * a value for that index in the resulting sequence. - * @param {number=} length The length of the sequence, for sequences with a - * definite length. - * @returns {GeneratedSequence} The generated sequence. - * - * @examples - * var randomNumbers = Lazy.generate(Math.random); - * var countingNumbers = Lazy.generate(function(i) { return i + 1; }, 5); - * - * randomNumbers // instanceof Lazy.GeneratedSequence - * randomNumbers.length() // => undefined - * countingNumbers // sequence: [1, 2, 3, 4, 5] - * countingNumbers.length() // => 5 - */ - Lazy.generate = function generate(generatorFn, length) { - return new GeneratedSequence(generatorFn, length); - }; - - /** - * Creates a sequence from a given starting value, up to a specified stopping - * value, incrementing by a given step. Invalid values for any of these - * arguments (e.g., a step of 0) result in an empty sequence. - * - * @public - * @returns {GeneratedSequence} The sequence defined by the given ranges. - * - * @examples - * Lazy.range(3) // sequence: [0, 1, 2] - * Lazy.range(1, 4) // sequence: [1, 2, 3] - * Lazy.range(2, 10, 2) // sequence: [2, 4, 6, 8] - * Lazy.range(5, 1, 2) // sequence: [] - * Lazy.range(5, 15, -2) // sequence: [] - * Lazy.range(3, 10, 3) // sequence: [3, 6, 9] - * Lazy.range(5, 2) // sequence: [5, 4, 3] - * Lazy.range(7, 2, -2) // sequence: [7, 5, 3] - * Lazy.range(3, 5, 0) // sequence: [] - */ - Lazy.range = function range() { - var start = arguments.length > 1 ? arguments[0] : 0, - stop = arguments.length > 1 ? arguments[1] : arguments[0], - step = arguments.length > 2 && arguments[2]; - - if (step === false) { - step = stop > start ? 1 : -1; - } - - if (step === 0) { - return Lazy([]); - } - - return Lazy.generate(function(i) { return start + (step * i); }) - .take(Math.ceil((stop - start) / step)); - }; - - /** - * Creates a sequence consisting of the given value repeated a specified number - * of times. - * - * @public - * @param {*} value The value to repeat. - * @param {number=} count The number of times the value should be repeated in - * the sequence. If this argument is omitted, the value will repeat forever. - * @returns {GeneratedSequence} The sequence containing the repeated value. - * - * @examples - * Lazy.repeat("hi", 3) // sequence: ["hi", "hi", "hi"] - * Lazy.repeat("young") // instanceof Lazy.GeneratedSequence - * Lazy.repeat("young").length() // => undefined - * Lazy.repeat("young").take(3) // sequence: ["young", "young", "young"] - */ - Lazy.repeat = function repeat(value, count) { - return Lazy.generate(function() { return value; }, count); - }; - - Lazy.Sequence = Sequence; - Lazy.ArrayLikeSequence = ArrayLikeSequence; - Lazy.ObjectLikeSequence = ObjectLikeSequence; - Lazy.StringLikeSequence = StringLikeSequence; - Lazy.StreamLikeSequence = StreamLikeSequence; - Lazy.GeneratedSequence = GeneratedSequence; - Lazy.AsyncSequence = AsyncSequence; - Lazy.AsyncHandle = AsyncHandle; - - /*** Useful utility methods ***/ - - /** - * Creates a shallow copy of an array or object. - * - * @examples - * var array = [1, 2, 3], clonedArray, - * object = { foo: 1, bar: 2 }, clonedObject; - * - * clonedArray = Lazy.clone(array); // => [1, 2, 3] - * clonedArray.push(4); // clonedArray == [1, 2, 3, 4] - * array; // => [1, 2, 3] - * - * clonedObject = Lazy.clone(object); // => { foo: 1, bar: 2 } - * clonedObject.baz = 3; // clonedObject == { foo: 1, bar: 2, baz: 3 } - * object; // => { foo: 1, bar: 2 } - */ - Lazy.clone = function clone(target) { - return Lazy(target).value(); - }; - - /** - * Marks a method as deprecated, so calling it will issue a console warning. - */ - Lazy.deprecate = function deprecate(message, fn) { - return function() { - console.warn(message); - return fn.apply(this, arguments); - }; - }; - - var arrayPop = Array.prototype.pop, - arraySlice = Array.prototype.slice; - - /** - * Creates a callback... you know, Lo-Dash style. - * - * - for functions, just returns the function - * - for strings, returns a pluck-style callback - * - for objects, returns a where-style callback - * - * @private - * @param {Function|string|Object} callback A function, string, or object to - * convert to a callback. - * @param {*} defaultReturn If the callback is undefined, a default return - * value to use for the function. - * @returns {Function} The callback function. - * - * @examples - * createCallback(function() {}) // instanceof Function - * createCallback('foo') // instanceof Function - * createCallback('foo')({ foo: 'bar'}) // => 'bar' - * createCallback({ foo: 'bar' })({ foo: 'bar' }) // => true - * createCallback({ foo: 'bar' })({ foo: 'baz' }) // => false - */ - function createCallback(callback, defaultValue) { - switch (typeof callback) { - case "function": - return callback; - - case "string": - return function(e) { - return e[callback]; - }; - - case "object": - return function(e) { - return Lazy(callback).all(function(value, key) { - return e[key] === value; - }); - }; - - case "undefined": - return defaultValue ? - function() { return defaultValue; } : - Lazy.identity; - - default: - throw new Error("Don't know how to make a callback from a " + typeof callback + "!"); - } - } - - /** - * Takes a function that returns a value for one argument and produces a - * function that compares two arguments. - * - * @private - * @param {Function|string|Object} callback A function, string, or object to - * convert to a callback using `createCallback`. - * @returns {Function} A function that accepts two values and returns 1 if - * the first is greater, -1 if the second is greater, or 0 if they are - * equivalent. - * - * @examples - * createComparator('a')({ a: 1 }, { a: 2 }); // => -1 - * createComparator('a')({ a: 6 }, { a: 2 }); // => 1 - * createComparator('a')({ a: 1 }, { a: 1 }); // => 0 - * createComparator()(3, 5); // => -1 - * createComparator()(7, 5); // => 1 - * createComparator()(3, 3); // => 0 - */ - function createComparator(callback, descending) { - if (!callback) { return compare; } - - callback = createCallback(callback); - - return function(x, y) { - return compare(callback(x), callback(y)); - }; - } - - /** - * Takes a function and returns a function with the same logic but the - * arguments reversed. Only applies to functions w/ arity=2 as this is private - * and I can do what I want. - * - * @private - * @param {Function} fn The function to "reverse" - * @returns {Function} The "reversed" function - * - * @examples - * reverseArguments(function(x, y) { return x + y; })('a', 'b'); // => 'ba' - */ - function reverseArguments(fn) { - return function(x, y) { return fn(y, x); }; - } - - /** - * Creates a Set containing the specified values. - * - * @param {...Array} values One or more array(s) of values used to populate the - * set. - * @returns {Set} A new set containing the values passed in. - */ - function createSet(values) { - var set = new Set(); - Lazy(values || []).flatten().each(function(e) { - set.add(e); - }); - return set; - } - - /** - * Compares two elements for sorting purposes. - * - * @private - * @param {*} x The left element to compare. - * @param {*} y The right element to compare. - * @returns {number} 1 if x > y, -1 if x < y, or 0 if x and y are equal. - * - * @examples - * compare(1, 2) // => -1 - * compare(1, 1) // => 0 - * compare(2, 1) // => 1 - * compare('a', 'b') // => -1 - */ - function compare(x, y) { - if (x === y) { - return 0; - } - - return x > y ? 1 : -1; - } - - /** - * Iterates over every element in an array. - * - * @param {Array} array The array. - * @param {Function} fn The function to call on every element, which can return - * false to stop the iteration early. - * @returns {boolean} True if every element in the entire sequence was iterated, - * otherwise false. - */ - function forEach(array, fn) { - var i = -1, - len = array.length; - - while (++i < len) { - if (fn(array[i], i) === false) { - return false; - } - } - - return true; - } - - function getFirst(sequence) { - var result; - sequence.each(function(e) { - result = e; - return false; - }); - return result; - } - - /** - * Checks if an element exists in an array. - * - * @private - * @param {Array} array - * @param {*} element - * @returns {boolean} Whether or not the element exists in the array. - * - * @examples - * arrayContains([1, 2], 2) // => true - * arrayContains([1, 2], 3) // => false - * arrayContains([undefined], undefined) // => true - * arrayContains([NaN], NaN) // => true - */ - function arrayContains(array, element) { - var i = -1, - length = array.length; - - // Special handling for NaN - if (element !== element) { - while (++i < length) { - if (array[i] !== array[i]) { - return true; - } - } - return false; - } - - while (++i < length) { - if (array[i] === element) { - return true; - } - } - return false; - } - - /** - * Checks if an element exists in an array before a given index. - * - * @private - * @param {Array} array - * @param {*} element - * @param {number} index - * @param {Function} keyFn - * @returns {boolean} - * - * @examples - * arrayContainsBefore([1, 2, 3], 3, 2) // => false - * arrayContainsBefore([1, 2, 3], 3, 3) // => true - */ - function arrayContainsBefore(array, element, index, keyFn) { - var i = -1; - - if (keyFn) { - keyFn = createCallback(keyFn); - while (++i < index) { - if (keyFn(array[i]) === keyFn(element)) { - return true; - } - } - - } else { - while (++i < index) { - if (array[i] === element) { - return true; - } - } - } - - return false; - } - - /** - * Swaps the elements at two specified positions of an array. - * - * @private - * @param {Array} array - * @param {number} i - * @param {number} j - * - * @examples - * var array = [1, 2, 3, 4, 5]; - * - * swap(array, 2, 3) // array == [1, 2, 4, 3, 5] - */ - function swap(array, i, j) { - var temp = array[i]; - array[i] = array[j]; - array[j] = temp; - } - - /** - * "Clones" a regular expression (but makes it always global). - * - * @private - * @param {RegExp|string} pattern - * @returns {RegExp} - */ - function cloneRegex(pattern) { - return eval("" + pattern + (!pattern.global ? "g" : "")); - }; - - /** - * A collection of unique elements. - * - * @private - * @constructor - * - * @examples - * var set = new Set(), - * obj1 = {}, - * obj2 = {}, - * fn1 = function fn1() {}, - * fn2 = function fn2() {}; - * - * set.add('foo') // => true - * set.add('foo') // => false - * set.add(1) // => true - * set.add(1) // => false - * set.add('1') // => true - * set.add('1') // => false - * set.add(obj1) // => true - * set.add(obj1) // => false - * set.add(obj2) // => true - * set.add(fn1) // => true - * set.add(fn2) // => true - * set.add(fn2) // => false - * set.contains('__proto__') // => false - * set.add('__proto__') // => true - * set.add('__proto__') // => false - * set.contains('add') // => false - * set.add('add') // => true - * set.add('add') // => false - * set.contains(undefined) // => false - * set.add(undefined) // => true - * set.contains(undefined) // => true - * set.contains('undefined') // => false - * set.add('undefined') // => true - * set.contains('undefined') // => true - * set.contains(NaN) // => false - * set.add(NaN) // => true - * set.contains(NaN) // => true - * set.contains('NaN') // => false - * set.add('NaN') // => true - * set.contains('NaN') // => true - * set.contains('@foo') // => false - * set.add('@foo') // => true - * set.contains('@foo') // => true - */ - function Set() { - this.table = {}; - this.objects = []; - } - - /** - * Attempts to add a unique value to the set. - * - * @param {*} value The value to add. - * @returns {boolean} True if the value was added to the set (meaning an equal - * value was not already present), or else false. - */ - Set.prototype.add = function add(value) { - var table = this.table, - type = typeof value, - - // only applies for strings - firstChar, - - // only applies for objects - objects; - - switch (type) { - case "number": - case "boolean": - case "undefined": - if (!table[value]) { - table[value] = true; - return true; - } - return false; - - case "string": - // Essentially, escape the first character if it could possibly collide - // with a number, boolean, or undefined (or a string that happens to start - // with the escape character!), OR if it could override a special property - // such as '__proto__' or 'constructor'. - switch (value.charAt(0)) { - case "_": // e.g., __proto__ - case "f": // for 'false' - case "t": // for 'true' - case "c": // for 'constructor' - case "u": // for 'undefined' - case "@": // escaped - case "0": - case "1": - case "2": - case "3": - case "4": - case "5": - case "6": - case "7": - case "8": - case "9": - case "N": // for NaN - value = "@" + value; - } - if (!table[value]) { - table[value] = true; - return true; - } - return false; - - default: - // For objects and functions, we can't really do anything other than store - // them in an array and do a linear search for reference equality. - objects = this.objects; - if (!arrayContains(objects, value)) { - objects.push(value); - return true; - } - return false; - } - }; - - /** - * Checks whether the set contains a value. - * - * @param {*} value The value to check for. - * @returns {boolean} True if the set contains the value, or else false. - */ - Set.prototype.contains = function contains(value) { - var type = typeof value, - - // only applies for strings - firstChar; - - switch (type) { - case "number": - case "boolean": - case "undefined": - return !!this.table[value]; - - case "string": - // Essentially, escape the first character if it could possibly collide - // with a number, boolean, or undefined (or a string that happens to start - // with the escape character!), OR if it could override a special property - // such as '__proto__' or 'constructor'. - switch (value.charAt(0)) { - case "_": // e.g., __proto__ - case "f": // for 'false' - case "t": // for 'true' - case "c": // for 'constructor' - case "u": // for 'undefined' - case "@": // escaped - case "0": - case "1": - case "2": - case "3": - case "4": - case "5": - case "6": - case "7": - case "8": - case "9": - case "N": // for NaN - value = "@" + value; - } - return !!this.table[value]; - - default: - // For objects and functions, we can't really do anything other than store - // them in an array and do a linear search for reference equality. - return arrayContains(this.objects, value); - } - }; - - /** - * A "rolling" queue, with a fixed capacity. As items are added to the head, - * excess items are dropped from the tail. - * - * @private - * @constructor - * - * @examples - * var queue = new Queue(3); - * - * queue.add(1).toArray() // => [1] - * queue.add(2).toArray() // => [1, 2] - * queue.add(3).toArray() // => [1, 2, 3] - * queue.add(4).toArray() // => [2, 3, 4] - * queue.add(5).add(6).toArray() // => [4, 5, 6] - * queue.add(7).add(8).toArray() // => [6, 7, 8] - * - * // also want to check corner cases - * new Queue(1).add('foo').add('bar').toArray() // => ['bar'] - * new Queue(0).add('foo').toArray() // => [] - * new Queue(-1) // throws - * - * @benchmarks - * function populateQueue(count, capacity) { - * var q = new Queue(capacity); - * for (var i = 0; i < count; ++i) { - * q.add(i); - * } - * } - * - * function populateArray(count, capacity) { - * var arr = []; - * for (var i = 0; i < count; ++i) { - * if (arr.length === capacity) { arr.shift(); } - * arr.push(i); - * } - * } - * - * populateQueue(100, 10); // populating a Queue - * populateArray(100, 10); // populating an Array - */ - function Queue(capacity) { - this.contents = new Array(capacity); - this.start = 0; - this.count = 0; - } - - /** - * Adds an item to the queue, and returns the queue. - */ - Queue.prototype.add = function add(element) { - var contents = this.contents, - capacity = contents.length, - start = this.start; - - if (this.count === capacity) { - contents[start] = element; - this.start = (start + 1) % capacity; - - } else { - contents[this.count++] = element; - } - - return this; - }; - - /** - * Returns an array containing snapshot of the queue's contents. - */ - Queue.prototype.toArray = function toArray() { - var contents = this.contents, - start = this.start, - count = this.count; - - var snapshot = contents.slice(start, start + count); - if (snapshot.length < count) { - snapshot = snapshot.concat(contents.slice(0, count - snapshot.length)); - } - - return snapshot; - }; - - /** - * Shared base method for defining new sequence types. - */ - function defineSequenceType(base, name, overrides) { - /** @constructor */ - var ctor = function ctor() {}; - - // Make this type inherit from the specified base. - ctor.prototype = new base(); - - // Attach overrides to the new sequence type's prototype. - for (var override in overrides) { - ctor.prototype[override] = overrides[override]; - } - - // Define a factory method that sets the new sequence's parent to the caller - // and (optionally) applies any additional initialization logic. - // Expose this as a chainable method so that we can do: - // Lazy(...).map(...).filter(...).blah(...); - var factory = function factory() { - var sequence = new ctor(); - - // Every sequence needs a reference to its parent in order to work. - sequence.parent = this; - - // If a custom init function was supplied, call it now. - if (sequence.init) { - sequence.init.apply(sequence, arguments); - } - - return sequence; - }; - - var methodNames = typeof name === 'string' ? [name] : name; - for (var i = 0; i < methodNames.length; ++i) { - base.prototype[methodNames[i]] = factory; - } - - return ctor; - } - - return Lazy; -}); - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11).setImmediate, __webpack_require__(11).clearImmediate)) - -/***/ }, -/* 32 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; - -const EventEmitter = __webpack_require__(40).EventEmitter; -const Log = __webpack_require__(138); -const Index = __webpack_require__(147); -const Cache = __webpack_require__(146); - -const DefaultMaxHistory = 256; - -class Store { - constructor(ipfs, id, dbname, options) { - this.id = id; - this.dbname = dbname; - this.events = new EventEmitter(); - - if(!options) options = {}; - if(options.Index === undefined) Object.assign(options, { Index: Index }); - if(options.cacheFile === undefined) Object.assign(options, { cacheFile: null }); - if(options.maxHistory === undefined) Object.assign(options, { maxHistory: DefaultMaxHistory }); - - this.options = options; - this._index = new this.options.Index(this.id); - this._oplog = null; - this._ipfs = ipfs; - this._lastWrite = []; - } - - use() { - this.events.emit('load', this.dbname); - this._oplog = new Log(this._ipfs, this.id, this.dbname, this.options); - return Cache.loadCache(this.options.cacheFile).then(() => { - const cached = Cache.get(this.dbname); - if(cached) { - if(this._lastWrite.indexOf(cached) > -1) this._lastWrite.push(cached); - return Log.fromIpfsHash(this._ipfs, cached, this.options) - .then((log) => this._oplog.join(log)) - .then((merged) => this._index.updateIndex(this._oplog, merged)) - .then(() => this.events.emit('ready', this.dbname)) - .then(() => this) - } - - this.events.emit('ready', this.dbname) - return Promise.resolve(this); - }); - } - - close() { - this.events.emit('close', this.dbname); - } - - sync(hash) { - if(!hash || this._lastWrite.indexOf(hash) > -1) { - this.events.emit('updated', this.dbname, []); - return Promise.resolve([]); - } - - let newItems = []; - this.events.emit('sync', this.dbname); - this._lastWrite.push(hash); - const startTime = new Date().getTime(); - return Log.fromIpfsHash(this._ipfs, hash, this.options) - .then((log) => this._oplog.join(log)) - .then((merged) => newItems = merged) - .then(() => Cache.set(this.dbname, hash)) - .then(() => this._index.updateIndex(this._oplog, newItems)) - .then(() => { - // if(newItems.length > 0) { - // console.log("Sync took", (new Date().getTime() - startTime) + "ms", this.id) - // } - this.events.emit('updated', this.dbname, newItems); - }) - .then(() => newItems) - } - - delete() { - this._index = new this.options.Index(this.id); - if(this._oplog) - this._oplog.clear(); - } - - _addOperation(data) { - let result, logHash; - if(this._oplog) { - return this._oplog.add(data) - .then((res) => result = res) - .then(() => Log.getIpfsHash(this._ipfs, this._oplog)) - .then((hash) => logHash = hash) - .then(() => this._lastWrite.push(logHash)) - .then(() => Cache.set(this.dbname, logHash)) - .then(() => this._index.updateIndex(this._oplog, [result])) - .then(() => this.events.emit('data', this.dbname, logHash)) - .then(() => result.hash); - } - } -} - -module.exports = Store; - - -/***/ }, -/* 33 */ -/***/ function(module, exports) { - -/** - * Compiles a querystring - * Returns string representation of the object - * - * @param {Object} - * @api private - */ - -exports.encode = function (obj) { - var str = ''; - - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - if (str.length) str += '&'; - str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]); - } - } - - return str; -}; - -/** - * Parses a simple querystring into an object - * - * @param {String} qs - * @api private - */ - -exports.decode = function(qs){ - var qry = {}; - var pairs = qs.split('&'); - for (var i = 0, l = pairs.length; i < l; i++) { - var pair = pairs[i].split('='); - qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); - } - return qry; -}; - - -/***/ }, -/* 34 */ -/***/ function(module, exports, __webpack_require__) { - - -/** - * Module dependencies. - */ - -var debug = __webpack_require__(4)('socket.io-parser'); -var json = __webpack_require__(140); -var isArray = __webpack_require__(68); -var Emitter = __webpack_require__(153); -var binary = __webpack_require__(152); -var isBuf = __webpack_require__(67); - -/** - * Protocol version. - * - * @api public - */ - -exports.protocol = 4; - -/** - * Packet types. - * - * @api public - */ - -exports.types = [ - 'CONNECT', - 'DISCONNECT', - 'EVENT', - 'ACK', - 'ERROR', - 'BINARY_EVENT', - 'BINARY_ACK' -]; - -/** - * Packet type `connect`. - * - * @api public - */ - -exports.CONNECT = 0; - -/** - * Packet type `disconnect`. - * - * @api public - */ - -exports.DISCONNECT = 1; - -/** - * Packet type `event`. - * - * @api public - */ - -exports.EVENT = 2; - -/** - * Packet type `ack`. - * - * @api public - */ - -exports.ACK = 3; - -/** - * Packet type `error`. - * - * @api public - */ - -exports.ERROR = 4; - -/** - * Packet type 'binary event' - * - * @api public - */ - -exports.BINARY_EVENT = 5; - -/** - * Packet type `binary ack`. For acks with binary arguments. - * - * @api public - */ - -exports.BINARY_ACK = 6; - -/** - * Encoder constructor. - * - * @api public - */ - -exports.Encoder = Encoder; - -/** - * Decoder constructor. - * - * @api public - */ - -exports.Decoder = Decoder; - -/** - * A socket.io Encoder instance - * - * @api public - */ - -function Encoder() {} - -/** - * Encode a packet as a single string if non-binary, or as a - * buffer sequence, depending on packet type. - * - * @param {Object} obj - packet object - * @param {Function} callback - function to handle encodings (likely engine.write) - * @return Calls callback with Array of encodings - * @api public - */ - -Encoder.prototype.encode = function(obj, callback){ - debug('encoding packet %j', obj); - - if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) { - encodeAsBinary(obj, callback); - } - else { - var encoding = encodeAsString(obj); - callback([encoding]); - } -}; - -/** - * Encode packet as string. - * - * @param {Object} packet - * @return {String} encoded - * @api private - */ - -function encodeAsString(obj) { - var str = ''; - var nsp = false; - - // first is type - str += obj.type; - - // attachments if we have them - if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) { - str += obj.attachments; - str += '-'; - } - - // if we have a namespace other than `/` - // we append it followed by a comma `,` - if (obj.nsp && '/' != obj.nsp) { - nsp = true; - str += obj.nsp; - } - - // immediately followed by the id - if (null != obj.id) { - if (nsp) { - str += ','; - nsp = false; - } - str += obj.id; - } - - // json data - if (null != obj.data) { - if (nsp) str += ','; - str += json.stringify(obj.data); - } - - debug('encoded %j as %s', obj, str); - return str; -} - -/** - * Encode packet as 'buffer sequence' by removing blobs, and - * deconstructing packet into object with placeholders and - * a list of buffers. - * - * @param {Object} packet - * @return {Buffer} encoded - * @api private - */ - -function encodeAsBinary(obj, callback) { - - function writeEncoding(bloblessData) { - var deconstruction = binary.deconstructPacket(bloblessData); - var pack = encodeAsString(deconstruction.packet); - var buffers = deconstruction.buffers; - - buffers.unshift(pack); // add packet info to beginning of data list - callback(buffers); // write all the buffers - } - - binary.removeBlobs(obj, writeEncoding); -} - -/** - * A socket.io Decoder instance - * - * @return {Object} decoder - * @api public - */ - -function Decoder() { - this.reconstructor = null; -} - -/** - * Mix in `Emitter` with Decoder. - */ - -Emitter(Decoder.prototype); - -/** - * Decodes an ecoded packet string into packet JSON. - * - * @param {String} obj - encoded packet - * @return {Object} packet - * @api public - */ - -Decoder.prototype.add = function(obj) { - var packet; - if ('string' == typeof obj) { - packet = decodeString(obj); - if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json - this.reconstructor = new BinaryReconstructor(packet); - - // no attachments, labeled binary but no binary data to follow - if (this.reconstructor.reconPack.attachments === 0) { - this.emit('decoded', packet); - } - } else { // non-binary full packet - this.emit('decoded', packet); - } - } - else if (isBuf(obj) || obj.base64) { // raw binary data - if (!this.reconstructor) { - throw new Error('got binary data when not reconstructing a packet'); - } else { - packet = this.reconstructor.takeBinaryData(obj); - if (packet) { // received final buffer - this.reconstructor = null; - this.emit('decoded', packet); - } - } - } - else { - throw new Error('Unknown type: ' + obj); - } -}; - -/** - * Decode a packet String (JSON data) - * - * @param {String} str - * @return {Object} packet - * @api private - */ - -function decodeString(str) { - var p = {}; - var i = 0; - - // look up type - p.type = Number(str.charAt(0)); - if (null == exports.types[p.type]) return error(); - - // look up attachments if type binary - if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) { - var buf = ''; - while (str.charAt(++i) != '-') { - buf += str.charAt(i); - if (i == str.length) break; - } - if (buf != Number(buf) || str.charAt(i) != '-') { - throw new Error('Illegal attachments'); - } - p.attachments = Number(buf); - } - - // look up namespace (if any) - if ('/' == str.charAt(i + 1)) { - p.nsp = ''; - while (++i) { - var c = str.charAt(i); - if (',' == c) break; - p.nsp += c; - if (i == str.length) break; - } - } else { - p.nsp = '/'; - } - - // look up id - var next = str.charAt(i + 1); - if ('' !== next && Number(next) == next) { - p.id = ''; - while (++i) { - var c = str.charAt(i); - if (null == c || Number(c) != c) { - --i; - break; - } - p.id += str.charAt(i); - if (i == str.length) break; - } - p.id = Number(p.id); - } - - // look up json data - if (str.charAt(++i)) { - try { - p.data = json.parse(str.substr(i)); - } catch(e){ - return error(); - } - } - - debug('decoded %s as %j', str, p); - return p; -} - -/** - * Deallocates a parser's resources - * - * @api public - */ - -Decoder.prototype.destroy = function() { - if (this.reconstructor) { - this.reconstructor.finishedReconstruction(); - } -}; - -/** - * A manager of a binary event's 'buffer sequence'. Should - * be constructed whenever a packet of type BINARY_EVENT is - * decoded. - * - * @param {Object} packet - * @return {BinaryReconstructor} initialized reconstructor - * @api private - */ - -function BinaryReconstructor(packet) { - this.reconPack = packet; - this.buffers = []; -} - -/** - * Method to be called when binary data received from connection - * after a BINARY_EVENT packet. - * - * @param {Buffer | ArrayBuffer} binData - the raw binary data received - * @return {null | Object} returns null if more binary data is expected or - * a reconstructed packet object if all buffers have been received. - * @api private - */ - -BinaryReconstructor.prototype.takeBinaryData = function(binData) { - this.buffers.push(binData); - if (this.buffers.length == this.reconPack.attachments) { // done with buffer list - var packet = binary.reconstructPacket(this.reconPack, this.buffers); - this.finishedReconstruction(); - return packet; - } - return null; -}; - -/** - * Cleans up binary packet reconstruction variables. - * - * @api private - */ - -BinaryReconstructor.prototype.finishedReconstruction = function() { - this.reconPack = null; - this.buffers = []; -}; - -function error(data){ - return { - type: exports.ERROR, - data: 'parser error' - }; -} - - -/***/ }, -/* 35 */ -/***/ function(module, exports) { - -module.exports = function(module) { - if(!module.webpackPolyfill) { - module.deprecate = function() {}; - module.paths = []; - // module.parent = undefined by default - if(!module.children) module.children = []; - Object.defineProperty(module, "loaded", { - enumerable: true, - configurable: false, - get: function() { return module.l; } - }); - Object.defineProperty(module, "id", { - enumerable: true, - configurable: false, - get: function() { return module.i; } - }); - module.webpackPolyfill = 1; - } - return module; -} - - -/***/ }, -/* 36 */ -/***/ function(module, exports, __webpack_require__) { - -module.exports = { "default": __webpack_require__(83), __esModule: true }; - -/***/ }, -/* 37 */ -/***/ function(module, exports, __webpack_require__) { - -module.exports = { "default": __webpack_require__(86), __esModule: true }; - -/***/ }, -/* 38 */ -/***/ function(module, exports) { - -"use strict"; -"use strict"; - -exports.__esModule = true; - -exports.default = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -}; - -/***/ }, -/* 39 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -"use strict"; - -exports.__esModule = true; - -var _defineProperty = __webpack_require__(77); - -var _defineProperty2 = _interopRequireDefault(_defineProperty); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.default = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - (0, _defineProperty2.default)(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; -}(); - -/***/ }, -/* 40 */ -/***/ function(module, exports) { - -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; - -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - - if (!this._events) - this._events = {}; - - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } else { - // At least give some kind of context to the user - var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); - err.context = er; - throw err; - } - } - } - - handler = this._events[type]; - - if (isUndefined(handler)) - return false; - - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); - } - } else if (isObject(handler)) { - args = Array.prototype.slice.call(arguments, 1); - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } - - return true; -}; - -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events) - this._events = {}; - - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); - - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } - - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events || !this._events[type]) - return this; - - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } - } - - if (position < 0) - return this; - - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } - - if (this._events.removeListener) - this.emit('removeListener', type, listener); - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } - - listeners = this._events[type]; - - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; - - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; - -EventEmitter.prototype.listenerCount = function(type) { - if (this._events) { - var evlistener = this._events[type]; - - if (isFunction(evlistener)) - return 1; - else if (evlistener) - return evlistener.length; - } - return 0; -}; - -EventEmitter.listenerCount = function(emitter, type) { - return emitter.listenerCount(type); -}; - -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isUndefined(arg) { - return arg === void 0; -} - - -/***/ }, -/* 41 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(process) {'use strict'; - -const fs = __webpack_require__(60); -const format = __webpack_require__(157).format; - -let isNodejs = process.version ? true : false; - -const LogLevels = { - 'DEBUG': 'DEBUG', - 'INFO': 'INFO', - 'WARN': 'WARN', - 'ERROR': 'ERROR', - 'NONE': 'NONE', -}; - -// Global log level -let GlobalLogLevel = LogLevels.DEBUG; - -// Global log file name -let GlobalLogfile = null; - -// ANSI colors -let Colors = { - 'Black': 0, - 'Red': 1, - 'Green': 2, - 'Yellow': 3, - 'Blue': 4, - 'Magenta': 5, - 'Cyan': 6, - 'Grey': 7, - 'White': 9, - 'Default': 9, -}; - -// CSS colors -if(!isNodejs) { - Colors = { - 'Black': 'Black', - 'Red': 'IndianRed', - 'Green': 'LimeGreen', - 'Yellow': 'Orange', - 'Blue': 'RoyalBlue', - 'Magenta': 'Orchid', - 'Cyan': 'SkyBlue', - 'Grey': 'DimGrey', - 'White': 'White', - 'Default': 'Black', - }; -} - -const loglevelColors = [Colors.Cyan, Colors.Green, Colors.Yellow, Colors.Red, Colors.Default]; - -const defaultOptions = { - useColors: true, - color: Colors.Default, - showTimestamp: true, - showLevel: true, - filename: GlobalLogfile, - appendFile: true, -}; - -class Logger { - constructor(category, options) { - this.category = category; - let opts = {}; - Object.assign(opts, defaultOptions); - Object.assign(opts, options); - this.options = opts; - } - - debug() { - this._write(LogLevels.DEBUG, format.apply(null, arguments)); - } - - log() { - this.debug.apply(this, arguments); - } - - info() { - this._write(LogLevels.INFO, format.apply(null, arguments)); - } - - warn() { - this._write(LogLevels.WARN, format.apply(null, arguments)); - } - - error() { - this._write(LogLevels.ERROR, format.apply(null, arguments)); - } - - _write(level, text) { - if(!this._shouldLog(level)) - return; - - if((this.options.filename || GlobalLogfile) && !this.fileWriter) - this.fileWriter = fs.openSync(this.options.filename || GlobalLogfile, this.options.appendFile ? 'a+' : 'w+'); - - let format = this._format(level, text); - let unformattedText = this._createLogMessage(level, text); - let formattedText = this._createLogMessage(level, text, format.timestamp, format.level, format.category, format.text); - - if(this.fileWriter) - fs.writeSync(this.fileWriter, unformattedText + '\n', null, 'utf-8'); - - if(isNodejs) { - console.log(formattedText) - } else { - // TODO: clean this up - if(level === LogLevels.ERROR) { - if(this.options.showTimestamp && this.options.showLevel) { - console.error(formattedText, format.timestamp, format.level, format.category, format.text) - } else if(this.options.showTimestamp && !this.options.showLevel) { - console.error(formattedText, format.timestamp, format.category, format.text) - } else if(!this.options.showTimestamp && this.options.showLevel) { - console.error(formattedText, format.level, format.category, format.text) - } else { - console.error(formattedText, format.category, format.text) - } - } else { - if(this.options.showTimestamp && this.options.showLevel) { - console.log(formattedText, format.timestamp, format.level, format.category, format.text) - } else if(this.options.showTimestamp && !this.options.showLevel) { - console.log(formattedText, format.timestamp, format.category, format.text) - } else if(!this.options.showTimestamp && this.options.showLevel) { - console.log(formattedText, format.level, format.category, format.text) - } else { - console.log(formattedText, format.category, format.text) - } - } - } - } - - _format(level, text) { - let timestampFormat = ''; - let levelFormat = ''; - let categoryFormat = ''; - let textFormat = ': '; - - if(this.options.useColors) { - const levelColor = Object.keys(LogLevels).map((f) => LogLevels[f]).indexOf(level); - const categoryColor = this.options.color; - - if(isNodejs) { - if(this.options.showTimestamp) - timestampFormat = '\u001b[3' + Colors.Grey + 'm'; - - if(this.options.showLevel) - levelFormat = '\u001b[3' + loglevelColors[levelColor] + ';22m'; - - categoryFormat = '\u001b[3' + categoryColor + ';1m'; - textFormat = '\u001b[0m: '; - } else { - if(this.options.showTimestamp) - timestampFormat = 'color:' + Colors.Grey; - - if(this.options.showLevel) - levelFormat = 'color:' + loglevelColors[levelColor]; - - categoryFormat = 'color:' + categoryColor + '; font-weight: bold'; - } - } - - return { - timestamp: timestampFormat, - level: levelFormat, - category: categoryFormat, - text: textFormat - }; - } - - _createLogMessage(level, text, timestampFormat, levelFormat, categoryFormat, textFormat) { - timestampFormat = timestampFormat || ''; - levelFormat = levelFormat || ''; - categoryFormat = categoryFormat || ''; - textFormat = textFormat || ': '; - - if(!isNodejs) { - if(this.options.showTimestamp) - timestampFormat = '%c'; - - if(this.options.showLevel) - levelFormat = '%c'; - - categoryFormat = '%c'; - textFormat = ': %c'; - } - - let result = ''; - - if(this.options.showTimestamp) - result += '' + new Date().toISOString() + ' '; - - result = timestampFormat + result; - - if(this.options.showLevel) - result += levelFormat + '[' + level +']' + (level === LogLevels.INFO || level === LogLevels.WARN ? ' ' : '') + ' '; - - result += categoryFormat + this.category; - result += textFormat + text; - return result; - } - - _shouldLog(level) { - const levels = Object.keys(LogLevels).map((f) => LogLevels[f]); - const index = levels.indexOf(level); - const levelIdx = levels.indexOf(GlobalLogLevel); - return index >= levelIdx; - } -}; - -/* Public API */ -module.exports = { - Colors: Colors, - LogLevels: LogLevels, - setLogLevel: (level) => { - GlobalLogLevel = level; - }, - setLogfile: (filename) => { - GlobalLogfile = filename; - }, - create: (category, options) => { - const logger = new Logger(category, options); - return logger; - }, - forceBrowserMode: (force) => isNodejs = !force, // for testing -}; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18))) - -/***/ }, -/* 42 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; - -const Lazy = __webpack_require__(31); -const Store = __webpack_require__(32); -const EventIndex = __webpack_require__(61); - -class EventStore extends Store { - constructor(ipfs, id, dbname, options) { - if(!options) options = {}; - if(options.Index === undefined) Object.assign(options, { Index: EventIndex }); - super(ipfs, id, dbname, options) - } - - add(data) { - return this._addOperation({ - op: 'ADD', - key: null, - value: data, - meta: { - ts: new Date().getTime() - } - }); - } - - get(hash) { - return this.iterator({ gte: hash, limit: 1 }).collect()[0]; - } - - iterator(options) { - const messages = this._query(this.dbname, options); - let currentIndex = 0; - let iterator = { - [Symbol.iterator]() { - return this; - }, - next() { - let item = { value: null, done: true }; - if(currentIndex < messages.length) { - item = { value: messages[currentIndex], done: false }; - currentIndex ++; - } - return item; - }, - collect: () => messages - } - - return iterator; - } - - _query(dbname, opts) { - if(!opts) opts = {}; - - const amount = opts.limit ? (opts.limit > -1 ? opts.limit : this._index.get().length) : 1; // Return 1 if no limit is provided - const events = this._index.get(); - let result = []; - - if(opts.gt || opts.gte) { - // Greater than case - result = this._read(events, opts.gt ? opts.gt : opts.gte, amount, opts.gte ? true : false) - } else { - // Lower than and lastN case, search latest first by reversing the sequence - result = this._read(events.reverse(), opts.lt ? opts.lt : opts.lte, amount, opts.lte || !opts.lt).reverse() - } - - if(opts.reverse) result.reverse(); - - return result.toArray(); - } - - _read(ops, hash, amount, inclusive) { - return Lazy(ops) - .skipWhile((f) => hash && f.hash !== hash) - .drop(inclusive ? 0 : 1) - .take(amount); - } -} - -module.exports = EventStore; - - -/***/ }, -/* 43 */ -/***/ function(module, exports) { - -/** - * Slice reference. - */ - -var slice = [].slice; - -/** - * Bind `obj` to `fn`. - * - * @param {Object} obj - * @param {Function|String} fn or string - * @return {Function} - * @api public - */ - -module.exports = function(obj, fn){ - if ('string' == typeof fn) fn = obj[fn]; - if ('function' != typeof fn) throw new Error('bind() requires a function'); - var args = slice.call(arguments, 2); - return function(){ - return fn.apply(obj, args.concat(slice.call(arguments))); - } -}; - - -/***/ }, -/* 44 */ -/***/ function(module, exports) { - - -/** - * Expose `Emitter`. - */ - -module.exports = Emitter; - -/** - * Initialize a new `Emitter`. - * - * @api public - */ - -function Emitter(obj) { - if (obj) return mixin(obj); -}; - -/** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; - } - return obj; -} - -/** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.on = -Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks['$' + event] = this._callbacks['$' + event] || []) - .push(fn); - return this; -}; - -/** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.once = function(event, fn){ - function on() { - this.off(event, on); - fn.apply(this, arguments); - } - - on.fn = fn; - this.on(event, on); - return this; -}; - -/** - * Remove the given callback for `event` or all - * registered callbacks. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.off = -Emitter.prototype.removeListener = -Emitter.prototype.removeAllListeners = -Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; - } - - // specific event - var callbacks = this._callbacks['$' + event]; - if (!callbacks) return this; - - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks['$' + event]; - return this; - } - - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; - } - } - return this; -}; - -/** - * Emit `event` with the given args. - * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} - */ - -Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks['$' + event]; - - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); - } - } - - return this; -}; - -/** - * Return array of callbacks for `event`. - * - * @param {String} event - * @return {Array} - * @api public - */ - -Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks['$' + event] || []; -}; - -/** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ - -Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; -}; - - -/***/ }, -/* 45 */ -/***/ function(module, exports, __webpack_require__) { - -// getting tag from 19.1.3.6 Object.prototype.toString() -var cof = __webpack_require__(13) - , TAG = __webpack_require__(1)('toStringTag') - // ES3 wrong here - , ARG = cof(function(){ return arguments; }()) == 'Arguments'; - -// fallback for IE11 Script Access Denied error -var tryGet = function(it, key){ - try { - return it[key]; - } catch(e){ /* empty */ } -}; - -module.exports = function(it){ - var O, T, B; - return it === undefined ? 'Undefined' : it === null ? 'Null' - // @@toStringTag case - : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T - // builtinTag case - : ARG ? cof(O) - // ES3 arguments fallback - : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; -}; - -/***/ }, -/* 46 */ -/***/ function(module, exports) { - -// IE 8- don't enum bug keys -module.exports = ( - 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' -).split(','); - -/***/ }, -/* 47 */ -/***/ function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(2).document && document.documentElement; - -/***/ }, -/* 48 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; -var LIBRARY = __webpack_require__(49) - , $export = __webpack_require__(15) - , redefine = __webpack_require__(106) - , hide = __webpack_require__(7) - , has = __webpack_require__(16) - , Iterators = __webpack_require__(9) - , $iterCreate = __webpack_require__(96) - , setToStringTag = __webpack_require__(24) - , getPrototypeOf = __webpack_require__(102) - , ITERATOR = __webpack_require__(1)('iterator') - , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next` - , FF_ITERATOR = '@@iterator' - , KEYS = 'keys' - , VALUES = 'values'; - -var returnThis = function(){ return this; }; - -module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){ - $iterCreate(Constructor, NAME, next); - var getMethod = function(kind){ - if(!BUGGY && kind in proto)return proto[kind]; - switch(kind){ - case KEYS: return function keys(){ return new Constructor(this, kind); }; - case VALUES: return function values(){ return new Constructor(this, kind); }; - } return function entries(){ return new Constructor(this, kind); }; - }; - var TAG = NAME + ' Iterator' - , DEF_VALUES = DEFAULT == VALUES - , VALUES_BUG = false - , proto = Base.prototype - , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT] - , $default = $native || getMethod(DEFAULT) - , $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined - , $anyNative = NAME == 'Array' ? proto.entries || $native : $native - , methods, key, IteratorPrototype; - // Fix native - if($anyNative){ - IteratorPrototype = getPrototypeOf($anyNative.call(new Base)); - if(IteratorPrototype !== Object.prototype){ - // Set @@toStringTag to native iterators - setToStringTag(IteratorPrototype, TAG, true); - // fix for some old engines - if(!LIBRARY && !has(IteratorPrototype, ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis); - } - } - // fix Array#{values, @@iterator}.name in V8 / FF - if(DEF_VALUES && $native && $native.name !== VALUES){ - VALUES_BUG = true; - $default = function values(){ return $native.call(this); }; - } - // Define iterator - if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){ - hide(proto, ITERATOR, $default); - } - // Plug for library - Iterators[NAME] = $default; - Iterators[TAG] = returnThis; - if(DEFAULT){ - methods = { - values: DEF_VALUES ? $default : getMethod(VALUES), - keys: IS_SET ? $default : getMethod(KEYS), - entries: $entries - }; - if(FORCED)for(key in methods){ - if(!(key in proto))redefine(proto, key, methods[key]); - } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); - } - return methods; -}; - -/***/ }, -/* 49 */ -/***/ function(module, exports) { - -module.exports = true; - -/***/ }, -/* 50 */ -/***/ function(module, exports, __webpack_require__) { - -// 19.1.2.14 / 15.2.3.14 Object.keys(O) -var $keys = __webpack_require__(103) - , enumBugKeys = __webpack_require__(46); - -module.exports = Object.keys || function keys(O){ - return $keys(O, enumBugKeys); -}; - -/***/ }, -/* 51 */ -/***/ function(module, exports) { - -module.exports = function(bitmap, value){ - return { - enumerable : !(bitmap & 1), - configurable: !(bitmap & 2), - writable : !(bitmap & 4), - value : value - }; -}; - -/***/ }, -/* 52 */ -/***/ function(module, exports, __webpack_require__) { - -var global = __webpack_require__(2) - , SHARED = '__core-js_shared__' - , store = global[SHARED] || (global[SHARED] = {}); -module.exports = function(key){ - return store[key] || (store[key] = {}); -}; - -/***/ }, -/* 53 */ -/***/ function(module, exports, __webpack_require__) { - -var ctx = __webpack_require__(14) - , invoke = __webpack_require__(92) - , html = __webpack_require__(47) - , cel = __webpack_require__(22) - , global = __webpack_require__(2) - , process = global.process - , setTask = global.setImmediate - , clearTask = global.clearImmediate - , MessageChannel = global.MessageChannel - , counter = 0 - , queue = {} - , ONREADYSTATECHANGE = 'onreadystatechange' - , defer, channel, port; -var run = function(){ - var id = +this; - if(queue.hasOwnProperty(id)){ - var fn = queue[id]; - delete queue[id]; - fn(); - } -}; -var listener = function(event){ - run.call(event.data); -}; -// Node.js 0.9+ & IE10+ has setImmediate, otherwise: -if(!setTask || !clearTask){ - setTask = function setImmediate(fn){ - var args = [], i = 1; - while(arguments.length > i)args.push(arguments[i++]); - queue[++counter] = function(){ - invoke(typeof fn == 'function' ? fn : Function(fn), args); - }; - defer(counter); - return counter; - }; - clearTask = function clearImmediate(id){ - delete queue[id]; - }; - // Node.js 0.8- - if(__webpack_require__(13)(process) == 'process'){ - defer = function(id){ - process.nextTick(ctx(run, id, 1)); - }; - // Browsers with MessageChannel, includes WebWorkers - } else if(MessageChannel){ - channel = new MessageChannel; - port = channel.port2; - channel.port1.onmessage = listener; - defer = ctx(port.postMessage, port, 1); - // Browsers with postMessage, skip WebWorkers - // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' - } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ - defer = function(id){ - global.postMessage(id + '', '*'); - }; - global.addEventListener('message', listener, false); - // IE8- - } else if(ONREADYSTATECHANGE in cel('script')){ - defer = function(id){ - html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ - html.removeChild(this); - run.call(id); - }; - }; - // Rest old browsers - } else { - defer = function(id){ - setTimeout(ctx(run, id, 1), 0); - }; - } -} -module.exports = { - set: setTask, - clear: clearTask -}; - -/***/ }, -/* 54 */ -/***/ function(module, exports, __webpack_require__) { - -// 7.1.15 ToLength -var toInteger = __webpack_require__(26) - , min = Math.min; -module.exports = function(it){ - return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 -}; - -/***/ }, -/* 55 */ -/***/ function(module, exports, __webpack_require__) { - -// 7.1.13 ToObject(argument) -var defined = __webpack_require__(21); -module.exports = function(it){ - return Object(defined(it)); -}; - -/***/ }, -/* 56 */ -/***/ function(module, exports) { - -var id = 0 - , px = Math.random(); -module.exports = function(key){ - return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); -}; - -/***/ }, -/* 57 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/** - * Module dependencies - */ - -var XMLHttpRequest = __webpack_require__(29); -var XHR = __webpack_require__(127); -var JSONP = __webpack_require__(126); -var websocket = __webpack_require__(128); - -/** - * Export transports. - */ - -exports.polling = polling; -exports.websocket = websocket; - -/** - * Polling transport polymorphic constructor. - * Decides on xhr vs jsonp based on feature detection. - * - * @api private - */ - -function polling(opts){ - var xhr; - var xd = false; - var xs = false; - var jsonp = false !== opts.jsonp; - - if (global.location) { - var isSSL = 'https:' == location.protocol; - var port = location.port; - - // some user agents have empty `location.port` - if (!port) { - port = isSSL ? 443 : 80; - } - - xd = opts.hostname != location.hostname || port != opts.port; - xs = opts.secure != isSSL; - } - - opts.xdomain = xd; - opts.xscheme = xs; - xhr = new XMLHttpRequest(opts); - - if ('open' in xhr && !opts.forceJSONP) { - return new XHR(opts); - } else { - if (!jsonp) throw new Error('JSONP disabled'); - return new JSONP(opts); - } -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }, -/* 58 */ -/***/ function(module, exports, __webpack_require__) { - -/** - * Module dependencies. - */ - -var Transport = __webpack_require__(28); -var parseqs = __webpack_require__(33); -var parser = __webpack_require__(8); -var inherit = __webpack_require__(12); -var yeast = __webpack_require__(69); -var debug = __webpack_require__(4)('engine.io-client:polling'); - -/** - * Module exports. - */ - -module.exports = Polling; - -/** - * Is XHR2 supported? - */ - -var hasXHR2 = (function() { - var XMLHttpRequest = __webpack_require__(29); - var xhr = new XMLHttpRequest({ xdomain: false }); - return null != xhr.responseType; -})(); - -/** - * Polling interface. - * - * @param {Object} opts - * @api private - */ - -function Polling(opts){ - var forceBase64 = (opts && opts.forceBase64); - if (!hasXHR2 || forceBase64) { - this.supportsBinary = false; - } - Transport.call(this, opts); -} - -/** - * Inherits from Transport. - */ - -inherit(Polling, Transport); - -/** - * Transport name. - */ - -Polling.prototype.name = 'polling'; - -/** - * Opens the socket (triggers polling). We write a PING message to determine - * when the transport is open. - * - * @api private - */ - -Polling.prototype.doOpen = function(){ - this.poll(); -}; - -/** - * Pauses polling. - * - * @param {Function} callback upon buffers are flushed and transport is paused - * @api private - */ - -Polling.prototype.pause = function(onPause){ - var pending = 0; - var self = this; - - this.readyState = 'pausing'; - - function pause(){ - debug('paused'); - self.readyState = 'paused'; - onPause(); - } - - if (this.polling || !this.writable) { - var total = 0; - - if (this.polling) { - debug('we are currently polling - waiting to pause'); - total++; - this.once('pollComplete', function(){ - debug('pre-pause polling complete'); - --total || pause(); - }); - } - - if (!this.writable) { - debug('we are currently writing - waiting to pause'); - total++; - this.once('drain', function(){ - debug('pre-pause writing complete'); - --total || pause(); - }); - } - } else { - pause(); - } -}; - -/** - * Starts polling cycle. - * - * @api public - */ - -Polling.prototype.poll = function(){ - debug('polling'); - this.polling = true; - this.doPoll(); - this.emit('poll'); -}; - -/** - * Overloads onData to detect payloads. - * - * @api private - */ - -Polling.prototype.onData = function(data){ - var self = this; - debug('polling got data %s', data); - var callback = function(packet, index, total) { - // if its the first message we consider the transport open - if ('opening' == self.readyState) { - self.onOpen(); - } - - // if its a close packet, we close the ongoing requests - if ('close' == packet.type) { - self.onClose(); - return false; - } - - // otherwise bypass onData and handle the message - self.onPacket(packet); - }; - - // decode payload - parser.decodePayload(data, this.socket.binaryType, callback); - - // if an event did not trigger closing - if ('closed' != this.readyState) { - // if we got data we're not polling - this.polling = false; - this.emit('pollComplete'); - - if ('open' == this.readyState) { - this.poll(); - } else { - debug('ignoring poll - transport state "%s"', this.readyState); - } - } -}; - -/** - * For polling, send a close packet. - * - * @api private - */ - -Polling.prototype.doClose = function(){ - var self = this; - - function close(){ - debug('writing close packet'); - self.write([{ type: 'close' }]); - } - - if ('open' == this.readyState) { - debug('transport open - closing'); - close(); - } else { - // in case we're trying to close while - // handshaking is in progress (GH-164) - debug('transport not open - deferring close'); - this.once('open', close); - } -}; - -/** - * Writes a packets payload. - * - * @param {Array} data packets - * @param {Function} drain callback - * @api private - */ - -Polling.prototype.write = function(packets){ - var self = this; - this.writable = false; - var callbackfn = function() { - self.writable = true; - self.emit('drain'); - }; - - var self = this; - parser.encodePayload(packets, this.supportsBinary, function(data) { - self.doWrite(data, callbackfn); - }); -}; - -/** - * Generates uri for connection. - * - * @api private - */ - -Polling.prototype.uri = function(){ - var query = this.query || {}; - var schema = this.secure ? 'https' : 'http'; - var port = ''; - - // cache busting is forced - if (false !== this.timestampRequests) { - query[this.timestampParam] = yeast(); - } - - if (!this.supportsBinary && !query.sid) { - query.b64 = 1; - } - - query = parseqs.encode(query); - - // avoid port if default for schema - if (this.port && (('https' == schema && this.port != 443) || - ('http' == schema && this.port != 80))) { - port = ':' + this.port; - } - - // prepend ? to query - if (query.length) { - query = '?' + query; - } - - var ipv6 = this.hostname.indexOf(':') !== -1; - return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query; -}; - - -/***/ }, -/* 59 */ -/***/ function(module, exports) { - - -var indexOf = [].indexOf; - -module.exports = function(arr, obj){ - if (indexOf) return arr.indexOf(obj); - for (var i = 0; i < arr.length; ++i) { - if (arr[i] === obj) return i; - } - return -1; -}; - -/***/ }, -/* 60 */ -/***/ function(module, exports) { - -"use strict"; -'use strict'; - -module.exports = { - createWriteStream: function(filename, options) { - return; - }, - writeFileSync: function() { - return; - }, - openSync: function() { - return; - }, - writeSync: function() { - return; - } -} - - -/***/ }, -/* 61 */ -/***/ function(module, exports) { - -"use strict"; -'use strict'; - -class EventIndex { - constructor() { - this._index = {}; - } - - get() { - return Object.keys(this._index).map((f) => this._index[f]); - } - - updateIndex(oplog, added) { - added.reduce((handled, item) => { - if(handled.indexOf(item.hash) === -1) { - handled.push(item.hash); - if(item.payload.op === 'ADD') - this._index[item.hash] = item - } - return handled; - }, []); - } -} - -module.exports = EventIndex; - - -/***/ }, -/* 62 */ -/***/ function(module, exports) { - -/** - * Parses an URI - * - * @author Steven Levithan (MIT license) - * @api private - */ - -var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; - -var parts = [ - 'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor' -]; - -module.exports = function parseuri(str) { - var src = str, - b = str.indexOf('['), - e = str.indexOf(']'); - - if (b != -1 && e != -1) { - str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length); - } - - var m = re.exec(str || ''), - uri = {}, - i = 14; - - while (i--) { - uri[parts[i]] = m[i] || ''; - } - - if (b != -1 && e != -1) { - uri.source = src; - uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':'); - uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':'); - uri.ipv6uri = true; - } - - return uri; -}; - - -/***/ }, -/* 63 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array -// (so also no leading and trailing slashes - it does not distinguish -// relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18))) - -/***/ }, -/* 64 */ -/***/ function(module, exports, __webpack_require__) { - - -/** - * Module dependencies. - */ - -var eio = __webpack_require__(123); -var Socket = __webpack_require__(66); -var Emitter = __webpack_require__(44); -var parser = __webpack_require__(34); -var on = __webpack_require__(65); -var bind = __webpack_require__(43); -var debug = __webpack_require__(4)('socket.io-client:manager'); -var indexOf = __webpack_require__(59); -var Backoff = __webpack_require__(78); - -/** - * IE6+ hasOwnProperty - */ - -var has = Object.prototype.hasOwnProperty; - -/** - * Module exports - */ - -module.exports = Manager; - -/** - * `Manager` constructor. - * - * @param {String} engine instance or engine uri/opts - * @param {Object} options - * @api public - */ - -function Manager(uri, opts){ - if (!(this instanceof Manager)) return new Manager(uri, opts); - if (uri && ('object' == typeof uri)) { - opts = uri; - uri = undefined; - } - opts = opts || {}; - - opts.path = opts.path || '/socket.io'; - this.nsps = {}; - this.subs = []; - this.opts = opts; - this.reconnection(opts.reconnection !== false); - this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); - this.reconnectionDelay(opts.reconnectionDelay || 1000); - this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000); - this.randomizationFactor(opts.randomizationFactor || 0.5); - this.backoff = new Backoff({ - min: this.reconnectionDelay(), - max: this.reconnectionDelayMax(), - jitter: this.randomizationFactor() - }); - this.timeout(null == opts.timeout ? 20000 : opts.timeout); - this.readyState = 'closed'; - this.uri = uri; - this.connecting = []; - this.lastPing = null; - this.encoding = false; - this.packetBuffer = []; - this.encoder = new parser.Encoder(); - this.decoder = new parser.Decoder(); - this.autoConnect = opts.autoConnect !== false; - if (this.autoConnect) this.open(); -} - -/** - * Propagate given event to sockets and emit on `this` - * - * @api private - */ - -Manager.prototype.emitAll = function() { - this.emit.apply(this, arguments); - for (var nsp in this.nsps) { - if (has.call(this.nsps, nsp)) { - this.nsps[nsp].emit.apply(this.nsps[nsp], arguments); - } - } -}; - -/** - * Update `socket.id` of all sockets - * - * @api private - */ - -Manager.prototype.updateSocketIds = function(){ - for (var nsp in this.nsps) { - if (has.call(this.nsps, nsp)) { - this.nsps[nsp].id = this.engine.id; - } - } -}; - -/** - * Mix in `Emitter`. - */ - -Emitter(Manager.prototype); - -/** - * Sets the `reconnection` config. - * - * @param {Boolean} true/false if it should automatically reconnect - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.reconnection = function(v){ - if (!arguments.length) return this._reconnection; - this._reconnection = !!v; - return this; -}; - -/** - * Sets the reconnection attempts config. - * - * @param {Number} max reconnection attempts before giving up - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.reconnectionAttempts = function(v){ - if (!arguments.length) return this._reconnectionAttempts; - this._reconnectionAttempts = v; - return this; -}; - -/** - * Sets the delay between reconnections. - * - * @param {Number} delay - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.reconnectionDelay = function(v){ - if (!arguments.length) return this._reconnectionDelay; - this._reconnectionDelay = v; - this.backoff && this.backoff.setMin(v); - return this; -}; - -Manager.prototype.randomizationFactor = function(v){ - if (!arguments.length) return this._randomizationFactor; - this._randomizationFactor = v; - this.backoff && this.backoff.setJitter(v); - return this; -}; - -/** - * Sets the maximum delay between reconnections. - * - * @param {Number} delay - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.reconnectionDelayMax = function(v){ - if (!arguments.length) return this._reconnectionDelayMax; - this._reconnectionDelayMax = v; - this.backoff && this.backoff.setMax(v); - return this; -}; - -/** - * Sets the connection timeout. `false` to disable - * - * @return {Manager} self or value - * @api public - */ - -Manager.prototype.timeout = function(v){ - if (!arguments.length) return this._timeout; - this._timeout = v; - return this; -}; - -/** - * Starts trying to reconnect if reconnection is enabled and we have not - * started reconnecting yet - * - * @api private - */ - -Manager.prototype.maybeReconnectOnOpen = function() { - // Only try to reconnect if it's the first time we're connecting - if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) { - // keeps reconnection from firing twice for the same reconnection loop - this.reconnect(); - } -}; - - -/** - * Sets the current transport `socket`. - * - * @param {Function} optional, callback - * @return {Manager} self - * @api public - */ - -Manager.prototype.open = -Manager.prototype.connect = function(fn){ - debug('readyState %s', this.readyState); - if (~this.readyState.indexOf('open')) return this; - - debug('opening %s', this.uri); - this.engine = eio(this.uri, this.opts); - var socket = this.engine; - var self = this; - this.readyState = 'opening'; - this.skipReconnect = false; - - // emit `open` - var openSub = on(socket, 'open', function() { - self.onopen(); - fn && fn(); - }); - - // emit `connect_error` - var errorSub = on(socket, 'error', function(data){ - debug('connect_error'); - self.cleanup(); - self.readyState = 'closed'; - self.emitAll('connect_error', data); - if (fn) { - var err = new Error('Connection error'); - err.data = data; - fn(err); - } else { - // Only do this if there is no fn to handle the error - self.maybeReconnectOnOpen(); - } - }); - - // emit `connect_timeout` - if (false !== this._timeout) { - var timeout = this._timeout; - debug('connect attempt will timeout after %d', timeout); - - // set timer - var timer = setTimeout(function(){ - debug('connect attempt timed out after %d', timeout); - openSub.destroy(); - socket.close(); - socket.emit('error', 'timeout'); - self.emitAll('connect_timeout', timeout); - }, timeout); - - this.subs.push({ - destroy: function(){ - clearTimeout(timer); - } - }); - } - - this.subs.push(openSub); - this.subs.push(errorSub); - - return this; -}; - -/** - * Called upon transport open. - * - * @api private - */ - -Manager.prototype.onopen = function(){ - debug('open'); - - // clear old subs - this.cleanup(); - - // mark as open - this.readyState = 'open'; - this.emit('open'); - - // add new subs - var socket = this.engine; - this.subs.push(on(socket, 'data', bind(this, 'ondata'))); - this.subs.push(on(socket, 'ping', bind(this, 'onping'))); - this.subs.push(on(socket, 'pong', bind(this, 'onpong'))); - this.subs.push(on(socket, 'error', bind(this, 'onerror'))); - this.subs.push(on(socket, 'close', bind(this, 'onclose'))); - this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded'))); -}; - -/** - * Called upon a ping. - * - * @api private - */ - -Manager.prototype.onping = function(){ - this.lastPing = new Date; - this.emitAll('ping'); -}; - -/** - * Called upon a packet. - * - * @api private - */ - -Manager.prototype.onpong = function(){ - this.emitAll('pong', new Date - this.lastPing); -}; - -/** - * Called with data. - * - * @api private - */ - -Manager.prototype.ondata = function(data){ - this.decoder.add(data); -}; - -/** - * Called when parser fully decodes a packet. - * - * @api private - */ - -Manager.prototype.ondecoded = function(packet) { - this.emit('packet', packet); -}; - -/** - * Called upon socket error. - * - * @api private - */ - -Manager.prototype.onerror = function(err){ - debug('error', err); - this.emitAll('error', err); -}; - -/** - * Creates a new socket for the given `nsp`. - * - * @return {Socket} - * @api public - */ - -Manager.prototype.socket = function(nsp){ - var socket = this.nsps[nsp]; - if (!socket) { - socket = new Socket(this, nsp); - this.nsps[nsp] = socket; - var self = this; - socket.on('connecting', onConnecting); - socket.on('connect', function(){ - socket.id = self.engine.id; - }); - - if (this.autoConnect) { - // manually call here since connecting evnet is fired before listening - onConnecting(); - } - } - - function onConnecting() { - if (!~indexOf(self.connecting, socket)) { - self.connecting.push(socket); - } - } - - return socket; -}; - -/** - * Called upon a socket close. - * - * @param {Socket} socket - */ - -Manager.prototype.destroy = function(socket){ - var index = indexOf(this.connecting, socket); - if (~index) this.connecting.splice(index, 1); - if (this.connecting.length) return; - - this.close(); -}; - -/** - * Writes a packet. - * - * @param {Object} packet - * @api private - */ - -Manager.prototype.packet = function(packet){ - debug('writing packet %j', packet); - var self = this; - - if (!self.encoding) { - // encode, then write to engine with result - self.encoding = true; - this.encoder.encode(packet, function(encodedPackets) { - for (var i = 0; i < encodedPackets.length; i++) { - self.engine.write(encodedPackets[i], packet.options); - } - self.encoding = false; - self.processPacketQueue(); - }); - } else { // add packet to the queue - self.packetBuffer.push(packet); - } -}; - -/** - * If packet buffer is non-empty, begins encoding the - * next packet in line. - * - * @api private - */ - -Manager.prototype.processPacketQueue = function() { - if (this.packetBuffer.length > 0 && !this.encoding) { - var pack = this.packetBuffer.shift(); - this.packet(pack); - } -}; - -/** - * Clean up transport subscriptions and packet buffer. - * - * @api private - */ - -Manager.prototype.cleanup = function(){ - debug('cleanup'); - - var sub; - while (sub = this.subs.shift()) sub.destroy(); - - this.packetBuffer = []; - this.encoding = false; - this.lastPing = null; - - this.decoder.destroy(); -}; - -/** - * Close the current socket. - * - * @api private - */ - -Manager.prototype.close = -Manager.prototype.disconnect = function(){ - debug('disconnect'); - this.skipReconnect = true; - this.reconnecting = false; - if ('opening' == this.readyState) { - // `onclose` will not fire because - // an open event never happened - this.cleanup(); - } - this.backoff.reset(); - this.readyState = 'closed'; - if (this.engine) this.engine.close(); -}; - -/** - * Called upon engine close. - * - * @api private - */ - -Manager.prototype.onclose = function(reason){ - debug('onclose'); - - this.cleanup(); - this.backoff.reset(); - this.readyState = 'closed'; - this.emit('close', reason); - - if (this._reconnection && !this.skipReconnect) { - this.reconnect(); - } -}; - -/** - * Attempt a reconnection. - * - * @api private - */ - -Manager.prototype.reconnect = function(){ - if (this.reconnecting || this.skipReconnect) return this; - - var self = this; - - if (this.backoff.attempts >= this._reconnectionAttempts) { - debug('reconnect failed'); - this.backoff.reset(); - this.emitAll('reconnect_failed'); - this.reconnecting = false; - } else { - var delay = this.backoff.duration(); - debug('will wait %dms before reconnect attempt', delay); - - this.reconnecting = true; - var timer = setTimeout(function(){ - if (self.skipReconnect) return; - - debug('attempting reconnect'); - self.emitAll('reconnect_attempt', self.backoff.attempts); - self.emitAll('reconnecting', self.backoff.attempts); - - // check again for the case socket closed in above events - if (self.skipReconnect) return; - - self.open(function(err){ - if (err) { - debug('reconnect attempt error'); - self.reconnecting = false; - self.reconnect(); - self.emitAll('reconnect_error', err.data); - } else { - debug('reconnect success'); - self.onreconnect(); - } - }); - }, delay); - - this.subs.push({ - destroy: function(){ - clearTimeout(timer); - } - }); - } -}; - -/** - * Called upon successful reconnect. - * - * @api private - */ - -Manager.prototype.onreconnect = function(){ - var attempt = this.backoff.attempts; - this.reconnecting = false; - this.backoff.reset(); - this.updateSocketIds(); - this.emitAll('reconnect', attempt); -}; - - -/***/ }, -/* 65 */ -/***/ function(module, exports) { - - -/** - * Module exports. - */ - -module.exports = on; - -/** - * Helper for subscriptions. - * - * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter` - * @param {String} event name - * @param {Function} callback - * @api public - */ - -function on(obj, ev, fn) { - obj.on(ev, fn); - return { - destroy: function(){ - obj.removeListener(ev, fn); - } - }; -} - - -/***/ }, -/* 66 */ -/***/ function(module, exports, __webpack_require__) { - - -/** - * Module dependencies. - */ - -var parser = __webpack_require__(34); -var Emitter = __webpack_require__(44); -var toArray = __webpack_require__(154); -var on = __webpack_require__(65); -var bind = __webpack_require__(43); -var debug = __webpack_require__(4)('socket.io-client:socket'); -var hasBin = __webpack_require__(132); - -/** - * Module exports. - */ - -module.exports = exports = Socket; - -/** - * Internal events (blacklisted). - * These events can't be emitted by the user. - * - * @api private - */ - -var events = { - connect: 1, - connect_error: 1, - connect_timeout: 1, - connecting: 1, - disconnect: 1, - error: 1, - reconnect: 1, - reconnect_attempt: 1, - reconnect_failed: 1, - reconnect_error: 1, - reconnecting: 1, - ping: 1, - pong: 1 -}; - -/** - * Shortcut to `Emitter#emit`. - */ - -var emit = Emitter.prototype.emit; - -/** - * `Socket` constructor. - * - * @api public - */ - -function Socket(io, nsp){ - this.io = io; - this.nsp = nsp; - this.json = this; // compat - this.ids = 0; - this.acks = {}; - this.receiveBuffer = []; - this.sendBuffer = []; - this.connected = false; - this.disconnected = true; - if (this.io.autoConnect) this.open(); -} - -/** - * Mix in `Emitter`. - */ - -Emitter(Socket.prototype); - -/** - * Subscribe to open, close and packet events - * - * @api private - */ - -Socket.prototype.subEvents = function() { - if (this.subs) return; - - var io = this.io; - this.subs = [ - on(io, 'open', bind(this, 'onopen')), - on(io, 'packet', bind(this, 'onpacket')), - on(io, 'close', bind(this, 'onclose')) - ]; -}; - -/** - * "Opens" the socket. - * - * @api public - */ - -Socket.prototype.open = -Socket.prototype.connect = function(){ - if (this.connected) return this; - - this.subEvents(); - this.io.open(); // ensure open - if ('open' == this.io.readyState) this.onopen(); - this.emit('connecting'); - return this; -}; - -/** - * Sends a `message` event. - * - * @return {Socket} self - * @api public - */ - -Socket.prototype.send = function(){ - var args = toArray(arguments); - args.unshift('message'); - this.emit.apply(this, args); - return this; -}; - -/** - * Override `emit`. - * If the event is in `events`, it's emitted normally. - * - * @param {String} event name - * @return {Socket} self - * @api public - */ - -Socket.prototype.emit = function(ev){ - if (events.hasOwnProperty(ev)) { - emit.apply(this, arguments); - return this; - } - - var args = toArray(arguments); - var parserType = parser.EVENT; // default - if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary - var packet = { type: parserType, data: args }; - - packet.options = {}; - packet.options.compress = !this.flags || false !== this.flags.compress; - - // event ack callback - if ('function' == typeof args[args.length - 1]) { - debug('emitting packet with ack id %d', this.ids); - this.acks[this.ids] = args.pop(); - packet.id = this.ids++; - } - - if (this.connected) { - this.packet(packet); - } else { - this.sendBuffer.push(packet); - } - - delete this.flags; - - return this; -}; - -/** - * Sends a packet. - * - * @param {Object} packet - * @api private - */ - -Socket.prototype.packet = function(packet){ - packet.nsp = this.nsp; - this.io.packet(packet); -}; - -/** - * Called upon engine `open`. - * - * @api private - */ - -Socket.prototype.onopen = function(){ - debug('transport is open - connecting'); - - // write connect packet if necessary - if ('/' != this.nsp) { - this.packet({ type: parser.CONNECT }); - } -}; - -/** - * Called upon engine `close`. - * - * @param {String} reason - * @api private - */ - -Socket.prototype.onclose = function(reason){ - debug('close (%s)', reason); - this.connected = false; - this.disconnected = true; - delete this.id; - this.emit('disconnect', reason); -}; - -/** - * Called with socket packet. - * - * @param {Object} packet - * @api private - */ - -Socket.prototype.onpacket = function(packet){ - if (packet.nsp != this.nsp) return; - - switch (packet.type) { - case parser.CONNECT: - this.onconnect(); - break; - - case parser.EVENT: - this.onevent(packet); - break; - - case parser.BINARY_EVENT: - this.onevent(packet); - break; - - case parser.ACK: - this.onack(packet); - break; - - case parser.BINARY_ACK: - this.onack(packet); - break; - - case parser.DISCONNECT: - this.ondisconnect(); - break; - - case parser.ERROR: - this.emit('error', packet.data); - break; - } -}; - -/** - * Called upon a server event. - * - * @param {Object} packet - * @api private - */ - -Socket.prototype.onevent = function(packet){ - var args = packet.data || []; - debug('emitting event %j', args); - - if (null != packet.id) { - debug('attaching ack callback to event'); - args.push(this.ack(packet.id)); - } - - if (this.connected) { - emit.apply(this, args); - } else { - this.receiveBuffer.push(args); - } -}; - -/** - * Produces an ack callback to emit with an event. - * - * @api private - */ - -Socket.prototype.ack = function(id){ - var self = this; - var sent = false; - return function(){ - // prevent double callbacks - if (sent) return; - sent = true; - var args = toArray(arguments); - debug('sending ack %j', args); - - var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK; - self.packet({ - type: type, - id: id, - data: args - }); - }; -}; - -/** - * Called upon a server acknowlegement. - * - * @param {Object} packet - * @api private - */ - -Socket.prototype.onack = function(packet){ - var ack = this.acks[packet.id]; - if ('function' == typeof ack) { - debug('calling ack %s with %j', packet.id, packet.data); - ack.apply(this, packet.data); - delete this.acks[packet.id]; - } else { - debug('bad ack %s', packet.id); - } -}; - -/** - * Called upon server connect. - * - * @api private - */ - -Socket.prototype.onconnect = function(){ - this.connected = true; - this.disconnected = false; - this.emit('connect'); - this.emitBuffered(); -}; - -/** - * Emit buffered events (received and emitted). - * - * @api private - */ - -Socket.prototype.emitBuffered = function(){ - var i; - for (i = 0; i < this.receiveBuffer.length; i++) { - emit.apply(this, this.receiveBuffer[i]); - } - this.receiveBuffer = []; - - for (i = 0; i < this.sendBuffer.length; i++) { - this.packet(this.sendBuffer[i]); - } - this.sendBuffer = []; -}; - -/** - * Called upon server disconnect. - * - * @api private - */ - -Socket.prototype.ondisconnect = function(){ - debug('server disconnect (%s)', this.nsp); - this.destroy(); - this.onclose('io server disconnect'); -}; - -/** - * Called upon forced client/server side disconnections, - * this method ensures the manager stops tracking us and - * that reconnections don't get triggered for this. - * - * @api private. - */ - -Socket.prototype.destroy = function(){ - if (this.subs) { - // clean subscriptions to avoid reconnections - for (var i = 0; i < this.subs.length; i++) { - this.subs[i].destroy(); - } - this.subs = null; - } - - this.io.destroy(this); -}; - -/** - * Disconnects the socket manually. - * - * @return {Socket} self - * @api public - */ - -Socket.prototype.close = -Socket.prototype.disconnect = function(){ - if (this.connected) { - debug('performing disconnect (%s)', this.nsp); - this.packet({ type: parser.DISCONNECT }); - } - - // remove socket from pool - this.destroy(); - - if (this.connected) { - // fire events - this.onclose('io client disconnect'); - } - return this; -}; - -/** - * Sets the compress flag. - * - * @param {Boolean} if `true`, compresses the sending data - * @return {Socket} self - * @api public - */ - -Socket.prototype.compress = function(compress){ - this.flags = this.flags || {}; - this.flags.compress = compress; - return this; -}; - - -/***/ }, -/* 67 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) { -module.exports = isBuf; - -/** - * Returns true if obj is a buffer or an arraybuffer. - * - * @api private - */ - -function isBuf(obj) { - return (global.Buffer && global.Buffer.isBuffer(obj)) || - (global.ArrayBuffer && obj instanceof ArrayBuffer); -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }, -/* 68 */ -/***/ function(module, exports) { - -module.exports = Array.isArray || function (arr) { - return Object.prototype.toString.call(arr) == '[object Array]'; -}; - - -/***/ }, -/* 69 */ -/***/ function(module, exports) { - -"use strict"; -'use strict'; - -var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split('') - , length = 64 - , map = {} - , seed = 0 - , i = 0 - , prev; - -/** - * Return a string representing the specified number. - * - * @param {Number} num The number to convert. - * @returns {String} The string representation of the number. - * @api public - */ -function encode(num) { - var encoded = ''; - - do { - encoded = alphabet[num % length] + encoded; - num = Math.floor(num / length); - } while (num > 0); - - return encoded; -} - -/** - * Return the integer value specified by the given string. - * - * @param {String} str The string to convert. - * @returns {Number} The integer value represented by the string. - * @api public - */ -function decode(str) { - var decoded = 0; - - for (i = 0; i < str.length; i++) { - decoded = decoded * length + map[str.charAt(i)]; - } - - return decoded; -} - -/** - * Yeast: A tiny growing id generator. - * - * @returns {String} A unique id. - * @api public - */ -function yeast() { - var now = encode(+new Date()); - - if (now !== prev) return seed = 0, prev = now; - return now +'.'+ encode(seed++); -} - -// -// Map each character to its index. -// -for (; i < length; i++) map[alphabet[i]] = i; - -// -// Expose the `yeast`, `encode` and `decode` functions. -// -yeast.encode = encode; -yeast.decode = decode; -module.exports = yeast; - - -/***/ }, -/* 70 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; - -var _stringify = __webpack_require__(36); - -var _stringify2 = _interopRequireDefault(_stringify); - -var _promise = __webpack_require__(37); - -var _promise2 = _interopRequireDefault(_promise); - -var _classCallCheck2 = __webpack_require__(38); - -var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); - -var _createClass2 = __webpack_require__(39); - -var _createClass3 = _interopRequireDefault(_createClass2); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var io = __webpack_require__(150); -var logger = __webpack_require__(41).create("orbit-db.Pubsub"); - -var Pubsub = function () { - function Pubsub() { - (0, _classCallCheck3.default)(this, Pubsub); - - this._socket = null; - this._subscriptions = {}; - } - - (0, _createClass3.default)(Pubsub, [{ - key: 'connect', - value: function connect(host, port, username, password) { - var _this = this; - - return new _promise2.default(function (resolve, reject) { - if (!_this._socket) _this._socket = io.connect('http://' + host + ':' + port, { 'forceNew': true }); - - _this._socket.on('connect', resolve); - _this._socket.on('connect_error', function (err) { - return reject(new Error('Connection refused to Pubsub at \'' + host + ':' + port + '\'')); - }); - _this._socket.on('disconnect', function (socket) { - return logger.warn('Disconnected from Pubsub at \'http://' + host + ':' + port + '\''); - }); - _this._socket.on('error', function (e) { - return logger.error('Pubsub socket error:', e); - }); - _this._socket.on('message', _this._handleMessage.bind(_this)); - _this._socket.on('subscribed', _this._handleSubscribed.bind(_this)); - }); - } - }, { - key: 'disconnect', - value: function disconnect() { - if (this._socket) this._socket.disconnect(); - } - }, { - key: 'subscribe', - value: function subscribe(hash, password, callback, fetchHistory) { - if (!this._subscriptions[hash]) { - this._subscriptions[hash] = { callback: callback, history: fetchHistory }; - this._socket.emit('subscribe', { channel: hash }); // calls back with 'subscribed' event - } - } - }, { - key: 'unsubscribe', - value: function unsubscribe(hash) { - if (this._subscriptions[hash]) { - this._socket.emit('unsubscribe', { channel: hash }); - delete this._subscriptions[hash]; - } - } - }, { - key: 'publish', - value: function publish(hash, message) { - if (this._subscriptions[hash]) this._socket.send((0, _stringify2.default)({ channel: hash, message: message })); - } - }, { - key: '_handleMessage', - value: function _handleMessage(hash, message) { - var subscription = this._subscriptions[hash]; - if (subscription && subscription.callback) subscription.callback(hash, message); - } - }, { - key: '_handleSubscribed', - value: function _handleSubscribed(hash, message) { - var subscription = this._subscriptions[hash]; - if (subscription && subscription.history && subscription.callback) subscription.callback(hash, message); - } - }]); - return Pubsub; -}(); - -module.exports = Pubsub; - -/***/ }, -/* 71 */ -/***/ function(module, exports, __webpack_require__) { - -module.exports = { "default": __webpack_require__(85), __esModule: true }; - -/***/ }, -/* 72 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; - -const Store = __webpack_require__(32); -const CounterIndex = __webpack_require__(143); - -class CounterStore extends Store { - constructor(ipfs, id, dbname, options) { - if(!options) options = {}; - if(!options.Index) Object.assign(options, { Index: CounterIndex }); - super(ipfs, id, dbname, options) - } - - value() { - return this._index.get().value; - } - - inc(amount) { - const counter = this._index.get(); - if(counter) { - counter.increment(amount); - return this._addOperation({ - op: 'COUNTER', - key: null, - value: counter.payload, - meta: { - ts: new Date().getTime() - } - }); - } - } -} - -module.exports = CounterStore; - - -/***/ }, -/* 73 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; - -const Lazy = __webpack_require__(31); -const EventStore = __webpack_require__(42); -const FeedIndex = __webpack_require__(144); - -class FeedStore extends EventStore { - constructor(ipfs, id, dbname, options) { - if(!options) options = {}; - if(!options.Index) Object.assign(options, { Index: FeedIndex }); - super(ipfs, id, dbname, options) - } - - remove(hash) { - const operation = { - op: 'DEL', - key: null, - value: hash, - meta: { - ts: new Date().getTime() - } - }; - return this._addOperation(operation); - } -} - -module.exports = FeedStore; - - -/***/ }, -/* 74 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; - -const Store = __webpack_require__(32); -const KeyValueIndex = __webpack_require__(145); - -class KeyValueStore extends Store { - constructor(ipfs, id, dbname, options) { - if(!options) options = {}; - if(!options.Index) Object.assign(options, { Index: KeyValueIndex }); - super(ipfs, id, dbname, options) - } - - get(key) { - return this._index.get(key); - } - - set(key, data) { - this.put(key, data); - } - - put(key, data) { - return this._addOperation({ - op: 'PUT', - key: key, - value: data, - meta: { - ts: new Date().getTime() - } - }); - } - - del(key) { - return this._addOperation({ - op: 'DEL', - key: key, - value: null, - meta: { - ts: new Date().getTime() - } - }); - } -} - -module.exports = KeyValueStore; - - -/***/ }, -/* 75 */ -/***/ function(module, exports) { - -module.exports = after - -function after(count, callback, err_cb) { - var bail = false - err_cb = err_cb || noop - proxy.count = count - - return (count === 0) ? callback() : proxy - - function proxy(err, result) { - if (proxy.count <= 0) { - throw new Error('after called too many times') - } - --proxy.count - - // after first error, rest are passed to err_cb - if (err) { - bail = true - callback(err) - // future error callbacks will go to error handler - callback = err_cb - } else if (proxy.count === 0 && !bail) { - callback(null, result) - } - } -} - -function noop() {} - - -/***/ }, -/* 76 */ -/***/ function(module, exports) { - -/** - * An abstraction for slicing an arraybuffer even when - * ArrayBuffer.prototype.slice is not supported - * - * @api public - */ - -module.exports = function(arraybuffer, start, end) { - var bytes = arraybuffer.byteLength; - start = start || 0; - end = end || bytes; - - if (arraybuffer.slice) { return arraybuffer.slice(start, end); } - - if (start < 0) { start += bytes; } - if (end < 0) { end += bytes; } - if (end > bytes) { end = bytes; } - - if (start >= bytes || start >= end || bytes === 0) { - return new ArrayBuffer(0); - } - - var abv = new Uint8Array(arraybuffer); - var result = new Uint8Array(end - start); - for (var i = start, ii = 0; i < end; i++, ii++) { - result[ii] = abv[i]; - } - return result.buffer; -}; - - -/***/ }, -/* 77 */ -/***/ function(module, exports, __webpack_require__) { - -module.exports = { "default": __webpack_require__(84), __esModule: true }; - -/***/ }, -/* 78 */ -/***/ function(module, exports) { - - -/** - * Expose `Backoff`. - */ - -module.exports = Backoff; - -/** - * Initialize backoff timer with `opts`. - * - * - `min` initial timeout in milliseconds [100] - * - `max` max timeout [10000] - * - `jitter` [0] - * - `factor` [2] - * - * @param {Object} opts - * @api public - */ - -function Backoff(opts) { - opts = opts || {}; - this.ms = opts.min || 100; - this.max = opts.max || 10000; - this.factor = opts.factor || 2; - this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; - this.attempts = 0; -} - -/** - * Return the backoff duration. - * - * @return {Number} - * @api public - */ - -Backoff.prototype.duration = function(){ - var ms = this.ms * Math.pow(this.factor, this.attempts++); - if (this.jitter) { - var rand = Math.random(); - var deviation = Math.floor(rand * this.jitter * ms); - ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; - } - return Math.min(ms, this.max) | 0; -}; - -/** - * Reset the number of attempts. - * - * @api public - */ - -Backoff.prototype.reset = function(){ - this.attempts = 0; -}; - -/** - * Set the minimum duration - * - * @api public - */ - -Backoff.prototype.setMin = function(min){ - this.ms = min; -}; - -/** - * Set the maximum duration - * - * @api public - */ - -Backoff.prototype.setMax = function(max){ - this.max = max; -}; - -/** - * Set the jitter - * - * @api public - */ - -Backoff.prototype.setJitter = function(jitter){ - this.jitter = jitter; -}; - - - -/***/ }, -/* 79 */ -/***/ function(module, exports) { - -/* - * base64-arraybuffer - * https://github.com/niklasvh/base64-arraybuffer - * - * Copyright (c) 2012 Niklas von Hertzen - * Licensed under the MIT license. - */ -(function(chars){ - "use strict"; - - exports.encode = function(arraybuffer) { - var bytes = new Uint8Array(arraybuffer), - i, len = bytes.length, base64 = ""; - - for (i = 0; i < len; i+=3) { - base64 += chars[bytes[i] >> 2]; - base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; - base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; - base64 += chars[bytes[i + 2] & 63]; - } - - if ((len % 3) === 2) { - base64 = base64.substring(0, base64.length - 1) + "="; - } else if (len % 3 === 1) { - base64 = base64.substring(0, base64.length - 2) + "=="; - } - - return base64; - }; - - exports.decode = function(base64) { - var bufferLength = base64.length * 0.75, - len = base64.length, i, p = 0, - encoded1, encoded2, encoded3, encoded4; - - if (base64[base64.length - 1] === "=") { - bufferLength--; - if (base64[base64.length - 2] === "=") { - bufferLength--; - } - } - - var arraybuffer = new ArrayBuffer(bufferLength), - bytes = new Uint8Array(arraybuffer); - - for (i = 0; i < len; i+=4) { - encoded1 = chars.indexOf(base64[i]); - encoded2 = chars.indexOf(base64[i+1]); - encoded3 = chars.indexOf(base64[i+2]); - encoded4 = chars.indexOf(base64[i+3]); - - bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); - bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); - bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); - } - - return arraybuffer; - }; -})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); - - -/***/ }, -/* 80 */ -/***/ function(module, exports) { - -"use strict"; -'use strict' - -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray - -var lookup = [] -var revLookup = [] -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array - -function init () { - var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i] - revLookup[code.charCodeAt(i)] = i - } - - revLookup['-'.charCodeAt(0)] = 62 - revLookup['_'.charCodeAt(0)] = 63 -} - -init() - -function toByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - var len = b64.length - - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(len * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? len - 4 : len - - var L = 0 - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] - arr[L++] = (tmp >> 16) & 0xFF - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - if (placeHolders === 2) { - tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[L++] = tmp & 0xFF - } else if (placeHolders === 1) { - tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[L++] = (tmp >> 8) & 0xFF - arr[L++] = tmp & 0xFF - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} - -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var output = '' - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - output += lookup[tmp >> 2] - output += lookup[(tmp << 4) & 0x3F] - output += '==' - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) - output += lookup[tmp >> 10] - output += lookup[(tmp >> 4) & 0x3F] - output += lookup[(tmp << 2) & 0x3F] - output += '=' - } - - parts.push(output) - - return parts.join('') -} - - -/***/ }, -/* 81 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/** - * Create a blob builder even when vendor prefixes exist - */ - -var BlobBuilder = global.BlobBuilder - || global.WebKitBlobBuilder - || global.MSBlobBuilder - || global.MozBlobBuilder; - -/** - * Check if Blob constructor is supported - */ - -var blobSupported = (function() { - try { - var a = new Blob(['hi']); - return a.size === 2; - } catch(e) { - return false; - } -})(); - -/** - * Check if Blob constructor supports ArrayBufferViews - * Fails in Safari 6, so we need to map to ArrayBuffers there. - */ - -var blobSupportsArrayBufferView = blobSupported && (function() { - try { - var b = new Blob([new Uint8Array([1,2])]); - return b.size === 2; - } catch(e) { - return false; - } -})(); - -/** - * Check if BlobBuilder is supported - */ - -var blobBuilderSupported = BlobBuilder - && BlobBuilder.prototype.append - && BlobBuilder.prototype.getBlob; - -/** - * Helper function that maps ArrayBufferViews to ArrayBuffers - * Used by BlobBuilder constructor and old browsers that didn't - * support it in the Blob constructor. - */ - -function mapArrayBufferViews(ary) { - for (var i = 0; i < ary.length; i++) { - var chunk = ary[i]; - if (chunk.buffer instanceof ArrayBuffer) { - var buf = chunk.buffer; - - // if this is a subarray, make a copy so we only - // include the subarray region from the underlying buffer - if (chunk.byteLength !== buf.byteLength) { - var copy = new Uint8Array(chunk.byteLength); - copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength)); - buf = copy.buffer; - } - - ary[i] = buf; - } - } -} - -function BlobBuilderConstructor(ary, options) { - options = options || {}; - - var bb = new BlobBuilder(); - mapArrayBufferViews(ary); - - for (var i = 0; i < ary.length; i++) { - bb.append(ary[i]); - } - - return (options.type) ? bb.getBlob(options.type) : bb.getBlob(); -}; - -function BlobConstructor(ary, options) { - mapArrayBufferViews(ary); - return new Blob(ary, options || {}); -}; - -module.exports = (function() { - if (blobSupported) { - return blobSupportsArrayBufferView ? global.Blob : BlobConstructor; - } else if (blobBuilderSupported) { - return BlobBuilderConstructor; - } else { - return undefined; - } -})(); - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }, -/* 82 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(process, global, setImmediate) {/* @preserve - * The MIT License (MIT) - * - * Copyright (c) 2013-2015 Petka Antonov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ -/** - * bluebird build version 3.4.1 - * Features enabled: core, race, call_get, generators, map, nodeify, promisify, props, reduce, settle, some, using, timers, filter, any, each -*/ -!function(e){if(true)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Promise=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof _dereq_=="function"&&_dereq_;for(var o=0;o 0) { - var fn = queue.shift(); - if (typeof fn !== "function") { - fn._settlePromises(); - continue; - } - var receiver = queue.shift(); - var arg = queue.shift(); - fn.call(receiver, arg); - } -}; - -Async.prototype._drainQueues = function () { - this._drainQueue(this._normalQueue); - this._reset(); - this._haveDrainedQueues = true; - this._drainQueue(this._lateQueue); -}; - -Async.prototype._queueTick = function () { - if (!this._isTickUsed) { - this._isTickUsed = true; - this._schedule(this.drainQueues); - } -}; - -Async.prototype._reset = function () { - this._isTickUsed = false; -}; - -module.exports = Async; -module.exports.firstLineError = firstLineError; - -},{"./queue":26,"./schedule":29,"./util":36}],3:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL, tryConvertToPromise, debug) { -var calledBind = false; -var rejectThis = function(_, e) { - this._reject(e); -}; - -var targetRejected = function(e, context) { - context.promiseRejectionQueued = true; - context.bindingPromise._then(rejectThis, rejectThis, null, this, e); -}; - -var bindingResolved = function(thisArg, context) { - if (((this._bitField & 50397184) === 0)) { - this._resolveCallback(context.target); - } -}; - -var bindingRejected = function(e, context) { - if (!context.promiseRejectionQueued) this._reject(e); -}; - -Promise.prototype.bind = function (thisArg) { - if (!calledBind) { - calledBind = true; - Promise.prototype._propagateFrom = debug.propagateFromFunction(); - Promise.prototype._boundValue = debug.boundValueFunction(); - } - var maybePromise = tryConvertToPromise(thisArg); - var ret = new Promise(INTERNAL); - ret._propagateFrom(this, 1); - var target = this._target(); - ret._setBoundTo(maybePromise); - if (maybePromise instanceof Promise) { - var context = { - promiseRejectionQueued: false, - promise: ret, - target: target, - bindingPromise: maybePromise - }; - target._then(INTERNAL, targetRejected, undefined, ret, context); - maybePromise._then( - bindingResolved, bindingRejected, undefined, ret, context); - ret._setOnCancel(maybePromise); - } else { - ret._resolveCallback(target); - } - return ret; -}; - -Promise.prototype._setBoundTo = function (obj) { - if (obj !== undefined) { - this._bitField = this._bitField | 2097152; - this._boundTo = obj; - } else { - this._bitField = this._bitField & (~2097152); - } -}; - -Promise.prototype._isBound = function () { - return (this._bitField & 2097152) === 2097152; -}; - -Promise.bind = function (thisArg, value) { - return Promise.resolve(value).bind(thisArg); -}; -}; - -},{}],4:[function(_dereq_,module,exports){ -"use strict"; -var old; -if (typeof Promise !== "undefined") old = Promise; -function noConflict() { - try { if (Promise === bluebird) Promise = old; } - catch (e) {} - return bluebird; -} -var bluebird = _dereq_("./promise")(); -bluebird.noConflict = noConflict; -module.exports = bluebird; - -},{"./promise":22}],5:[function(_dereq_,module,exports){ -"use strict"; -var cr = Object.create; -if (cr) { - var callerCache = cr(null); - var getterCache = cr(null); - callerCache[" size"] = getterCache[" size"] = 0; -} - -module.exports = function(Promise) { -var util = _dereq_("./util"); -var canEvaluate = util.canEvaluate; -var isIdentifier = util.isIdentifier; - -var getMethodCaller; -var getGetter; -if (false) { -var makeMethodCaller = function (methodName) { - return new Function("ensureMethod", " \n\ - return function(obj) { \n\ - 'use strict' \n\ - var len = this.length; \n\ - ensureMethod(obj, 'methodName'); \n\ - switch(len) { \n\ - case 1: return obj.methodName(this[0]); \n\ - case 2: return obj.methodName(this[0], this[1]); \n\ - case 3: return obj.methodName(this[0], this[1], this[2]); \n\ - case 0: return obj.methodName(); \n\ - default: \n\ - return obj.methodName.apply(obj, this); \n\ - } \n\ - }; \n\ - ".replace(/methodName/g, methodName))(ensureMethod); -}; - -var makeGetter = function (propertyName) { - return new Function("obj", " \n\ - 'use strict'; \n\ - return obj.propertyName; \n\ - ".replace("propertyName", propertyName)); -}; - -var getCompiled = function(name, compiler, cache) { - var ret = cache[name]; - if (typeof ret !== "function") { - if (!isIdentifier(name)) { - return null; - } - ret = compiler(name); - cache[name] = ret; - cache[" size"]++; - if (cache[" size"] > 512) { - var keys = Object.keys(cache); - for (var i = 0; i < 256; ++i) delete cache[keys[i]]; - cache[" size"] = keys.length - 256; - } - } - return ret; -}; - -getMethodCaller = function(name) { - return getCompiled(name, makeMethodCaller, callerCache); -}; - -getGetter = function(name) { - return getCompiled(name, makeGetter, getterCache); -}; -} - -function ensureMethod(obj, methodName) { - var fn; - if (obj != null) fn = obj[methodName]; - if (typeof fn !== "function") { - var message = "Object " + util.classString(obj) + " has no method '" + - util.toString(methodName) + "'"; - throw new Promise.TypeError(message); - } - return fn; -} - -function caller(obj) { - var methodName = this.pop(); - var fn = ensureMethod(obj, methodName); - return fn.apply(obj, this); -} -Promise.prototype.call = function (methodName) { - var args = [].slice.call(arguments, 1);; - if (false) { - if (canEvaluate) { - var maybeCaller = getMethodCaller(methodName); - if (maybeCaller !== null) { - return this._then( - maybeCaller, undefined, undefined, args, undefined); - } - } - } - args.push(methodName); - return this._then(caller, undefined, undefined, args, undefined); -}; - -function namedGetter(obj) { - return obj[this]; -} -function indexedGetter(obj) { - var index = +this; - if (index < 0) index = Math.max(0, index + obj.length); - return obj[index]; -} -Promise.prototype.get = function (propertyName) { - var isIndex = (typeof propertyName === "number"); - var getter; - if (!isIndex) { - if (canEvaluate) { - var maybeGetter = getGetter(propertyName); - getter = maybeGetter !== null ? maybeGetter : namedGetter; - } else { - getter = namedGetter; - } - } else { - getter = indexedGetter; - } - return this._then(getter, undefined, undefined, propertyName, undefined); -}; -}; - -},{"./util":36}],6:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, PromiseArray, apiRejection, debug) { -var util = _dereq_("./util"); -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; -var async = Promise._async; - -Promise.prototype["break"] = Promise.prototype.cancel = function() { - if (!debug.cancellation()) return this._warn("cancellation is disabled"); - - var promise = this; - var child = promise; - while (promise.isCancellable()) { - if (!promise._cancelBy(child)) { - if (child._isFollowing()) { - child._followee().cancel(); - } else { - child._cancelBranched(); - } - break; - } - - var parent = promise._cancellationParent; - if (parent == null || !parent.isCancellable()) { - if (promise._isFollowing()) { - promise._followee().cancel(); - } else { - promise._cancelBranched(); - } - break; - } else { - if (promise._isFollowing()) promise._followee().cancel(); - child = promise; - promise = parent; - } - } -}; - -Promise.prototype._branchHasCancelled = function() { - this._branchesRemainingToCancel--; -}; - -Promise.prototype._enoughBranchesHaveCancelled = function() { - return this._branchesRemainingToCancel === undefined || - this._branchesRemainingToCancel <= 0; -}; - -Promise.prototype._cancelBy = function(canceller) { - if (canceller === this) { - this._branchesRemainingToCancel = 0; - this._invokeOnCancel(); - return true; - } else { - this._branchHasCancelled(); - if (this._enoughBranchesHaveCancelled()) { - this._invokeOnCancel(); - return true; - } - } - return false; -}; - -Promise.prototype._cancelBranched = function() { - if (this._enoughBranchesHaveCancelled()) { - this._cancel(); - } -}; - -Promise.prototype._cancel = function() { - if (!this.isCancellable()) return; - - this._setCancelled(); - async.invoke(this._cancelPromises, this, undefined); -}; - -Promise.prototype._cancelPromises = function() { - if (this._length() > 0) this._settlePromises(); -}; - -Promise.prototype._unsetOnCancel = function() { - this._onCancelField = undefined; -}; - -Promise.prototype.isCancellable = function() { - return this.isPending() && !this.isCancelled(); -}; - -Promise.prototype._doInvokeOnCancel = function(onCancelCallback, internalOnly) { - if (util.isArray(onCancelCallback)) { - for (var i = 0; i < onCancelCallback.length; ++i) { - this._doInvokeOnCancel(onCancelCallback[i], internalOnly); - } - } else if (onCancelCallback !== undefined) { - if (typeof onCancelCallback === "function") { - if (!internalOnly) { - var e = tryCatch(onCancelCallback).call(this._boundValue()); - if (e === errorObj) { - this._attachExtraTrace(e.e); - async.throwLater(e.e); - } - } - } else { - onCancelCallback._resultCancelled(this); - } - } -}; - -Promise.prototype._invokeOnCancel = function() { - var onCancelCallback = this._onCancel(); - this._unsetOnCancel(); - async.invoke(this._doInvokeOnCancel, this, onCancelCallback); -}; - -Promise.prototype._invokeInternalOnCancel = function() { - if (this.isCancellable()) { - this._doInvokeOnCancel(this._onCancel(), true); - this._unsetOnCancel(); - } -}; - -Promise.prototype._resultCancelled = function() { - this.cancel(); -}; - -}; - -},{"./util":36}],7:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(NEXT_FILTER) { -var util = _dereq_("./util"); -var getKeys = _dereq_("./es5").keys; -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; - -function catchFilter(instances, cb, promise) { - return function(e) { - var boundTo = promise._boundValue(); - predicateLoop: for (var i = 0; i < instances.length; ++i) { - var item = instances[i]; - - if (item === Error || - (item != null && item.prototype instanceof Error)) { - if (e instanceof item) { - return tryCatch(cb).call(boundTo, e); - } - } else if (typeof item === "function") { - var matchesPredicate = tryCatch(item).call(boundTo, e); - if (matchesPredicate === errorObj) { - return matchesPredicate; - } else if (matchesPredicate) { - return tryCatch(cb).call(boundTo, e); - } - } else if (util.isObject(e)) { - var keys = getKeys(item); - for (var j = 0; j < keys.length; ++j) { - var key = keys[j]; - if (item[key] != e[key]) { - continue predicateLoop; - } - } - return tryCatch(cb).call(boundTo, e); - } - } - return NEXT_FILTER; - }; -} - -return catchFilter; -}; - -},{"./es5":13,"./util":36}],8:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise) { -var longStackTraces = false; -var contextStack = []; - -Promise.prototype._promiseCreated = function() {}; -Promise.prototype._pushContext = function() {}; -Promise.prototype._popContext = function() {return null;}; -Promise._peekContext = Promise.prototype._peekContext = function() {}; - -function Context() { - this._trace = new Context.CapturedTrace(peekContext()); -} -Context.prototype._pushContext = function () { - if (this._trace !== undefined) { - this._trace._promiseCreated = null; - contextStack.push(this._trace); - } -}; - -Context.prototype._popContext = function () { - if (this._trace !== undefined) { - var trace = contextStack.pop(); - var ret = trace._promiseCreated; - trace._promiseCreated = null; - return ret; - } - return null; -}; - -function createContext() { - if (longStackTraces) return new Context(); -} - -function peekContext() { - var lastIndex = contextStack.length - 1; - if (lastIndex >= 0) { - return contextStack[lastIndex]; - } - return undefined; -} -Context.CapturedTrace = null; -Context.create = createContext; -Context.deactivateLongStackTraces = function() {}; -Context.activateLongStackTraces = function() { - var Promise_pushContext = Promise.prototype._pushContext; - var Promise_popContext = Promise.prototype._popContext; - var Promise_PeekContext = Promise._peekContext; - var Promise_peekContext = Promise.prototype._peekContext; - var Promise_promiseCreated = Promise.prototype._promiseCreated; - Context.deactivateLongStackTraces = function() { - Promise.prototype._pushContext = Promise_pushContext; - Promise.prototype._popContext = Promise_popContext; - Promise._peekContext = Promise_PeekContext; - Promise.prototype._peekContext = Promise_peekContext; - Promise.prototype._promiseCreated = Promise_promiseCreated; - longStackTraces = false; - }; - longStackTraces = true; - Promise.prototype._pushContext = Context.prototype._pushContext; - Promise.prototype._popContext = Context.prototype._popContext; - Promise._peekContext = Promise.prototype._peekContext = peekContext; - Promise.prototype._promiseCreated = function() { - var ctx = this._peekContext(); - if (ctx && ctx._promiseCreated == null) ctx._promiseCreated = this; - }; -}; -return Context; -}; - -},{}],9:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, Context) { -var getDomain = Promise._getDomain; -var async = Promise._async; -var Warning = _dereq_("./errors").Warning; -var util = _dereq_("./util"); -var canAttachTrace = util.canAttachTrace; -var unhandledRejectionHandled; -var possiblyUnhandledRejection; -var bluebirdFramePattern = - /[\\\/]bluebird[\\\/]js[\\\/](release|debug|instrumented)/; -var stackFramePattern = null; -var formatStack = null; -var indentStackFrames = false; -var printWarning; -var debugging = !!(util.env("BLUEBIRD_DEBUG") != 0 && - (true || - util.env("BLUEBIRD_DEBUG") || - util.env("NODE_ENV") === "development")); - -var warnings = !!(util.env("BLUEBIRD_WARNINGS") != 0 && - (debugging || util.env("BLUEBIRD_WARNINGS"))); - -var longStackTraces = !!(util.env("BLUEBIRD_LONG_STACK_TRACES") != 0 && - (debugging || util.env("BLUEBIRD_LONG_STACK_TRACES"))); - -var wForgottenReturn = util.env("BLUEBIRD_W_FORGOTTEN_RETURN") != 0 && - (warnings || !!util.env("BLUEBIRD_W_FORGOTTEN_RETURN")); - -Promise.prototype.suppressUnhandledRejections = function() { - var target = this._target(); - target._bitField = ((target._bitField & (~1048576)) | - 524288); -}; - -Promise.prototype._ensurePossibleRejectionHandled = function () { - if ((this._bitField & 524288) !== 0) return; - this._setRejectionIsUnhandled(); - async.invokeLater(this._notifyUnhandledRejection, this, undefined); -}; - -Promise.prototype._notifyUnhandledRejectionIsHandled = function () { - fireRejectionEvent("rejectionHandled", - unhandledRejectionHandled, undefined, this); -}; - -Promise.prototype._setReturnedNonUndefined = function() { - this._bitField = this._bitField | 268435456; -}; - -Promise.prototype._returnedNonUndefined = function() { - return (this._bitField & 268435456) !== 0; -}; - -Promise.prototype._notifyUnhandledRejection = function () { - if (this._isRejectionUnhandled()) { - var reason = this._settledValue(); - this._setUnhandledRejectionIsNotified(); - fireRejectionEvent("unhandledRejection", - possiblyUnhandledRejection, reason, this); - } -}; - -Promise.prototype._setUnhandledRejectionIsNotified = function () { - this._bitField = this._bitField | 262144; -}; - -Promise.prototype._unsetUnhandledRejectionIsNotified = function () { - this._bitField = this._bitField & (~262144); -}; - -Promise.prototype._isUnhandledRejectionNotified = function () { - return (this._bitField & 262144) > 0; -}; - -Promise.prototype._setRejectionIsUnhandled = function () { - this._bitField = this._bitField | 1048576; -}; - -Promise.prototype._unsetRejectionIsUnhandled = function () { - this._bitField = this._bitField & (~1048576); - if (this._isUnhandledRejectionNotified()) { - this._unsetUnhandledRejectionIsNotified(); - this._notifyUnhandledRejectionIsHandled(); - } -}; - -Promise.prototype._isRejectionUnhandled = function () { - return (this._bitField & 1048576) > 0; -}; - -Promise.prototype._warn = function(message, shouldUseOwnTrace, promise) { - return warn(message, shouldUseOwnTrace, promise || this); -}; - -Promise.onPossiblyUnhandledRejection = function (fn) { - var domain = getDomain(); - possiblyUnhandledRejection = - typeof fn === "function" ? (domain === null ? fn : domain.bind(fn)) - : undefined; -}; - -Promise.onUnhandledRejectionHandled = function (fn) { - var domain = getDomain(); - unhandledRejectionHandled = - typeof fn === "function" ? (domain === null ? fn : domain.bind(fn)) - : undefined; -}; - -var disableLongStackTraces = function() {}; -Promise.longStackTraces = function () { - if (async.haveItemsQueued() && !config.longStackTraces) { - throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - if (!config.longStackTraces && longStackTracesIsSupported()) { - var Promise_captureStackTrace = Promise.prototype._captureStackTrace; - var Promise_attachExtraTrace = Promise.prototype._attachExtraTrace; - config.longStackTraces = true; - disableLongStackTraces = function() { - if (async.haveItemsQueued() && !config.longStackTraces) { - throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - Promise.prototype._captureStackTrace = Promise_captureStackTrace; - Promise.prototype._attachExtraTrace = Promise_attachExtraTrace; - Context.deactivateLongStackTraces(); - async.enableTrampoline(); - config.longStackTraces = false; - }; - Promise.prototype._captureStackTrace = longStackTracesCaptureStackTrace; - Promise.prototype._attachExtraTrace = longStackTracesAttachExtraTrace; - Context.activateLongStackTraces(); - async.disableTrampolineIfNecessary(); - } -}; - -Promise.hasLongStackTraces = function () { - return config.longStackTraces && longStackTracesIsSupported(); -}; - -var fireDomEvent = (function() { - try { - var event = document.createEvent("CustomEvent"); - event.initCustomEvent("testingtheevent", false, true, {}); - util.global.dispatchEvent(event); - return function(name, event) { - var domEvent = document.createEvent("CustomEvent"); - domEvent.initCustomEvent(name.toLowerCase(), false, true, event); - return !util.global.dispatchEvent(domEvent); - }; - } catch (e) {} - return function() { - return false; - }; -})(); - -var fireGlobalEvent = (function() { - if (util.isNode) { - return function() { - return process.emit.apply(process, arguments); - }; - } else { - if (!util.global) { - return function() { - return false; - }; - } - return function(name) { - var methodName = "on" + name.toLowerCase(); - var method = util.global[methodName]; - if (!method) return false; - method.apply(util.global, [].slice.call(arguments, 1)); - return true; - }; - } -})(); - -function generatePromiseLifecycleEventObject(name, promise) { - return {promise: promise}; -} - -var eventToObjectGenerator = { - promiseCreated: generatePromiseLifecycleEventObject, - promiseFulfilled: generatePromiseLifecycleEventObject, - promiseRejected: generatePromiseLifecycleEventObject, - promiseResolved: generatePromiseLifecycleEventObject, - promiseCancelled: generatePromiseLifecycleEventObject, - promiseChained: function(name, promise, child) { - return {promise: promise, child: child}; - }, - warning: function(name, warning) { - return {warning: warning}; - }, - unhandledRejection: function (name, reason, promise) { - return {reason: reason, promise: promise}; - }, - rejectionHandled: generatePromiseLifecycleEventObject -}; - -var activeFireEvent = function (name) { - var globalEventFired = false; - try { - globalEventFired = fireGlobalEvent.apply(null, arguments); - } catch (e) { - async.throwLater(e); - globalEventFired = true; - } - - var domEventFired = false; - try { - domEventFired = fireDomEvent(name, - eventToObjectGenerator[name].apply(null, arguments)); - } catch (e) { - async.throwLater(e); - domEventFired = true; - } - - return domEventFired || globalEventFired; -}; - -Promise.config = function(opts) { - opts = Object(opts); - if ("longStackTraces" in opts) { - if (opts.longStackTraces) { - Promise.longStackTraces(); - } else if (!opts.longStackTraces && Promise.hasLongStackTraces()) { - disableLongStackTraces(); - } - } - if ("warnings" in opts) { - var warningsOption = opts.warnings; - config.warnings = !!warningsOption; - wForgottenReturn = config.warnings; - - if (util.isObject(warningsOption)) { - if ("wForgottenReturn" in warningsOption) { - wForgottenReturn = !!warningsOption.wForgottenReturn; - } - } - } - if ("cancellation" in opts && opts.cancellation && !config.cancellation) { - if (async.haveItemsQueued()) { - throw new Error( - "cannot enable cancellation after promises are in use"); - } - Promise.prototype._clearCancellationData = - cancellationClearCancellationData; - Promise.prototype._propagateFrom = cancellationPropagateFrom; - Promise.prototype._onCancel = cancellationOnCancel; - Promise.prototype._setOnCancel = cancellationSetOnCancel; - Promise.prototype._attachCancellationCallback = - cancellationAttachCancellationCallback; - Promise.prototype._execute = cancellationExecute; - propagateFromFunction = cancellationPropagateFrom; - config.cancellation = true; - } - if ("monitoring" in opts) { - if (opts.monitoring && !config.monitoring) { - config.monitoring = true; - Promise.prototype._fireEvent = activeFireEvent; - } else if (!opts.monitoring && config.monitoring) { - config.monitoring = false; - Promise.prototype._fireEvent = defaultFireEvent; - } - } -}; - -function defaultFireEvent() { return false; } - -Promise.prototype._fireEvent = defaultFireEvent; -Promise.prototype._execute = function(executor, resolve, reject) { - try { - executor(resolve, reject); - } catch (e) { - return e; - } -}; -Promise.prototype._onCancel = function () {}; -Promise.prototype._setOnCancel = function (handler) { ; }; -Promise.prototype._attachCancellationCallback = function(onCancel) { - ; -}; -Promise.prototype._captureStackTrace = function () {}; -Promise.prototype._attachExtraTrace = function () {}; -Promise.prototype._clearCancellationData = function() {}; -Promise.prototype._propagateFrom = function (parent, flags) { - ; - ; -}; - -function cancellationExecute(executor, resolve, reject) { - var promise = this; - try { - executor(resolve, reject, function(onCancel) { - if (typeof onCancel !== "function") { - throw new TypeError("onCancel must be a function, got: " + - util.toString(onCancel)); - } - promise._attachCancellationCallback(onCancel); - }); - } catch (e) { - return e; - } -} - -function cancellationAttachCancellationCallback(onCancel) { - if (!this.isCancellable()) return this; - - var previousOnCancel = this._onCancel(); - if (previousOnCancel !== undefined) { - if (util.isArray(previousOnCancel)) { - previousOnCancel.push(onCancel); - } else { - this._setOnCancel([previousOnCancel, onCancel]); - } - } else { - this._setOnCancel(onCancel); - } -} - -function cancellationOnCancel() { - return this._onCancelField; -} - -function cancellationSetOnCancel(onCancel) { - this._onCancelField = onCancel; -} - -function cancellationClearCancellationData() { - this._cancellationParent = undefined; - this._onCancelField = undefined; -} - -function cancellationPropagateFrom(parent, flags) { - if ((flags & 1) !== 0) { - this._cancellationParent = parent; - var branchesRemainingToCancel = parent._branchesRemainingToCancel; - if (branchesRemainingToCancel === undefined) { - branchesRemainingToCancel = 0; - } - parent._branchesRemainingToCancel = branchesRemainingToCancel + 1; - } - if ((flags & 2) !== 0 && parent._isBound()) { - this._setBoundTo(parent._boundTo); - } -} - -function bindingPropagateFrom(parent, flags) { - if ((flags & 2) !== 0 && parent._isBound()) { - this._setBoundTo(parent._boundTo); - } -} -var propagateFromFunction = bindingPropagateFrom; - -function boundValueFunction() { - var ret = this._boundTo; - if (ret !== undefined) { - if (ret instanceof Promise) { - if (ret.isFulfilled()) { - return ret.value(); - } else { - return undefined; - } - } - } - return ret; -} - -function longStackTracesCaptureStackTrace() { - this._trace = new CapturedTrace(this._peekContext()); -} - -function longStackTracesAttachExtraTrace(error, ignoreSelf) { - if (canAttachTrace(error)) { - var trace = this._trace; - if (trace !== undefined) { - if (ignoreSelf) trace = trace._parent; - } - if (trace !== undefined) { - trace.attachExtraTrace(error); - } else if (!error.__stackCleaned__) { - var parsed = parseStackAndMessage(error); - util.notEnumerableProp(error, "stack", - parsed.message + "\n" + parsed.stack.join("\n")); - util.notEnumerableProp(error, "__stackCleaned__", true); - } - } -} - -function checkForgottenReturns(returnValue, promiseCreated, name, promise, - parent) { - if (returnValue === undefined && promiseCreated !== null && - wForgottenReturn) { - if (parent !== undefined && parent._returnedNonUndefined()) return; - if ((promise._bitField & 65535) === 0) return; - - if (name) name = name + " "; - var msg = "a promise was created in a " + name + - "handler but was not returned from it"; - promise._warn(msg, true, promiseCreated); - } -} - -function deprecated(name, replacement) { - var message = name + - " is deprecated and will be removed in a future version."; - if (replacement) message += " Use " + replacement + " instead."; - return warn(message); -} - -function warn(message, shouldUseOwnTrace, promise) { - if (!config.warnings) return; - var warning = new Warning(message); - var ctx; - if (shouldUseOwnTrace) { - promise._attachExtraTrace(warning); - } else if (config.longStackTraces && (ctx = Promise._peekContext())) { - ctx.attachExtraTrace(warning); - } else { - var parsed = parseStackAndMessage(warning); - warning.stack = parsed.message + "\n" + parsed.stack.join("\n"); - } - - if (!activeFireEvent("warning", warning)) { - formatAndLogError(warning, "", true); - } -} - -function reconstructStack(message, stacks) { - for (var i = 0; i < stacks.length - 1; ++i) { - stacks[i].push("From previous event:"); - stacks[i] = stacks[i].join("\n"); - } - if (i < stacks.length) { - stacks[i] = stacks[i].join("\n"); - } - return message + "\n" + stacks.join("\n"); -} - -function removeDuplicateOrEmptyJumps(stacks) { - for (var i = 0; i < stacks.length; ++i) { - if (stacks[i].length === 0 || - ((i + 1 < stacks.length) && stacks[i][0] === stacks[i+1][0])) { - stacks.splice(i, 1); - i--; - } - } -} - -function removeCommonRoots(stacks) { - var current = stacks[0]; - for (var i = 1; i < stacks.length; ++i) { - var prev = stacks[i]; - var currentLastIndex = current.length - 1; - var currentLastLine = current[currentLastIndex]; - var commonRootMeetPoint = -1; - - for (var j = prev.length - 1; j >= 0; --j) { - if (prev[j] === currentLastLine) { - commonRootMeetPoint = j; - break; - } - } - - for (var j = commonRootMeetPoint; j >= 0; --j) { - var line = prev[j]; - if (current[currentLastIndex] === line) { - current.pop(); - currentLastIndex--; - } else { - break; - } - } - current = prev; - } -} - -function cleanStack(stack) { - var ret = []; - for (var i = 0; i < stack.length; ++i) { - var line = stack[i]; - var isTraceLine = " (No stack trace)" === line || - stackFramePattern.test(line); - var isInternalFrame = isTraceLine && shouldIgnore(line); - if (isTraceLine && !isInternalFrame) { - if (indentStackFrames && line.charAt(0) !== " ") { - line = " " + line; - } - ret.push(line); - } - } - return ret; -} - -function stackFramesAsArray(error) { - var stack = error.stack.replace(/\s+$/g, "").split("\n"); - for (var i = 0; i < stack.length; ++i) { - var line = stack[i]; - if (" (No stack trace)" === line || stackFramePattern.test(line)) { - break; - } - } - if (i > 0) { - stack = stack.slice(i); - } - return stack; -} - -function parseStackAndMessage(error) { - var stack = error.stack; - var message = error.toString(); - stack = typeof stack === "string" && stack.length > 0 - ? stackFramesAsArray(error) : [" (No stack trace)"]; - return { - message: message, - stack: cleanStack(stack) - }; -} - -function formatAndLogError(error, title, isSoft) { - if (typeof console !== "undefined") { - var message; - if (util.isObject(error)) { - var stack = error.stack; - message = title + formatStack(stack, error); - } else { - message = title + String(error); - } - if (typeof printWarning === "function") { - printWarning(message, isSoft); - } else if (typeof console.log === "function" || - typeof console.log === "object") { - console.log(message); - } - } -} - -function fireRejectionEvent(name, localHandler, reason, promise) { - var localEventFired = false; - try { - if (typeof localHandler === "function") { - localEventFired = true; - if (name === "rejectionHandled") { - localHandler(promise); - } else { - localHandler(reason, promise); - } - } - } catch (e) { - async.throwLater(e); - } - - if (name === "unhandledRejection") { - if (!activeFireEvent(name, reason, promise) && !localEventFired) { - formatAndLogError(reason, "Unhandled rejection "); - } - } else { - activeFireEvent(name, promise); - } -} - -function formatNonError(obj) { - var str; - if (typeof obj === "function") { - str = "[function " + - (obj.name || "anonymous") + - "]"; - } else { - str = obj && typeof obj.toString === "function" - ? obj.toString() : util.toString(obj); - var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/; - if (ruselessToString.test(str)) { - try { - var newStr = JSON.stringify(obj); - str = newStr; - } - catch(e) { - - } - } - if (str.length === 0) { - str = "(empty array)"; - } - } - return ("(<" + snip(str) + ">, no stack trace)"); -} - -function snip(str) { - var maxChars = 41; - if (str.length < maxChars) { - return str; - } - return str.substr(0, maxChars - 3) + "..."; -} - -function longStackTracesIsSupported() { - return typeof captureStackTrace === "function"; -} - -var shouldIgnore = function() { return false; }; -var parseLineInfoRegex = /[\/<\(]([^:\/]+):(\d+):(?:\d+)\)?\s*$/; -function parseLineInfo(line) { - var matches = line.match(parseLineInfoRegex); - if (matches) { - return { - fileName: matches[1], - line: parseInt(matches[2], 10) - }; - } -} - -function setBounds(firstLineError, lastLineError) { - if (!longStackTracesIsSupported()) return; - var firstStackLines = firstLineError.stack.split("\n"); - var lastStackLines = lastLineError.stack.split("\n"); - var firstIndex = -1; - var lastIndex = -1; - var firstFileName; - var lastFileName; - for (var i = 0; i < firstStackLines.length; ++i) { - var result = parseLineInfo(firstStackLines[i]); - if (result) { - firstFileName = result.fileName; - firstIndex = result.line; - break; - } - } - for (var i = 0; i < lastStackLines.length; ++i) { - var result = parseLineInfo(lastStackLines[i]); - if (result) { - lastFileName = result.fileName; - lastIndex = result.line; - break; - } - } - if (firstIndex < 0 || lastIndex < 0 || !firstFileName || !lastFileName || - firstFileName !== lastFileName || firstIndex >= lastIndex) { - return; - } - - shouldIgnore = function(line) { - if (bluebirdFramePattern.test(line)) return true; - var info = parseLineInfo(line); - if (info) { - if (info.fileName === firstFileName && - (firstIndex <= info.line && info.line <= lastIndex)) { - return true; - } - } - return false; - }; -} - -function CapturedTrace(parent) { - this._parent = parent; - this._promisesCreated = 0; - var length = this._length = 1 + (parent === undefined ? 0 : parent._length); - captureStackTrace(this, CapturedTrace); - if (length > 32) this.uncycle(); -} -util.inherits(CapturedTrace, Error); -Context.CapturedTrace = CapturedTrace; - -CapturedTrace.prototype.uncycle = function() { - var length = this._length; - if (length < 2) return; - var nodes = []; - var stackToIndex = {}; - - for (var i = 0, node = this; node !== undefined; ++i) { - nodes.push(node); - node = node._parent; - } - length = this._length = i; - for (var i = length - 1; i >= 0; --i) { - var stack = nodes[i].stack; - if (stackToIndex[stack] === undefined) { - stackToIndex[stack] = i; - } - } - for (var i = 0; i < length; ++i) { - var currentStack = nodes[i].stack; - var index = stackToIndex[currentStack]; - if (index !== undefined && index !== i) { - if (index > 0) { - nodes[index - 1]._parent = undefined; - nodes[index - 1]._length = 1; - } - nodes[i]._parent = undefined; - nodes[i]._length = 1; - var cycleEdgeNode = i > 0 ? nodes[i - 1] : this; - - if (index < length - 1) { - cycleEdgeNode._parent = nodes[index + 1]; - cycleEdgeNode._parent.uncycle(); - cycleEdgeNode._length = - cycleEdgeNode._parent._length + 1; - } else { - cycleEdgeNode._parent = undefined; - cycleEdgeNode._length = 1; - } - var currentChildLength = cycleEdgeNode._length + 1; - for (var j = i - 2; j >= 0; --j) { - nodes[j]._length = currentChildLength; - currentChildLength++; - } - return; - } - } -}; - -CapturedTrace.prototype.attachExtraTrace = function(error) { - if (error.__stackCleaned__) return; - this.uncycle(); - var parsed = parseStackAndMessage(error); - var message = parsed.message; - var stacks = [parsed.stack]; - - var trace = this; - while (trace !== undefined) { - stacks.push(cleanStack(trace.stack.split("\n"))); - trace = trace._parent; - } - removeCommonRoots(stacks); - removeDuplicateOrEmptyJumps(stacks); - util.notEnumerableProp(error, "stack", reconstructStack(message, stacks)); - util.notEnumerableProp(error, "__stackCleaned__", true); -}; - -var captureStackTrace = (function stackDetection() { - var v8stackFramePattern = /^\s*at\s*/; - var v8stackFormatter = function(stack, error) { - if (typeof stack === "string") return stack; - - if (error.name !== undefined && - error.message !== undefined) { - return error.toString(); - } - return formatNonError(error); - }; - - if (typeof Error.stackTraceLimit === "number" && - typeof Error.captureStackTrace === "function") { - Error.stackTraceLimit += 6; - stackFramePattern = v8stackFramePattern; - formatStack = v8stackFormatter; - var captureStackTrace = Error.captureStackTrace; - - shouldIgnore = function(line) { - return bluebirdFramePattern.test(line); - }; - return function(receiver, ignoreUntil) { - Error.stackTraceLimit += 6; - captureStackTrace(receiver, ignoreUntil); - Error.stackTraceLimit -= 6; - }; - } - var err = new Error(); - - if (typeof err.stack === "string" && - err.stack.split("\n")[0].indexOf("stackDetection@") >= 0) { - stackFramePattern = /@/; - formatStack = v8stackFormatter; - indentStackFrames = true; - return function captureStackTrace(o) { - o.stack = new Error().stack; - }; - } - - var hasStackAfterThrow; - try { throw new Error(); } - catch(e) { - hasStackAfterThrow = ("stack" in e); - } - if (!("stack" in err) && hasStackAfterThrow && - typeof Error.stackTraceLimit === "number") { - stackFramePattern = v8stackFramePattern; - formatStack = v8stackFormatter; - return function captureStackTrace(o) { - Error.stackTraceLimit += 6; - try { throw new Error(); } - catch(e) { o.stack = e.stack; } - Error.stackTraceLimit -= 6; - }; - } - - formatStack = function(stack, error) { - if (typeof stack === "string") return stack; - - if ((typeof error === "object" || - typeof error === "function") && - error.name !== undefined && - error.message !== undefined) { - return error.toString(); - } - return formatNonError(error); - }; - - return null; - -})([]); - -if (typeof console !== "undefined" && typeof console.warn !== "undefined") { - printWarning = function (message) { - console.warn(message); - }; - if (util.isNode && process.stderr.isTTY) { - printWarning = function(message, isSoft) { - var color = isSoft ? "\u001b[33m" : "\u001b[31m"; - console.warn(color + message + "\u001b[0m\n"); - }; - } else if (!util.isNode && typeof (new Error().stack) === "string") { - printWarning = function(message, isSoft) { - console.warn("%c" + message, - isSoft ? "color: darkorange" : "color: red"); - }; - } -} - -var config = { - warnings: warnings, - longStackTraces: false, - cancellation: false, - monitoring: false -}; - -if (longStackTraces) Promise.longStackTraces(); - -return { - longStackTraces: function() { - return config.longStackTraces; - }, - warnings: function() { - return config.warnings; - }, - cancellation: function() { - return config.cancellation; - }, - monitoring: function() { - return config.monitoring; - }, - propagateFromFunction: function() { - return propagateFromFunction; - }, - boundValueFunction: function() { - return boundValueFunction; - }, - checkForgottenReturns: checkForgottenReturns, - setBounds: setBounds, - warn: warn, - deprecated: deprecated, - CapturedTrace: CapturedTrace, - fireDomEvent: fireDomEvent, - fireGlobalEvent: fireGlobalEvent -}; -}; - -},{"./errors":12,"./util":36}],10:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise) { -function returner() { - return this.value; -} -function thrower() { - throw this.reason; -} - -Promise.prototype["return"] = -Promise.prototype.thenReturn = function (value) { - if (value instanceof Promise) value.suppressUnhandledRejections(); - return this._then( - returner, undefined, undefined, {value: value}, undefined); -}; - -Promise.prototype["throw"] = -Promise.prototype.thenThrow = function (reason) { - return this._then( - thrower, undefined, undefined, {reason: reason}, undefined); -}; - -Promise.prototype.catchThrow = function (reason) { - if (arguments.length <= 1) { - return this._then( - undefined, thrower, undefined, {reason: reason}, undefined); - } else { - var _reason = arguments[1]; - var handler = function() {throw _reason;}; - return this.caught(reason, handler); - } -}; - -Promise.prototype.catchReturn = function (value) { - if (arguments.length <= 1) { - if (value instanceof Promise) value.suppressUnhandledRejections(); - return this._then( - undefined, returner, undefined, {value: value}, undefined); - } else { - var _value = arguments[1]; - if (_value instanceof Promise) _value.suppressUnhandledRejections(); - var handler = function() {return _value;}; - return this.caught(value, handler); - } -}; -}; - -},{}],11:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var PromiseReduce = Promise.reduce; -var PromiseAll = Promise.all; - -function promiseAllThis() { - return PromiseAll(this); -} - -function PromiseMapSeries(promises, fn) { - return PromiseReduce(promises, fn, INTERNAL, INTERNAL); -} - -Promise.prototype.each = function (fn) { - return this.mapSeries(fn) - ._then(promiseAllThis, undefined, undefined, this, undefined); -}; - -Promise.prototype.mapSeries = function (fn) { - return PromiseReduce(this, fn, INTERNAL, INTERNAL); -}; - -Promise.each = function (promises, fn) { - return PromiseMapSeries(promises, fn) - ._then(promiseAllThis, undefined, undefined, promises, undefined); -}; - -Promise.mapSeries = PromiseMapSeries; -}; - -},{}],12:[function(_dereq_,module,exports){ -"use strict"; -var es5 = _dereq_("./es5"); -var Objectfreeze = es5.freeze; -var util = _dereq_("./util"); -var inherits = util.inherits; -var notEnumerableProp = util.notEnumerableProp; - -function subError(nameProperty, defaultMessage) { - function SubError(message) { - if (!(this instanceof SubError)) return new SubError(message); - notEnumerableProp(this, "message", - typeof message === "string" ? message : defaultMessage); - notEnumerableProp(this, "name", nameProperty); - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } else { - Error.call(this); - } - } - inherits(SubError, Error); - return SubError; -} - -var _TypeError, _RangeError; -var Warning = subError("Warning", "warning"); -var CancellationError = subError("CancellationError", "cancellation error"); -var TimeoutError = subError("TimeoutError", "timeout error"); -var AggregateError = subError("AggregateError", "aggregate error"); -try { - _TypeError = TypeError; - _RangeError = RangeError; -} catch(e) { - _TypeError = subError("TypeError", "type error"); - _RangeError = subError("RangeError", "range error"); -} - -var methods = ("join pop push shift unshift slice filter forEach some " + - "every map indexOf lastIndexOf reduce reduceRight sort reverse").split(" "); - -for (var i = 0; i < methods.length; ++i) { - if (typeof Array.prototype[methods[i]] === "function") { - AggregateError.prototype[methods[i]] = Array.prototype[methods[i]]; - } -} - -es5.defineProperty(AggregateError.prototype, "length", { - value: 0, - configurable: false, - writable: true, - enumerable: true -}); -AggregateError.prototype["isOperational"] = true; -var level = 0; -AggregateError.prototype.toString = function() { - var indent = Array(level * 4 + 1).join(" "); - var ret = "\n" + indent + "AggregateError of:" + "\n"; - level++; - indent = Array(level * 4 + 1).join(" "); - for (var i = 0; i < this.length; ++i) { - var str = this[i] === this ? "[Circular AggregateError]" : this[i] + ""; - var lines = str.split("\n"); - for (var j = 0; j < lines.length; ++j) { - lines[j] = indent + lines[j]; - } - str = lines.join("\n"); - ret += str + "\n"; - } - level--; - return ret; -}; - -function OperationalError(message) { - if (!(this instanceof OperationalError)) - return new OperationalError(message); - notEnumerableProp(this, "name", "OperationalError"); - notEnumerableProp(this, "message", message); - this.cause = message; - this["isOperational"] = true; - - if (message instanceof Error) { - notEnumerableProp(this, "message", message.message); - notEnumerableProp(this, "stack", message.stack); - } else if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } - -} -inherits(OperationalError, Error); - -var errorTypes = Error["__BluebirdErrorTypes__"]; -if (!errorTypes) { - errorTypes = Objectfreeze({ - CancellationError: CancellationError, - TimeoutError: TimeoutError, - OperationalError: OperationalError, - RejectionError: OperationalError, - AggregateError: AggregateError - }); - es5.defineProperty(Error, "__BluebirdErrorTypes__", { - value: errorTypes, - writable: false, - enumerable: false, - configurable: false - }); -} - -module.exports = { - Error: Error, - TypeError: _TypeError, - RangeError: _RangeError, - CancellationError: errorTypes.CancellationError, - OperationalError: errorTypes.OperationalError, - TimeoutError: errorTypes.TimeoutError, - AggregateError: errorTypes.AggregateError, - Warning: Warning -}; - -},{"./es5":13,"./util":36}],13:[function(_dereq_,module,exports){ -var isES5 = (function(){ - "use strict"; - return this === undefined; -})(); - -if (isES5) { - module.exports = { - freeze: Object.freeze, - defineProperty: Object.defineProperty, - getDescriptor: Object.getOwnPropertyDescriptor, - keys: Object.keys, - names: Object.getOwnPropertyNames, - getPrototypeOf: Object.getPrototypeOf, - isArray: Array.isArray, - isES5: isES5, - propertyIsWritable: function(obj, prop) { - var descriptor = Object.getOwnPropertyDescriptor(obj, prop); - return !!(!descriptor || descriptor.writable || descriptor.set); - } - }; -} else { - var has = {}.hasOwnProperty; - var str = {}.toString; - var proto = {}.constructor.prototype; - - var ObjectKeys = function (o) { - var ret = []; - for (var key in o) { - if (has.call(o, key)) { - ret.push(key); - } - } - return ret; - }; - - var ObjectGetDescriptor = function(o, key) { - return {value: o[key]}; - }; - - var ObjectDefineProperty = function (o, key, desc) { - o[key] = desc.value; - return o; - }; - - var ObjectFreeze = function (obj) { - return obj; - }; - - var ObjectGetPrototypeOf = function (obj) { - try { - return Object(obj).constructor.prototype; - } - catch (e) { - return proto; - } - }; - - var ArrayIsArray = function (obj) { - try { - return str.call(obj) === "[object Array]"; - } - catch(e) { - return false; - } - }; - - module.exports = { - isArray: ArrayIsArray, - keys: ObjectKeys, - names: ObjectKeys, - defineProperty: ObjectDefineProperty, - getDescriptor: ObjectGetDescriptor, - freeze: ObjectFreeze, - getPrototypeOf: ObjectGetPrototypeOf, - isES5: isES5, - propertyIsWritable: function() { - return true; - } - }; -} - -},{}],14:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var PromiseMap = Promise.map; - -Promise.prototype.filter = function (fn, options) { - return PromiseMap(this, fn, options, INTERNAL); -}; - -Promise.filter = function (promises, fn, options) { - return PromiseMap(promises, fn, options, INTERNAL); -}; -}; - -},{}],15:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, tryConvertToPromise) { -var util = _dereq_("./util"); -var CancellationError = Promise.CancellationError; -var errorObj = util.errorObj; - -function PassThroughHandlerContext(promise, type, handler) { - this.promise = promise; - this.type = type; - this.handler = handler; - this.called = false; - this.cancelPromise = null; -} - -PassThroughHandlerContext.prototype.isFinallyHandler = function() { - return this.type === 0; -}; - -function FinallyHandlerCancelReaction(finallyHandler) { - this.finallyHandler = finallyHandler; -} - -FinallyHandlerCancelReaction.prototype._resultCancelled = function() { - checkCancel(this.finallyHandler); -}; - -function checkCancel(ctx, reason) { - if (ctx.cancelPromise != null) { - if (arguments.length > 1) { - ctx.cancelPromise._reject(reason); - } else { - ctx.cancelPromise._cancel(); - } - ctx.cancelPromise = null; - return true; - } - return false; -} - -function succeed() { - return finallyHandler.call(this, this.promise._target()._settledValue()); -} -function fail(reason) { - if (checkCancel(this, reason)) return; - errorObj.e = reason; - return errorObj; -} -function finallyHandler(reasonOrValue) { - var promise = this.promise; - var handler = this.handler; - - if (!this.called) { - this.called = true; - var ret = this.isFinallyHandler() - ? handler.call(promise._boundValue()) - : handler.call(promise._boundValue(), reasonOrValue); - if (ret !== undefined) { - promise._setReturnedNonUndefined(); - var maybePromise = tryConvertToPromise(ret, promise); - if (maybePromise instanceof Promise) { - if (this.cancelPromise != null) { - if (maybePromise.isCancelled()) { - var reason = - new CancellationError("late cancellation observer"); - promise._attachExtraTrace(reason); - errorObj.e = reason; - return errorObj; - } else if (maybePromise.isPending()) { - maybePromise._attachCancellationCallback( - new FinallyHandlerCancelReaction(this)); - } - } - return maybePromise._then( - succeed, fail, undefined, this, undefined); - } - } - } - - if (promise.isRejected()) { - checkCancel(this); - errorObj.e = reasonOrValue; - return errorObj; - } else { - checkCancel(this); - return reasonOrValue; - } -} - -Promise.prototype._passThrough = function(handler, type, success, fail) { - if (typeof handler !== "function") return this.then(); - return this._then(success, - fail, - undefined, - new PassThroughHandlerContext(this, type, handler), - undefined); -}; - -Promise.prototype.lastly = -Promise.prototype["finally"] = function (handler) { - return this._passThrough(handler, - 0, - finallyHandler, - finallyHandler); -}; - -Promise.prototype.tap = function (handler) { - return this._passThrough(handler, 1, finallyHandler); -}; - -return PassThroughHandlerContext; -}; - -},{"./util":36}],16:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, - apiRejection, - INTERNAL, - tryConvertToPromise, - Proxyable, - debug) { -var errors = _dereq_("./errors"); -var TypeError = errors.TypeError; -var util = _dereq_("./util"); -var errorObj = util.errorObj; -var tryCatch = util.tryCatch; -var yieldHandlers = []; - -function promiseFromYieldHandler(value, yieldHandlers, traceParent) { - for (var i = 0; i < yieldHandlers.length; ++i) { - traceParent._pushContext(); - var result = tryCatch(yieldHandlers[i])(value); - traceParent._popContext(); - if (result === errorObj) { - traceParent._pushContext(); - var ret = Promise.reject(errorObj.e); - traceParent._popContext(); - return ret; - } - var maybePromise = tryConvertToPromise(result, traceParent); - if (maybePromise instanceof Promise) return maybePromise; - } - return null; -} - -function PromiseSpawn(generatorFunction, receiver, yieldHandler, stack) { - if (debug.cancellation()) { - var internal = new Promise(INTERNAL); - var _finallyPromise = this._finallyPromise = new Promise(INTERNAL); - this._promise = internal.lastly(function() { - return _finallyPromise; - }); - internal._captureStackTrace(); - internal._setOnCancel(this); - } else { - var promise = this._promise = new Promise(INTERNAL); - promise._captureStackTrace(); - } - this._stack = stack; - this._generatorFunction = generatorFunction; - this._receiver = receiver; - this._generator = undefined; - this._yieldHandlers = typeof yieldHandler === "function" - ? [yieldHandler].concat(yieldHandlers) - : yieldHandlers; - this._yieldedPromise = null; - this._cancellationPhase = false; -} -util.inherits(PromiseSpawn, Proxyable); - -PromiseSpawn.prototype._isResolved = function() { - return this._promise === null; -}; - -PromiseSpawn.prototype._cleanup = function() { - this._promise = this._generator = null; - if (debug.cancellation() && this._finallyPromise !== null) { - this._finallyPromise._fulfill(); - this._finallyPromise = null; - } -}; - -PromiseSpawn.prototype._promiseCancelled = function() { - if (this._isResolved()) return; - var implementsReturn = typeof this._generator["return"] !== "undefined"; - - var result; - if (!implementsReturn) { - var reason = new Promise.CancellationError( - "generator .return() sentinel"); - Promise.coroutine.returnSentinel = reason; - this._promise._attachExtraTrace(reason); - this._promise._pushContext(); - result = tryCatch(this._generator["throw"]).call(this._generator, - reason); - this._promise._popContext(); - } else { - this._promise._pushContext(); - result = tryCatch(this._generator["return"]).call(this._generator, - undefined); - this._promise._popContext(); - } - this._cancellationPhase = true; - this._yieldedPromise = null; - this._continue(result); -}; - -PromiseSpawn.prototype._promiseFulfilled = function(value) { - this._yieldedPromise = null; - this._promise._pushContext(); - var result = tryCatch(this._generator.next).call(this._generator, value); - this._promise._popContext(); - this._continue(result); -}; - -PromiseSpawn.prototype._promiseRejected = function(reason) { - this._yieldedPromise = null; - this._promise._attachExtraTrace(reason); - this._promise._pushContext(); - var result = tryCatch(this._generator["throw"]) - .call(this._generator, reason); - this._promise._popContext(); - this._continue(result); -}; - -PromiseSpawn.prototype._resultCancelled = function() { - if (this._yieldedPromise instanceof Promise) { - var promise = this._yieldedPromise; - this._yieldedPromise = null; - promise.cancel(); - } -}; - -PromiseSpawn.prototype.promise = function () { - return this._promise; -}; - -PromiseSpawn.prototype._run = function () { - this._generator = this._generatorFunction.call(this._receiver); - this._receiver = - this._generatorFunction = undefined; - this._promiseFulfilled(undefined); -}; - -PromiseSpawn.prototype._continue = function (result) { - var promise = this._promise; - if (result === errorObj) { - this._cleanup(); - if (this._cancellationPhase) { - return promise.cancel(); - } else { - return promise._rejectCallback(result.e, false); - } - } - - var value = result.value; - if (result.done === true) { - this._cleanup(); - if (this._cancellationPhase) { - return promise.cancel(); - } else { - return promise._resolveCallback(value); - } - } else { - var maybePromise = tryConvertToPromise(value, this._promise); - if (!(maybePromise instanceof Promise)) { - maybePromise = - promiseFromYieldHandler(maybePromise, - this._yieldHandlers, - this._promise); - if (maybePromise === null) { - this._promiseRejected( - new TypeError( - "A value %s was yielded that could not be treated as a promise\u000a\u000a See http://goo.gl/MqrFmX\u000a\u000a".replace("%s", value) + - "From coroutine:\u000a" + - this._stack.split("\n").slice(1, -7).join("\n") - ) - ); - return; - } - } - maybePromise = maybePromise._target(); - var bitField = maybePromise._bitField; - ; - if (((bitField & 50397184) === 0)) { - this._yieldedPromise = maybePromise; - maybePromise._proxy(this, null); - } else if (((bitField & 33554432) !== 0)) { - this._promiseFulfilled(maybePromise._value()); - } else if (((bitField & 16777216) !== 0)) { - this._promiseRejected(maybePromise._reason()); - } else { - this._promiseCancelled(); - } - } -}; - -Promise.coroutine = function (generatorFunction, options) { - if (typeof generatorFunction !== "function") { - throw new TypeError("generatorFunction must be a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - var yieldHandler = Object(options).yieldHandler; - var PromiseSpawn$ = PromiseSpawn; - var stack = new Error().stack; - return function () { - var generator = generatorFunction.apply(this, arguments); - var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler, - stack); - var ret = spawn.promise(); - spawn._generator = generator; - spawn._promiseFulfilled(undefined); - return ret; - }; -}; - -Promise.coroutine.addYieldHandler = function(fn) { - if (typeof fn !== "function") { - throw new TypeError("expecting a function but got " + util.classString(fn)); - } - yieldHandlers.push(fn); -}; - -Promise.spawn = function (generatorFunction) { - debug.deprecated("Promise.spawn()", "Promise.coroutine()"); - if (typeof generatorFunction !== "function") { - return apiRejection("generatorFunction must be a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - var spawn = new PromiseSpawn(generatorFunction, this); - var ret = spawn.promise(); - spawn._run(Promise.spawn); - return ret; -}; -}; - -},{"./errors":12,"./util":36}],17:[function(_dereq_,module,exports){ -"use strict"; -module.exports = -function(Promise, PromiseArray, tryConvertToPromise, INTERNAL) { -var util = _dereq_("./util"); -var canEvaluate = util.canEvaluate; -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; -var reject; - -if (false) { -if (canEvaluate) { - var thenCallback = function(i) { - return new Function("value", "holder", " \n\ - 'use strict'; \n\ - holder.pIndex = value; \n\ - holder.checkFulfillment(this); \n\ - ".replace(/Index/g, i)); - }; - - var promiseSetter = function(i) { - return new Function("promise", "holder", " \n\ - 'use strict'; \n\ - holder.pIndex = promise; \n\ - ".replace(/Index/g, i)); - }; - - var generateHolderClass = function(total) { - var props = new Array(total); - for (var i = 0; i < props.length; ++i) { - props[i] = "this.p" + (i+1); - } - var assignment = props.join(" = ") + " = null;"; - var cancellationCode= "var promise;\n" + props.map(function(prop) { - return " \n\ - promise = " + prop + "; \n\ - if (promise instanceof Promise) { \n\ - promise.cancel(); \n\ - } \n\ - "; - }).join("\n"); - var passedArguments = props.join(", "); - var name = "Holder$" + total; - - - var code = "return function(tryCatch, errorObj, Promise) { \n\ - 'use strict'; \n\ - function [TheName](fn) { \n\ - [TheProperties] \n\ - this.fn = fn; \n\ - this.now = 0; \n\ - } \n\ - [TheName].prototype.checkFulfillment = function(promise) { \n\ - var now = ++this.now; \n\ - if (now === [TheTotal]) { \n\ - promise._pushContext(); \n\ - var callback = this.fn; \n\ - var ret = tryCatch(callback)([ThePassedArguments]); \n\ - promise._popContext(); \n\ - if (ret === errorObj) { \n\ - promise._rejectCallback(ret.e, false); \n\ - } else { \n\ - promise._resolveCallback(ret); \n\ - } \n\ - } \n\ - }; \n\ - \n\ - [TheName].prototype._resultCancelled = function() { \n\ - [CancellationCode] \n\ - }; \n\ - \n\ - return [TheName]; \n\ - }(tryCatch, errorObj, Promise); \n\ - "; - - code = code.replace(/\[TheName\]/g, name) - .replace(/\[TheTotal\]/g, total) - .replace(/\[ThePassedArguments\]/g, passedArguments) - .replace(/\[TheProperties\]/g, assignment) - .replace(/\[CancellationCode\]/g, cancellationCode); - - return new Function("tryCatch", "errorObj", "Promise", code) - (tryCatch, errorObj, Promise); - }; - - var holderClasses = []; - var thenCallbacks = []; - var promiseSetters = []; - - for (var i = 0; i < 8; ++i) { - holderClasses.push(generateHolderClass(i + 1)); - thenCallbacks.push(thenCallback(i + 1)); - promiseSetters.push(promiseSetter(i + 1)); - } - - reject = function (reason) { - this._reject(reason); - }; -}} - -Promise.join = function () { - var last = arguments.length - 1; - var fn; - if (last > 0 && typeof arguments[last] === "function") { - fn = arguments[last]; - if (false) { - if (last <= 8 && canEvaluate) { - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - var HolderClass = holderClasses[last - 1]; - var holder = new HolderClass(fn); - var callbacks = thenCallbacks; - - for (var i = 0; i < last; ++i) { - var maybePromise = tryConvertToPromise(arguments[i], ret); - if (maybePromise instanceof Promise) { - maybePromise = maybePromise._target(); - var bitField = maybePromise._bitField; - ; - if (((bitField & 50397184) === 0)) { - maybePromise._then(callbacks[i], reject, - undefined, ret, holder); - promiseSetters[i](maybePromise, holder); - } else if (((bitField & 33554432) !== 0)) { - callbacks[i].call(ret, - maybePromise._value(), holder); - } else if (((bitField & 16777216) !== 0)) { - ret._reject(maybePromise._reason()); - } else { - ret._cancel(); - } - } else { - callbacks[i].call(ret, maybePromise, holder); - } - } - if (!ret._isFateSealed()) { - ret._setAsyncGuaranteed(); - ret._setOnCancel(holder); - } - return ret; - } - } - } - var args = [].slice.call(arguments);; - if (fn) args.pop(); - var ret = new PromiseArray(args).promise(); - return fn !== undefined ? ret.spread(fn) : ret; -}; - -}; - -},{"./util":36}],18:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, - PromiseArray, - apiRejection, - tryConvertToPromise, - INTERNAL, - debug) { -var getDomain = Promise._getDomain; -var util = _dereq_("./util"); -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; -var EMPTY_ARRAY = []; - -function MappingPromiseArray(promises, fn, limit, _filter) { - this.constructor$(promises); - this._promise._captureStackTrace(); - var domain = getDomain(); - this._callback = domain === null ? fn : domain.bind(fn); - this._preservedValues = _filter === INTERNAL - ? new Array(this.length()) - : null; - this._limit = limit; - this._inFlight = 0; - this._queue = limit >= 1 ? [] : EMPTY_ARRAY; - this._init$(undefined, -2); -} -util.inherits(MappingPromiseArray, PromiseArray); - -MappingPromiseArray.prototype._init = function () {}; - -MappingPromiseArray.prototype._promiseFulfilled = function (value, index) { - var values = this._values; - var length = this.length(); - var preservedValues = this._preservedValues; - var limit = this._limit; - - if (index < 0) { - index = (index * -1) - 1; - values[index] = value; - if (limit >= 1) { - this._inFlight--; - this._drainQueue(); - if (this._isResolved()) return true; - } - } else { - if (limit >= 1 && this._inFlight >= limit) { - values[index] = value; - this._queue.push(index); - return false; - } - if (preservedValues !== null) preservedValues[index] = value; - - var promise = this._promise; - var callback = this._callback; - var receiver = promise._boundValue(); - promise._pushContext(); - var ret = tryCatch(callback).call(receiver, value, index, length); - var promiseCreated = promise._popContext(); - debug.checkForgottenReturns( - ret, - promiseCreated, - preservedValues !== null ? "Promise.filter" : "Promise.map", - promise - ); - if (ret === errorObj) { - this._reject(ret.e); - return true; - } - - var maybePromise = tryConvertToPromise(ret, this._promise); - if (maybePromise instanceof Promise) { - maybePromise = maybePromise._target(); - var bitField = maybePromise._bitField; - ; - if (((bitField & 50397184) === 0)) { - if (limit >= 1) this._inFlight++; - values[index] = maybePromise; - maybePromise._proxy(this, (index + 1) * -1); - return false; - } else if (((bitField & 33554432) !== 0)) { - ret = maybePromise._value(); - } else if (((bitField & 16777216) !== 0)) { - this._reject(maybePromise._reason()); - return true; - } else { - this._cancel(); - return true; - } - } - values[index] = ret; - } - var totalResolved = ++this._totalResolved; - if (totalResolved >= length) { - if (preservedValues !== null) { - this._filter(values, preservedValues); - } else { - this._resolve(values); - } - return true; - } - return false; -}; - -MappingPromiseArray.prototype._drainQueue = function () { - var queue = this._queue; - var limit = this._limit; - var values = this._values; - while (queue.length > 0 && this._inFlight < limit) { - if (this._isResolved()) return; - var index = queue.pop(); - this._promiseFulfilled(values[index], index); - } -}; - -MappingPromiseArray.prototype._filter = function (booleans, values) { - var len = values.length; - var ret = new Array(len); - var j = 0; - for (var i = 0; i < len; ++i) { - if (booleans[i]) ret[j++] = values[i]; - } - ret.length = j; - this._resolve(ret); -}; - -MappingPromiseArray.prototype.preservedValues = function () { - return this._preservedValues; -}; - -function map(promises, fn, options, _filter) { - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - - var limit = 0; - if (options !== undefined) { - if (typeof options === "object" && options !== null) { - if (typeof options.concurrency !== "number") { - return Promise.reject( - new TypeError("'concurrency' must be a number but it is " + - util.classString(options.concurrency))); - } - limit = options.concurrency; - } else { - return Promise.reject(new TypeError( - "options argument must be an object but it is " + - util.classString(options))); - } - } - limit = typeof limit === "number" && - isFinite(limit) && limit >= 1 ? limit : 0; - return new MappingPromiseArray(promises, fn, limit, _filter).promise(); -} - -Promise.prototype.map = function (fn, options) { - return map(this, fn, options, null); -}; - -Promise.map = function (promises, fn, options, _filter) { - return map(promises, fn, options, _filter); -}; - - -}; - -},{"./util":36}],19:[function(_dereq_,module,exports){ -"use strict"; -module.exports = -function(Promise, INTERNAL, tryConvertToPromise, apiRejection, debug) { -var util = _dereq_("./util"); -var tryCatch = util.tryCatch; - -Promise.method = function (fn) { - if (typeof fn !== "function") { - throw new Promise.TypeError("expecting a function but got " + util.classString(fn)); - } - return function () { - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - ret._pushContext(); - var value = tryCatch(fn).apply(this, arguments); - var promiseCreated = ret._popContext(); - debug.checkForgottenReturns( - value, promiseCreated, "Promise.method", ret); - ret._resolveFromSyncValue(value); - return ret; - }; -}; - -Promise.attempt = Promise["try"] = function (fn) { - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - ret._pushContext(); - var value; - if (arguments.length > 1) { - debug.deprecated("calling Promise.try with more than 1 argument"); - var arg = arguments[1]; - var ctx = arguments[2]; - value = util.isArray(arg) ? tryCatch(fn).apply(ctx, arg) - : tryCatch(fn).call(ctx, arg); - } else { - value = tryCatch(fn)(); - } - var promiseCreated = ret._popContext(); - debug.checkForgottenReturns( - value, promiseCreated, "Promise.try", ret); - ret._resolveFromSyncValue(value); - return ret; -}; - -Promise.prototype._resolveFromSyncValue = function (value) { - if (value === util.errorObj) { - this._rejectCallback(value.e, false); - } else { - this._resolveCallback(value, true); - } -}; -}; - -},{"./util":36}],20:[function(_dereq_,module,exports){ -"use strict"; -var util = _dereq_("./util"); -var maybeWrapAsError = util.maybeWrapAsError; -var errors = _dereq_("./errors"); -var OperationalError = errors.OperationalError; -var es5 = _dereq_("./es5"); - -function isUntypedError(obj) { - return obj instanceof Error && - es5.getPrototypeOf(obj) === Error.prototype; -} - -var rErrorKey = /^(?:name|message|stack|cause)$/; -function wrapAsOperationalError(obj) { - var ret; - if (isUntypedError(obj)) { - ret = new OperationalError(obj); - ret.name = obj.name; - ret.message = obj.message; - ret.stack = obj.stack; - var keys = es5.keys(obj); - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (!rErrorKey.test(key)) { - ret[key] = obj[key]; - } - } - return ret; - } - util.markAsOriginatingFromRejection(obj); - return obj; -} - -function nodebackForPromise(promise, multiArgs) { - return function(err, value) { - if (promise === null) return; - if (err) { - var wrapped = wrapAsOperationalError(maybeWrapAsError(err)); - promise._attachExtraTrace(wrapped); - promise._reject(wrapped); - } else if (!multiArgs) { - promise._fulfill(value); - } else { - var args = [].slice.call(arguments, 1);; - promise._fulfill(args); - } - promise = null; - }; -} - -module.exports = nodebackForPromise; - -},{"./errors":12,"./es5":13,"./util":36}],21:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise) { -var util = _dereq_("./util"); -var async = Promise._async; -var tryCatch = util.tryCatch; -var errorObj = util.errorObj; - -function spreadAdapter(val, nodeback) { - var promise = this; - if (!util.isArray(val)) return successAdapter.call(promise, val, nodeback); - var ret = - tryCatch(nodeback).apply(promise._boundValue(), [null].concat(val)); - if (ret === errorObj) { - async.throwLater(ret.e); - } -} - -function successAdapter(val, nodeback) { - var promise = this; - var receiver = promise._boundValue(); - var ret = val === undefined - ? tryCatch(nodeback).call(receiver, null) - : tryCatch(nodeback).call(receiver, null, val); - if (ret === errorObj) { - async.throwLater(ret.e); - } -} -function errorAdapter(reason, nodeback) { - var promise = this; - if (!reason) { - var newReason = new Error(reason + ""); - newReason.cause = reason; - reason = newReason; - } - var ret = tryCatch(nodeback).call(promise._boundValue(), reason); - if (ret === errorObj) { - async.throwLater(ret.e); - } -} - -Promise.prototype.asCallback = Promise.prototype.nodeify = function (nodeback, - options) { - if (typeof nodeback == "function") { - var adapter = successAdapter; - if (options !== undefined && Object(options).spread) { - adapter = spreadAdapter; - } - this._then( - adapter, - errorAdapter, - undefined, - this, - nodeback - ); - } - return this; -}; -}; - -},{"./util":36}],22:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function() { -var makeSelfResolutionError = function () { - return new TypeError("circular promise resolution chain\u000a\u000a See http://goo.gl/MqrFmX\u000a"); -}; -var reflectHandler = function() { - return new Promise.PromiseInspection(this._target()); -}; -var apiRejection = function(msg) { - return Promise.reject(new TypeError(msg)); -}; -function Proxyable() {} -var UNDEFINED_BINDING = {}; -var util = _dereq_("./util"); - -var getDomain; -if (util.isNode) { - getDomain = function() { - var ret = process.domain; - if (ret === undefined) ret = null; - return ret; - }; -} else { - getDomain = function() { - return null; - }; -} -util.notEnumerableProp(Promise, "_getDomain", getDomain); - -var es5 = _dereq_("./es5"); -var Async = _dereq_("./async"); -var async = new Async(); -es5.defineProperty(Promise, "_async", {value: async}); -var errors = _dereq_("./errors"); -var TypeError = Promise.TypeError = errors.TypeError; -Promise.RangeError = errors.RangeError; -var CancellationError = Promise.CancellationError = errors.CancellationError; -Promise.TimeoutError = errors.TimeoutError; -Promise.OperationalError = errors.OperationalError; -Promise.RejectionError = errors.OperationalError; -Promise.AggregateError = errors.AggregateError; -var INTERNAL = function(){}; -var APPLY = {}; -var NEXT_FILTER = {}; -var tryConvertToPromise = _dereq_("./thenables")(Promise, INTERNAL); -var PromiseArray = - _dereq_("./promise_array")(Promise, INTERNAL, - tryConvertToPromise, apiRejection, Proxyable); -var Context = _dereq_("./context")(Promise); - /*jshint unused:false*/ -var createContext = Context.create; -var debug = _dereq_("./debuggability")(Promise, Context); -var CapturedTrace = debug.CapturedTrace; -var PassThroughHandlerContext = - _dereq_("./finally")(Promise, tryConvertToPromise); -var catchFilter = _dereq_("./catch_filter")(NEXT_FILTER); -var nodebackForPromise = _dereq_("./nodeback"); -var errorObj = util.errorObj; -var tryCatch = util.tryCatch; -function check(self, executor) { - if (typeof executor !== "function") { - throw new TypeError("expecting a function but got " + util.classString(executor)); - } - if (self.constructor !== Promise) { - throw new TypeError("the promise constructor cannot be invoked directly\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } -} - -function Promise(executor) { - this._bitField = 0; - this._fulfillmentHandler0 = undefined; - this._rejectionHandler0 = undefined; - this._promise0 = undefined; - this._receiver0 = undefined; - if (executor !== INTERNAL) { - check(this, executor); - this._resolveFromExecutor(executor); - } - this._promiseCreated(); - this._fireEvent("promiseCreated", this); -} - -Promise.prototype.toString = function () { - return "[object Promise]"; -}; - -Promise.prototype.caught = Promise.prototype["catch"] = function (fn) { - var len = arguments.length; - if (len > 1) { - var catchInstances = new Array(len - 1), - j = 0, i; - for (i = 0; i < len - 1; ++i) { - var item = arguments[i]; - if (util.isObject(item)) { - catchInstances[j++] = item; - } else { - return apiRejection("expecting an object but got " + util.classString(item)); - } - } - catchInstances.length = j; - fn = arguments[i]; - return this.then(undefined, catchFilter(catchInstances, fn, this)); - } - return this.then(undefined, fn); -}; - -Promise.prototype.reflect = function () { - return this._then(reflectHandler, - reflectHandler, undefined, this, undefined); -}; - -Promise.prototype.then = function (didFulfill, didReject) { - if (debug.warnings() && arguments.length > 0 && - typeof didFulfill !== "function" && - typeof didReject !== "function") { - var msg = ".then() only accepts functions but was passed: " + - util.classString(didFulfill); - if (arguments.length > 1) { - msg += ", " + util.classString(didReject); - } - this._warn(msg); - } - return this._then(didFulfill, didReject, undefined, undefined, undefined); -}; - -Promise.prototype.done = function (didFulfill, didReject) { - var promise = - this._then(didFulfill, didReject, undefined, undefined, undefined); - promise._setIsFinal(); -}; - -Promise.prototype.spread = function (fn) { - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - return this.all()._then(fn, undefined, undefined, APPLY, undefined); -}; - -Promise.prototype.toJSON = function () { - var ret = { - isFulfilled: false, - isRejected: false, - fulfillmentValue: undefined, - rejectionReason: undefined - }; - if (this.isFulfilled()) { - ret.fulfillmentValue = this.value(); - ret.isFulfilled = true; - } else if (this.isRejected()) { - ret.rejectionReason = this.reason(); - ret.isRejected = true; - } - return ret; -}; - -Promise.prototype.all = function () { - if (arguments.length > 0) { - this._warn(".all() was passed arguments but it does not take any"); - } - return new PromiseArray(this).promise(); -}; - -Promise.prototype.error = function (fn) { - return this.caught(util.originatesFromRejection, fn); -}; - -Promise.getNewLibraryCopy = module.exports; - -Promise.is = function (val) { - return val instanceof Promise; -}; - -Promise.fromNode = Promise.fromCallback = function(fn) { - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - var multiArgs = arguments.length > 1 ? !!Object(arguments[1]).multiArgs - : false; - var result = tryCatch(fn)(nodebackForPromise(ret, multiArgs)); - if (result === errorObj) { - ret._rejectCallback(result.e, true); - } - if (!ret._isFateSealed()) ret._setAsyncGuaranteed(); - return ret; -}; - -Promise.all = function (promises) { - return new PromiseArray(promises).promise(); -}; - -Promise.cast = function (obj) { - var ret = tryConvertToPromise(obj); - if (!(ret instanceof Promise)) { - ret = new Promise(INTERNAL); - ret._captureStackTrace(); - ret._setFulfilled(); - ret._rejectionHandler0 = obj; - } - return ret; -}; - -Promise.resolve = Promise.fulfilled = Promise.cast; - -Promise.reject = Promise.rejected = function (reason) { - var ret = new Promise(INTERNAL); - ret._captureStackTrace(); - ret._rejectCallback(reason, true); - return ret; -}; - -Promise.setScheduler = function(fn) { - if (typeof fn !== "function") { - throw new TypeError("expecting a function but got " + util.classString(fn)); - } - return async.setScheduler(fn); -}; - -Promise.prototype._then = function ( - didFulfill, - didReject, - _, receiver, - internalData -) { - var haveInternalData = internalData !== undefined; - var promise = haveInternalData ? internalData : new Promise(INTERNAL); - var target = this._target(); - var bitField = target._bitField; - - if (!haveInternalData) { - promise._propagateFrom(this, 3); - promise._captureStackTrace(); - if (receiver === undefined && - ((this._bitField & 2097152) !== 0)) { - if (!((bitField & 50397184) === 0)) { - receiver = this._boundValue(); - } else { - receiver = target === this ? undefined : this._boundTo; - } - } - this._fireEvent("promiseChained", this, promise); - } - - var domain = getDomain(); - if (!((bitField & 50397184) === 0)) { - var handler, value, settler = target._settlePromiseCtx; - if (((bitField & 33554432) !== 0)) { - value = target._rejectionHandler0; - handler = didFulfill; - } else if (((bitField & 16777216) !== 0)) { - value = target._fulfillmentHandler0; - handler = didReject; - target._unsetRejectionIsUnhandled(); - } else { - settler = target._settlePromiseLateCancellationObserver; - value = new CancellationError("late cancellation observer"); - target._attachExtraTrace(value); - handler = didReject; - } - - async.invoke(settler, target, { - handler: domain === null ? handler - : (typeof handler === "function" && domain.bind(handler)), - promise: promise, - receiver: receiver, - value: value - }); - } else { - target._addCallbacks(didFulfill, didReject, promise, receiver, domain); - } - - return promise; -}; - -Promise.prototype._length = function () { - return this._bitField & 65535; -}; - -Promise.prototype._isFateSealed = function () { - return (this._bitField & 117506048) !== 0; -}; - -Promise.prototype._isFollowing = function () { - return (this._bitField & 67108864) === 67108864; -}; - -Promise.prototype._setLength = function (len) { - this._bitField = (this._bitField & -65536) | - (len & 65535); -}; - -Promise.prototype._setFulfilled = function () { - this._bitField = this._bitField | 33554432; - this._fireEvent("promiseFulfilled", this); -}; - -Promise.prototype._setRejected = function () { - this._bitField = this._bitField | 16777216; - this._fireEvent("promiseRejected", this); -}; - -Promise.prototype._setFollowing = function () { - this._bitField = this._bitField | 67108864; - this._fireEvent("promiseResolved", this); -}; - -Promise.prototype._setIsFinal = function () { - this._bitField = this._bitField | 4194304; -}; - -Promise.prototype._isFinal = function () { - return (this._bitField & 4194304) > 0; -}; - -Promise.prototype._unsetCancelled = function() { - this._bitField = this._bitField & (~65536); -}; - -Promise.prototype._setCancelled = function() { - this._bitField = this._bitField | 65536; - this._fireEvent("promiseCancelled", this); -}; - -Promise.prototype._setAsyncGuaranteed = function() { - if (async.hasCustomScheduler()) return; - this._bitField = this._bitField | 134217728; -}; - -Promise.prototype._receiverAt = function (index) { - var ret = index === 0 ? this._receiver0 : this[ - index * 4 - 4 + 3]; - if (ret === UNDEFINED_BINDING) { - return undefined; - } else if (ret === undefined && this._isBound()) { - return this._boundValue(); - } - return ret; -}; - -Promise.prototype._promiseAt = function (index) { - return this[ - index * 4 - 4 + 2]; -}; - -Promise.prototype._fulfillmentHandlerAt = function (index) { - return this[ - index * 4 - 4 + 0]; -}; - -Promise.prototype._rejectionHandlerAt = function (index) { - return this[ - index * 4 - 4 + 1]; -}; - -Promise.prototype._boundValue = function() {}; - -Promise.prototype._migrateCallback0 = function (follower) { - var bitField = follower._bitField; - var fulfill = follower._fulfillmentHandler0; - var reject = follower._rejectionHandler0; - var promise = follower._promise0; - var receiver = follower._receiverAt(0); - if (receiver === undefined) receiver = UNDEFINED_BINDING; - this._addCallbacks(fulfill, reject, promise, receiver, null); -}; - -Promise.prototype._migrateCallbackAt = function (follower, index) { - var fulfill = follower._fulfillmentHandlerAt(index); - var reject = follower._rejectionHandlerAt(index); - var promise = follower._promiseAt(index); - var receiver = follower._receiverAt(index); - if (receiver === undefined) receiver = UNDEFINED_BINDING; - this._addCallbacks(fulfill, reject, promise, receiver, null); -}; - -Promise.prototype._addCallbacks = function ( - fulfill, - reject, - promise, - receiver, - domain -) { - var index = this._length(); - - if (index >= 65535 - 4) { - index = 0; - this._setLength(0); - } - - if (index === 0) { - this._promise0 = promise; - this._receiver0 = receiver; - if (typeof fulfill === "function") { - this._fulfillmentHandler0 = - domain === null ? fulfill : domain.bind(fulfill); - } - if (typeof reject === "function") { - this._rejectionHandler0 = - domain === null ? reject : domain.bind(reject); - } - } else { - var base = index * 4 - 4; - this[base + 2] = promise; - this[base + 3] = receiver; - if (typeof fulfill === "function") { - this[base + 0] = - domain === null ? fulfill : domain.bind(fulfill); - } - if (typeof reject === "function") { - this[base + 1] = - domain === null ? reject : domain.bind(reject); - } - } - this._setLength(index + 1); - return index; -}; - -Promise.prototype._proxy = function (proxyable, arg) { - this._addCallbacks(undefined, undefined, arg, proxyable, null); -}; - -Promise.prototype._resolveCallback = function(value, shouldBind) { - if (((this._bitField & 117506048) !== 0)) return; - if (value === this) - return this._rejectCallback(makeSelfResolutionError(), false); - var maybePromise = tryConvertToPromise(value, this); - if (!(maybePromise instanceof Promise)) return this._fulfill(value); - - if (shouldBind) this._propagateFrom(maybePromise, 2); - - var promise = maybePromise._target(); - - if (promise === this) { - this._reject(makeSelfResolutionError()); - return; - } - - var bitField = promise._bitField; - if (((bitField & 50397184) === 0)) { - var len = this._length(); - if (len > 0) promise._migrateCallback0(this); - for (var i = 1; i < len; ++i) { - promise._migrateCallbackAt(this, i); - } - this._setFollowing(); - this._setLength(0); - this._setFollowee(promise); - } else if (((bitField & 33554432) !== 0)) { - this._fulfill(promise._value()); - } else if (((bitField & 16777216) !== 0)) { - this._reject(promise._reason()); - } else { - var reason = new CancellationError("late cancellation observer"); - promise._attachExtraTrace(reason); - this._reject(reason); - } -}; - -Promise.prototype._rejectCallback = -function(reason, synchronous, ignoreNonErrorWarnings) { - var trace = util.ensureErrorObject(reason); - var hasStack = trace === reason; - if (!hasStack && !ignoreNonErrorWarnings && debug.warnings()) { - var message = "a promise was rejected with a non-error: " + - util.classString(reason); - this._warn(message, true); - } - this._attachExtraTrace(trace, synchronous ? hasStack : false); - this._reject(reason); -}; - -Promise.prototype._resolveFromExecutor = function (executor) { - var promise = this; - this._captureStackTrace(); - this._pushContext(); - var synchronous = true; - var r = this._execute(executor, function(value) { - promise._resolveCallback(value); - }, function (reason) { - promise._rejectCallback(reason, synchronous); - }); - synchronous = false; - this._popContext(); - - if (r !== undefined) { - promise._rejectCallback(r, true); - } -}; - -Promise.prototype._settlePromiseFromHandler = function ( - handler, receiver, value, promise -) { - var bitField = promise._bitField; - if (((bitField & 65536) !== 0)) return; - promise._pushContext(); - var x; - if (receiver === APPLY) { - if (!value || typeof value.length !== "number") { - x = errorObj; - x.e = new TypeError("cannot .spread() a non-array: " + - util.classString(value)); - } else { - x = tryCatch(handler).apply(this._boundValue(), value); - } - } else { - x = tryCatch(handler).call(receiver, value); - } - var promiseCreated = promise._popContext(); - bitField = promise._bitField; - if (((bitField & 65536) !== 0)) return; - - if (x === NEXT_FILTER) { - promise._reject(value); - } else if (x === errorObj) { - promise._rejectCallback(x.e, false); - } else { - debug.checkForgottenReturns(x, promiseCreated, "", promise, this); - promise._resolveCallback(x); - } -}; - -Promise.prototype._target = function() { - var ret = this; - while (ret._isFollowing()) ret = ret._followee(); - return ret; -}; - -Promise.prototype._followee = function() { - return this._rejectionHandler0; -}; - -Promise.prototype._setFollowee = function(promise) { - this._rejectionHandler0 = promise; -}; - -Promise.prototype._settlePromise = function(promise, handler, receiver, value) { - var isPromise = promise instanceof Promise; - var bitField = this._bitField; - var asyncGuaranteed = ((bitField & 134217728) !== 0); - if (((bitField & 65536) !== 0)) { - if (isPromise) promise._invokeInternalOnCancel(); - - if (receiver instanceof PassThroughHandlerContext && - receiver.isFinallyHandler()) { - receiver.cancelPromise = promise; - if (tryCatch(handler).call(receiver, value) === errorObj) { - promise._reject(errorObj.e); - } - } else if (handler === reflectHandler) { - promise._fulfill(reflectHandler.call(receiver)); - } else if (receiver instanceof Proxyable) { - receiver._promiseCancelled(promise); - } else if (isPromise || promise instanceof PromiseArray) { - promise._cancel(); - } else { - receiver.cancel(); - } - } else if (typeof handler === "function") { - if (!isPromise) { - handler.call(receiver, value, promise); - } else { - if (asyncGuaranteed) promise._setAsyncGuaranteed(); - this._settlePromiseFromHandler(handler, receiver, value, promise); - } - } else if (receiver instanceof Proxyable) { - if (!receiver._isResolved()) { - if (((bitField & 33554432) !== 0)) { - receiver._promiseFulfilled(value, promise); - } else { - receiver._promiseRejected(value, promise); - } - } - } else if (isPromise) { - if (asyncGuaranteed) promise._setAsyncGuaranteed(); - if (((bitField & 33554432) !== 0)) { - promise._fulfill(value); - } else { - promise._reject(value); - } - } -}; - -Promise.prototype._settlePromiseLateCancellationObserver = function(ctx) { - var handler = ctx.handler; - var promise = ctx.promise; - var receiver = ctx.receiver; - var value = ctx.value; - if (typeof handler === "function") { - if (!(promise instanceof Promise)) { - handler.call(receiver, value, promise); - } else { - this._settlePromiseFromHandler(handler, receiver, value, promise); - } - } else if (promise instanceof Promise) { - promise._reject(value); - } -}; - -Promise.prototype._settlePromiseCtx = function(ctx) { - this._settlePromise(ctx.promise, ctx.handler, ctx.receiver, ctx.value); -}; - -Promise.prototype._settlePromise0 = function(handler, value, bitField) { - var promise = this._promise0; - var receiver = this._receiverAt(0); - this._promise0 = undefined; - this._receiver0 = undefined; - this._settlePromise(promise, handler, receiver, value); -}; - -Promise.prototype._clearCallbackDataAtIndex = function(index) { - var base = index * 4 - 4; - this[base + 2] = - this[base + 3] = - this[base + 0] = - this[base + 1] = undefined; -}; - -Promise.prototype._fulfill = function (value) { - var bitField = this._bitField; - if (((bitField & 117506048) >>> 16)) return; - if (value === this) { - var err = makeSelfResolutionError(); - this._attachExtraTrace(err); - return this._reject(err); - } - this._setFulfilled(); - this._rejectionHandler0 = value; - - if ((bitField & 65535) > 0) { - if (((bitField & 134217728) !== 0)) { - this._settlePromises(); - } else { - async.settlePromises(this); - } - } -}; - -Promise.prototype._reject = function (reason) { - var bitField = this._bitField; - if (((bitField & 117506048) >>> 16)) return; - this._setRejected(); - this._fulfillmentHandler0 = reason; - - if (this._isFinal()) { - return async.fatalError(reason, util.isNode); - } - - if ((bitField & 65535) > 0) { - async.settlePromises(this); - } else { - this._ensurePossibleRejectionHandled(); - } -}; - -Promise.prototype._fulfillPromises = function (len, value) { - for (var i = 1; i < len; i++) { - var handler = this._fulfillmentHandlerAt(i); - var promise = this._promiseAt(i); - var receiver = this._receiverAt(i); - this._clearCallbackDataAtIndex(i); - this._settlePromise(promise, handler, receiver, value); - } -}; - -Promise.prototype._rejectPromises = function (len, reason) { - for (var i = 1; i < len; i++) { - var handler = this._rejectionHandlerAt(i); - var promise = this._promiseAt(i); - var receiver = this._receiverAt(i); - this._clearCallbackDataAtIndex(i); - this._settlePromise(promise, handler, receiver, reason); - } -}; - -Promise.prototype._settlePromises = function () { - var bitField = this._bitField; - var len = (bitField & 65535); - - if (len > 0) { - if (((bitField & 16842752) !== 0)) { - var reason = this._fulfillmentHandler0; - this._settlePromise0(this._rejectionHandler0, reason, bitField); - this._rejectPromises(len, reason); - } else { - var value = this._rejectionHandler0; - this._settlePromise0(this._fulfillmentHandler0, value, bitField); - this._fulfillPromises(len, value); - } - this._setLength(0); - } - this._clearCancellationData(); -}; - -Promise.prototype._settledValue = function() { - var bitField = this._bitField; - if (((bitField & 33554432) !== 0)) { - return this._rejectionHandler0; - } else if (((bitField & 16777216) !== 0)) { - return this._fulfillmentHandler0; - } -}; - -function deferResolve(v) {this.promise._resolveCallback(v);} -function deferReject(v) {this.promise._rejectCallback(v, false);} - -Promise.defer = Promise.pending = function() { - debug.deprecated("Promise.defer", "new Promise"); - var promise = new Promise(INTERNAL); - return { - promise: promise, - resolve: deferResolve, - reject: deferReject - }; -}; - -util.notEnumerableProp(Promise, - "_makeSelfResolutionError", - makeSelfResolutionError); - -_dereq_("./method")(Promise, INTERNAL, tryConvertToPromise, apiRejection, - debug); -_dereq_("./bind")(Promise, INTERNAL, tryConvertToPromise, debug); -_dereq_("./cancel")(Promise, PromiseArray, apiRejection, debug); -_dereq_("./direct_resolve")(Promise); -_dereq_("./synchronous_inspection")(Promise); -_dereq_("./join")( - Promise, PromiseArray, tryConvertToPromise, INTERNAL, debug); -Promise.Promise = Promise; -Promise.version = "3.4.0"; -_dereq_('./map.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug); -_dereq_('./call_get.js')(Promise); -_dereq_('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, INTERNAL, debug); -_dereq_('./timers.js')(Promise, INTERNAL, debug); -_dereq_('./generators.js')(Promise, apiRejection, INTERNAL, tryConvertToPromise, Proxyable, debug); -_dereq_('./nodeify.js')(Promise); -_dereq_('./promisify.js')(Promise, INTERNAL); -_dereq_('./props.js')(Promise, PromiseArray, tryConvertToPromise, apiRejection); -_dereq_('./race.js')(Promise, INTERNAL, tryConvertToPromise, apiRejection); -_dereq_('./reduce.js')(Promise, PromiseArray, apiRejection, tryConvertToPromise, INTERNAL, debug); -_dereq_('./settle.js')(Promise, PromiseArray, debug); -_dereq_('./some.js')(Promise, PromiseArray, apiRejection); -_dereq_('./filter.js')(Promise, INTERNAL); -_dereq_('./each.js')(Promise, INTERNAL); -_dereq_('./any.js')(Promise); - - util.toFastProperties(Promise); - util.toFastProperties(Promise.prototype); - function fillTypes(value) { - var p = new Promise(INTERNAL); - p._fulfillmentHandler0 = value; - p._rejectionHandler0 = value; - p._promise0 = value; - p._receiver0 = value; - } - // Complete slack tracking, opt out of field-type tracking and - // stabilize map - fillTypes({a: 1}); - fillTypes({b: 2}); - fillTypes({c: 3}); - fillTypes(1); - fillTypes(function(){}); - fillTypes(undefined); - fillTypes(false); - fillTypes(new Promise(INTERNAL)); - debug.setBounds(Async.firstLineError, util.lastLineError); - return Promise; - -}; - -},{"./any.js":1,"./async":2,"./bind":3,"./call_get.js":5,"./cancel":6,"./catch_filter":7,"./context":8,"./debuggability":9,"./direct_resolve":10,"./each.js":11,"./errors":12,"./es5":13,"./filter.js":14,"./finally":15,"./generators.js":16,"./join":17,"./map.js":18,"./method":19,"./nodeback":20,"./nodeify.js":21,"./promise_array":23,"./promisify.js":24,"./props.js":25,"./race.js":27,"./reduce.js":28,"./settle.js":30,"./some.js":31,"./synchronous_inspection":32,"./thenables":33,"./timers.js":34,"./using.js":35,"./util":36}],23:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL, tryConvertToPromise, - apiRejection, Proxyable) { -var util = _dereq_("./util"); -var isArray = util.isArray; - -function toResolutionValue(val) { - switch(val) { - case -2: return []; - case -3: return {}; - } -} - -function PromiseArray(values) { - var promise = this._promise = new Promise(INTERNAL); - if (values instanceof Promise) { - promise._propagateFrom(values, 3); - } - promise._setOnCancel(this); - this._values = values; - this._length = 0; - this._totalResolved = 0; - this._init(undefined, -2); -} -util.inherits(PromiseArray, Proxyable); - -PromiseArray.prototype.length = function () { - return this._length; -}; - -PromiseArray.prototype.promise = function () { - return this._promise; -}; - -PromiseArray.prototype._init = function init(_, resolveValueIfEmpty) { - var values = tryConvertToPromise(this._values, this._promise); - if (values instanceof Promise) { - values = values._target(); - var bitField = values._bitField; - ; - this._values = values; - - if (((bitField & 50397184) === 0)) { - this._promise._setAsyncGuaranteed(); - return values._then( - init, - this._reject, - undefined, - this, - resolveValueIfEmpty - ); - } else if (((bitField & 33554432) !== 0)) { - values = values._value(); - } else if (((bitField & 16777216) !== 0)) { - return this._reject(values._reason()); - } else { - return this._cancel(); - } - } - values = util.asArray(values); - if (values === null) { - var err = apiRejection( - "expecting an array or an iterable object but got " + util.classString(values)).reason(); - this._promise._rejectCallback(err, false); - return; - } - - if (values.length === 0) { - if (resolveValueIfEmpty === -5) { - this._resolveEmptyArray(); - } - else { - this._resolve(toResolutionValue(resolveValueIfEmpty)); - } - return; - } - this._iterate(values); -}; - -PromiseArray.prototype._iterate = function(values) { - var len = this.getActualLength(values.length); - this._length = len; - this._values = this.shouldCopyValues() ? new Array(len) : this._values; - var result = this._promise; - var isResolved = false; - var bitField = null; - for (var i = 0; i < len; ++i) { - var maybePromise = tryConvertToPromise(values[i], result); - - if (maybePromise instanceof Promise) { - maybePromise = maybePromise._target(); - bitField = maybePromise._bitField; - } else { - bitField = null; - } - - if (isResolved) { - if (bitField !== null) { - maybePromise.suppressUnhandledRejections(); - } - } else if (bitField !== null) { - if (((bitField & 50397184) === 0)) { - maybePromise._proxy(this, i); - this._values[i] = maybePromise; - } else if (((bitField & 33554432) !== 0)) { - isResolved = this._promiseFulfilled(maybePromise._value(), i); - } else if (((bitField & 16777216) !== 0)) { - isResolved = this._promiseRejected(maybePromise._reason(), i); - } else { - isResolved = this._promiseCancelled(i); - } - } else { - isResolved = this._promiseFulfilled(maybePromise, i); - } - } - if (!isResolved) result._setAsyncGuaranteed(); -}; - -PromiseArray.prototype._isResolved = function () { - return this._values === null; -}; - -PromiseArray.prototype._resolve = function (value) { - this._values = null; - this._promise._fulfill(value); -}; - -PromiseArray.prototype._cancel = function() { - if (this._isResolved() || !this._promise.isCancellable()) return; - this._values = null; - this._promise._cancel(); -}; - -PromiseArray.prototype._reject = function (reason) { - this._values = null; - this._promise._rejectCallback(reason, false); -}; - -PromiseArray.prototype._promiseFulfilled = function (value, index) { - this._values[index] = value; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - this._resolve(this._values); - return true; - } - return false; -}; - -PromiseArray.prototype._promiseCancelled = function() { - this._cancel(); - return true; -}; - -PromiseArray.prototype._promiseRejected = function (reason) { - this._totalResolved++; - this._reject(reason); - return true; -}; - -PromiseArray.prototype._resultCancelled = function() { - if (this._isResolved()) return; - var values = this._values; - this._cancel(); - if (values instanceof Promise) { - values.cancel(); - } else { - for (var i = 0; i < values.length; ++i) { - if (values[i] instanceof Promise) { - values[i].cancel(); - } - } - } -}; - -PromiseArray.prototype.shouldCopyValues = function () { - return true; -}; - -PromiseArray.prototype.getActualLength = function (len) { - return len; -}; - -return PromiseArray; -}; - -},{"./util":36}],24:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var THIS = {}; -var util = _dereq_("./util"); -var nodebackForPromise = _dereq_("./nodeback"); -var withAppended = util.withAppended; -var maybeWrapAsError = util.maybeWrapAsError; -var canEvaluate = util.canEvaluate; -var TypeError = _dereq_("./errors").TypeError; -var defaultSuffix = "Async"; -var defaultPromisified = {__isPromisified__: true}; -var noCopyProps = [ - "arity", "length", - "name", - "arguments", - "caller", - "callee", - "prototype", - "__isPromisified__" -]; -var noCopyPropsPattern = new RegExp("^(?:" + noCopyProps.join("|") + ")$"); - -var defaultFilter = function(name) { - return util.isIdentifier(name) && - name.charAt(0) !== "_" && - name !== "constructor"; -}; - -function propsFilter(key) { - return !noCopyPropsPattern.test(key); -} - -function isPromisified(fn) { - try { - return fn.__isPromisified__ === true; - } - catch (e) { - return false; - } -} - -function hasPromisified(obj, key, suffix) { - var val = util.getDataPropertyOrDefault(obj, key + suffix, - defaultPromisified); - return val ? isPromisified(val) : false; -} -function checkValid(ret, suffix, suffixRegexp) { - for (var i = 0; i < ret.length; i += 2) { - var key = ret[i]; - if (suffixRegexp.test(key)) { - var keyWithoutAsyncSuffix = key.replace(suffixRegexp, ""); - for (var j = 0; j < ret.length; j += 2) { - if (ret[j] === keyWithoutAsyncSuffix) { - throw new TypeError("Cannot promisify an API that has normal methods with '%s'-suffix\u000a\u000a See http://goo.gl/MqrFmX\u000a" - .replace("%s", suffix)); - } - } - } - } -} - -function promisifiableMethods(obj, suffix, suffixRegexp, filter) { - var keys = util.inheritedDataKeys(obj); - var ret = []; - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - var value = obj[key]; - var passesDefaultFilter = filter === defaultFilter - ? true : defaultFilter(key, value, obj); - if (typeof value === "function" && - !isPromisified(value) && - !hasPromisified(obj, key, suffix) && - filter(key, value, obj, passesDefaultFilter)) { - ret.push(key, value); - } - } - checkValid(ret, suffix, suffixRegexp); - return ret; -} - -var escapeIdentRegex = function(str) { - return str.replace(/([$])/, "\\$"); -}; - -var makeNodePromisifiedEval; -if (false) { -var switchCaseArgumentOrder = function(likelyArgumentCount) { - var ret = [likelyArgumentCount]; - var min = Math.max(0, likelyArgumentCount - 1 - 3); - for(var i = likelyArgumentCount - 1; i >= min; --i) { - ret.push(i); - } - for(var i = likelyArgumentCount + 1; i <= 3; ++i) { - ret.push(i); - } - return ret; -}; - -var argumentSequence = function(argumentCount) { - return util.filledRange(argumentCount, "_arg", ""); -}; - -var parameterDeclaration = function(parameterCount) { - return util.filledRange( - Math.max(parameterCount, 3), "_arg", ""); -}; - -var parameterCount = function(fn) { - if (typeof fn.length === "number") { - return Math.max(Math.min(fn.length, 1023 + 1), 0); - } - return 0; -}; - -makeNodePromisifiedEval = -function(callback, receiver, originalName, fn, _, multiArgs) { - var newParameterCount = Math.max(0, parameterCount(fn) - 1); - var argumentOrder = switchCaseArgumentOrder(newParameterCount); - var shouldProxyThis = typeof callback === "string" || receiver === THIS; - - function generateCallForArgumentCount(count) { - var args = argumentSequence(count).join(", "); - var comma = count > 0 ? ", " : ""; - var ret; - if (shouldProxyThis) { - ret = "ret = callback.call(this, {{args}}, nodeback); break;\n"; - } else { - ret = receiver === undefined - ? "ret = callback({{args}}, nodeback); break;\n" - : "ret = callback.call(receiver, {{args}}, nodeback); break;\n"; - } - return ret.replace("{{args}}", args).replace(", ", comma); - } - - function generateArgumentSwitchCase() { - var ret = ""; - for (var i = 0; i < argumentOrder.length; ++i) { - ret += "case " + argumentOrder[i] +":" + - generateCallForArgumentCount(argumentOrder[i]); - } - - ret += " \n\ - default: \n\ - var args = new Array(len + 1); \n\ - var i = 0; \n\ - for (var i = 0; i < len; ++i) { \n\ - args[i] = arguments[i]; \n\ - } \n\ - args[i] = nodeback; \n\ - [CodeForCall] \n\ - break; \n\ - ".replace("[CodeForCall]", (shouldProxyThis - ? "ret = callback.apply(this, args);\n" - : "ret = callback.apply(receiver, args);\n")); - return ret; - } - - var getFunctionCode = typeof callback === "string" - ? ("this != null ? this['"+callback+"'] : fn") - : "fn"; - var body = "'use strict'; \n\ - var ret = function (Parameters) { \n\ - 'use strict'; \n\ - var len = arguments.length; \n\ - var promise = new Promise(INTERNAL); \n\ - promise._captureStackTrace(); \n\ - var nodeback = nodebackForPromise(promise, " + multiArgs + "); \n\ - var ret; \n\ - var callback = tryCatch([GetFunctionCode]); \n\ - switch(len) { \n\ - [CodeForSwitchCase] \n\ - } \n\ - if (ret === errorObj) { \n\ - promise._rejectCallback(maybeWrapAsError(ret.e), true, true);\n\ - } \n\ - if (!promise._isFateSealed()) promise._setAsyncGuaranteed(); \n\ - return promise; \n\ - }; \n\ - notEnumerableProp(ret, '__isPromisified__', true); \n\ - return ret; \n\ - ".replace("[CodeForSwitchCase]", generateArgumentSwitchCase()) - .replace("[GetFunctionCode]", getFunctionCode); - body = body.replace("Parameters", parameterDeclaration(newParameterCount)); - return new Function("Promise", - "fn", - "receiver", - "withAppended", - "maybeWrapAsError", - "nodebackForPromise", - "tryCatch", - "errorObj", - "notEnumerableProp", - "INTERNAL", - body)( - Promise, - fn, - receiver, - withAppended, - maybeWrapAsError, - nodebackForPromise, - util.tryCatch, - util.errorObj, - util.notEnumerableProp, - INTERNAL); -}; -} - -function makeNodePromisifiedClosure(callback, receiver, _, fn, __, multiArgs) { - var defaultThis = (function() {return this;})(); - var method = callback; - if (typeof method === "string") { - callback = fn; - } - function promisified() { - var _receiver = receiver; - if (receiver === THIS) _receiver = this; - var promise = new Promise(INTERNAL); - promise._captureStackTrace(); - var cb = typeof method === "string" && this !== defaultThis - ? this[method] : callback; - var fn = nodebackForPromise(promise, multiArgs); - try { - cb.apply(_receiver, withAppended(arguments, fn)); - } catch(e) { - promise._rejectCallback(maybeWrapAsError(e), true, true); - } - if (!promise._isFateSealed()) promise._setAsyncGuaranteed(); - return promise; - } - util.notEnumerableProp(promisified, "__isPromisified__", true); - return promisified; -} - -var makeNodePromisified = canEvaluate - ? makeNodePromisifiedEval - : makeNodePromisifiedClosure; - -function promisifyAll(obj, suffix, filter, promisifier, multiArgs) { - var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + "$"); - var methods = - promisifiableMethods(obj, suffix, suffixRegexp, filter); - - for (var i = 0, len = methods.length; i < len; i+= 2) { - var key = methods[i]; - var fn = methods[i+1]; - var promisifiedKey = key + suffix; - if (promisifier === makeNodePromisified) { - obj[promisifiedKey] = - makeNodePromisified(key, THIS, key, fn, suffix, multiArgs); - } else { - var promisified = promisifier(fn, function() { - return makeNodePromisified(key, THIS, key, - fn, suffix, multiArgs); - }); - util.notEnumerableProp(promisified, "__isPromisified__", true); - obj[promisifiedKey] = promisified; - } - } - util.toFastProperties(obj); - return obj; -} - -function promisify(callback, receiver, multiArgs) { - return makeNodePromisified(callback, receiver, undefined, - callback, null, multiArgs); -} - -Promise.promisify = function (fn, options) { - if (typeof fn !== "function") { - throw new TypeError("expecting a function but got " + util.classString(fn)); - } - if (isPromisified(fn)) { - return fn; - } - options = Object(options); - var receiver = options.context === undefined ? THIS : options.context; - var multiArgs = !!options.multiArgs; - var ret = promisify(fn, receiver, multiArgs); - util.copyDescriptors(fn, ret, propsFilter); - return ret; -}; - -Promise.promisifyAll = function (target, options) { - if (typeof target !== "function" && typeof target !== "object") { - throw new TypeError("the target of promisifyAll must be an object or a function\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - options = Object(options); - var multiArgs = !!options.multiArgs; - var suffix = options.suffix; - if (typeof suffix !== "string") suffix = defaultSuffix; - var filter = options.filter; - if (typeof filter !== "function") filter = defaultFilter; - var promisifier = options.promisifier; - if (typeof promisifier !== "function") promisifier = makeNodePromisified; - - if (!util.isIdentifier(suffix)) { - throw new RangeError("suffix must be a valid identifier\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - - var keys = util.inheritedDataKeys(target); - for (var i = 0; i < keys.length; ++i) { - var value = target[keys[i]]; - if (keys[i] !== "constructor" && - util.isClass(value)) { - promisifyAll(value.prototype, suffix, filter, promisifier, - multiArgs); - promisifyAll(value, suffix, filter, promisifier, multiArgs); - } - } - - return promisifyAll(target, suffix, filter, promisifier, multiArgs); -}; -}; - - -},{"./errors":12,"./nodeback":20,"./util":36}],25:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function( - Promise, PromiseArray, tryConvertToPromise, apiRejection) { -var util = _dereq_("./util"); -var isObject = util.isObject; -var es5 = _dereq_("./es5"); -var Es6Map; -if (typeof Map === "function") Es6Map = Map; - -var mapToEntries = (function() { - var index = 0; - var size = 0; - - function extractEntry(value, key) { - this[index] = value; - this[index + size] = key; - index++; - } - - return function mapToEntries(map) { - size = map.size; - index = 0; - var ret = new Array(map.size * 2); - map.forEach(extractEntry, ret); - return ret; - }; -})(); - -var entriesToMap = function(entries) { - var ret = new Es6Map(); - var length = entries.length / 2 | 0; - for (var i = 0; i < length; ++i) { - var key = entries[length + i]; - var value = entries[i]; - ret.set(key, value); - } - return ret; -}; - -function PropertiesPromiseArray(obj) { - var isMap = false; - var entries; - if (Es6Map !== undefined && obj instanceof Es6Map) { - entries = mapToEntries(obj); - isMap = true; - } else { - var keys = es5.keys(obj); - var len = keys.length; - entries = new Array(len * 2); - for (var i = 0; i < len; ++i) { - var key = keys[i]; - entries[i] = obj[key]; - entries[i + len] = key; - } - } - this.constructor$(entries); - this._isMap = isMap; - this._init$(undefined, -3); -} -util.inherits(PropertiesPromiseArray, PromiseArray); - -PropertiesPromiseArray.prototype._init = function () {}; - -PropertiesPromiseArray.prototype._promiseFulfilled = function (value, index) { - this._values[index] = value; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - var val; - if (this._isMap) { - val = entriesToMap(this._values); - } else { - val = {}; - var keyOffset = this.length(); - for (var i = 0, len = this.length(); i < len; ++i) { - val[this._values[i + keyOffset]] = this._values[i]; - } - } - this._resolve(val); - return true; - } - return false; -}; - -PropertiesPromiseArray.prototype.shouldCopyValues = function () { - return false; -}; - -PropertiesPromiseArray.prototype.getActualLength = function (len) { - return len >> 1; -}; - -function props(promises) { - var ret; - var castValue = tryConvertToPromise(promises); - - if (!isObject(castValue)) { - return apiRejection("cannot await properties of a non-object\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } else if (castValue instanceof Promise) { - ret = castValue._then( - Promise.props, undefined, undefined, undefined, undefined); - } else { - ret = new PropertiesPromiseArray(castValue).promise(); - } - - if (castValue instanceof Promise) { - ret._propagateFrom(castValue, 2); - } - return ret; -} - -Promise.prototype.props = function () { - return props(this); -}; - -Promise.props = function (promises) { - return props(promises); -}; -}; - -},{"./es5":13,"./util":36}],26:[function(_dereq_,module,exports){ -"use strict"; -function arrayMove(src, srcIndex, dst, dstIndex, len) { - for (var j = 0; j < len; ++j) { - dst[j + dstIndex] = src[j + srcIndex]; - src[j + srcIndex] = void 0; - } -} - -function Queue(capacity) { - this._capacity = capacity; - this._length = 0; - this._front = 0; -} - -Queue.prototype._willBeOverCapacity = function (size) { - return this._capacity < size; -}; - -Queue.prototype._pushOne = function (arg) { - var length = this.length(); - this._checkCapacity(length + 1); - var i = (this._front + length) & (this._capacity - 1); - this[i] = arg; - this._length = length + 1; -}; - -Queue.prototype._unshiftOne = function(value) { - var capacity = this._capacity; - this._checkCapacity(this.length() + 1); - var front = this._front; - var i = (((( front - 1 ) & - ( capacity - 1) ) ^ capacity ) - capacity ); - this[i] = value; - this._front = i; - this._length = this.length() + 1; -}; - -Queue.prototype.unshift = function(fn, receiver, arg) { - this._unshiftOne(arg); - this._unshiftOne(receiver); - this._unshiftOne(fn); -}; - -Queue.prototype.push = function (fn, receiver, arg) { - var length = this.length() + 3; - if (this._willBeOverCapacity(length)) { - this._pushOne(fn); - this._pushOne(receiver); - this._pushOne(arg); - return; - } - var j = this._front + length - 3; - this._checkCapacity(length); - var wrapMask = this._capacity - 1; - this[(j + 0) & wrapMask] = fn; - this[(j + 1) & wrapMask] = receiver; - this[(j + 2) & wrapMask] = arg; - this._length = length; -}; - -Queue.prototype.shift = function () { - var front = this._front, - ret = this[front]; - - this[front] = undefined; - this._front = (front + 1) & (this._capacity - 1); - this._length--; - return ret; -}; - -Queue.prototype.length = function () { - return this._length; -}; - -Queue.prototype._checkCapacity = function (size) { - if (this._capacity < size) { - this._resizeTo(this._capacity << 1); - } -}; - -Queue.prototype._resizeTo = function (capacity) { - var oldCapacity = this._capacity; - this._capacity = capacity; - var front = this._front; - var length = this._length; - var moveItemsCount = (front + length) & (oldCapacity - 1); - arrayMove(this, 0, this, oldCapacity, moveItemsCount); -}; - -module.exports = Queue; - -},{}],27:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function( - Promise, INTERNAL, tryConvertToPromise, apiRejection) { -var util = _dereq_("./util"); - -var raceLater = function (promise) { - return promise.then(function(array) { - return race(array, promise); - }); -}; - -function race(promises, parent) { - var maybePromise = tryConvertToPromise(promises); - - if (maybePromise instanceof Promise) { - return raceLater(maybePromise); - } else { - promises = util.asArray(promises); - if (promises === null) - return apiRejection("expecting an array or an iterable object but got " + util.classString(promises)); - } - - var ret = new Promise(INTERNAL); - if (parent !== undefined) { - ret._propagateFrom(parent, 3); - } - var fulfill = ret._fulfill; - var reject = ret._reject; - for (var i = 0, len = promises.length; i < len; ++i) { - var val = promises[i]; - - if (val === undefined && !(i in promises)) { - continue; - } - - Promise.cast(val)._then(fulfill, reject, undefined, ret, null); - } - return ret; -} - -Promise.race = function (promises) { - return race(promises, undefined); -}; - -Promise.prototype.race = function () { - return race(this, undefined); -}; - -}; - -},{"./util":36}],28:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, - PromiseArray, - apiRejection, - tryConvertToPromise, - INTERNAL, - debug) { -var getDomain = Promise._getDomain; -var util = _dereq_("./util"); -var tryCatch = util.tryCatch; - -function ReductionPromiseArray(promises, fn, initialValue, _each) { - this.constructor$(promises); - var domain = getDomain(); - this._fn = domain === null ? fn : domain.bind(fn); - if (initialValue !== undefined) { - initialValue = Promise.resolve(initialValue); - initialValue._attachCancellationCallback(this); - } - this._initialValue = initialValue; - this._currentCancellable = null; - this._eachValues = _each === INTERNAL ? [] : undefined; - this._promise._captureStackTrace(); - this._init$(undefined, -5); -} -util.inherits(ReductionPromiseArray, PromiseArray); - -ReductionPromiseArray.prototype._gotAccum = function(accum) { - if (this._eachValues !== undefined && accum !== INTERNAL) { - this._eachValues.push(accum); - } -}; - -ReductionPromiseArray.prototype._eachComplete = function(value) { - this._eachValues.push(value); - return this._eachValues; -}; - -ReductionPromiseArray.prototype._init = function() {}; - -ReductionPromiseArray.prototype._resolveEmptyArray = function() { - this._resolve(this._eachValues !== undefined ? this._eachValues - : this._initialValue); -}; - -ReductionPromiseArray.prototype.shouldCopyValues = function () { - return false; -}; - -ReductionPromiseArray.prototype._resolve = function(value) { - this._promise._resolveCallback(value); - this._values = null; -}; - -ReductionPromiseArray.prototype._resultCancelled = function(sender) { - if (sender === this._initialValue) return this._cancel(); - if (this._isResolved()) return; - this._resultCancelled$(); - if (this._currentCancellable instanceof Promise) { - this._currentCancellable.cancel(); - } - if (this._initialValue instanceof Promise) { - this._initialValue.cancel(); - } -}; - -ReductionPromiseArray.prototype._iterate = function (values) { - this._values = values; - var value; - var i; - var length = values.length; - if (this._initialValue !== undefined) { - value = this._initialValue; - i = 0; - } else { - value = Promise.resolve(values[0]); - i = 1; - } - - this._currentCancellable = value; - - if (!value.isRejected()) { - for (; i < length; ++i) { - var ctx = { - accum: null, - value: values[i], - index: i, - length: length, - array: this - }; - value = value._then(gotAccum, undefined, undefined, ctx, undefined); - } - } - - if (this._eachValues !== undefined) { - value = value - ._then(this._eachComplete, undefined, undefined, this, undefined); - } - value._then(completed, completed, undefined, value, this); -}; - -Promise.prototype.reduce = function (fn, initialValue) { - return reduce(this, fn, initialValue, null); -}; - -Promise.reduce = function (promises, fn, initialValue, _each) { - return reduce(promises, fn, initialValue, _each); -}; - -function completed(valueOrReason, array) { - if (this.isFulfilled()) { - array._resolve(valueOrReason); - } else { - array._reject(valueOrReason); - } -} - -function reduce(promises, fn, initialValue, _each) { - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - var array = new ReductionPromiseArray(promises, fn, initialValue, _each); - return array.promise(); -} - -function gotAccum(accum) { - this.accum = accum; - this.array._gotAccum(accum); - var value = tryConvertToPromise(this.value, this.array._promise); - if (value instanceof Promise) { - this.array._currentCancellable = value; - return value._then(gotValue, undefined, undefined, this, undefined); - } else { - return gotValue.call(this, value); - } -} - -function gotValue(value) { - var array = this.array; - var promise = array._promise; - var fn = tryCatch(array._fn); - promise._pushContext(); - var ret; - if (array._eachValues !== undefined) { - ret = fn.call(promise._boundValue(), value, this.index, this.length); - } else { - ret = fn.call(promise._boundValue(), - this.accum, value, this.index, this.length); - } - if (ret instanceof Promise) { - array._currentCancellable = ret; - } - var promiseCreated = promise._popContext(); - debug.checkForgottenReturns( - ret, - promiseCreated, - array._eachValues !== undefined ? "Promise.each" : "Promise.reduce", - promise - ); - return ret; -} -}; - -},{"./util":36}],29:[function(_dereq_,module,exports){ -"use strict"; -var util = _dereq_("./util"); -var schedule; -var noAsyncScheduler = function() { - throw new Error("No async scheduler available\u000a\u000a See http://goo.gl/MqrFmX\u000a"); -}; -var NativePromise = util.getNativePromise(); -if (util.isNode && typeof MutationObserver === "undefined") { - var GlobalSetImmediate = global.setImmediate; - var ProcessNextTick = process.nextTick; - schedule = util.isRecentNode - ? function(fn) { GlobalSetImmediate.call(global, fn); } - : function(fn) { ProcessNextTick.call(process, fn); }; -} else if (typeof NativePromise === "function") { - var nativePromise = NativePromise.resolve(); - schedule = function(fn) { - nativePromise.then(fn); - }; -} else if ((typeof MutationObserver !== "undefined") && - !(typeof window !== "undefined" && - window.navigator && - window.navigator.standalone)) { - schedule = (function() { - var div = document.createElement("div"); - var opts = {attributes: true}; - var toggleScheduled = false; - var div2 = document.createElement("div"); - var o2 = new MutationObserver(function() { - div.classList.toggle("foo"); - toggleScheduled = false; - }); - o2.observe(div2, opts); - - var scheduleToggle = function() { - if (toggleScheduled) return; - toggleScheduled = true; - div2.classList.toggle("foo"); - }; - - return function schedule(fn) { - var o = new MutationObserver(function() { - o.disconnect(); - fn(); - }); - o.observe(div, opts); - scheduleToggle(); - }; - })(); -} else if (typeof setImmediate !== "undefined") { - schedule = function (fn) { - setImmediate(fn); - }; -} else if (typeof setTimeout !== "undefined") { - schedule = function (fn) { - setTimeout(fn, 0); - }; -} else { - schedule = noAsyncScheduler; -} -module.exports = schedule; - -},{"./util":36}],30:[function(_dereq_,module,exports){ -"use strict"; -module.exports = - function(Promise, PromiseArray, debug) { -var PromiseInspection = Promise.PromiseInspection; -var util = _dereq_("./util"); - -function SettledPromiseArray(values) { - this.constructor$(values); -} -util.inherits(SettledPromiseArray, PromiseArray); - -SettledPromiseArray.prototype._promiseResolved = function (index, inspection) { - this._values[index] = inspection; - var totalResolved = ++this._totalResolved; - if (totalResolved >= this._length) { - this._resolve(this._values); - return true; - } - return false; -}; - -SettledPromiseArray.prototype._promiseFulfilled = function (value, index) { - var ret = new PromiseInspection(); - ret._bitField = 33554432; - ret._settledValueField = value; - return this._promiseResolved(index, ret); -}; -SettledPromiseArray.prototype._promiseRejected = function (reason, index) { - var ret = new PromiseInspection(); - ret._bitField = 16777216; - ret._settledValueField = reason; - return this._promiseResolved(index, ret); -}; - -Promise.settle = function (promises) { - debug.deprecated(".settle()", ".reflect()"); - return new SettledPromiseArray(promises).promise(); -}; - -Promise.prototype.settle = function () { - return Promise.settle(this); -}; -}; - -},{"./util":36}],31:[function(_dereq_,module,exports){ -"use strict"; -module.exports = -function(Promise, PromiseArray, apiRejection) { -var util = _dereq_("./util"); -var RangeError = _dereq_("./errors").RangeError; -var AggregateError = _dereq_("./errors").AggregateError; -var isArray = util.isArray; -var CANCELLATION = {}; - - -function SomePromiseArray(values) { - this.constructor$(values); - this._howMany = 0; - this._unwrap = false; - this._initialized = false; -} -util.inherits(SomePromiseArray, PromiseArray); - -SomePromiseArray.prototype._init = function () { - if (!this._initialized) { - return; - } - if (this._howMany === 0) { - this._resolve([]); - return; - } - this._init$(undefined, -5); - var isArrayResolved = isArray(this._values); - if (!this._isResolved() && - isArrayResolved && - this._howMany > this._canPossiblyFulfill()) { - this._reject(this._getRangeError(this.length())); - } -}; - -SomePromiseArray.prototype.init = function () { - this._initialized = true; - this._init(); -}; - -SomePromiseArray.prototype.setUnwrap = function () { - this._unwrap = true; -}; - -SomePromiseArray.prototype.howMany = function () { - return this._howMany; -}; - -SomePromiseArray.prototype.setHowMany = function (count) { - this._howMany = count; -}; - -SomePromiseArray.prototype._promiseFulfilled = function (value) { - this._addFulfilled(value); - if (this._fulfilled() === this.howMany()) { - this._values.length = this.howMany(); - if (this.howMany() === 1 && this._unwrap) { - this._resolve(this._values[0]); - } else { - this._resolve(this._values); - } - return true; - } - return false; - -}; -SomePromiseArray.prototype._promiseRejected = function (reason) { - this._addRejected(reason); - return this._checkOutcome(); -}; - -SomePromiseArray.prototype._promiseCancelled = function () { - if (this._values instanceof Promise || this._values == null) { - return this._cancel(); - } - this._addRejected(CANCELLATION); - return this._checkOutcome(); -}; - -SomePromiseArray.prototype._checkOutcome = function() { - if (this.howMany() > this._canPossiblyFulfill()) { - var e = new AggregateError(); - for (var i = this.length(); i < this._values.length; ++i) { - if (this._values[i] !== CANCELLATION) { - e.push(this._values[i]); - } - } - if (e.length > 0) { - this._reject(e); - } else { - this._cancel(); - } - return true; - } - return false; -}; - -SomePromiseArray.prototype._fulfilled = function () { - return this._totalResolved; -}; - -SomePromiseArray.prototype._rejected = function () { - return this._values.length - this.length(); -}; - -SomePromiseArray.prototype._addRejected = function (reason) { - this._values.push(reason); -}; - -SomePromiseArray.prototype._addFulfilled = function (value) { - this._values[this._totalResolved++] = value; -}; - -SomePromiseArray.prototype._canPossiblyFulfill = function () { - return this.length() - this._rejected(); -}; - -SomePromiseArray.prototype._getRangeError = function (count) { - var message = "Input array must contain at least " + - this._howMany + " items but contains only " + count + " items"; - return new RangeError(message); -}; - -SomePromiseArray.prototype._resolveEmptyArray = function () { - this._reject(this._getRangeError(0)); -}; - -function some(promises, howMany) { - if ((howMany | 0) !== howMany || howMany < 0) { - return apiRejection("expecting a positive integer\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - var ret = new SomePromiseArray(promises); - var promise = ret.promise(); - ret.setHowMany(howMany); - ret.init(); - return promise; -} - -Promise.some = function (promises, howMany) { - return some(promises, howMany); -}; - -Promise.prototype.some = function (howMany) { - return some(this, howMany); -}; - -Promise._SomePromiseArray = SomePromiseArray; -}; - -},{"./errors":12,"./util":36}],32:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise) { -function PromiseInspection(promise) { - if (promise !== undefined) { - promise = promise._target(); - this._bitField = promise._bitField; - this._settledValueField = promise._isFateSealed() - ? promise._settledValue() : undefined; - } - else { - this._bitField = 0; - this._settledValueField = undefined; - } -} - -PromiseInspection.prototype._settledValue = function() { - return this._settledValueField; -}; - -var value = PromiseInspection.prototype.value = function () { - if (!this.isFulfilled()) { - throw new TypeError("cannot get fulfillment value of a non-fulfilled promise\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - return this._settledValue(); -}; - -var reason = PromiseInspection.prototype.error = -PromiseInspection.prototype.reason = function () { - if (!this.isRejected()) { - throw new TypeError("cannot get rejection reason of a non-rejected promise\u000a\u000a See http://goo.gl/MqrFmX\u000a"); - } - return this._settledValue(); -}; - -var isFulfilled = PromiseInspection.prototype.isFulfilled = function() { - return (this._bitField & 33554432) !== 0; -}; - -var isRejected = PromiseInspection.prototype.isRejected = function () { - return (this._bitField & 16777216) !== 0; -}; - -var isPending = PromiseInspection.prototype.isPending = function () { - return (this._bitField & 50397184) === 0; -}; - -var isResolved = PromiseInspection.prototype.isResolved = function () { - return (this._bitField & 50331648) !== 0; -}; - -PromiseInspection.prototype.isCancelled = -Promise.prototype._isCancelled = function() { - return (this._bitField & 65536) === 65536; -}; - -Promise.prototype.isCancelled = function() { - return this._target()._isCancelled(); -}; - -Promise.prototype.isPending = function() { - return isPending.call(this._target()); -}; - -Promise.prototype.isRejected = function() { - return isRejected.call(this._target()); -}; - -Promise.prototype.isFulfilled = function() { - return isFulfilled.call(this._target()); -}; - -Promise.prototype.isResolved = function() { - return isResolved.call(this._target()); -}; - -Promise.prototype.value = function() { - return value.call(this._target()); -}; - -Promise.prototype.reason = function() { - var target = this._target(); - target._unsetRejectionIsUnhandled(); - return reason.call(target); -}; - -Promise.prototype._value = function() { - return this._settledValue(); -}; - -Promise.prototype._reason = function() { - this._unsetRejectionIsUnhandled(); - return this._settledValue(); -}; - -Promise.PromiseInspection = PromiseInspection; -}; - -},{}],33:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL) { -var util = _dereq_("./util"); -var errorObj = util.errorObj; -var isObject = util.isObject; - -function tryConvertToPromise(obj, context) { - if (isObject(obj)) { - if (obj instanceof Promise) return obj; - var then = getThen(obj); - if (then === errorObj) { - if (context) context._pushContext(); - var ret = Promise.reject(then.e); - if (context) context._popContext(); - return ret; - } else if (typeof then === "function") { - if (isAnyBluebirdPromise(obj)) { - var ret = new Promise(INTERNAL); - obj._then( - ret._fulfill, - ret._reject, - undefined, - ret, - null - ); - return ret; - } - return doThenable(obj, then, context); - } - } - return obj; -} - -function doGetThen(obj) { - return obj.then; -} - -function getThen(obj) { - try { - return doGetThen(obj); - } catch (e) { - errorObj.e = e; - return errorObj; - } -} - -var hasProp = {}.hasOwnProperty; -function isAnyBluebirdPromise(obj) { - try { - return hasProp.call(obj, "_promise0"); - } catch (e) { - return false; - } -} - -function doThenable(x, then, context) { - var promise = new Promise(INTERNAL); - var ret = promise; - if (context) context._pushContext(); - promise._captureStackTrace(); - if (context) context._popContext(); - var synchronous = true; - var result = util.tryCatch(then).call(x, resolve, reject); - synchronous = false; - - if (promise && result === errorObj) { - promise._rejectCallback(result.e, true, true); - promise = null; - } - - function resolve(value) { - if (!promise) return; - promise._resolveCallback(value); - promise = null; - } - - function reject(reason) { - if (!promise) return; - promise._rejectCallback(reason, synchronous, true); - promise = null; - } - return ret; -} - -return tryConvertToPromise; -}; - -},{"./util":36}],34:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function(Promise, INTERNAL, debug) { -var util = _dereq_("./util"); -var TimeoutError = Promise.TimeoutError; - -function HandleWrapper(handle) { - this.handle = handle; -} - -HandleWrapper.prototype._resultCancelled = function() { - clearTimeout(this.handle); -}; - -var afterValue = function(value) { return delay(+this).thenReturn(value); }; -var delay = Promise.delay = function (ms, value) { - var ret; - var handle; - if (value !== undefined) { - ret = Promise.resolve(value) - ._then(afterValue, null, null, ms, undefined); - if (debug.cancellation() && value instanceof Promise) { - ret._setOnCancel(value); - } - } else { - ret = new Promise(INTERNAL); - handle = setTimeout(function() { ret._fulfill(); }, +ms); - if (debug.cancellation()) { - ret._setOnCancel(new HandleWrapper(handle)); - } - } - ret._setAsyncGuaranteed(); - return ret; -}; - -Promise.prototype.delay = function (ms) { - return delay(ms, this); -}; - -var afterTimeout = function (promise, message, parent) { - var err; - if (typeof message !== "string") { - if (message instanceof Error) { - err = message; - } else { - err = new TimeoutError("operation timed out"); - } - } else { - err = new TimeoutError(message); - } - util.markAsOriginatingFromRejection(err); - promise._attachExtraTrace(err); - promise._reject(err); - - if (parent != null) { - parent.cancel(); - } -}; - -function successClear(value) { - clearTimeout(this.handle); - return value; -} - -function failureClear(reason) { - clearTimeout(this.handle); - throw reason; -} - -Promise.prototype.timeout = function (ms, message) { - ms = +ms; - var ret, parent; - - var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() { - if (ret.isPending()) { - afterTimeout(ret, message, parent); - } - }, ms)); - - if (debug.cancellation()) { - parent = this.then(); - ret = parent._then(successClear, failureClear, - undefined, handleWrapper, undefined); - ret._setOnCancel(handleWrapper); - } else { - ret = this._then(successClear, failureClear, - undefined, handleWrapper, undefined); - } - - return ret; -}; - -}; - -},{"./util":36}],35:[function(_dereq_,module,exports){ -"use strict"; -module.exports = function (Promise, apiRejection, tryConvertToPromise, - createContext, INTERNAL, debug) { - var util = _dereq_("./util"); - var TypeError = _dereq_("./errors").TypeError; - var inherits = _dereq_("./util").inherits; - var errorObj = util.errorObj; - var tryCatch = util.tryCatch; - var NULL = {}; - - function thrower(e) { - setTimeout(function(){throw e;}, 0); - } - - function castPreservingDisposable(thenable) { - var maybePromise = tryConvertToPromise(thenable); - if (maybePromise !== thenable && - typeof thenable._isDisposable === "function" && - typeof thenable._getDisposer === "function" && - thenable._isDisposable()) { - maybePromise._setDisposable(thenable._getDisposer()); - } - return maybePromise; - } - function dispose(resources, inspection) { - var i = 0; - var len = resources.length; - var ret = new Promise(INTERNAL); - function iterator() { - if (i >= len) return ret._fulfill(); - var maybePromise = castPreservingDisposable(resources[i++]); - if (maybePromise instanceof Promise && - maybePromise._isDisposable()) { - try { - maybePromise = tryConvertToPromise( - maybePromise._getDisposer().tryDispose(inspection), - resources.promise); - } catch (e) { - return thrower(e); - } - if (maybePromise instanceof Promise) { - return maybePromise._then(iterator, thrower, - null, null, null); - } - } - iterator(); - } - iterator(); - return ret; - } - - function Disposer(data, promise, context) { - this._data = data; - this._promise = promise; - this._context = context; - } - - Disposer.prototype.data = function () { - return this._data; - }; - - Disposer.prototype.promise = function () { - return this._promise; - }; - - Disposer.prototype.resource = function () { - if (this.promise().isFulfilled()) { - return this.promise().value(); - } - return NULL; - }; - - Disposer.prototype.tryDispose = function(inspection) { - var resource = this.resource(); - var context = this._context; - if (context !== undefined) context._pushContext(); - var ret = resource !== NULL - ? this.doDispose(resource, inspection) : null; - if (context !== undefined) context._popContext(); - this._promise._unsetDisposable(); - this._data = null; - return ret; - }; - - Disposer.isDisposer = function (d) { - return (d != null && - typeof d.resource === "function" && - typeof d.tryDispose === "function"); - }; - - function FunctionDisposer(fn, promise, context) { - this.constructor$(fn, promise, context); - } - inherits(FunctionDisposer, Disposer); - - FunctionDisposer.prototype.doDispose = function (resource, inspection) { - var fn = this.data(); - return fn.call(resource, resource, inspection); - }; - - function maybeUnwrapDisposer(value) { - if (Disposer.isDisposer(value)) { - this.resources[this.index]._setDisposable(value); - return value.promise(); - } - return value; - } - - function ResourceList(length) { - this.length = length; - this.promise = null; - this[length-1] = null; - } - - ResourceList.prototype._resultCancelled = function() { - var len = this.length; - for (var i = 0; i < len; ++i) { - var item = this[i]; - if (item instanceof Promise) { - item.cancel(); - } - } - }; - - Promise.using = function () { - var len = arguments.length; - if (len < 2) return apiRejection( - "you must pass at least 2 arguments to Promise.using"); - var fn = arguments[len - 1]; - if (typeof fn !== "function") { - return apiRejection("expecting a function but got " + util.classString(fn)); - } - var input; - var spreadArgs = true; - if (len === 2 && Array.isArray(arguments[0])) { - input = arguments[0]; - len = input.length; - spreadArgs = false; - } else { - input = arguments; - len--; - } - var resources = new ResourceList(len); - for (var i = 0; i < len; ++i) { - var resource = input[i]; - if (Disposer.isDisposer(resource)) { - var disposer = resource; - resource = resource.promise(); - resource._setDisposable(disposer); - } else { - var maybePromise = tryConvertToPromise(resource); - if (maybePromise instanceof Promise) { - resource = - maybePromise._then(maybeUnwrapDisposer, null, null, { - resources: resources, - index: i - }, undefined); - } - } - resources[i] = resource; - } - - var reflectedResources = new Array(resources.length); - for (var i = 0; i < reflectedResources.length; ++i) { - reflectedResources[i] = Promise.resolve(resources[i]).reflect(); - } - - var resultPromise = Promise.all(reflectedResources) - .then(function(inspections) { - for (var i = 0; i < inspections.length; ++i) { - var inspection = inspections[i]; - if (inspection.isRejected()) { - errorObj.e = inspection.error(); - return errorObj; - } else if (!inspection.isFulfilled()) { - resultPromise.cancel(); - return; - } - inspections[i] = inspection.value(); - } - promise._pushContext(); - - fn = tryCatch(fn); - var ret = spreadArgs - ? fn.apply(undefined, inspections) : fn(inspections); - var promiseCreated = promise._popContext(); - debug.checkForgottenReturns( - ret, promiseCreated, "Promise.using", promise); - return ret; - }); - - var promise = resultPromise.lastly(function() { - var inspection = new Promise.PromiseInspection(resultPromise); - return dispose(resources, inspection); - }); - resources.promise = promise; - promise._setOnCancel(resources); - return promise; - }; - - Promise.prototype._setDisposable = function (disposer) { - this._bitField = this._bitField | 131072; - this._disposer = disposer; - }; - - Promise.prototype._isDisposable = function () { - return (this._bitField & 131072) > 0; - }; - - Promise.prototype._getDisposer = function () { - return this._disposer; - }; - - Promise.prototype._unsetDisposable = function () { - this._bitField = this._bitField & (~131072); - this._disposer = undefined; - }; - - Promise.prototype.disposer = function (fn) { - if (typeof fn === "function") { - return new FunctionDisposer(fn, this, createContext()); - } - throw new TypeError(); - }; - -}; - -},{"./errors":12,"./util":36}],36:[function(_dereq_,module,exports){ -"use strict"; -var es5 = _dereq_("./es5"); -var canEvaluate = typeof navigator == "undefined"; - -var errorObj = {e: {}}; -var tryCatchTarget; -var globalObject = typeof self !== "undefined" ? self : - typeof window !== "undefined" ? window : - typeof global !== "undefined" ? global : - this !== undefined ? this : null; - -function tryCatcher() { - try { - var target = tryCatchTarget; - tryCatchTarget = null; - return target.apply(this, arguments); - } catch (e) { - errorObj.e = e; - return errorObj; - } -} -function tryCatch(fn) { - tryCatchTarget = fn; - return tryCatcher; -} - -var inherits = function(Child, Parent) { - var hasProp = {}.hasOwnProperty; - - function T() { - this.constructor = Child; - this.constructor$ = Parent; - for (var propertyName in Parent.prototype) { - if (hasProp.call(Parent.prototype, propertyName) && - propertyName.charAt(propertyName.length-1) !== "$" - ) { - this[propertyName + "$"] = Parent.prototype[propertyName]; - } - } - } - T.prototype = Parent.prototype; - Child.prototype = new T(); - return Child.prototype; -}; - - -function isPrimitive(val) { - return val == null || val === true || val === false || - typeof val === "string" || typeof val === "number"; - -} - -function isObject(value) { - return typeof value === "function" || - typeof value === "object" && value !== null; -} - -function maybeWrapAsError(maybeError) { - if (!isPrimitive(maybeError)) return maybeError; - - return new Error(safeToString(maybeError)); -} - -function withAppended(target, appendee) { - var len = target.length; - var ret = new Array(len + 1); - var i; - for (i = 0; i < len; ++i) { - ret[i] = target[i]; - } - ret[i] = appendee; - return ret; -} - -function getDataPropertyOrDefault(obj, key, defaultValue) { - if (es5.isES5) { - var desc = Object.getOwnPropertyDescriptor(obj, key); - - if (desc != null) { - return desc.get == null && desc.set == null - ? desc.value - : defaultValue; - } - } else { - return {}.hasOwnProperty.call(obj, key) ? obj[key] : undefined; - } -} - -function notEnumerableProp(obj, name, value) { - if (isPrimitive(obj)) return obj; - var descriptor = { - value: value, - configurable: true, - enumerable: false, - writable: true - }; - es5.defineProperty(obj, name, descriptor); - return obj; -} - -function thrower(r) { - throw r; -} - -var inheritedDataKeys = (function() { - var excludedPrototypes = [ - Array.prototype, - Object.prototype, - Function.prototype - ]; - - var isExcludedProto = function(val) { - for (var i = 0; i < excludedPrototypes.length; ++i) { - if (excludedPrototypes[i] === val) { - return true; - } - } - return false; - }; - - if (es5.isES5) { - var getKeys = Object.getOwnPropertyNames; - return function(obj) { - var ret = []; - var visitedKeys = Object.create(null); - while (obj != null && !isExcludedProto(obj)) { - var keys; - try { - keys = getKeys(obj); - } catch (e) { - return ret; - } - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (visitedKeys[key]) continue; - visitedKeys[key] = true; - var desc = Object.getOwnPropertyDescriptor(obj, key); - if (desc != null && desc.get == null && desc.set == null) { - ret.push(key); - } - } - obj = es5.getPrototypeOf(obj); - } - return ret; - }; - } else { - var hasProp = {}.hasOwnProperty; - return function(obj) { - if (isExcludedProto(obj)) return []; - var ret = []; - - /*jshint forin:false */ - enumeration: for (var key in obj) { - if (hasProp.call(obj, key)) { - ret.push(key); - } else { - for (var i = 0; i < excludedPrototypes.length; ++i) { - if (hasProp.call(excludedPrototypes[i], key)) { - continue enumeration; - } - } - ret.push(key); - } - } - return ret; - }; - } - -})(); - -var thisAssignmentPattern = /this\s*\.\s*\S+\s*=/; -function isClass(fn) { - try { - if (typeof fn === "function") { - var keys = es5.names(fn.prototype); - - var hasMethods = es5.isES5 && keys.length > 1; - var hasMethodsOtherThanConstructor = keys.length > 0 && - !(keys.length === 1 && keys[0] === "constructor"); - var hasThisAssignmentAndStaticMethods = - thisAssignmentPattern.test(fn + "") && es5.names(fn).length > 0; - - if (hasMethods || hasMethodsOtherThanConstructor || - hasThisAssignmentAndStaticMethods) { - return true; - } - } - return false; - } catch (e) { - return false; - } -} - -function toFastProperties(obj) { - /*jshint -W027,-W055,-W031*/ - function FakeConstructor() {} - FakeConstructor.prototype = obj; - var l = 8; - while (l--) new FakeConstructor(); - return obj; - eval(obj); -} - -var rident = /^[a-z$_][a-z$_0-9]*$/i; -function isIdentifier(str) { - return rident.test(str); -} - -function filledRange(count, prefix, suffix) { - var ret = new Array(count); - for(var i = 0; i < count; ++i) { - ret[i] = prefix + i + suffix; - } - return ret; -} - -function safeToString(obj) { - try { - return obj + ""; - } catch (e) { - return "[no string representation]"; - } -} - -function isError(obj) { - return obj !== null && - typeof obj === "object" && - typeof obj.message === "string" && - typeof obj.name === "string"; -} - -function markAsOriginatingFromRejection(e) { - try { - notEnumerableProp(e, "isOperational", true); - } - catch(ignore) {} -} - -function originatesFromRejection(e) { - if (e == null) return false; - return ((e instanceof Error["__BluebirdErrorTypes__"].OperationalError) || - e["isOperational"] === true); -} - -function canAttachTrace(obj) { - return isError(obj) && es5.propertyIsWritable(obj, "stack"); -} - -var ensureErrorObject = (function() { - if (!("stack" in new Error())) { - return function(value) { - if (canAttachTrace(value)) return value; - try {throw new Error(safeToString(value));} - catch(err) {return err;} - }; - } else { - return function(value) { - if (canAttachTrace(value)) return value; - return new Error(safeToString(value)); - }; - } -})(); - -function classString(obj) { - return {}.toString.call(obj); -} - -function copyDescriptors(from, to, filter) { - var keys = es5.names(from); - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (filter(key)) { - try { - es5.defineProperty(to, key, es5.getDescriptor(from, key)); - } catch (ignore) {} - } - } -} - -var asArray = function(v) { - if (es5.isArray(v)) { - return v; - } - return null; -}; - -if (typeof Symbol !== "undefined" && Symbol.iterator) { - var ArrayFrom = typeof Array.from === "function" ? function(v) { - return Array.from(v); - } : function(v) { - var ret = []; - var it = v[Symbol.iterator](); - var itResult; - while (!((itResult = it.next()).done)) { - ret.push(itResult.value); - } - return ret; - }; - - asArray = function(v) { - if (es5.isArray(v)) { - return v; - } else if (v != null && typeof v[Symbol.iterator] === "function") { - return ArrayFrom(v); - } - return null; - }; -} - -var isNode = typeof process !== "undefined" && - classString(process).toLowerCase() === "[object process]"; - -function env(key, def) { - return isNode ? process.env[key] : def; -} - -function getNativePromise() { - if (typeof Promise === "function") { - try { - var promise = new Promise(function(){}); - if ({}.toString.call(promise) === "[object Promise]") { - return Promise; - } - } catch (e) {} - } -} - -var ret = { - isClass: isClass, - isIdentifier: isIdentifier, - inheritedDataKeys: inheritedDataKeys, - getDataPropertyOrDefault: getDataPropertyOrDefault, - thrower: thrower, - isArray: es5.isArray, - asArray: asArray, - notEnumerableProp: notEnumerableProp, - isPrimitive: isPrimitive, - isObject: isObject, - isError: isError, - canEvaluate: canEvaluate, - errorObj: errorObj, - tryCatch: tryCatch, - inherits: inherits, - withAppended: withAppended, - maybeWrapAsError: maybeWrapAsError, - toFastProperties: toFastProperties, - filledRange: filledRange, - toString: safeToString, - canAttachTrace: canAttachTrace, - ensureErrorObject: ensureErrorObject, - originatesFromRejection: originatesFromRejection, - markAsOriginatingFromRejection: markAsOriginatingFromRejection, - classString: classString, - copyDescriptors: copyDescriptors, - hasDevTools: typeof chrome !== "undefined" && chrome && - typeof chrome.loadTimes === "function", - isNode: isNode, - env: env, - global: globalObject, - getNativePromise: getNativePromise -}; -ret.isRecentNode = ret.isNode && (function() { - var version = process.versions.node.split(".").map(Number); - return (version[0] === 0 && version[1] > 10) || (version[0] > 0); -})(); - -if (ret.isNode) ret.toFastProperties(process); - -try {throw new Error(); } catch (e) {ret.lastLineError = e;} -module.exports = ret; - -},{"./es5":13}]},{},[4])(4) -}); ;if (typeof window !== 'undefined' && window !== null) { window.P = window.Promise; } else if (typeof self !== 'undefined' && self !== null) { self.P = self.Promise; } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(18), __webpack_require__(0), __webpack_require__(11).setImmediate)) - -/***/ }, -/* 83 */ -/***/ function(module, exports, __webpack_require__) { - -var core = __webpack_require__(3) - , $JSON = core.JSON || (core.JSON = {stringify: JSON.stringify}); -module.exports = function stringify(it){ // eslint-disable-line no-unused-vars - return $JSON.stringify.apply($JSON, arguments); -}; - -/***/ }, -/* 84 */ -/***/ function(module, exports, __webpack_require__) { - -__webpack_require__(114); -var $Object = __webpack_require__(3).Object; -module.exports = function defineProperty(it, key, desc){ - return $Object.defineProperty(it, key, desc); -}; - -/***/ }, -/* 85 */ -/***/ function(module, exports, __webpack_require__) { - -__webpack_require__(115); -module.exports = __webpack_require__(3).Object.keys; - -/***/ }, -/* 86 */ -/***/ function(module, exports, __webpack_require__) { - -__webpack_require__(116); -__webpack_require__(118); -__webpack_require__(119); -__webpack_require__(117); -module.exports = __webpack_require__(3).Promise; - -/***/ }, -/* 87 */ -/***/ function(module, exports) { - -module.exports = function(){ /* empty */ }; - -/***/ }, -/* 88 */ -/***/ function(module, exports) { - -module.exports = function(it, Constructor, name, forbiddenField){ - if(!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)){ - throw TypeError(name + ': incorrect invocation!'); - } return it; -}; - -/***/ }, -/* 89 */ -/***/ function(module, exports, __webpack_require__) { - -// false -> Array#indexOf -// true -> Array#includes -var toIObject = __webpack_require__(27) - , toLength = __webpack_require__(54) - , toIndex = __webpack_require__(110); -module.exports = function(IS_INCLUDES){ - return function($this, el, fromIndex){ - var O = toIObject($this) - , length = toLength(O.length) - , index = toIndex(fromIndex, length) - , value; - // Array#includes uses SameValueZero equality algorithm - if(IS_INCLUDES && el != el)while(length > index){ - value = O[index++]; - if(value != value)return true; - // Array#toIndex ignores holes, Array#includes - not - } else for(;length > index; index++)if(IS_INCLUDES || index in O){ - if(O[index] === el)return IS_INCLUDES || index || 0; - } return !IS_INCLUDES && -1; - }; -}; - -/***/ }, -/* 90 */ -/***/ function(module, exports, __webpack_require__) { - -var ctx = __webpack_require__(14) - , call = __webpack_require__(95) - , isArrayIter = __webpack_require__(94) - , anObject = __webpack_require__(5) - , toLength = __webpack_require__(54) - , getIterFn = __webpack_require__(112) - , BREAK = {} - , RETURN = {}; -var exports = module.exports = function(iterable, entries, fn, that, ITERATOR){ - var iterFn = ITERATOR ? function(){ return iterable; } : getIterFn(iterable) - , f = ctx(fn, that, entries ? 2 : 1) - , index = 0 - , length, step, iterator, result; - if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!'); - // fast case for arrays with default iterator - if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){ - result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); - if(result === BREAK || result === RETURN)return result; - } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){ - result = call(iterator, f, step.value, entries); - if(result === BREAK || result === RETURN)return result; - } -}; -exports.BREAK = BREAK; -exports.RETURN = RETURN; - -/***/ }, -/* 91 */ -/***/ function(module, exports, __webpack_require__) { - -module.exports = !__webpack_require__(6) && !__webpack_require__(23)(function(){ - return Object.defineProperty(__webpack_require__(22)('div'), 'a', {get: function(){ return 7; }}).a != 7; -}); - -/***/ }, -/* 92 */ -/***/ function(module, exports) { - -// fast apply, http://jsperf.lnkit.com/fast-apply/5 -module.exports = function(fn, args, that){ - var un = that === undefined; - switch(args.length){ - case 0: return un ? fn() - : fn.call(that); - case 1: return un ? fn(args[0]) - : fn.call(that, args[0]); - case 2: return un ? fn(args[0], args[1]) - : fn.call(that, args[0], args[1]); - case 3: return un ? fn(args[0], args[1], args[2]) - : fn.call(that, args[0], args[1], args[2]); - case 4: return un ? fn(args[0], args[1], args[2], args[3]) - : fn.call(that, args[0], args[1], args[2], args[3]); - } return fn.apply(that, args); -}; - -/***/ }, -/* 93 */ -/***/ function(module, exports, __webpack_require__) { - -// fallback for non-array-like ES3 and non-enumerable old V8 strings -var cof = __webpack_require__(13); -module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){ - return cof(it) == 'String' ? it.split('') : Object(it); -}; - -/***/ }, -/* 94 */ -/***/ function(module, exports, __webpack_require__) { - -// check on default Array iterator -var Iterators = __webpack_require__(9) - , ITERATOR = __webpack_require__(1)('iterator') - , ArrayProto = Array.prototype; - -module.exports = function(it){ - return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); -}; - -/***/ }, -/* 95 */ -/***/ function(module, exports, __webpack_require__) { - -// call something on iterator step with safe closing on error -var anObject = __webpack_require__(5); -module.exports = function(iterator, fn, value, entries){ - try { - return entries ? fn(anObject(value)[0], value[1]) : fn(value); - // 7.4.6 IteratorClose(iterator, completion) - } catch(e){ - var ret = iterator['return']; - if(ret !== undefined)anObject(ret.call(iterator)); - throw e; - } -}; - -/***/ }, -/* 96 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; -var create = __webpack_require__(100) - , descriptor = __webpack_require__(51) - , setToStringTag = __webpack_require__(24) - , IteratorPrototype = {}; - -// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() -__webpack_require__(7)(IteratorPrototype, __webpack_require__(1)('iterator'), function(){ return this; }); - -module.exports = function(Constructor, NAME, next){ - Constructor.prototype = create(IteratorPrototype, {next: descriptor(1, next)}); - setToStringTag(Constructor, NAME + ' Iterator'); -}; - -/***/ }, -/* 97 */ -/***/ function(module, exports, __webpack_require__) { - -var ITERATOR = __webpack_require__(1)('iterator') - , SAFE_CLOSING = false; - -try { - var riter = [7][ITERATOR](); - riter['return'] = function(){ SAFE_CLOSING = true; }; - Array.from(riter, function(){ throw 2; }); -} catch(e){ /* empty */ } - -module.exports = function(exec, skipClosing){ - if(!skipClosing && !SAFE_CLOSING)return false; - var safe = false; - try { - var arr = [7] - , iter = arr[ITERATOR](); - iter.next = function(){ return {done: safe = true}; }; - arr[ITERATOR] = function(){ return iter; }; - exec(arr); - } catch(e){ /* empty */ } - return safe; -}; - -/***/ }, -/* 98 */ -/***/ function(module, exports) { - -module.exports = function(done, value){ - return {value: value, done: !!done}; -}; - -/***/ }, -/* 99 */ -/***/ function(module, exports, __webpack_require__) { - -var global = __webpack_require__(2) - , macrotask = __webpack_require__(53).set - , Observer = global.MutationObserver || global.WebKitMutationObserver - , process = global.process - , Promise = global.Promise - , isNode = __webpack_require__(13)(process) == 'process'; - -module.exports = function(){ - var head, last, notify; - - var flush = function(){ - var parent, fn; - if(isNode && (parent = process.domain))parent.exit(); - while(head){ - fn = head.fn; - head = head.next; - try { - fn(); - } catch(e){ - if(head)notify(); - else last = undefined; - throw e; - } - } last = undefined; - if(parent)parent.enter(); - }; - - // Node.js - if(isNode){ - notify = function(){ - process.nextTick(flush); - }; - // browsers with MutationObserver - } else if(Observer){ - var toggle = true - , node = document.createTextNode(''); - new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new - notify = function(){ - node.data = toggle = !toggle; - }; - // environments with maybe non-completely correct, but existent Promise - } else if(Promise && Promise.resolve){ - var promise = Promise.resolve(); - notify = function(){ - promise.then(flush); - }; - // for other environments - macrotask based on: - // - setImmediate - // - MessageChannel - // - window.postMessag - // - onreadystatechange - // - setTimeout - } else { - notify = function(){ - // strange IE + webpack dev server bug - use .call(global) - macrotask.call(global, flush); - }; - } - - return function(fn){ - var task = {fn: fn, next: undefined}; - if(last)last.next = task; - if(!head){ - head = task; - notify(); - } last = task; - }; -}; - -/***/ }, -/* 100 */ -/***/ function(module, exports, __webpack_require__) { - -// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) -var anObject = __webpack_require__(5) - , dPs = __webpack_require__(101) - , enumBugKeys = __webpack_require__(46) - , IE_PROTO = __webpack_require__(25)('IE_PROTO') - , Empty = function(){ /* empty */ } - , PROTOTYPE = 'prototype'; - -// Create object with fake `null` prototype: use iframe Object with cleared prototype -var createDict = function(){ - // Thrash, waste and sodomy: IE GC bug - var iframe = __webpack_require__(22)('iframe') - , i = enumBugKeys.length - , lt = '<' - , gt = '>' - , iframeDocument; - iframe.style.display = 'none'; - __webpack_require__(47).appendChild(iframe); - iframe.src = 'javascript:'; // eslint-disable-line no-script-url - // createDict = iframe.contentWindow.Object; - // html.removeChild(iframe); - iframeDocument = iframe.contentWindow.document; - iframeDocument.open(); - iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); - iframeDocument.close(); - createDict = iframeDocument.F; - while(i--)delete createDict[PROTOTYPE][enumBugKeys[i]]; - return createDict(); -}; - -module.exports = Object.create || function create(O, Properties){ - var result; - if(O !== null){ - Empty[PROTOTYPE] = anObject(O); - result = new Empty; - Empty[PROTOTYPE] = null; - // add "__proto__" for Object.getPrototypeOf polyfill - result[IE_PROTO] = O; - } else result = createDict(); - return Properties === undefined ? result : dPs(result, Properties); -}; - - -/***/ }, -/* 101 */ -/***/ function(module, exports, __webpack_require__) { - -var dP = __webpack_require__(10) - , anObject = __webpack_require__(5) - , getKeys = __webpack_require__(50); - -module.exports = __webpack_require__(6) ? Object.defineProperties : function defineProperties(O, Properties){ - anObject(O); - var keys = getKeys(Properties) - , length = keys.length - , i = 0 - , P; - while(length > i)dP.f(O, P = keys[i++], Properties[P]); - return O; -}; - -/***/ }, -/* 102 */ -/***/ function(module, exports, __webpack_require__) { - -// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) -var has = __webpack_require__(16) - , toObject = __webpack_require__(55) - , IE_PROTO = __webpack_require__(25)('IE_PROTO') - , ObjectProto = Object.prototype; - -module.exports = Object.getPrototypeOf || function(O){ - O = toObject(O); - if(has(O, IE_PROTO))return O[IE_PROTO]; - if(typeof O.constructor == 'function' && O instanceof O.constructor){ - return O.constructor.prototype; - } return O instanceof Object ? ObjectProto : null; -}; - -/***/ }, -/* 103 */ -/***/ function(module, exports, __webpack_require__) { - -var has = __webpack_require__(16) - , toIObject = __webpack_require__(27) - , arrayIndexOf = __webpack_require__(89)(false) - , IE_PROTO = __webpack_require__(25)('IE_PROTO'); - -module.exports = function(object, names){ - var O = toIObject(object) - , i = 0 - , result = [] - , key; - for(key in O)if(key != IE_PROTO)has(O, key) && result.push(key); - // Don't enum bug & hidden keys - while(names.length > i)if(has(O, key = names[i++])){ - ~arrayIndexOf(result, key) || result.push(key); - } - return result; -}; - -/***/ }, -/* 104 */ -/***/ function(module, exports, __webpack_require__) { - -// most Object methods by ES6 should accept primitives -var $export = __webpack_require__(15) - , core = __webpack_require__(3) - , fails = __webpack_require__(23); -module.exports = function(KEY, exec){ - var fn = (core.Object || {})[KEY] || Object[KEY] - , exp = {}; - exp[KEY] = exec(fn); - $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp); -}; - -/***/ }, -/* 105 */ -/***/ function(module, exports, __webpack_require__) { - -var hide = __webpack_require__(7); -module.exports = function(target, src, safe){ - for(var key in src){ - if(safe && target[key])target[key] = src[key]; - else hide(target, key, src[key]); - } return target; -}; - -/***/ }, -/* 106 */ -/***/ function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(7); - -/***/ }, -/* 107 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; -var global = __webpack_require__(2) - , core = __webpack_require__(3) - , dP = __webpack_require__(10) - , DESCRIPTORS = __webpack_require__(6) - , SPECIES = __webpack_require__(1)('species'); - -module.exports = function(KEY){ - var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY]; - if(DESCRIPTORS && C && !C[SPECIES])dP.f(C, SPECIES, { - configurable: true, - get: function(){ return this; } - }); -}; - -/***/ }, -/* 108 */ -/***/ function(module, exports, __webpack_require__) { - -// 7.3.20 SpeciesConstructor(O, defaultConstructor) -var anObject = __webpack_require__(5) - , aFunction = __webpack_require__(20) - , SPECIES = __webpack_require__(1)('species'); -module.exports = function(O, D){ - var C = anObject(O).constructor, S; - return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); -}; - -/***/ }, -/* 109 */ -/***/ function(module, exports, __webpack_require__) { - -var toInteger = __webpack_require__(26) - , defined = __webpack_require__(21); -// true -> String#at -// false -> String#codePointAt -module.exports = function(TO_STRING){ - return function(that, pos){ - var s = String(defined(that)) - , i = toInteger(pos) - , l = s.length - , a, b; - if(i < 0 || i >= l)return TO_STRING ? '' : undefined; - a = s.charCodeAt(i); - return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff - ? TO_STRING ? s.charAt(i) : a - : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; - }; -}; - -/***/ }, -/* 110 */ -/***/ function(module, exports, __webpack_require__) { - -var toInteger = __webpack_require__(26) - , max = Math.max - , min = Math.min; -module.exports = function(index, length){ - index = toInteger(index); - return index < 0 ? max(index + length, 0) : min(index, length); -}; - -/***/ }, -/* 111 */ -/***/ function(module, exports, __webpack_require__) { - -// 7.1.1 ToPrimitive(input [, PreferredType]) -var isObject = __webpack_require__(17); -// instead of the ES6 spec version, we didn't implement @@toPrimitive case -// and the second argument - flag - preferred type is a string -module.exports = function(it, S){ - if(!isObject(it))return it; - var fn, val; - if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; - if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val; - if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val; - throw TypeError("Can't convert object to primitive value"); -}; - -/***/ }, -/* 112 */ -/***/ function(module, exports, __webpack_require__) { - -var classof = __webpack_require__(45) - , ITERATOR = __webpack_require__(1)('iterator') - , Iterators = __webpack_require__(9); -module.exports = __webpack_require__(3).getIteratorMethod = function(it){ - if(it != undefined)return it[ITERATOR] - || it['@@iterator'] - || Iterators[classof(it)]; -}; - -/***/ }, -/* 113 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; -var addToUnscopables = __webpack_require__(87) - , step = __webpack_require__(98) - , Iterators = __webpack_require__(9) - , toIObject = __webpack_require__(27); - -// 22.1.3.4 Array.prototype.entries() -// 22.1.3.13 Array.prototype.keys() -// 22.1.3.29 Array.prototype.values() -// 22.1.3.30 Array.prototype[@@iterator]() -module.exports = __webpack_require__(48)(Array, 'Array', function(iterated, kind){ - this._t = toIObject(iterated); // target - this._i = 0; // next index - this._k = kind; // kind -// 22.1.5.2.1 %ArrayIteratorPrototype%.next() -}, function(){ - var O = this._t - , kind = this._k - , index = this._i++; - if(!O || index >= O.length){ - this._t = undefined; - return step(1); - } - if(kind == 'keys' )return step(0, index); - if(kind == 'values')return step(0, O[index]); - return step(0, [index, O[index]]); -}, 'values'); - -// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) -Iterators.Arguments = Iterators.Array; - -addToUnscopables('keys'); -addToUnscopables('values'); -addToUnscopables('entries'); - -/***/ }, -/* 114 */ -/***/ function(module, exports, __webpack_require__) { - -var $export = __webpack_require__(15); -// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes) -$export($export.S + $export.F * !__webpack_require__(6), 'Object', {defineProperty: __webpack_require__(10).f}); - -/***/ }, -/* 115 */ -/***/ function(module, exports, __webpack_require__) { - -// 19.1.2.14 Object.keys(O) -var toObject = __webpack_require__(55) - , $keys = __webpack_require__(50); - -__webpack_require__(104)('keys', function(){ - return function keys(it){ - return $keys(toObject(it)); - }; -}); - -/***/ }, -/* 116 */ -/***/ function(module, exports) { - - - -/***/ }, -/* 117 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; -var LIBRARY = __webpack_require__(49) - , global = __webpack_require__(2) - , ctx = __webpack_require__(14) - , classof = __webpack_require__(45) - , $export = __webpack_require__(15) - , isObject = __webpack_require__(17) - , aFunction = __webpack_require__(20) - , anInstance = __webpack_require__(88) - , forOf = __webpack_require__(90) - , speciesConstructor = __webpack_require__(108) - , task = __webpack_require__(53).set - , microtask = __webpack_require__(99)() - , PROMISE = 'Promise' - , TypeError = global.TypeError - , process = global.process - , $Promise = global[PROMISE] - , process = global.process - , isNode = classof(process) == 'process' - , empty = function(){ /* empty */ } - , Internal, GenericPromiseCapability, Wrapper; - -var USE_NATIVE = !!function(){ - try { - // correct subclassing with @@species support - var promise = $Promise.resolve(1) - , FakePromise = (promise.constructor = {})[__webpack_require__(1)('species')] = function(exec){ exec(empty, empty); }; - // unhandled rejections tracking support, NodeJS Promise without it fails @@species test - return (isNode || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise; - } catch(e){ /* empty */ } -}(); - -// helpers -var sameConstructor = function(a, b){ - // with library wrapper special case - return a === b || a === $Promise && b === Wrapper; -}; -var isThenable = function(it){ - var then; - return isObject(it) && typeof (then = it.then) == 'function' ? then : false; -}; -var newPromiseCapability = function(C){ - return sameConstructor($Promise, C) - ? new PromiseCapability(C) - : new GenericPromiseCapability(C); -}; -var PromiseCapability = GenericPromiseCapability = function(C){ - var resolve, reject; - this.promise = new C(function($$resolve, $$reject){ - if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor'); - resolve = $$resolve; - reject = $$reject; - }); - this.resolve = aFunction(resolve); - this.reject = aFunction(reject); -}; -var perform = function(exec){ - try { - exec(); - } catch(e){ - return {error: e}; - } -}; -var notify = function(promise, isReject){ - if(promise._n)return; - promise._n = true; - var chain = promise._c; - microtask(function(){ - var value = promise._v - , ok = promise._s == 1 - , i = 0; - var run = function(reaction){ - var handler = ok ? reaction.ok : reaction.fail - , resolve = reaction.resolve - , reject = reaction.reject - , domain = reaction.domain - , result, then; - try { - if(handler){ - if(!ok){ - if(promise._h == 2)onHandleUnhandled(promise); - promise._h = 1; - } - if(handler === true)result = value; - else { - if(domain)domain.enter(); - result = handler(value); - if(domain)domain.exit(); - } - if(result === reaction.promise){ - reject(TypeError('Promise-chain cycle')); - } else if(then = isThenable(result)){ - then.call(result, resolve, reject); - } else resolve(result); - } else reject(value); - } catch(e){ - reject(e); - } - }; - while(chain.length > i)run(chain[i++]); // variable length - can't use forEach - promise._c = []; - promise._n = false; - if(isReject && !promise._h)onUnhandled(promise); - }); -}; -var onUnhandled = function(promise){ - task.call(global, function(){ - var value = promise._v - , abrupt, handler, console; - if(isUnhandled(promise)){ - abrupt = perform(function(){ - if(isNode){ - process.emit('unhandledRejection', value, promise); - } else if(handler = global.onunhandledrejection){ - handler({promise: promise, reason: value}); - } else if((console = global.console) && console.error){ - console.error('Unhandled promise rejection', value); - } - }); - // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should - promise._h = isNode || isUnhandled(promise) ? 2 : 1; - } promise._a = undefined; - if(abrupt)throw abrupt.error; - }); -}; -var isUnhandled = function(promise){ - if(promise._h == 1)return false; - var chain = promise._a || promise._c - , i = 0 - , reaction; - while(chain.length > i){ - reaction = chain[i++]; - if(reaction.fail || !isUnhandled(reaction.promise))return false; - } return true; -}; -var onHandleUnhandled = function(promise){ - task.call(global, function(){ - var handler; - if(isNode){ - process.emit('rejectionHandled', promise); - } else if(handler = global.onrejectionhandled){ - handler({promise: promise, reason: promise._v}); - } - }); -}; -var $reject = function(value){ - var promise = this; - if(promise._d)return; - promise._d = true; - promise = promise._w || promise; // unwrap - promise._v = value; - promise._s = 2; - if(!promise._a)promise._a = promise._c.slice(); - notify(promise, true); -}; -var $resolve = function(value){ - var promise = this - , then; - if(promise._d)return; - promise._d = true; - promise = promise._w || promise; // unwrap - try { - if(promise === value)throw TypeError("Promise can't be resolved itself"); - if(then = isThenable(value)){ - microtask(function(){ - var wrapper = {_w: promise, _d: false}; // wrap - try { - then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); - } catch(e){ - $reject.call(wrapper, e); - } - }); - } else { - promise._v = value; - promise._s = 1; - notify(promise, false); - } - } catch(e){ - $reject.call({_w: promise, _d: false}, e); // wrap - } -}; - -// constructor polyfill -if(!USE_NATIVE){ - // 25.4.3.1 Promise(executor) - $Promise = function Promise(executor){ - anInstance(this, $Promise, PROMISE, '_h'); - aFunction(executor); - Internal.call(this); - try { - executor(ctx($resolve, this, 1), ctx($reject, this, 1)); - } catch(err){ - $reject.call(this, err); - } - }; - Internal = function Promise(executor){ - this._c = []; // <- awaiting reactions - this._a = undefined; // <- checked in isUnhandled reactions - this._s = 0; // <- state - this._d = false; // <- done - this._v = undefined; // <- value - this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled - this._n = false; // <- notify - }; - Internal.prototype = __webpack_require__(105)($Promise.prototype, { - // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) - then: function then(onFulfilled, onRejected){ - var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); - reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; - reaction.fail = typeof onRejected == 'function' && onRejected; - reaction.domain = isNode ? process.domain : undefined; - this._c.push(reaction); - if(this._a)this._a.push(reaction); - if(this._s)notify(this, false); - return reaction.promise; - }, - // 25.4.5.1 Promise.prototype.catch(onRejected) - 'catch': function(onRejected){ - return this.then(undefined, onRejected); - } - }); - PromiseCapability = function(){ - var promise = new Internal; - this.promise = promise; - this.resolve = ctx($resolve, promise, 1); - this.reject = ctx($reject, promise, 1); - }; -} - -$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: $Promise}); -__webpack_require__(24)($Promise, PROMISE); -__webpack_require__(107)(PROMISE); -Wrapper = __webpack_require__(3)[PROMISE]; - -// statics -$export($export.S + $export.F * !USE_NATIVE, PROMISE, { - // 25.4.4.5 Promise.reject(r) - reject: function reject(r){ - var capability = newPromiseCapability(this) - , $$reject = capability.reject; - $$reject(r); - return capability.promise; - } -}); -$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { - // 25.4.4.6 Promise.resolve(x) - resolve: function resolve(x){ - // instanceof instead of internal slot check because we should fix it without replacement native Promise core - if(x instanceof $Promise && sameConstructor(x.constructor, this))return x; - var capability = newPromiseCapability(this) - , $$resolve = capability.resolve; - $$resolve(x); - return capability.promise; - } -}); -$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(97)(function(iter){ - $Promise.all(iter)['catch'](empty); -})), PROMISE, { - // 25.4.4.1 Promise.all(iterable) - all: function all(iterable){ - var C = this - , capability = newPromiseCapability(C) - , resolve = capability.resolve - , reject = capability.reject; - var abrupt = perform(function(){ - var values = [] - , index = 0 - , remaining = 1; - forOf(iterable, false, function(promise){ - var $index = index++ - , alreadyCalled = false; - values.push(undefined); - remaining++; - C.resolve(promise).then(function(value){ - if(alreadyCalled)return; - alreadyCalled = true; - values[$index] = value; - --remaining || resolve(values); - }, reject); - }); - --remaining || resolve(values); - }); - if(abrupt)reject(abrupt.error); - return capability.promise; - }, - // 25.4.4.4 Promise.race(iterable) - race: function race(iterable){ - var C = this - , capability = newPromiseCapability(C) - , reject = capability.reject; - var abrupt = perform(function(){ - forOf(iterable, false, function(promise){ - C.resolve(promise).then(capability.resolve, reject); - }); - }); - if(abrupt)reject(abrupt.error); - return capability.promise; - } -}); - -/***/ }, -/* 118 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; -var $at = __webpack_require__(109)(true); - -// 21.1.3.27 String.prototype[@@iterator]() -__webpack_require__(48)(String, 'String', function(iterated){ - this._t = String(iterated); // target - this._i = 0; // next index -// 21.1.5.2.1 %StringIteratorPrototype%.next() -}, function(){ - var O = this._t - , index = this._i - , point; - if(index >= O.length)return {value: undefined, done: true}; - point = $at(O, index); - this._i += point.length; - return {value: point, done: false}; -}); - -/***/ }, -/* 119 */ -/***/ function(module, exports, __webpack_require__) { - -__webpack_require__(113); -var global = __webpack_require__(2) - , hide = __webpack_require__(7) - , Iterators = __webpack_require__(9) - , TO_STRING_TAG = __webpack_require__(1)('toStringTag'); - -for(var collections = ['NodeList', 'DOMTokenList', 'MediaList', 'StyleSheetList', 'CSSRuleList'], i = 0; i < 5; i++){ - var NAME = collections[i] - , Collection = global[NAME] - , proto = Collection && Collection.prototype; - if(proto && !proto[TO_STRING_TAG])hide(proto, TO_STRING_TAG, NAME); - Iterators[NAME] = Iterators.Array; -} - -/***/ }, -/* 120 */ -/***/ function(module, exports, __webpack_require__) { - -"use strict"; -'use strict'; - -const isEqual = __webpack_require__(121).isEqual; - -class GCounter { - constructor(id, payload) { - this.id = id; - this._counters = payload ? payload : {}; - this._counters[this.id] = this._counters[this.id] ? this._counters[this.id] : 0; - } - - increment(amount) { - if(!amount) amount = 1; - this._counters[this.id] = this._counters[this.id] + amount; - } - - get value() { - return Object.keys(this._counters) - .map((f) => this._counters[f]) - .reduce((previousValue, currentValue) => previousValue + currentValue, 0); - } - - get payload() { - return { id: this.id, counters: this._counters }; - } - - compare(other) { - if(other.id !== this.id) - return false; - - return isEqual(other._counters, this._counters); - } - - merge(other) { - Object.keys(other._counters).forEach((f) => { - this._counters[f] = Math.max(this._counters[f] ? this._counters[f] : 0, other._counters[f]); - }); - } - - static from(payload) { - return new GCounter(payload.id, payload.counters); - } - -} - -module.exports = GCounter; - - -/***/ }, -/* 121 */ -/***/ function(module, exports) { - -"use strict"; -'use strict'; - -exports.isEqual = (a, b) => { - const propsA = Object.getOwnPropertyNames(a); - const propsB = Object.getOwnPropertyNames(b); - - if(propsA.length !== propsB.length) - return false; - - for(let i = 0; i < propsA.length; i ++) { - const prop = propsA[i]; - if(a[prop] !== b[prop]) - return false; - } - - return true; -} - - -/***/ }, -/* 122 */ -/***/ function(module, exports, __webpack_require__) { - - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = debug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = __webpack_require__(142); - -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; - -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lowercased letter, i.e. "n". - */ - -exports.formatters = {}; - -/** - * Previously assigned color. - */ - -var prevColor = 0; - -/** - * Previous log timestamp. - */ - -var prevTime; - -/** - * Select a color. - * - * @return {Number} - * @api private - */ - -function selectColor() { - return exports.colors[prevColor++ % exports.colors.length]; -} - -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - -function debug(namespace) { - - // define the `disabled` version - function disabled() { - } - disabled.enabled = false; - - // define the `enabled` version - function enabled() { - - var self = enabled; - - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - - // add the `color` if not set - if (null == self.useColors) self.useColors = exports.useColors(); - if (null == self.color && self.useColors) self.color = selectColor(); - - var args = Array.prototype.slice.call(arguments); - - args[0] = exports.coerce(args[0]); - - if ('string' !== typeof args[0]) { - // anything else let's inspect with %o - args = ['%o'].concat(args); - } - - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var val = args[index]; - match = formatter.call(self, val); - - // now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); - - if ('function' === typeof exports.formatArgs) { - args = exports.formatArgs.apply(self, args); - } - var logFn = enabled.log || exports.log || console.log.bind(console); - logFn.apply(self, args); - } - enabled.enabled = true; - - var fn = exports.enabled(namespace) ? enabled : disabled; - - fn.namespace = namespace; - - return fn; -} - -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - -function enable(namespaces) { - exports.save(namespaces); - - var split = (namespaces || '').split(/[\s,]+/); - var len = split.length; - - for (var i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } - } -} - -/** - * Disable debug output. - * - * @api public - */ - -function disable() { - exports.enable(''); -} - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -function enabled(name) { - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } - } - return false; -} - -/** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} - - -/***/ }, -/* 123 */ -/***/ function(module, exports, __webpack_require__) { - - -module.exports = __webpack_require__(124); - - -/***/ }, -/* 124 */ -/***/ function(module, exports, __webpack_require__) { - - -module.exports = __webpack_require__(125); - -/** - * Exports parser - * - * @api public - * - */ -module.exports.parser = __webpack_require__(8); - - -/***/ }, -/* 125 */ -/***/ function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/** - * Module dependencies. - */ - -var transports = __webpack_require__(57); -var Emitter = __webpack_require__(30); -var debug = __webpack_require__(4)('engine.io-client:socket'); -var index = __webpack_require__(59); -var parser = __webpack_require__(8); -var parseuri = __webpack_require__(62); -var parsejson = __webpack_require__(148); -var parseqs = __webpack_require__(33); - -/** - * Module exports. - */ - -module.exports = Socket; - -/** - * Noop function. - * - * @api private - */ - -function noop(){} - -/** - * Socket constructor. - * - * @param {String|Object} uri or options - * @param {Object} options - * @api public - */ - -function Socket(uri, opts){ - if (!(this instanceof Socket)) return new Socket(uri, opts); - - opts = opts || {}; - - if (uri && 'object' == typeof uri) { - opts = uri; - uri = null; - } - - if (uri) { - uri = parseuri(uri); - opts.hostname = uri.host; - opts.secure = uri.protocol == 'https' || uri.protocol == 'wss'; - opts.port = uri.port; - if (uri.query) opts.query = uri.query; - } else if (opts.host) { - opts.hostname = parseuri(opts.host).host; - } - - this.secure = null != opts.secure ? opts.secure : - (global.location && 'https:' == location.protocol); - - if (opts.hostname && !opts.port) { - // if no port is specified manually, use the protocol default - opts.port = this.secure ? '443' : '80'; - } - - this.agent = opts.agent || false; - this.hostname = opts.hostname || - (global.location ? location.hostname : 'localhost'); - this.port = opts.port || (global.location && location.port ? - location.port : - (this.secure ? 443 : 80)); - this.query = opts.query || {}; - if ('string' == typeof this.query) this.query = parseqs.decode(this.query); - this.upgrade = false !== opts.upgrade; - this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/'; - this.forceJSONP = !!opts.forceJSONP; - this.jsonp = false !== opts.jsonp; - this.forceBase64 = !!opts.forceBase64; - this.enablesXDR = !!opts.enablesXDR; - this.timestampParam = opts.timestampParam || 't'; - this.timestampRequests = opts.timestampRequests; - this.transports = opts.transports || ['polling', 'websocket']; - this.readyState = ''; - this.writeBuffer = []; - this.policyPort = opts.policyPort || 843; - this.rememberUpgrade = opts.rememberUpgrade || false; - this.binaryType = null; - this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades; - this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false; - - if (true === this.perMessageDeflate) this.perMessageDeflate = {}; - if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) { - this.perMessageDeflate.threshold = 1024; - } - - // SSL options for Node.js client - this.pfx = opts.pfx || null; - this.key = opts.key || null; - this.passphrase = opts.passphrase || null; - this.cert = opts.cert || null; - this.ca = opts.ca || null; - this.ciphers = opts.ciphers || null; - this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? true : opts.rejectUnauthorized; - - // other options for Node.js client - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal) { - if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) { - this.extraHeaders = opts.extraHeaders; - } - } - - this.open(); -} - -Socket.priorWebsocketSuccess = false; - -/** - * Mix in `Emitter`. - */ - -Emitter(Socket.prototype); - -/** - * Protocol version. - * - * @api public - */ - -Socket.protocol = parser.protocol; // this is an int - -/** - * Expose deps for legacy compatibility - * and standalone browser access. - */ - -Socket.Socket = Socket; -Socket.Transport = __webpack_require__(28); -Socket.transports = __webpack_require__(57); -Socket.parser = __webpack_require__(8); - -/** - * Creates transport of the given type. - * - * @param {String} transport name - * @return {Transport} - * @api private - */ - -Socket.prototype.createTransport = function (name) { - debug('creating transport "%s"', name); - var query = clone(this.query); - - // append engine.io protocol identifier - query.EIO = parser.protocol; - - // transport name - query.transport = name; - - // session id if we already have one - if (this.id) query.sid = this.id; - - var transport = new transports[name]({ - agent: this.agent, - hostname: this.hostname, - port: this.port, - secure: this.secure, - path: this.path, - query: query, - forceJSONP: this.forceJSONP, - jsonp: this.jsonp, - forceBase64: this.forceBase64, - enablesXDR: this.enablesXDR, - timestampRequests: this.timestampRequests, - timestampParam: this.timestampParam, - policyPort: this.policyPort, - socket: this, - pfx: this.pfx, - key: this.key, - passphrase: this.passphrase, - cert: this.cert, - ca: this.ca, - ciphers: this.ciphers, - rejectUnauthorized: this.rejectUnauthorized, - perMessageDeflate: this.perMessageDeflate, - extraHeaders: this.extraHeaders - }); - - return transport; -}; - -function clone (obj) { - var o = {}; - for (var i in obj) { - if (obj.hasOwnProperty(i)) { - o[i] = obj[i]; - } - } - return o; -} - -/** - * Initializes transport to use and starts probe. - * - * @api private - */ -Socket.prototype.open = function () { - var transport; - if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) { - transport = 'websocket'; - } else if (0 === this.transports.length) { - // Emit error on next tick so it can be listened to - var self = this; - setTimeout(function() { - self.emit('error', 'No transports available'); - }, 0); - return; - } else { - transport = this.transports[0]; - } - this.readyState = 'opening'; - - // Retry with the next transport if the transport is disabled (jsonp: false) - try { - transport = this.createTransport(transport); - } catch (e) { - this.transports.shift(); - this.open(); - return; - } - - transport.open(); - this.setTransport(transport); -}; - -/** - * Sets the current transport. Disables the existing one (if any). - * - * @api private - */ - -Socket.prototype.setTransport = function(transport){ - debug('setting transport %s', transport.name); - var self = this; - - if (this.transport) { - debug('clearing existing transport %s', this.transport.name); - this.transport.removeAllListeners(); - } - - // set up transport - this.transport = transport; - - // set up transport listeners - transport - .on('drain', function(){ - self.onDrain(); - }) - .on('packet', function(packet){ - self.onPacket(packet); - }) - .on('error', function(e){ - self.onError(e); - }) - .on('close', function(){ - self.onClose('transport close'); - }); -}; - -/** - * Probes a transport. - * - * @param {String} transport name - * @api private - */ - -Socket.prototype.probe = function (name) { - debug('probing transport "%s"', name); - var transport = this.createTransport(name, { probe: 1 }) - , failed = false - , self = this; - - Socket.priorWebsocketSuccess = false; - - function onTransportOpen(){ - if (self.onlyBinaryUpgrades) { - var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; - failed = failed || upgradeLosesBinary; - } - if (failed) return; - - debug('probe transport "%s" opened', name); - transport.send([{ type: 'ping', data: 'probe' }]); - transport.once('packet', function (msg) { - if (failed) return; - if ('pong' == msg.type && 'probe' == msg.data) { - debug('probe transport "%s" pong', name); - self.upgrading = true; - self.emit('upgrading', transport); - if (!transport) return; - Socket.priorWebsocketSuccess = 'websocket' == transport.name; - - debug('pausing current transport "%s"', self.transport.name); - self.transport.pause(function () { - if (failed) return; - if ('closed' == self.readyState) return; - debug('changing transport and sending upgrade packet'); - - cleanup(); - - self.setTransport(transport); - transport.send([{ type: 'upgrade' }]); - self.emit('upgrade', transport); - transport = null; - self.upgrading = false; - self.flush(); - }); - } else { - debug('probe transport "%s" failed', name); - var err = new Error('probe error'); - err.transport = transport.name; - self.emit('upgradeError', err); - } - }); - } - - function freezeTransport() { - if (failed) return; - - // Any callback called by transport should be ignored since now - failed = true; - - cleanup(); - - transport.close(); - transport = null; - } - - //Handle any error that happens while probing - function onerror(err) { - var error = new Error('probe error: ' + err); - error.transport = transport.name; - - freezeTransport(); - - debug('probe transport "%s" failed because of error: %s', name, err); - - self.emit('upgradeError', error); - } - - function onTransportClose(){ - onerror("transport closed"); - } - - //When the socket is closed while we're probing - function onclose(){ - onerror("socket closed"); - } - - //When the socket is upgraded while we're probing - function onupgrade(to){ - if (transport && to.name != transport.name) { - debug('"%s" works - aborting "%s"', to.name, transport.name); - freezeTransport(); - } - } - - //Remove all listeners on the transport and on self - function cleanup(){ - transport.removeListener('open', onTransportOpen); - transport.removeListener('error', onerror); - transport.removeListener('close', onTransportClose); - self.removeListener('close', onclose); - self.removeListener('upgrading', onupgrade); - } - - transport.once('open', onTransportOpen); - transport.once('error', onerror); - transport.once('close', onTransportClose); - - this.once('close', onclose); - this.once('upgrading', onupgrade); - - transport.open(); - -}; - -/** - * Called when connection is deemed open. - * - * @api public - */ - -Socket.prototype.onOpen = function () { - debug('socket open'); - this.readyState = 'open'; - Socket.priorWebsocketSuccess = 'websocket' == this.transport.name; - this.emit('open'); - this.flush(); - - // we check for `readyState` in case an `open` - // listener already closed the socket - if ('open' == this.readyState && this.upgrade && this.transport.pause) { - debug('starting upgrade probes'); - for (var i = 0, l = this.upgrades.length; i < l; i++) { - this.probe(this.upgrades[i]); - } - } -}; - -/** - * Handles a packet. - * - * @api private - */ - -Socket.prototype.onPacket = function (packet) { - if ('opening' == this.readyState || 'open' == this.readyState) { - debug('socket receive: type "%s", data "%s"', packet.type, packet.data); - - this.emit('packet', packet); - - // Socket is live - any packet counts - this.emit('heartbeat'); - - switch (packet.type) { - case 'open': - this.onHandshake(parsejson(packet.data)); - break; - - case 'pong': - this.setPing(); - this.emit('pong'); - break; - - case 'error': - var err = new Error('server error'); - err.code = packet.data; - this.onError(err); - break; - - case 'message': - this.emit('data', packet.data); - this.emit('message', packet.data); - break; - } - } else { - debug('packet received with socket readyState "%s"', this.readyState); - } -}; - -/** - * Called upon handshake completion. - * - * @param {Object} handshake obj - * @api private - */ - -Socket.prototype.onHandshake = function (data) { - this.emit('handshake', data); - this.id = data.sid; - this.transport.query.sid = data.sid; - this.upgrades = this.filterUpgrades(data.upgrades); - this.pingInterval = data.pingInterval; - this.pingTimeout = data.pingTimeout; - this.onOpen(); - // In case open handler closes socket - if ('closed' == this.readyState) return; - this.setPing(); - - // Prolong liveness of socket on heartbeat - this.removeListener('heartbeat', this.onHeartbeat); - this.on('heartbeat', this.onHeartbeat); -}; - -/** - * Resets ping timeout. - * - * @api private - */ - -Socket.prototype.onHeartbeat = function (timeout) { - clearTimeout(this.pingTimeoutTimer); - var self = this; - self.pingTimeoutTimer = setTimeout(function () { - if ('closed' == self.readyState) return; - self.onClose('ping timeout'); - }, timeout || (self.pingInterval + self.pingTimeout)); -}; - -/** - * Pings server every `this.pingInterval` and expects response - * within `this.pingTimeout` or closes connection. - * - * @api private - */ - -Socket.prototype.setPing = function () { - var self = this; - clearTimeout(self.pingIntervalTimer); - self.pingIntervalTimer = setTimeout(function () { - debug('writing ping packet - expecting pong within %sms', self.pingTimeout); - self.ping(); - self.onHeartbeat(self.pingTimeout); - }, self.pingInterval); -}; - -/** -* Sends a ping packet. -* -* @api private -*/ - -Socket.prototype.ping = function () { - var self = this; - this.sendPacket('ping', function(){ - self.emit('ping'); - }); -}; - -/** - * Called on `drain` event - * - * @api private - */ - -Socket.prototype.onDrain = function() { - this.writeBuffer.splice(0, this.prevBufferLen); - - // setting prevBufferLen = 0 is very important - // for example, when upgrading, upgrade packet is sent over, - // and a nonzero prevBufferLen could cause problems on `drain` - this.prevBufferLen = 0; - - if (0 === this.writeBuffer.length) { - this.emit('drain'); - } else { - this.flush(); - } -}; - -/** - * Flush write buffers. - * - * @api private - */ - -Socket.prototype.flush = function () { - if ('closed' != this.readyState && this.transport.writable && - !this.upgrading && this.writeBuffer.length) { - debug('flushing %d packets in socket', this.writeBuffer.length); - this.transport.send(this.writeBuffer); - // keep track of current length of writeBuffer - // splice writeBuffer and callbackBuffer on `drain` - this.prevBufferLen = this.writeBuffer.length; - this.emit('flush'); - } -}; - -/** - * Sends a message. - * - * @param {String} message. - * @param {Function} callback function. - * @param {Object} options. - * @return {Socket} for chaining. - * @api public - */ - -Socket.prototype.write = -Socket.prototype.send = function (msg, options, fn) { - this.sendPacket('message', msg, options, fn); - return this; -}; - -/** - * Sends a packet. - * - * @param {String} packet type. - * @param {String} data. - * @param {Object} options. - * @param {Function} callback function. - * @api private - */ - -Socket.prototype.sendPacket = function (type, data, options, fn) { - if('function' == typeof data) { - fn = data; - data = undefined; - } - - if ('function' == typeof options) { - fn = options; - options = null; - } - - if ('closing' == this.readyState || 'closed' == this.readyState) { - return; - } - - options = options || {}; - options.compress = false !== options.compress; - - var packet = { - type: type, - data: data, - options: options - }; - this.emit('packetCreate', packet); - this.writeBuffer.push(packet); - if (fn) this.once('flush', fn); - this.flush(); -}; - -/** - * Closes the connection. - * - * @api private - */ - -Socket.prototype.close = function () { - if ('opening' == this.readyState || 'open' == this.readyState) { - this.readyState = 'closing'; - - var self = this; - - if (this.writeBuffer.length) { - this.once('drain', function() { - if (this.upgrading) { - waitForUpgrade(); - } else { - close(); - } - }); - } else if (this.upgrading) { - waitForUpgrade(); - } else { - close(); - } - } - - function close() { - self.onClose('forced close'); - debug('socket closing - telling transport to close'); - self.transport.close(); - } - - function cleanupAndClose() { - self.removeListener('upgrade', cleanupAndClose); - self.removeListener('upgradeError', cleanupAndClose); - close(); - } - - function waitForUpgrade() { - // wait for upgrade to finish since we can't send packets while pausing a transport - self.once('upgrade', cleanupAndClose); - self.once('upgradeError', cleanupAndClose); - } - - return this; -}; - -/** - * Called upon transport error - * - * @api private - */ - -Socket.prototype.onError = function (err) { - debug('socket error %j', err); - Socket.priorWebsocketSuccess = false; - this.emit('error', err); - this.onClose('transport error', err); -}; - -/** - * Called upon transport close. - * - * @api private - */ - -Socket.prototype.onClose = function (reason, desc) { - if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) { - debug('socket close with reason: "%s"', reason); - var self = this; - - // clear timers - clearTimeout(this.pingIntervalTimer); - clearTimeout(this.pingTimeoutTimer); - - // stop event from firing again for transport - this.transport.removeAllListeners('close'); - - // ensure transport won't stay open - this.transport.close(); - - // ignore further transport communication - this.transport.removeAllListeners(); - - // set ready state - this.readyState = 'closed'; - - // clear session id - this.id = null; - - // emit close event - this.emit('close', reason, desc); - - // clean buffers after, so users can still - // grab the buffers on `close` event - self.writeBuffer = []; - self.prevBufferLen = 0; - } -}; - -/** - * Filters upgrades, returning only those matching client transports. - * - * @param {Array} server upgrades - * @api private - * - */ - -Socket.prototype.filterUpgrades = function (upgrades) { - var filteredUpgrades = []; - for (var i = 0, j = upgrades.length; i