on (EventHandler)
@param  {string} eventDomain
@params {string} listenerElement
@return {Function}
777308
function on(eventDomain, listenerElement = 'local') {

	if(!eventDomain){
		throw new Error('Please pass an event type e.g "click"');
	}

	return ({ constructor }, method, { value }) => {

		let Class = constructor;

		initCoreMap(storage, Class);
		initOnMap(storage, Class);

		let mapClassOn = storage.get(Class);
		let handler = value;
		let eventsMap = mapClassOn.get('@on').get('events');

		if(listenerElement === 'local'){
			eventsMap.get('local').push([
				eventDomain, handler
			]);
		} else {
			eventsMap.get('context').push([
				eventDomain, [ handler, listenerElement ]
			]);
		}

		/**
		 * ### Ensure "registerCallback('created', ..." (see below) registered only once ###
		 * This function will called every time if an event will be registered e.g. over @on('click .foo')
		 * but registerOnCreatedCallback can only call once because we want only Create
		 * one Eventhandler
		 */
		if(mapClassOn.get('@on').get('callbacksDefined')){
			return;
		}

		mapClassOn.get('@callbacks').get('created').push(domNode => {

			// register local (domNode) events e.g. thats depends on element click mousemove, etc
			let eventsLocal = mapClassOn.get('@on').get('events').get('local');
			if(eventsLocal.length){
				let eventHandler = on.helper.createLocalEventHandler(eventsLocal, domNode);
				namespace.create(domNode, '$eventHandler.local', eventHandler);
			}

			// register custom events e.g. thats depend on e.g. window onresize, onwheel, etc
			let eventsContext = mapClassOn.get('@on').get('events').get('context');
			if(eventsContext.length){
				on.helper.createCustomEventHandler(eventsContext, domNode, (eventHandler, name) => {
					namespace.create(domNode, `$eventHandler.${name}`, eventHandler);
				});
			}

		});

		mapClassOn.get('@callbacks').get('attached').push(domNode => {

			// this behavior ensures that when the domNode is
			// attached, detached, attached
			let eventHandlerLength = 0;
			let $eventHandler = Object.values(domNode.$eventHandler);
			$eventHandler.forEach(eventHandler => {
				if(eventHandler.initialized()){
                    eventHandlerLength++
				}
			});

			if(eventHandlerLength === $eventHandler.length){
				return;
			}

			Object.entries(domNode.$eventHandler).forEach(([name, eventHandler]) => {

				/**
				 * Using the same instance is 30% faster in
				 * (Chrome, Opera) and no difference in Firefox
				 * @see: https://jsperf.com/new-class-vs-singleton
				 */
				eventHandler.reinit({
					events:  mapClassOn.get('@on').get('events').get(name),
					element: domNode,
					bind: domNode,
				});
			});

		});

		mapClassOn.get('@callbacks').get('detached').push(domNode => {

			Object.values(domNode.$eventHandler).forEach(eventHandler => {
				eventHandler.destroy();
			});
		});

		mapClassOn.get('@on').set('callbacksDefined', true);

	}
}
958694
function(event, selector, handler, fn) {
      if (/^f/.test(typeof selector)) {
        handler = selector;
        fn = handler;
      }
      else if (/^s/.test(typeof selector)) {
        fn = handler;
        handler = function(e) {
          var element;
          if (u(e.target).is(selector)) {
            element = e.target;
          }
          else if (u(e.target).parents(selector).length) {
            element = u(e.target).parents(selector)[0];
          }
          if (element) {
            fn.apply(element, [e]);
          }
        };
      }
      return this.each(function(index, el) {
        var events = event.split(' ');
        u.each(events, function(i, event){
          u._events.add(el, event, fn, handler);
          el.addEventListener(event, function temp(e) {
            el.removeEventListener(event, temp);
            u._events.remove(el, event, fn);
            handler.call(this,e);
          });
        });
      });
    }
544461
function (eventName,handler) {
			var event;
			if (event = this.getEvent(eventName))
			{
				if (!event.prependListener(handler))
					this.e.log('Invalid handler sent to event `'+eventName+'` on `'+this.getConfig('id')+'`','warning');
			} else
				this.e.log('Not existent event `'+eventName+'` on `'+this.getConfig('id')+'`','warning');
			return this;
		}
934401
function addHandler(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false)
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler)
        } else {
            element["on" + type] = handler
        }
    }
603508
function(eventName, options) {
    if (!this.__eventListeners) {
      this.__eventListeners = { }
    }
    var listenersForEvent = this.__eventListeners[eventName];
    if (!listenersForEvent) return;
    for (var i = 0, len = listenersForEvent.length; i < len; i++) {
      // avoiding try/catch for perf. reasons
      listenersForEvent[i](options || { });
    }
  }
