You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					498 lines
				
				14 KiB
			
		
		
			
		
	
	
					498 lines
				
				14 KiB
			| 
											3 years ago
										 | // 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.
 | ||
|  | 
 | ||
|  | 'use strict'; | ||
|  | 
 | ||
|  | var R = typeof Reflect === 'object' ? Reflect : null | ||
|  | var ReflectApply = R && typeof R.apply === 'function' | ||
|  |   ? R.apply | ||
|  |   : function ReflectApply(target, receiver, args) { | ||
|  |     return Function.prototype.apply.call(target, receiver, args); | ||
|  |   } | ||
|  | 
 | ||
|  | var ReflectOwnKeys | ||
|  | if (R && typeof R.ownKeys === 'function') { | ||
|  |   ReflectOwnKeys = R.ownKeys | ||
|  | } else if (Object.getOwnPropertySymbols) { | ||
|  |   ReflectOwnKeys = function ReflectOwnKeys(target) { | ||
|  |     return Object.getOwnPropertyNames(target) | ||
|  |       .concat(Object.getOwnPropertySymbols(target)); | ||
|  |   }; | ||
|  | } else { | ||
|  |   ReflectOwnKeys = function ReflectOwnKeys(target) { | ||
|  |     return Object.getOwnPropertyNames(target); | ||
|  |   }; | ||
|  | } | ||
|  | 
 | ||
|  | function ProcessEmitWarning(warning) { | ||
|  |   if (console && console.warn) console.warn(warning); | ||
|  | } | ||
|  | 
 | ||
|  | var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { | ||
|  |   return value !== value; | ||
|  | } | ||
|  | 
 | ||
|  | function EventEmitter() { | ||
|  |   EventEmitter.init.call(this); | ||
|  | } | ||
|  | module.exports = EventEmitter; | ||
|  | module.exports.once = once; | ||
|  | 
 | ||
|  | // Backwards-compat with node 0.10.x
 | ||
|  | EventEmitter.EventEmitter = EventEmitter; | ||
|  | 
 | ||
|  | EventEmitter.prototype._events = undefined; | ||
|  | EventEmitter.prototype._eventsCount = 0; | ||
|  | 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.
 | ||
|  | var defaultMaxListeners = 10; | ||
|  | 
 | ||
|  | function checkListener(listener) { | ||
|  |   if (typeof listener !== 'function') { | ||
|  |     throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | Object.defineProperty(EventEmitter, 'defaultMaxListeners', { | ||
|  |   enumerable: true, | ||
|  |   get: function() { | ||
|  |     return defaultMaxListeners; | ||
|  |   }, | ||
|  |   set: function(arg) { | ||
|  |     if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { | ||
|  |       throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); | ||
|  |     } | ||
|  |     defaultMaxListeners = arg; | ||
|  |   } | ||
|  | }); | ||
|  | 
 | ||
|  | EventEmitter.init = function() { | ||
|  | 
 | ||
|  |   if (this._events === undefined || | ||
|  |       this._events === Object.getPrototypeOf(this)._events) { | ||
|  |     this._events = Object.create(null); | ||
|  |     this._eventsCount = 0; | ||
|  |   } | ||
|  | 
 | ||
|  |   this._maxListeners = this._maxListeners || undefined; | ||
|  | }; | ||
|  | 
 | ||
|  | // 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 setMaxListeners(n) { | ||
|  |   if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { | ||
|  |     throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); | ||
|  |   } | ||
|  |   this._maxListeners = n; | ||
|  |   return this; | ||
|  | }; | ||
|  | 
 | ||
|  | function _getMaxListeners(that) { | ||
|  |   if (that._maxListeners === undefined) | ||
|  |     return EventEmitter.defaultMaxListeners; | ||
|  |   return that._maxListeners; | ||
|  | } | ||
|  | 
 | ||
|  | EventEmitter.prototype.getMaxListeners = function getMaxListeners() { | ||
|  |   return _getMaxListeners(this); | ||
|  | }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.emit = function emit(type) { | ||
|  |   var args = []; | ||
|  |   for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); | ||
|  |   var doError = (type === 'error'); | ||
|  | 
 | ||
|  |   var events = this._events; | ||
|  |   if (events !== undefined) | ||
|  |     doError = (doError && events.error === undefined); | ||
|  |   else if (!doError) | ||
|  |     return false; | ||
|  | 
 | ||
|  |   // If there is no 'error' event listener then throw.
 | ||
