text: /**
   * This object contains all possible options. It will check if the types are correct, if required if the option is one
   * of the allowed values.
   *
   * __any__ means that the name of the property does not matter.
   * __type__ is a required field for all objects and contains the allowed types of all objects
   */
  let string = 'string';
  let bool = 'boolean';
  let number = 'number';
  let array = 'array';
  let object = 'object'; // should only be in a __type__ property
  let dom = 'dom';
  let any = 'any';
  
  
  let allOptions = {
    configure: {
      enabled: { boolean: bool },
      filter: { boolean: bool, string, array, 'function': 'function' },
      container: { dom },
      showButton: { boolean: bool },
      __type__: { object, boolean: bool, string, array, 'function': 'function' }
    },
    edges: {
      arrows: {
        to: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } },
        middle: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } },
        from: { enabled: { boolean: bool }, scaleFactor: { number }, type: { string: ['arrow', 'circle'] }, __type__: { object, boolean: bool } },
        __type__: { string: ['from', 'to', 'middle'], object }
      },
      arrowStrikethrough: { boolean: bool },
      chosen: {
        label: { boolean: bool, 'function': 'function' },
        edge: { boolean: bool, 'function': 'function' },
        __type__: { object, boolean: bool }
      },
      color: {
        color: { string },
        highlight: { string },
        hover: { string },
        inherit: { string: ['from', 'to', 'both'], boolean: bool },
        opacity: { number },
        __type__: { object, string }
      },
      dashes: { boolean: bool, array },
      font: {
        color: { string },
        size: { number }, // px
        face: { string },
        background: { string },
        strokeWidth: { number }, // px
        strokeColor: { string },
        align: { string: ['horizontal', 'top', 'middle', 'bottom'] },
        vadjust: { number },
        multi: { boolean: bool, string },
        bold: {
          color: { string },
          size: { number }, // px
          face: { string },
          mod: { string },
          vadjust: { number },
          __type__: { object, string }
        },
        boldital: {
          color: { string },
          size: { number }, // px
          face: { string },
          mod: { string },
          vadjust: { number },
          __type__: { object, string }
        },
        ital: {
          color: { string },
          size: { number }, // px
          face: { string },
          mod: { string },
          vadjust: { number },
          __type__: { object, string }
        },
        mono: {
          color: { string },
          size: { number }, // px
          face: { string },
          mod: { string },
          vadjust: { number },
          __type__: { object, string }
        },
        __type__: { object, string }
      },
      hidden: { boolean: bool },
      hoverWidth: { 'function': 'function', number },
      label: { string, 'undefined': 'undefined' },
      labelHighlightBold: { boolean: bool },
      length: { number, 'undefined': 'undefined' },
      physics: { boolean: bool },
      scaling: {
        min: { number },
        max: { number },
        label: {
          enabled: { boolean: bool },
          min: { number },
          max: { number },
          maxVisible: { number },
          drawThreshold: { number },
          __type__: { object, boolean: bool }
        },
        customScalingFunction: { 'function': 'function' },
        __type__: { object }
      },
      selectionWidth: { 'function': 'function', number },
      selfReferenceSize: { number },
      shadow: {
        enabled: { boolean: bool },
        color: { string },
        size: { number },
        x: { number },
        y: { number },
        __type__: { object, boolean: bool }
      },
      smooth: {
        enabled: { boolean: bool },
        type: { string: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier'] },
        roundness: { number },
        forceDirection: { string: ['horizontal', 'vertical', 'none'], boolean: bool },
        __type__: { object, boolean: bool }
      },
      title: { string, 'undefined': 'undefined' },
      width: { number },
      widthConstraint: {
        maximum: { number },
        __type__: { object, boolean: bool, number }
      },
      value: { number, 'undefined': 'undefined' },
      __type__: { object }
    },
    groups: {
      useDefaultGroups: { boolean: bool },
      __any__: 'get from nodes, will be overwritten below',
      __type__: { object }
    },
    interaction: {
      dragNodes: { boolean: bool },
      dragView: { boolean: bool },
      hideEdgesOnDrag: { boolean: bool },
      hideNodesOnDrag: { boolean: bool },
      hover: { boolean: bool },
      keyboard: {
        enabled: { boolean: bool },
        speed: { x: { number }, y: { number }, zoom: { number }, __type__: { object } },
        bindToWindow: { boolean: bool },
        __type__: { object, boolean: bool }
      },
      multiselect: { boolean: bool },
      navigationButtons: { boolean: bool },
      selectable: { boolean: bool },
      selectConnectedEdges: { boolean: bool },
      hoverConnectedEdges: { boolean: bool },
      tooltipDelay: { number },
      zoomView: { boolean: bool },
      __type__: { object }
    },
    layout: {
      randomSeed: { 'undefined': 'undefined', number },
      improvedLayout: { boolean: bool },
      hierarchical: {
        enabled: { boolean: bool },
        levelSeparation: { number },
        nodeSpacing: { number },
        treeSpacing: { number },
        blockShifting: { boolean: bool },
        edgeMinimization: { boolean: bool },
        parentCentralization: { boolean: bool },
        direction: { string: ['UD', 'DU', 'LR', 'RL'] },   // UD, DU, LR, RL
        sortMethod: { string: ['hubsize', 'directed'] }, // hubsize, directed
        __type__: { object, boolean: bool }
      },
      __type__: { object }
    },
    manipulation: {
      enabled: { boolean: bool },
      initiallyActive: { boolean: bool },
      addNode: { boolean: bool, 'function': 'function' },
      addEdge: { boolean: bool, 'function': 'function' },
      editNode: { 'function': 'function' },
      editEdge: {
        editWithoutDrag: { 'function' : 'function' },
        __type__: {object, boolean: bool, 'function': 'function' }
      },
      deleteNode: { boolean: bool, 'function': 'function' },
      deleteEdge: { boolean: bool, 'function': 'function' },
      controlNodeStyle: 'get from nodes, will be overwritten below',
      __type__: { object, boolean: bool }
    },
    nodes: {
      borderWidth: { number },
      borderWidthSelected: { number, 'undefined': 'undefined' },
      brokenImage: { string, 'undefined': 'undefined' },
      chosen: {
        label: { boolean: bool, 'function': 'function' },
        node: { boolean: bool, 'function': 'function' },
        __type__: { object, boolean: bool }
      },
      color: {
        border: { string },
        background: { string },
        highlight: {
          border: { string },
          background: { string },
          __type__: { object, string }
        },
        hover: {
          border: { string },
          background: { string },
          __type__: { object, string }
        },
        __type__: { object, string }
      },
      fixed: {
        x: { boolean: bool },
        y: { boolean: bool },
        __type__: { object, boolean: bool }
      },
      font: {
        align: { string },
        color: { string },
        size: { number }, // px
        face: { string },
        background: { string },
        strokeWidth: { number }, // px
        strokeColor: { string },
        vadjust: { number },
        multi: { boolean: bool, string },
        bold: {
          color: { string },
          size: { number }, // px
          face: { string },
          mod: { string },
          vadjust: { number },
          __type__: { object, string }
        },
        boldital: {
          color: { string },
          size: { number }, // px
          face: { string },
          mod: { string },
          vadjust: { number },
          __type__: { object, string }
        },
        ital: {
          color: { string },
          size: { number }, // px
          face: { string },
          mod: { string },
          vadjust: { number },
          __type__: { object, string }
        },
        mono: {
          color: { string },
          size: { number }, // px
          face: { string },
          mod: { string },
          vadjust: { number },
          __type__: { object, string }
        },
        __type__: { object, string }
      },
      group: { string, number, 'undefined': 'undefined' },
      heightConstraint: {
        minimum: { number },
        valign: { string },
        __type__: { object, boolean: bool, number }
      },
      hidden: { boolean: bool },
      icon: {
        face: { string },
        code: { string },  //'\uf007',
        size: { number },  //50,
        color: { string },
        __type__: { object }
      },
      id: { string, number },
      image: {
        selected: { string, 'undefined': 'undefined' }, // --> URL
        unselected: { string, 'undefined': 'undefined' }, // --> URL
        __type__: { object, string }
      },
      label: { string, 'undefined': 'undefined' },
      labelHighlightBold: { boolean: bool },
      level: { number, 'undefined': 'undefined' },
      margin: {
        top: { number },
        right: { number },
        bottom: { number },
        left: { number },
        __type__: { object, number }
      },
      mass: { number },
      physics: { boolean: bool },
      scaling: {
        min: { number },
        max: { number },
        label: {
          enabled: { boolean: bool },
          min: { number },
          max: { number },
          maxVisible: { number },
          drawThreshold: { number },
          __type__: { object, boolean: bool }
        },
        customScalingFunction: { 'function': 'function' },
        __type__: { object }
      },
      shadow: {
        enabled: { boolean: bool },
        color: { string },
        size: { number },
        x: { number },
        y: { number },
        __type__: { object, boolean: bool }
      },
      shape: { string: ['ellipse', 'circle', 'database', 'box', 'text', 'image', 'circularImage', 'diamond', 'dot', 'star', 'triangle', 'triangleDown', 'square', 'icon'] },
      shapeProperties: {
        borderDashes: { boolean: bool, array },
        borderRadius: { number },
        interpolation: { boolean: bool },
        useImageSize: { boolean: bool },
        useBorderWithImage: { boolean: bool },
        __type__: { object }
      },
      size: { number },
      title: { string, 'undefined': 'undefined' },
      value: { number, 'undefined': 'undefined' },
      widthConstraint: {
        minimum: { number },
        maximum: { number },
        __type__: { object, boolean: bool, number }
      },
      x: { number },
      y: { number },
      __type__: { object }
    },
    physics: {
      enabled: { boolean: bool },
      barnesHut: {
        gravitationalConstant: { number },
        centralGravity: { number },
        springLength: { number },
        springConstant: { number },
        damping: { number },
        avoidOverlap: { number },
        __type__: { object }
      },
      forceAtlas2Based: {
        gravitationalConstant: { number },
        centralGravity: { number },
        springLength: { number },
        springConstant: { number },
        damping: { number },
        avoidOverlap: { number },
        __type__: { object }
      },
      repulsion: {
        centralGravity: { number },
        springLength: { number },
        springConstant: { number },
        nodeDistance: { number },
        damping: { number },
        __type__: { object }
      },
      hierarchicalRepulsion: {
        centralGravity: { number },
        springLength: { number },
        springConstant: { number },
        nodeDistance: { number },
        damping: { number },
        __type__: { object }
      },
      maxVelocity: { number },
      minVelocity: { number },    // px/s
      solver: { string: ['barnesHut', 'repulsion', 'hierarchicalRepulsion', 'forceAtlas2Based'] },
      stabilization: {
        enabled: { boolean: bool },
        iterations: { number },   // maximum number of iteration to stabilize
        updateInterval: { number },
        onlyDynamicEdges: { boolean: bool },
        fit: { boolean: bool },
        __type__: { object, boolean: bool }
      },
      timestep: { number },
      adaptiveTimestep: { boolean: bool },
      __type__: { object, boolean: bool }
    },
  
    //globals :
    autoResize: { boolean: bool },
    clickToUse: { boolean: bool },
    locale: { string },
    locales: {
      __any__: { any },
      __type__: { object }
    },
    height: { string },
    width: { string },
    __type__: { object }
  };
  
  allOptions.groups.__any__ = allOptions.nodes;
  allOptions.manipulation.controlNodeStyle = allOptions.nodes;
  
  
  let configureOptions = {
    nodes: {
      borderWidth: [1, 0, 10, 1],
      borderWidthSelected: [2, 0, 10, 1],
      color: {
        border: ['color', '#2B7CE9'],
        background: ['color', '#97C2FC'],
        highlight: {
          border: ['color', '#2B7CE9'],
          background: ['color', '#D2E5FF']
        },
        hover: {
          border: ['color', '#2B7CE9'],
          background: ['color', '#D2E5FF']
        }
      },
      fixed: {
        x: false,
        y: false
      },
      font: {
        color: ['color', '#343434'],
        size: [14, 0, 100, 1], // px
        face: ['arial', 'verdana', 'tahoma'],
        background: ['color', 'none'],
        strokeWidth: [0, 0, 50, 1], // px
        strokeColor: ['color', '#ffffff']
      },
      //group: 'string',
      hidden: false,
      labelHighlightBold: true,
      //icon: {
      //  face: 'string',  //'FontAwesome',
      //  code: 'string',  //'\uf007',
      //  size: [50, 0, 200, 1],  //50,
      //  color: ['color','#2B7CE9']   //'#aa00ff'
      //},
      //image: 'string', // --> URL
      physics: true,
      scaling: {
        min: [10, 0, 200, 1],
        max: [30, 0, 200, 1],
        label: {
          enabled: false,
          min: [14, 0, 200, 1],
          max: [30, 0, 200, 1],
          maxVisible: [30, 0, 200, 1],
          drawThreshold: [5, 0, 20, 1]
        }
      },
      shadow: {
        enabled: false,
        color: 'rgba(0,0,0,0.5)',
        size: [10, 0, 20, 1],
        x: [5, -30, 30, 1],
        y: [5, -30, 30, 1]
      },
      shape: ['ellipse', 'box', 'circle', 'database', 'diamond', 'dot', 'square', 'star', 'text', 'triangle', 'triangleDown'],
      shapeProperties: {
        borderDashes: false,
        borderRadius: [6, 0, 20, 1],
        interpolation: true,
        useImageSize: false
      },
      size: [25, 0, 200, 1]
    },
    edges: {
      arrows: {
        to: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' },
        middle: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' },
        from: { enabled: false, scaleFactor: [1, 0, 3, 0.05], type: 'arrow' }
      },
      arrowStrikethrough: true,
      color: {
        color: ['color', '#848484'],
        highlight: ['color', '#848484'],
        hover: ['color', '#848484'],
        inherit: ['from', 'to', 'both', true, false],
        opacity: [1, 0, 1, 0.05]
      },
      dashes: false,
      font: {
        color: ['color', '#343434'],
        size: [14, 0, 100, 1], // px
        face: ['arial', 'verdana', 'tahoma'],
        background: ['color', 'none'],
        strokeWidth: [2, 0, 50, 1], // px
        strokeColor: ['color', '#ffffff'],
        align: ['horizontal', 'top', 'middle', 'bottom']
      },
      hidden: false,
      hoverWidth: [1.5, 0, 5, 0.1],
      labelHighlightBold: true,
      physics: true,
      scaling: {
        min: [1, 0, 100, 1],
        max: [15, 0, 100, 1],
        label: {
          enabled: true,
          min: [14, 0, 200, 1],
          max: [30, 0, 200, 1],
          maxVisible: [30, 0, 200, 1],
          drawThreshold: [5, 0, 20, 1]
        }
      },
      selectionWidth: [1.5, 0, 5, 0.1],
      selfReferenceSize: [20, 0, 200, 1],
      shadow: {
        enabled: false,
        color: 'rgba(0,0,0,0.5)',
        size: [10, 0, 20, 1],
        x: [5, -30, 30, 1],
        y: [5, -30, 30, 1]
      },
      smooth: {
        enabled: true,
        type: ['dynamic', 'continuous', 'discrete', 'diagonalCross', 'straightCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier'],
        forceDirection: ['horizontal', 'vertical', 'none'],
        roundness: [0.5, 0, 1, 0.05]
      },
      width: [1, 0, 30, 1]
    },
    layout: {
      //randomSeed: [0, 0, 500, 1],
      //improvedLayout: true,
      hierarchical: {
        enabled: false,
        levelSeparation: [150, 20, 500, 5],
        nodeSpacing: [100, 20, 500, 5],
        treeSpacing: [200, 20, 500, 5],
        blockShifting: true,
        edgeMinimization: true,
        parentCentralization: true,
        direction: ['UD', 'DU', 'LR', 'RL'],   // UD, DU, LR, RL
        sortMethod: ['hubsize', 'directed'] // hubsize, directed
      }
    },
    interaction: {
      dragNodes: true,
      dragView: true,
      hideEdgesOnDrag: false,
      hideNodesOnDrag: false,
      hover: false,
      keyboard: {
        enabled: false,
        speed: { x: [10, 0, 40, 1], y: [10, 0, 40, 1], zoom: [0.02, 0, 0.1, 0.005] },
        bindToWindow: true
      },
      multiselect: false,
      navigationButtons: false,
      selectable: true,
      selectConnectedEdges: true,
      hoverConnectedEdges: true,
      tooltipDelay: [300, 0, 1000, 25],
      zoomView: true
    },
    manipulation: {
      enabled: false,
      initiallyActive: false
    },
    physics: {
      enabled: true,
      barnesHut: {
        //theta: [0.5, 0.1, 1, 0.05],
        gravitationalConstant: [-2000, -30000, 0, 50],
        centralGravity: [0.3, 0, 10, 0.05],
        springLength: [95, 0, 500, 5],
        springConstant: [0.04, 0, 1.2, 0.005],
        damping: [0.09, 0, 1, 0.01],
        avoidOverlap: [0, 0, 1, 0.01]
      },
      forceAtlas2Based: {
        //theta: [0.5, 0.1, 1, 0.05],
        gravitationalConstant: [-50, -500, 0, 1],
        centralGravity: [0.01, 0, 1, 0.005],
        springLength: [95, 0, 500, 5],
        springConstant: [0.08, 0, 1.2, 0.005],
        damping: [0.4, 0, 1, 0.01],
        avoidOverlap: [0, 0, 1, 0.01]
      },
      repulsion: {
        centralGravity: [0.2, 0, 10, 0.05],
        springLength: [200, 0, 500, 5],
        springConstant: [0.05, 0, 1.2, 0.005],
        nodeDistance: [100, 0, 500, 5],
        damping: [0.09, 0, 1, 0.01]
      },
      hierarchicalRepulsion: {
        centralGravity: [0.2, 0, 10, 0.05],
        springLength: [100, 0, 500, 5],
        springConstant: [0.01, 0, 1.2, 0.005],
        nodeDistance: [120, 0, 500, 5],
        damping: [0.09, 0, 1, 0.01]
      },
      maxVelocity: [50, 0, 150, 1],
      minVelocity: [0.1, 0.01, 0.5, 0.01],
      solver: ['barnesHut', 'forceAtlas2Based', 'repulsion', 'hierarchicalRepulsion'],
      timestep: [0.5, 0.01, 1, 0.01],
      //adaptiveTimestep: true
    }
  };
  
  export {allOptions, configureOptions};
  