755092
function _on (event, method, context) {
  /* eslint-disable no-invalid-this */
  var bindings
  validateMethod(method, context)
  if (this.__events__.hasOwnProperty(event)) {
    bindings = this.__events__[event]
  } else {
    // Auto-initialize bindings list
    bindings = this.__events__[event] = []
  }
  // Add binding
  bindings.push({
    method: method,
    context: context || null
  })
  if (DEBUG) {
    count++
    console.info('_on()', event, method.name, context, this)
    console.info(COUNT_MSG, count)
  }
  return this
  /* eslint-enable no-invalid-this */
}
1260925
function elementOwnOnEl(name, listener, capture) {
    capture = !!capture;
    this._elFns.push([name, listener, capture]);
    on(this.el, name, listener, capture);
}
1341356
function on(element, type, handler, opt) {
    util.addEventListener(element, type, handler, opt, true);
  }
92193
function eventListenerHub(emitter, eventName) {
  var self = object.create(eventListenerHub.prototype);

  self.emitter = emitter;
  self.eventName = eventName;
  self.handlers = [];
  self.defaultHandlerFn = null;

  return self;
}
1091266
function(element, type, handler) {
    if(element.addEventListener) {
      addEvent = function(element, type, handler) {
        element.addEventListener(type, handler, false);
      };
    } else if(element.attachEvent) {
      addEvent = function(element, type, handler) {
        element.attachEvent('on' + type, handler);
      };
    } else {
      addEvent = function(element, type, handler) {
        element['on' + type] = handler;
      };
    }
    addEvent(element, type, handler);
  }