|  |   if (doError) { | ||
|  |     var er; | ||
|  |     if (args.length > 0) | ||
|  |       er = args[0]; | ||
|  |     if (er instanceof Error) { | ||
|  |       // Note: The comments on the `throw` lines are intentional, they show
 | ||
|  |       // up in Node's output if this results in an unhandled exception.
 | ||
|  |       throw er; // Unhandled 'error' event
 | ||
|  |     } | ||
|  |     // At least give some kind of context to the user
 | ||
|  |     var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); | ||
|  |     err.context = er; | ||
|  |     throw err; // Unhandled 'error' event
 | ||
|  |   } | ||
|  | 
 | ||
|  |   var handler = events[type]; | ||
|  | 
 | ||
|  |   if (handler === undefined) | ||
|  |     return false; | ||
|  | 
 | ||
|  |   if (typeof handler === 'function') { | ||
|  |     ReflectApply(handler, this, args); | ||
|  |   } else { | ||
|  |     var len = handler.length; | ||
|  |     var listeners = arrayClone(handler, len); | ||
|  |     for (var i = 0; i < len; ++i) | ||
|  |       ReflectApply(listeners[i], this, args); | ||
|  |   } | ||
|  | 
 | ||
|  |   return true; | ||
|  | }; | ||
|  | 
 | ||
