weird cloudflare "javascripts" folder bug
[disclosr.git] / js / sigma.min.js
blob:a/js/sigma.min.js -> blob:b/js/sigma.min.js
  // Define packages:
  var sigma = {};
  sigma.tools = {};
  sigma.classes = {};
  sigma.instances = {};
   
  // Adding Array helpers, if not present yet:
  (function() {
  if (!Array.prototype.some) {
  Array.prototype.some = function(fun /*, thisp*/) {
  var len = this.length;
  if (typeof fun != 'function') {
  throw new TypeError();
  }
   
  var thisp = arguments[1];
  for (var i = 0; i < len; i++) {
  if (i in this &&
  fun.call(thisp, this[i], i, this)) {
  return true;
  }
  }
   
  return false;
  };
  }
   
  if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(fun /*, thisp*/) {
  var len = this.length;
  if (typeof fun != 'function') {
  throw new TypeError();
  }
   
  var thisp = arguments[1];
  for (var i = 0; i < len; i++) {
  if (i in this) {
  fun.call(thisp, this[i], i, this);
  }
  }
  };
  }
   
  if (!Array.prototype.map) {
  Array.prototype.map = function(fun /*, thisp*/) {
  var len = this.length;
  if (typeof fun != 'function') {
  throw new TypeError();
  }
   
  var res = new Array(len);
  var thisp = arguments[1];
  for (var i = 0; i < len; i++) {
  if (i in this) {
  res[i] = fun.call(thisp, this[i], i, this);
  }
  }
   
  return res;
  };
  }
   
  if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun /*, thisp*/) {
  var len = this.length;
  if (typeof fun != 'function')
  throw new TypeError();
   
  var res = new Array();
  var thisp = arguments[1];
  for (var i = 0; i < len; i++) {
  if (i in this) {
  var val = this[i]; // in case fun mutates this
  if (fun.call(thisp, val, i, this)) {
  res.push(val);
  }
  }
  }
   
  return res;
  };
  }
   
  if (!Object.keys) {
  Object.keys = (function() {
  var hasOwnProperty = Object.prototype.hasOwnProperty,
  hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
  dontEnums = [
  'toString',
  'toLocaleString',
  'valueOf',
  'hasOwnProperty',
  'isPrototypeOf',
  'propertyIsEnumerable',
  'constructor'
  ],
  dontEnumsLength = dontEnums.length;
   
  return function(obj) {
  if (typeof obj !== 'object' &&
  typeof obj !== 'function' ||
  obj === null
  ) {
  throw new TypeError('Object.keys called on non-object');
  }
   
  var result = [];
   
  for (var prop in obj) {
  if (hasOwnProperty.call(obj, prop)) result.push(prop);
  }
   
  if (hasDontEnumBug) {
  for (var i = 0; i < dontEnumsLength; i++) {
  if (hasOwnProperty.call(obj, dontEnums[i])) {
  result.push(dontEnums[i]);
  }
  }
  }
  return result;
  }
  })();
  }
  })();
   
  /**
  * A jQuery like properties management class. It works like jQuery .css()
  * method: You can call it with juste one string to get the corresponding
  * property, with a string and anything else to set the corresponding property,
  * or directly with an object, and then each pair string / object (or any type)
  * will be set in the properties.
  * @constructor
  * @this {sigma.classes.Cascade}
  */
  sigma.classes.Cascade = function() {
  /**
  * This instance properties.
  * @protected
  * @type {Object}
  */
  this.p = {};
   
  /**
  * The method to use to set/get any property of this instance.
  * @param {(string|Object)} a1 If it is a string and if a2 is undefined,
  * then it will return the corresponding
  * property.
  * If it is a string and if a2 is set, then it
  * will set a2 as the property corresponding to
  * a1, and return this.
  * If it is an object, then each pair string /
  * object (or any other type) will be set as a
  * property.
  * @param {*?} a2 The new property corresponding to a1 if a1 is
  * a string.
  * @return {(*|sigma.classes.Cascade)} Returns itself or the corresponding
  * property.
  */
  this.config = function(a1, a2) {
  if (typeof a1 == 'string' && a2 == undefined) {
  return this.p[a1];
  } else {
  var o = (typeof a1 == 'object' && a2 == undefined) ? a1 : {};
  if (typeof a1 == 'string') {
  o[a1] = a2;
  }
   
  for (var k in o) {
  if (this.p[k] != undefined) {
  this.p[k] = o[k];
  }
  }
  return this;
  }
  };
  };
   
  /**
  * sigma.js custom event dispatcher class.
  * @constructor
  * @this {sigma.classes.EventDispatcher}
  */
  sigma.classes.EventDispatcher = function() {
  /**
  * An object containing all the different handlers bound to one or many
  * events, indexed by these events.
  * @private
  * @type {Object.<string,Object>}
  */
  var _h = {};
   
  /**
  * Represents "this", without the well-known scope issue.
  * @private
  * @type {sigma.classes.EventDispatcher}
  */
  var _self = this;
   
  /**
  * Will execute the handler the next (and only the next) time that the
  * indicated event (or the indicated events) will be triggered.
  * @param {string} events The name of the event (or the events
  * separated by spaces).
  * @param {function(Object)} handler The handler to bind.
  * @return {sigma.classes.EventDispatcher} Returns itself.
  */
  function one(events, handler) {
  if (!handler || !events) {
  return _self;
  }
   
  var eArray = ((typeof events) == 'string') ? events.split(' ') : events;
   
  eArray.forEach(function(event) {
  if (!_h[event]) {
  _h[event] = [];
  }
   
  _h[event].push({
  'h': handler,
  'one': true
  });
  });
   
  return _self;
  }
   
  /**
  * Will execute the handler everytime that the indicated event (or the
  * indicated events) will be triggered.
  * @param {string} events The name of the event (or the events
  * separated by spaces).
  * @param {function(Object)} handler The handler to bind.
  * @return {sigma.classes.EventDispatcher} Returns itself.
  */
  function bind(events, handler) {
  if (!handler || !events) {
  return _self;
  }
   
  var eArray = ((typeof events) == 'string') ? events.split(' ') : events;
   
  eArray.forEach(function(event) {
  if (!_h[event]) {
  _h[event] = [];
  }
   
  _h[event].push({
  'h': handler,
  'one': false
  });
  });
   
  return _self;
  }
   
  /**
  * Unbinds the handler from a specified event (or specified events).
  * @param {?string} events The name of the event (or the events
  * separated by spaces). If undefined,
  * then all handlers are unbound.
  * @param {?function(Object)} handler The handler to unbind. If undefined,
  * each handler bound to the event or the
  * events will be unbound.
  * @return {sigma.classes.EventDispatcher} Returns itself.
  */
  function unbind(events, handler) {
  if (!events) {
  _h = {};
  }
   
  var eArray = typeof events == 'string' ? events.split(' ') : events;
   
  if (handler) {
  eArray.forEach(function(event) {
  if (_h[event]) {
  _h[event] = _h[event].filter(function(e) {
  return e['h'] != handler;
  });
  }
   
  if (_h[event] && _h[event].length == 0) {
  delete _h[event];
  }
  });
  }else {
  eArray.forEach(function(event) {
  delete _h[event];
  });
  }
   
  return _self;
  }
   
  /**
  * Executes each handler bound to the event
  * @param {string} type The type of the event.
  * @param {?Object} content The content of the event (optional).
  * @return {sigma.classes.EventDispatcher} Returns itself.
  */
  function dispatch(type, content) {
  if (_h[type]) {
  _h[type].forEach(function(e) {
  e['h']({
  'type': type,
  'content': content,
  'target': _self
  });
  });
   
  _h[type] = _h[type].filter(function(e) {
  return !e['one'];
  });
  }
   
  return _self;
  }
   
  /* PUBLIC INTERFACE: */
  this.one = one;
  this.bind = bind;
  this.unbind = unbind;
  this.dispatch = dispatch;
  };
   
  (function() {
  // Define local shortcut:
  var id = 0;
   
  // Define local package:
  var local = {};
  local.plugins = [];
   
  sigma.init = function(dom) {
  var inst = new Sigma(dom, (++id).toString());
  sigma.instances[id] = new SigmaPublic(inst);
  return sigma.instances[id];
  };
   
  /**
  * This class listen to all the different mouse events, to normalize them and
  * dispatch action events instead (from "startinterpolate" to "isdragging",
  * etc).
  * @constructor
  * @extends sigma.classes.Cascade
  * @extends sigma.classes.EventDispatcher
  * @param {element} dom The DOM element to bind the handlers on.
  * @this {MouseCaptor}
  */
  function MouseCaptor(dom) {
  sigma.classes.Cascade.call(this);
  sigma.classes.EventDispatcher.call(this);
   
  /**
  * Represents "this", without the well-known scope issue.
  * @private
  * @type {MouseCaptor}
  */
  var self = this;
   
  /**
  * The DOM element to bind the handlers on.
  * @type {element}
  */
  var dom = dom;
   
  /**
  * The different parameters that define how this instance should work.
  * @see sigma.classes.Cascade
  * @type {Object}
  */
  this.p = {
  minRatio: 1,
  maxRatio: 32,
  marginRatio: 1,
  zoomDelta: 0.1,
  dragDelta: 0.3,
  zoomMultiply: 2,
  directZooming: false,
  blockScroll: true,
  inertia: 1.1,
  mouseEnabled: true
  };
   
  var oldMouseX = 0;
  var oldMouseY = 0;
  var startX = 0;
  var startY = 0;
   
  var oldStageX = 0;
  var oldStageY = 0;
  var oldRatio = 1;
   
  var targetRatio = 1;
  var targetStageX = 0;
  var targetStageY = 0;
   
  var lastStageX = 0;
  var lastStageX2 = 0;