238895
function listenersHelp (element, events, handler, method) {
  let list = events.split(' ')
  for (let i = 0, len = list.length; i < len; i++) {
    let item = list[i]
    if (method === false) {
      element.removeEventListener(item, handler)
    } else {
      element.addEventListener(item, handler, false)
    }
  }
}
1095192
function EventUtils() {
      var self = this, events = {}, count, expando, hasFocusIn, hasMouseEnterLeave, mouseEnterLeave;

      expando = eventExpandoPrefix + (+new Date()).toString(32);
      hasMouseEnterLeave = "onmouseenter" in document.documentElement;
      hasFocusIn = "onfocusin" in document.documentElement;
      mouseEnterLeave = { mouseenter: 'mouseover', mouseleave: 'mouseout' };
      count = 1;

      // State if the DOMContentLoaded was executed or not
      self.domLoaded = false;
      self.events = events;

      /**
       * Executes all event handler callbacks for a specific event.
       *
       * @private
       * @param {Event} evt Event object.
       * @param {String} id Expando id value to look for.
       */
      function executeHandlers(evt, id) {
        var callbackList, i, l, callback, container = events[id];

        callbackList = container && container[evt.type];
        if (callbackList) {
          for (i = 0, l = callbackList.length; i < l; i++) {
            callback = callbackList[i];

            // Check if callback exists might be removed if a unbind is called inside the callback
            if (callback && callback.func.call(callback.scope, evt) === false) {
              evt.preventDefault();
            }

            // Should we stop propagation to immediate listeners
            if (evt.isImmediatePropagationStopped()) {
              return;
            }
          }
        }
      }

      /**
       * Binds a callback to an event on the specified target.
       *
       * @method bind
       * @param {Object} target Target node/window or custom object.
       * @param {String} names Name of the event to bind.
       * @param {function} callback Callback function to execute when the event occurs.
       * @param {Object} scope Scope to call the callback function on, defaults to target.
       * @return {function} Callback function that got bound.
       */
      self.bind = function (target, names, callback, scope) {
        var id, callbackList, i, name, fakeName, nativeHandler, capture, win = window;

        // Native event handler function patches the event and executes the callbacks for the expando
        function defaultNativeHandler(evt) {
          executeHandlers(fix(evt || win.event), id);
        }

        // Don't bind to text nodes or comments
        if (!target || target.nodeType === 3 || target.nodeType === 8) {
          return;
        }

        // Create or get events id for the target
        if (!target[expando]) {
          id = count++;
          target[expando] = id;
          events[id] = {};
        } else {
          id = target[expando];
        }

        // Setup the specified scope or use the target as a default
        scope = scope || target;

        // Split names and bind each event, enables you to bind multiple events with one call
        names = names.split(' ');
        i = names.length;
        while (i--) {
          name = names[i];
          nativeHandler = defaultNativeHandler;
          fakeName = capture = false;

          // Use ready instead of DOMContentLoaded
          if (name === "DOMContentLoaded") {
            name = "ready";
          }

          // DOM is already ready
          if (self.domLoaded && name === "ready" && target.readyState == 'complete') {
            callback.call(scope, fix({ type: name }));
            continue;
          }

          // Handle mouseenter/mouseleaver
          if (!hasMouseEnterLeave) {
            fakeName = mouseEnterLeave[name];

            if (fakeName) {
              nativeHandler = function (evt) {
                var current, related;

                current = evt.currentTarget;
                related = evt.relatedTarget;

                // Check if related is inside the current target if it's not then the event should
                // be ignored since it's a mouseover/mouseout inside the element
                if (related && current.contains) {
                  // Use contains for performance
                  related = current.contains(related);
                } else {
                  while (related && related !== current) {
                    related = related.parentNode;
                  }
                }

                // Fire fake event
                if (!related) {
                  evt = fix(evt || win.event);
                  evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter';
                  evt.target = current;
                  executeHandlers(evt, id);
                }
              };
            }
          }

          // Fake bubbling of focusin/focusout
          if (!hasFocusIn && (name === "focusin" || name === "focusout")) {
            capture = true;
            fakeName = name === "focusin" ? "focus" : "blur";
            nativeHandler = function (evt) {
              evt = fix(evt || win.event);
              evt.type = evt.type === 'focus' ? 'focusin' : 'focusout';
              executeHandlers(evt, id);
            };
          }

          // Setup callback list and bind native event
          callbackList = events[id][name];
          if (!callbackList) {
            events[id][name] = callbackList = [{ func: callback, scope: scope }];
            callbackList.fakeName = fakeName;
            callbackList.capture = capture;
            //callbackList.callback = callback;

            // Add the nativeHandler to the callback list so that we can later unbind it
            callbackList.nativeHandler = nativeHandler;

            // Check if the target has native events support

            if (name === "ready") {
              bindOnReady(target, nativeHandler, self);
            } else {
              addEvent(target, fakeName || name, nativeHandler, capture);
            }
          } else {
            if (name === "ready" && self.domLoaded) {
              callback({ type: name });
            } else {
              // If it already has an native handler then just push the callback
              callbackList.push({ func: callback, scope: scope });
            }
          }
        }

        target = callbackList = 0; // Clean memory for IE

        return callback;
      };

      /**
       * Unbinds the specified event by name, name and callback or all events on the target.
       *
       * @method unbind
       * @param {Object} target Target node/window or custom object.
       * @param {String} names Optional event name to unbind.
       * @param {function} callback Optional callback function to unbind.
       * @return {EventUtils} Event utils instance.
       */
      self.unbind = function (target, names, callback) {
        var id, callbackList, i, ci, name, eventMap;

        // Don't bind to text nodes or comments
        if (!target || target.nodeType === 3 || target.nodeType === 8) {
          return self;
        }

        // Unbind event or events if the target has the expando
        id = target[expando];
        if (id) {
          eventMap = events[id];

          // Specific callback
          if (names) {
            names = names.split(' ');
            i = names.length;
            while (i--) {
              name = names[i];
              callbackList = eventMap[name];

              // Unbind the event if it exists in the map
              if (callbackList) {
                // Remove specified callback
                if (callback) {
                  ci = callbackList.length;
                  while (ci--) {
                    if (callbackList[ci].func === callback) {
                      var nativeHandler = callbackList.nativeHandler;
                      var fakeName = callbackList.fakeName, capture = callbackList.capture;

                      // Clone callbackList since unbind inside a callback would otherwise break the handlers loop
                      callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1));
                      callbackList.nativeHandler = nativeHandler;
                      callbackList.fakeName = fakeName;
                      callbackList.capture = capture;

                      eventMap[name] = callbackList;
                    }
                  }
                }

                // Remove all callbacks if there isn't a specified callback or there is no callbacks left
                if (!callback || callbackList.length === 0) {
                  delete eventMap[name];
                  removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
                }
              }
            }
          } else {
            // All events for a specific element
            for (name in eventMap) {
              callbackList = eventMap[name];
              removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
            }

            eventMap = {};
          }

          // Check if object is empty, if it isn't then we won't remove the expando map
          for (name in eventMap) {
            return self;
          }

          // Delete event object
          delete events[id];

          // Remove expando from target
          try {
            // IE will fail here since it can't delete properties from window
            delete target[expando];
          } catch (ex) {
            // IE will set it to null
            target[expando] = null;
          }
        }

        return self;
      };

      /**
       * Fires the specified event on the specified target.
       *
       * @method fire
       * @param {Object} target Target node/window or custom object.
       * @param {String} name Event name to fire.
       * @param {Object} args Optional arguments to send to the observers.
       * @return {EventUtils} Event utils instance.
       */
      self.fire = function (target, name, args) {
        var id;

        // Don't bind to text nodes or comments
        if (!target || target.nodeType === 3 || target.nodeType === 8) {
          return self;
        }

        // Build event object by patching the args
        args = fix(null, args);
        args.type = name;
        args.target = target;

        do {
          // Found an expando that means there is listeners to execute
          id = target[expando];
          if (id) {
            executeHandlers(args, id);
          }

          // Walk up the DOM
          target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow;
        } while (target && !args.isPropagationStopped());

        return self;
      };

      /**
       * Removes all bound event listeners for the specified target. This will also remove any bound
       * listeners to child nodes within that target.
       *
       * @method clean
       * @param {Object} target Target node/window object.
       * @return {EventUtils} Event utils instance.
       */
      self.clean = function (target) {
        var i, children, unbind = self.unbind;

        // Don't bind to text nodes or comments
        if (!target || target.nodeType === 3 || target.nodeType === 8) {
          return self;
        }

        // Unbind any element on the specified target
        if (target[expando]) {
          unbind(target);
        }

        // Target doesn't have getElementsByTagName it's probably a window object then use it's document to find the children
        if (!target.getElementsByTagName) {
          target = target.document;
        }

        // Remove events from each child element
        if (target && target.getElementsByTagName) {
          unbind(target);

          children = target.getElementsByTagName('*');
          i = children.length;
          while (i--) {
            target = children[i];

            if (target[expando]) {
              unbind(target);
            }
          }
        }

        return self;
      };

      /**
       * Destroys the event object. Call this on IE to remove memory leaks.
       */
      self.destroy = function () {
        events = {};
      };

      // Legacy function for canceling events
      self.cancel = function (e) {
        if (e) {
          e.preventDefault();
          e.stopImmediatePropagation();
        }

        return false;
      };
    }