|  | function _addListener(target, type, listener, prepend) { | ||
|  |   var m; | ||
|  |   var events; | ||
|  |   var existing; | ||
|  | 
 | ||
|  |   checkListener(listener); | ||
|  | 
 | ||
|  |   events = target._events; | ||
|  |   if (events === undefined) { | ||
|  |     events = target._events = Object.create(null); | ||
|  |     target._eventsCount = 0; | ||
|  |   } else { | ||
|  |     // To avoid recursion in the case that type === "newListener"! Before
 | ||
|  |     // adding it to the listeners, first emit "newListener".
 | ||
|  |     if (events.newListener !== undefined) { | ||
|  |       target.emit('newListener', type, | ||
|  |                   listener.listener ? listener.listener : listener); | ||
|  | 
 | ||
|  |       // Re-assign `events` because a newListener handler could have caused the
 | ||
|  |       // this._events to be assigned to a new object
 | ||
|  |       events = target._events; | ||
|  |     } | ||
|  |     existing = events[type]; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (existing === undefined) { | ||
|  |     // Optimize the case of one listener. Don't need the extra array object.
 | ||
|  |     existing = events[type] = listener; | ||
|  |     ++target._eventsCount; | ||
|  |   } else { | ||
|  |     if (typeof existing === 'function') { | ||
|  |       // Adding the second element, need to change to array.
 | ||
|  |       existing = events[type] = | ||
|  |         prepend ? [listener, existing] : [existing, listener]; | ||
|  |       // If we've already got an array, just append.
 | ||
|  |     } else if (prepend) { | ||
|  |       existing.unshift(listener); | ||
|  |     } else { | ||
|  |       existing.push(listener); | ||
|  |     } | ||
|  | 
 | ||
|  |     // Check for listener leak
 | ||
|  |     m = _getMaxListeners(target); | ||
|  |     if (m > 0 && existing.length > m && !existing.warned) { | ||
|  |       existing.warned = true; | ||
|  |       // No error code for this since it is a Warning
 | ||
|  |       // eslint-disable-next-line no-restricted-syntax
 | ||
|  |       var w = new Error('Possible EventEmitter memory leak detected. ' + | ||
|  |                           existing.length + ' ' + String(type) + ' listeners ' + | ||
|  |                           'added. Use emitter.setMaxListeners() to ' + | ||
|  |                           'increase limit'); | ||
|  |       w.name = 'MaxListenersExceededWarning'; | ||
|  |       w.emitter = target; | ||
|  |       w.type = type; | ||
|  |       w.count = existing.length; | ||
|  |       ProcessEmitWarning(w); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return target; | ||
|  | } | ||
|  | 
 | ||
|  | EventEmitter.prototype.addListener = function addListener(type, listener) { | ||
|  |   return _addListener(this, type, listener, false); | ||
|  | }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.on = EventEmitter.prototype.addListener; | ||
|  | 
 | ||
|  | EventEmitter.prototype.prependListener = | ||
|  |     function prependListener(type, listener) { | ||
|  |       return _addListener(this, type, listener, true); | ||
|  |     }; | ||
|  | 
 | ||
|  | function onceWrapper() { | ||
|  |   if (!this.fired) { | ||
|  |     this.target.removeListener(this.type, this.wrapFn); | ||
|  |     this.fired = true; | ||
|  |     if (arguments.length === 0) | ||
|  |       return this.listener.call(this.target); | ||
|  |     return this.listener.apply(this.target, arguments); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function _onceWrap(target, type, listener) { | ||
|  |   var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; | ||
|  |   var wrapped = onceWrapper.bind(state); | ||
|  |   wrapped.listener = listener; | ||
|  |   state.wrapFn = wrapped; | ||
|  |   return wrapped; | ||
|  | } | ||
|  | 
 | ||
|  | EventEmitter.prototype.once = function once(type, listener) { | ||
|  |   checkListener(listener); | ||
|  |   this.on(type, _onceWrap(this, type, listener)); | ||
|  |   return this; | ||
|  | }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.prependOnceListener = | ||
|  |     function prependOnceListener(type, listener) { | ||
|  |       checkListener(listener); | ||
|  |       this.prependListener(type, _onceWrap(this, type, listener)); | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  | // Emits a 'removeListener' event if and only if the listener was removed.
 | ||
|  | EventEmitter.prototype.removeListener = | ||
|  |     function removeListener(type, listener) { | ||
|  |       var list, events, position, i, originalListener; | ||
|  | 
 | ||
|  |       checkListener(listener); | ||
|  | 
 | ||
|  |       events = this._events; | ||
|  |       if (events === undefined) | ||
|  |         return this; | ||
|  | 
 | ||
|  |       list = events[type]; | ||
|  |       if (list === undefined) | ||
|  |         return this; | ||
|  | 
 | ||
|  |       if (list === listener || list.listener === listener) { | ||
|  |         if (--this._eventsCount === 0) | ||
|  |           this._events = Object.create(null); | ||
|  |         else { | ||
|  |           delete events[type]; | ||
|  |           if (events.removeListener) | ||
|  |             this.emit('removeListener', type, list.listener || listener); | ||
|  |         } | ||
|  |       } else if (typeof list !== 'function') { | ||
|  |         position = -1; | ||
|  | 
 | ||
|  |         for (i = list.length - 1; i >= 0; i--) { | ||
|  |           if (list[i] === listener || list[i].listener === listener) { | ||
|  |             originalListener = list[i].listener; | ||
|  |             position = i; | ||
|  |             break; | ||
|  |           } | ||
|  |         } | ||
|  | 
 | ||
|  |         if (position < 0) | ||
|  |           return this; | ||
|  | 
 | ||
|  |         if (position === 0) | ||
|  |           list.shift(); | ||
|  |         else { | ||
|  |           spliceOne(list, position); | ||
|  |         } | ||
|  | 
 | ||
|  |         if (list.length === 1) | ||
|  |           events[type] = list[0]; | ||
|  | 
 | ||
|  |         if (events.removeListener !== undefined) | ||
|  |           this.emit('removeListener', type, originalListener || listener); | ||
|  |       } | ||
|  | 
 | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.off = EventEmitter.prototype.removeListener; | ||
|  | 
 | ||
|  | EventEmitter.prototype.removeAllListeners = | ||
|  |     function removeAllListeners(type) { | ||
|  |       var listeners, events, i; | ||
|  | 
 | ||
|  |       events = this._events; | ||
|  |       if (events === undefined) | ||
|  |         return this; | ||
|  | 
 | ||
|  |       // not listening for removeListener, no need to emit
 | ||
|  |       if (events.removeListener === undefined) { | ||
|  |         if (arguments.length === 0) { | ||
|  |           this._events = Object.create(null); | ||
|  |           this._eventsCount = 0; | ||
|  |         } else if (events[type] !== undefined) { | ||
|  |           if (--this._eventsCount === 0) | ||
|  |             this._events = Object.create(null); | ||
|  |           else | ||
|  |             delete events[type]; | ||
|  |         } | ||
|  |         return this; | ||
|  |       } | ||
|  | 
 | ||
|  |       // emit removeListener for all listeners on all events
 | ||
|  |       if (arguments.length === 0) { | ||
|  |         var keys = Object.keys(events); | ||
|  |         var key; | ||
|  |         for (i = 0; i < keys.length; ++i) { | ||
|  |           key = keys[i]; | ||
|  |           if (key === 'removeListener') continue; | ||
|  |           this.removeAllListeners(key); | ||
|  |         } | ||
|  |         this.removeAllListeners('removeListener'); | ||
|  |         this._events = Object.create(null); | ||
|  |         this._eventsCount = 0; | ||
|  |         return this; | ||
|  |       } | ||
|  | 
 | ||
|  |       listeners = events[type]; | ||
|  | 
 | ||
|  |       if (typeof listeners === 'function') { | ||
|  |         this.removeListener(type, listeners); | ||
|  |       } else if (listeners !== undefined) { | ||
|  |         // LIFO order
 | ||
|  |         for (i = listeners.length - 1; i >= 0; i--) { | ||
|  |           this.removeListener(type, listeners[i]); | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  | function _listeners(target, type, unwrap) { | ||
|  |   var events = target._events; | ||
|  | 
 | ||
|  |   if (events === undefined) | ||
|  |     return []; | ||
|  | 
 | ||
|  |   var evlistener = events[type]; | ||
|  |   if (evlistener === undefined) | ||
|  |     return []; | ||
|  | 
 | ||
|  |   if (typeof evlistener === 'function') | ||
|  |     return unwrap ? [evlistener.listener || evlistener] : [evlistener]; | ||
|  | 
 | ||
|  |   return unwrap ? | ||
|  |     unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); | ||
|  | } | ||
|  | 
 | ||
|  | EventEmitter.prototype.listeners = function listeners(type) { | ||
|  |   return _listeners(this, type, true); | ||
|  | }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.rawListeners = function rawListeners(type) { | ||
|  |   return _listeners(this, type, false); | ||
|  | }; | ||
|  | 
 | ||
|  | EventEmitter.listenerCount = function(emitter, type) { | ||
|  |   if (typeof emitter.listenerCount === 'function') { | ||
|  |     return emitter.listenerCount(type); | ||
|  |   } else { | ||
|  |     return listenerCount.call(emitter, type); | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | EventEmitter.prototype.listenerCount = listenerCount; | ||
|  | function listenerCount(type) { | ||
|  |   var events = this._events; | ||
|  | 
 | ||
|  |   if (events !== undefined) { | ||
|  |     var evlistener = events[type]; | ||
|  | 
 | ||
|  |     if (typeof evlistener === 'function') { | ||
|  |       return 1; | ||
|  |     } else if (evlistener !== undefined) { | ||
|  |       return evlistener.length; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return 0; | ||
|  | } | ||
|  | 
 | ||
|  | EventEmitter.prototype.eventNames = function eventNames() { | ||
|  |   return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; | ||
|  | }; | ||
|  | 
 | ||
|  | function arrayClone(arr, n) { | ||
|  |   var copy = new Array(n); | ||
|  |   for (var i = 0; i < n; ++i) | ||
|  |     copy[i] = arr[i]; | ||
|  |   return copy; | ||
|  | } | ||
|  | 
 | ||
|  | function spliceOne(list, index) { | ||
|  |   for (; index + 1 < list.length; index++) | ||
|  |     list[index] = list[index + 1]; | ||
|  |   list.pop(); | ||
|  | } | ||
|  | 
 | ||
|  | function unwrapListeners(arr) { | ||
|  |   var ret = new Array(arr.length); | ||
|  |   for (var i = 0; i < ret.length; ++i) { | ||
|  |     ret[i] = arr[i].listener || arr[i]; | ||
|  |   } | ||
|  |   return ret; | ||
|  | } | ||
|  | 
 | ||
|  | function once(emitter, name) { | ||
|  |   return new Promise(function (resolve, reject) { | ||
|  |     function errorListener(err) { | ||
|  |       emitter.removeListener(name, resolver); | ||
|  |       reject(err); | ||
|  |     } | ||
|  | 
 | ||
|  |     function resolver() { | ||
|  |       if (typeof emitter.removeListener === 'function') { | ||
|  |         emitter.removeListener('error', errorListener); | ||
|  |       } | ||
|  |       resolve([].slice.call(arguments)); | ||
|  |     }; | ||
|  | 
 | ||
|  |     eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); | ||
|  |     if (name !== 'error') { | ||
|  |       addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true }); | ||
|  |     } | ||
|  |   }); | ||
|  | } | ||
|  | 
 | ||
|  | function addErrorHandlerIfEventEmitter(emitter, handler, flags) { | ||
|  |   if (typeof emitter.on === 'function') { | ||
|  |     eventTargetAgnosticAddListener(emitter, 'error', handler, flags); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | function eventTargetAgnosticAddListener(emitter, name, listener, flags) { | ||
|  |   if (typeof emitter.on === 'function') { | ||
|  |     if (flags.once) { | ||
|  |       emitter.once(name, listener); | ||
|  |     } else { | ||
|  |       emitter.on(name, listener); | ||
|  |     } | ||
|  |   } else if (typeof emitter.addEventListener === 'function') { | ||
|  |     // EventTarget does not have `error` event semantics like Node
 | ||
|  |     // EventEmitters, we do not listen for `error` events here.
 | ||
|  |     emitter.addEventListener(name, function wrapListener(arg) { | ||
|  |       // IE does not have builtin `{ once: true }` support so we
 | ||
|  |       // have to do it manually.
 | ||
|  |       if (flags.once) { | ||
|  |         emitter.removeEventListener(name, wrapListener); | ||
|  |       } | ||
|  |       listener(arg); | ||
|  |     }); | ||
|  |   } else { | ||
|  |     throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter); | ||
|  |   } | ||
|  | } |