1201006
function (/*HTMLElement*/ obj, /*String*/ type, /*Function*/ fn, /*Object*/ context) {
		var id = TL.Util.stamp(fn),
			key = '_tl_' + type + id;

		if (obj[key]) {
			return;
		}

		var handler = function (e) {
			return fn.call(context || obj, e || TL.DomEvent._getEvent());
		};

		if (TL.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) {
			this.addDoubleTapListener(obj, handler, id);
		} else if ('addEventListener' in obj) {
			if (type === 'mousewheel') {
				obj.addEventListener('DOMMouseScroll', handler, false);
				obj.addEventListener(type, handler, false);
			} else if ((type === 'mouseenter') || (type === 'mouseleave')) {
				var originalHandler = handler,
					newType = (type === 'mouseenter' ? 'mouseover' : 'mouseout');
				handler = function (e) {
					if (!TL.DomEvent._checkMouse(obj, e)) {
						return;
					}
					return originalHandler(e);
				};
				obj.addEventListener(newType, handler, false);
			} else {
				obj.addEventListener(type, handler, false);
			}
		} else if ('attachEvent' in obj) {
			obj.attachEvent("on" + type, handler);
		}

		obj[key] = handler;
	}
225805
function (name, fn, ctx) {
        assert(isString(name), 'EventEmitter#on: name is not a string');
        assert(isFunction(fn), 'EventEmitter#on: fn is not a function');

        // If the context is not passed, use `this`.
        ctx = ctx || this;

        // Push to private lists of listeners.
        this._listeners.push({
            name: name,
            fn: fn,
            ctx: ctx
        });

        return this;
    }
695994
function (element, events, func) {
            for (var i = 0; i < events.length; i++) {
                element.addEventListener(events[i], func);
            }
        }
331246
function addEventListener(el, eventName, handler) {
    removeEventListener(el, eventName, handler);

    if (window.jQuery) {
      $(el).on(eventName, handler);
    } else if (el.addEventListener) {
      el.addEventListener(eventName, handler);
    } else {
      el.attachEvent('on' + eventName, function () {
        handler.call(el);
      });
    }
  }
1223468
function ElementsEventHandler(socket) {
  var _this = this;
  //Call EventEmmiter _contructor_
  events.EventEmitter.call(this);
  this.socket = socket;

  // On every message event received by socket we get
  // an message event object like {event:, data:} 
  // we emit  a local event through an EventEmitter interface
  // with .event as event type and .data as
  // event data;
  this.socket.on('message', function(message, callback) {
    debug("Forwarding frontend message '%s', with data %j", message.event, message.data);
    if (message.event !== undefined) {
      _this.emit(message.event, message.data);
      if (typeof callback === 'function') {
        callback();
      }
    }
    if (message.event === "userinput" && message.scope !== undefined) {
      debug("userinput received: %s", JSON.stringify(message));
      _this.emit(message.scope, message.data);
    }
  });
  this.socket.on("disconnect", function() {
    delete(this.socket);
    _this.emit("disconnect");
  });
}