{"version":3,"sources":["jsdelivr-header.js","/npm/ngx-treantjs@1.0.1/Treant.js"],"names":[],"mappings":"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","file":"/npm/ngx-treantjs@1.0.1/Treant.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/ngx-treantjs@1.0.1/Treant.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/*\r\n * Treant-js\r\n *\r\n * (c) 2013 Fran Peručić\r\n * Treant-js may be freely distributed under the MIT license.\r\n * For all details and documentation:\r\n * http://fperucic.github.io/treant-js\r\n *\r\n * Treant is an open-source JavaScipt library for visualization of tree diagrams.\r\n * It implements the node positioning algorithm of John Q. Walker II \"Positioning nodes for General Trees\".\r\n *\r\n * References:\r\n * Emilio Cortegoso Lobato: ECOTree.js v1.0 (October 26th, 2006)\r\n *\r\n * Contributors:\r\n * Fran Peručić, https://github.com/fperucic\r\n * Dave Goodchild, https://github.com/dlgoodchild\r\n */\r\n\r\n;( function(exports) {\r\n    // Polyfill for IE to use startsWith\r\n    if (!String.prototype.startsWith) {\r\n        String.prototype.startsWith = function(searchString, position){\r\n            return this.substr(position || 0, searchString.length) === searchString;\r\n        };\r\n    }\r\n\r\n    var $ = null;\r\n\r\n    var UTIL = {\r\n\r\n        /**\r\n         * Directly updates, recursively/deeply, the first object with all properties in the second object\r\n         * @param {object} applyTo\r\n         * @param {object} applyFrom\r\n         * @return {object}\r\n         */\r\n        inheritAttrs: function( applyTo, applyFrom ) {\r\n            for ( var attr in applyFrom ) {\r\n                if ( applyFrom.hasOwnProperty( attr ) ) {\r\n                    if ( ( applyTo[attr] instanceof Object && applyFrom[attr] instanceof Object ) && ( typeof applyFrom[attr] !== 'function' ) ) {\r\n                        this.inheritAttrs( applyTo[attr], applyFrom[attr] );\r\n                    }\r\n                    else {\r\n                        applyTo[attr] = applyFrom[attr];\r\n                    }\r\n                }\r\n            }\r\n            return applyTo;\r\n        },\r\n\r\n        /**\r\n         * Returns a new object by merging the two supplied objects\r\n         * @param {object} obj1\r\n         * @param {object} obj2\r\n         * @returns {object}\r\n         */\r\n        createMerge: function( obj1, obj2 ) {\r\n            var newObj = {};\r\n            if ( obj1 ) {\r\n                this.inheritAttrs( newObj, this.cloneObj( obj1 ) );\r\n            }\r\n            if ( obj2 ) {\r\n                this.inheritAttrs( newObj, obj2 );\r\n            }\r\n            return newObj;\r\n        },\r\n\r\n        /**\r\n         * Takes any number of arguments\r\n         * @returns {*}\r\n         */\r\n        extend: function() {\r\n            if ( $ ) {\r\n                Array.prototype.unshift.apply( arguments, [true, {}] );\r\n                return $.extend.apply( $, arguments );\r\n            }\r\n            else {\r\n                return UTIL.createMerge.apply( this, arguments );\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @param {object} obj\r\n         * @returns {*}\r\n         */\r\n        cloneObj: function ( obj ) {\r\n            if ( Object( obj ) !== obj ) {\r\n                return obj;\r\n            }\r\n            var res = new obj.constructor();\r\n            for ( var key in obj ) {\r\n                if ( obj.hasOwnProperty(key) ) {\r\n                    res[key] = this.cloneObj(obj[key]);\r\n                }\r\n            }\r\n            return res;\r\n        },\r\n\r\n        /**\r\n         * @param {Element} el\r\n         * @param {string} eventType\r\n         * @param {function} handler\r\n         */\r\n        addEvent: function( el, eventType, handler ) {\r\n            if ( $ ) {\r\n                $( el ).on( eventType+'.treant', handler );\r\n            }\r\n            else if ( el.addEventListener ) { // DOM Level 2 browsers\r\n                el.addEventListener( eventType, handler, false );\r\n            }\r\n            else if ( el.attachEvent ) { // IE <= 8\r\n                el.attachEvent( 'on' + eventType, handler );\r\n            }\r\n            else { // ancient browsers\r\n                el['on' + eventType] = handler;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @param {string} selector\r\n         * @param {boolean} raw\r\n         * @param {Element} parentEl\r\n         * @returns {Element|jQuery}\r\n         */\r\n        findEl: function( selector, raw, parentEl ) {\r\n            parentEl = parentEl || document;\r\n\r\n            if ( $ ) {\r\n                var $element = $( selector, parentEl );\r\n                return ( raw? $element.get( 0 ): $element );\r\n            }\r\n            else {\r\n                // todo: getElementsByName()\r\n                // todo: getElementsByTagName()\r\n                // todo: getElementsByTagNameNS()\r\n                if ( selector.charAt( 0 ) === '#' ) {\r\n                    return parentEl.getElementById( selector.substring( 1 ) );\r\n                }\r\n                else if ( selector.charAt( 0 ) === '.' ) {\r\n                    var oElements = parentEl.getElementsByClassName( selector.substring( 1 ) );\r\n                    return ( oElements.length? oElements[0]: null );\r\n                }\r\n\r\n                throw new Error( 'Unknown container element' );\r\n            }\r\n        },\r\n\r\n        getOuterHeight: function( element ) {\r\n            var nRoundingCompensation = 1;\r\n            if ( typeof element.getBoundingClientRect === 'function' ) {\r\n                return element.getBoundingClientRect().height;\r\n            }\r\n            else if ( $ ) {\r\n                return Math.ceil( $( element ).outerHeight() ) + nRoundingCompensation;\r\n            }\r\n            else {\r\n                return Math.ceil(\r\n                    element.clientHeight\r\n                    + UTIL.getStyle( element, 'border-top-width', true )\r\n                    + UTIL.getStyle( element, 'border-bottom-width', true )\r\n                    + UTIL.getStyle( element, 'padding-top', true )\r\n                    + UTIL.getStyle( element, 'padding-bottom', true )\r\n                    + nRoundingCompensation\r\n                );\r\n            }\r\n        },\r\n\r\n        getOuterWidth: function( element ) {\r\n            var nRoundingCompensation = 1;\r\n            if ( typeof element.getBoundingClientRect === 'function' ) {\r\n                return element.getBoundingClientRect().width;\r\n            }\r\n            else if ( $ ) {\r\n                return Math.ceil( $( element ).outerWidth() ) + nRoundingCompensation;\r\n            }\r\n            else {\r\n                return Math.ceil(\r\n                    element.clientWidth\r\n                    + UTIL.getStyle( element, 'border-left-width', true )\r\n                    + UTIL.getStyle( element, 'border-right-width', true )\r\n                    + UTIL.getStyle( element, 'padding-left', true )\r\n                    + UTIL.getStyle( element, 'padding-right', true )\r\n                    + nRoundingCompensation\r\n                );\r\n            }\r\n        },\r\n\r\n        getStyle: function( element, strCssRule, asInt ) {\r\n            var strValue = \"\";\r\n            if ( document.defaultView && document.defaultView.getComputedStyle ) {\r\n                strValue = document.defaultView.getComputedStyle( element, '' ).getPropertyValue( strCssRule );\r\n            }\r\n            else if( element.currentStyle ) {\r\n                strCssRule = strCssRule.replace(/\\-(\\w)/g,\r\n                    function (strMatch, p1){\r\n                        return p1.toUpperCase();\r\n                    }\r\n                );\r\n                strValue = element.currentStyle[strCssRule];\r\n            }\r\n            //Number(elem.style.width.replace(/[^\\d\\.\\-]/g, ''));\r\n            return ( asInt? parseFloat( strValue ): strValue );\r\n        },\r\n\r\n        addClass: function( element, cssClass ) {\r\n            if ( $ ) {\r\n                $( element ).addClass( cssClass );\r\n            }\r\n            else {\r\n                if ( !UTIL.hasClass( element, cssClass ) ) {\r\n                    if ( element.classList ) {\r\n                        element.classList.add( cssClass );\r\n                    }\r\n                    else {\r\n                        element.className += \" \"+cssClass;\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        hasClass: function(element, my_class) {\r\n            return (\" \" + element.className + \" \").replace(/[\\n\\t]/g, \" \").indexOf(\" \"+my_class+\" \") > -1;\r\n        },\r\n\r\n        toggleClass: function ( element, cls, apply ) {\r\n            if ( $ ) {\r\n                $( element ).toggleClass( cls, apply );\r\n            }\r\n            else {\r\n                if ( apply ) {\r\n                    //element.className += \" \"+cls;\r\n                    element.classList.add( cls );\r\n                }\r\n                else {\r\n                    element.classList.remove( cls );\r\n                }\r\n            }\r\n        },\r\n\r\n        setDimensions: function( element, width, height ) {\r\n            if ( $ ) {\r\n                $( element ).width( width ).height( height );\r\n            }\r\n            else {\r\n                element.style.width = width+'px';\r\n                element.style.height = height+'px';\r\n            }\r\n        },\r\n        isjQueryAvailable: function() {return(typeof ($) !== 'undefined' && $);},\r\n    };\r\n\r\n    /**\r\n     * ImageLoader is used for determining if all the images from the Tree are loaded.\r\n     * Node size (width, height) can be correctly determined only when all inner images are loaded\r\n     */\r\n    var ImageLoader = function() {\r\n        this.reset();\r\n    };\r\n\r\n    ImageLoader.prototype = {\r\n\r\n        /**\r\n         * @returns {ImageLoader}\r\n         */\r\n        reset: function() {\r\n            this.loading = [];\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @param {TreeNode} node\r\n         * @returns {ImageLoader}\r\n         */\r\n        processNode: function( node ) {\r\n            var aImages = node.nodeDOM.getElementsByTagName( 'img' );\r\n\r\n            var i = aImages.length;\r\n            while ( i-- ) {\r\n                this.create( node, aImages[i] );\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @returns {ImageLoader}\r\n         */\r\n        removeAll: function( img_src ) {\r\n            var i = this.loading.length;\r\n            while ( i-- ) {\r\n                if ( this.loading[i] === img_src ) {\r\n                    this.loading.splice( i, 1 );\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @param {TreeNode} node\r\n         * @param {Element} image\r\n         * @returns {*}\r\n         */\r\n        create: function ( node, image ) {\r\n            var self = this, source = image.src;\r\n\r\n            function imgTrigger() {\r\n                self.removeAll( source );\r\n                node.width = node.nodeDOM.offsetWidth;\r\n                node.height = node.nodeDOM.offsetHeight;\r\n            }\r\n\r\n            if ( image.src.indexOf( 'data:' ) !== 0 ) {\r\n                this.loading.push( source );\r\n\r\n                if ( image.complete ) {\r\n                    return imgTrigger();\r\n                }\r\n\r\n                UTIL.addEvent( image, 'load', imgTrigger );\r\n                UTIL.addEvent( image, 'error', imgTrigger ); // handle broken url-s\r\n\r\n                // load event is not fired for cached images, force the load event\r\n                image.src += ( ( image.src.indexOf( '?' ) > 0)? '&': '?' ) + new Date().getTime();\r\n            }\r\n            else {\r\n                imgTrigger();\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @returns {boolean}\r\n         */\r\n        isNotLoading: function() {\r\n            return ( this.loading.length === 0 );\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Class: TreeStore\r\n     * TreeStore is used for holding initialized Tree objects\r\n     *  Its purpose is to avoid global variables and enable multiple Trees on the page.\r\n     */\r\n    var TreeStore = {\r\n\r\n        store: [],\r\n\r\n        /**\r\n         * @param {object} jsonConfig\r\n         * @returns {Tree}\r\n         */\r\n        createTree: function( jsonConfig ) {\r\n            var nNewTreeId = this.store.length;\r\n            this.store.push( new Tree( jsonConfig, nNewTreeId ) );\r\n            return this.get( nNewTreeId );\r\n        },\r\n\r\n        /**\r\n         * @param {number} treeId\r\n         * @returns {Tree}\r\n         */\r\n        get: function ( treeId ) {\r\n            return this.store[treeId];\r\n        },\r\n\r\n        /**\r\n         * @param {number} treeId\r\n         * @returns {TreeStore}\r\n         */\r\n        destroy: function( treeId ) {\r\n            var tree = this.get( treeId );\r\n            if ( tree ) {\r\n                tree._R.remove();\r\n                var draw_area = tree.drawArea;\r\n\r\n                while ( draw_area.firstChild ) {\r\n                    draw_area.removeChild( draw_area.firstChild );\r\n                }\r\n\r\n                var classes = draw_area.className.split(' '),\r\n                    classes_to_stay = [];\r\n\r\n                for ( var i = 0; i < classes.length; i++ ) {\r\n                    var cls = classes[i];\r\n                    if ( cls !== 'Treant' && cls !== 'Treant-loaded' ) {\r\n                        classes_to_stay.push(cls);\r\n                    }\r\n                }\r\n                draw_area.style.overflowY = '';\r\n                draw_area.style.overflowX = '';\r\n                draw_area.className = classes_to_stay.join(' ');\r\n\r\n                this.store[treeId] = null;\r\n            }\r\n            return this;\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Tree constructor.\r\n     * @param {object} jsonConfig\r\n     * @param {number} treeId\r\n     * @constructor\r\n     */\r\n    var Tree = function (jsonConfig, treeId ) {\r\n\r\n        /**\r\n         * @param {object} jsonConfig\r\n         * @param {number} treeId\r\n         * @returns {Tree}\r\n         */\r\n        this.reset = function( jsonConfig, treeId ) {\r\n            this.initJsonConfig = jsonConfig;\r\n            this.initTreeId = treeId;\r\n\r\n            this.id = treeId;\r\n\r\n            this.CONFIG = UTIL.extend( Tree.CONFIG, jsonConfig.chart );\r\n            this.drawArea = UTIL.findEl( this.CONFIG.container, true );\r\n            if ( !this.drawArea ) {\r\n                throw new Error( 'Failed to find element by selector \"'+this.CONFIG.container+'\"' );\r\n            }\r\n\r\n            UTIL.addClass( this.drawArea, 'Treant' );\r\n\r\n            // kill of any child elements that may be there\r\n            this.drawArea.innerHTML = '';\r\n\r\n            this.imageLoader = new ImageLoader();\r\n\r\n            this.nodeDB = new NodeDB( jsonConfig.nodeStructure, this );\r\n\r\n            // key store for storing reference to node connectors,\r\n            // key = nodeId where the connector ends\r\n            this.connectionStore = {};\r\n\r\n            this.loaded = false;\r\n\r\n            this._R = new Raphael( this.drawArea, 100, 100 );\r\n\r\n            return this;\r\n        };\r\n\r\n        /**\r\n         * @returns {Tree}\r\n         */\r\n        this.reload = function() {\r\n            this.reset( this.initJsonConfig, this.initTreeId ).redraw();\r\n            return this;\r\n        };\r\n\r\n        this.reset( jsonConfig, treeId );\r\n    };\r\n\r\n    Tree.prototype = {\r\n\r\n        /**\r\n         * @returns {NodeDB}\r\n         */\r\n        getNodeDb: function() {\r\n            return this.nodeDB;\r\n        },\r\n\r\n        /**\r\n         * @param {TreeNode} parentTreeNode\r\n         * @param {object} nodeDefinition\r\n         * @returns {TreeNode}\r\n         */\r\n        addNode: function( parentTreeNode, nodeDefinition ) {\r\n            var dbEntry = this.nodeDB.get( parentTreeNode.id );\r\n\r\n            this.CONFIG.callback.onBeforeAddNode.apply( this, [parentTreeNode, nodeDefinition] );\r\n\r\n            var oNewNode = this.nodeDB.createNode( nodeDefinition, parentTreeNode.id, this );\r\n            oNewNode.createGeometry( this );\r\n\r\n            oNewNode.parent().createSwitchGeometry( this );\r\n\r\n            this.positionTree();\r\n\r\n            this.CONFIG.callback.onAfterAddNode.apply( this, [oNewNode, parentTreeNode, nodeDefinition] );\r\n\r\n            return oNewNode;\r\n        },\r\n\r\n        /**\r\n         * @returns {Tree}\r\n         */\r\n        redraw: function() {\r\n            this.positionTree();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @param {function} callback\r\n         * @returns {Tree}\r\n         */\r\n        positionTree: function( callback ) {\r\n            var self = this;\r\n\r\n            if ( this.imageLoader.isNotLoading() ) {\r\n                var root = this.root(),\r\n                    orient = this.CONFIG.rootOrientation;\r\n\r\n                this.resetLevelData();\r\n\r\n                this.firstWalk( root, 0 );\r\n                this.secondWalk( root, 0, 0, 0 );\r\n\r\n                this.positionNodes();\r\n\r\n                if ( this.CONFIG.animateOnInit ) {\r\n                    setTimeout(\r\n                        function() {\r\n                            root.toggleCollapse();\r\n                        },\r\n                        this.CONFIG.animateOnInitDelay\r\n                    );\r\n                }\r\n\r\n                if ( !this.loaded ) {\r\n                    UTIL.addClass( this.drawArea, 'Treant-loaded' ); // nodes are hidden until .loaded class is added\r\n                    if ( Object.prototype.toString.call( callback ) === \"[object Function]\" ) {\r\n                        callback( self );\r\n                    }\r\n                    self.CONFIG.callback.onTreeLoaded.apply( self, [root] );\r\n                    this.loaded = true;\r\n                }\r\n\r\n            }\r\n            else {\r\n                setTimeout(\r\n                    function() {\r\n                        self.positionTree( callback );\r\n                    }, 10\r\n                );\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * In a first post-order walk, every node of the tree is assigned a preliminary\r\n         * x-coordinate (held in field node->prelim).\r\n         * In addition, internal nodes are given modifiers, which will be used to move their\r\n         * children to the right (held in field node->modifier).\r\n         * @param {TreeNode} node\r\n         * @param {number} level\r\n         * @returns {Tree}\r\n         */\r\n        firstWalk: function( node, level ) {\r\n            node.prelim = null;\r\n            node.modifier = null;\r\n\r\n            this.setNeighbors( node, level );\r\n            this.calcLevelDim( node, level );\r\n\r\n            var leftSibling = node.leftSibling();\r\n\r\n            if ( node.childrenCount() === 0 || level == this.CONFIG.maxDepth ) {\r\n                // set preliminary x-coordinate\r\n                if ( leftSibling ) {\r\n                    node.prelim = leftSibling.prelim + leftSibling.size() + this.CONFIG.siblingSeparation;\r\n                }\r\n                else {\r\n                    node.prelim = 0;\r\n                }\r\n            }\r\n            else {\r\n                //node is not a leaf,  firstWalk for each child\r\n                for ( var i = 0, n = node.childrenCount(); i < n; i++ ) {\r\n                    this.firstWalk(node.childAt(i), level + 1);\r\n                }\r\n\r\n                var midPoint = node.childrenCenter() - node.size() / 2;\r\n\r\n                if ( leftSibling ) {\r\n                    node.prelim = leftSibling.prelim + leftSibling.size() + this.CONFIG.siblingSeparation;\r\n                    node.modifier = node.prelim - midPoint;\r\n                    this.apportion( node, level );\r\n                }\r\n                else {\r\n                    node.prelim = midPoint;\r\n                }\r\n\r\n                // handle stacked children positioning\r\n                if ( node.stackParent ) { // handle the parent of stacked children\r\n                    node.modifier += this.nodeDB.get( node.stackChildren[0] ).size()/2 + node.connStyle.stackIndent;\r\n                }\r\n                else if ( node.stackParentId ) { // handle stacked children\r\n                    node.prelim = 0;\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /*\r\n         * Clean up the positioning of small sibling subtrees.\r\n         * Subtrees of a node are formed independently and\r\n         * placed as close together as possible. By requiring\r\n         * that the subtrees be rigid at the time they are put\r\n         * together, we avoid the undesirable effects that can\r\n         * accrue from positioning nodes rather than subtrees.\r\n         */\r\n        apportion: function (node, level) {\r\n            var firstChild              = node.firstChild(),\r\n                firstChildLeftNeighbor  = firstChild.leftNeighbor(),\r\n                compareDepth            = 1,\r\n                depthToStop             = this.CONFIG.maxDepth - level;\r\n\r\n            while( firstChild && firstChildLeftNeighbor && compareDepth <= depthToStop ) {\r\n                // calculate the position of the firstChild, according to the position of firstChildLeftNeighbor\r\n\r\n                var modifierSumRight    = 0,\r\n                    modifierSumLeft     = 0,\r\n                    leftAncestor        = firstChildLeftNeighbor,\r\n                    rightAncestor       = firstChild;\r\n\r\n                for ( var i = 0; i < compareDepth; i++ ) {\r\n                    leftAncestor = leftAncestor.parent();\r\n                    rightAncestor = rightAncestor.parent();\r\n                    modifierSumLeft += leftAncestor.modifier;\r\n                    modifierSumRight += rightAncestor.modifier;\r\n\r\n                    // all the stacked children are oriented towards right so use right variables\r\n                    if ( rightAncestor.stackParent !== undefined ) {\r\n                        modifierSumRight += rightAncestor.size() / 2;\r\n                    }\r\n                }\r\n\r\n                // find the gap between two trees and apply it to subTrees\r\n                // and mathing smaller gaps to smaller subtrees\r\n\r\n                var totalGap = (firstChildLeftNeighbor.prelim + modifierSumLeft + firstChildLeftNeighbor.size() + this.CONFIG.subTeeSeparation) - (firstChild.prelim + modifierSumRight );\r\n\r\n                if ( totalGap > 0 ) {\r\n                    var subtreeAux = node,\r\n                        numSubtrees = 0;\r\n\r\n                    // count all the subtrees in the LeftSibling\r\n                    while ( subtreeAux && subtreeAux.id !== leftAncestor.id ) {\r\n                        subtreeAux = subtreeAux.leftSibling();\r\n                        numSubtrees++;\r\n                    }\r\n\r\n                    if ( subtreeAux ) {\r\n                        var subtreeMoveAux = node,\r\n                            singleGap = totalGap / numSubtrees;\r\n\r\n                        while ( subtreeMoveAux.id !== leftAncestor.id ) {\r\n                            subtreeMoveAux.prelim += totalGap;\r\n                            subtreeMoveAux.modifier += totalGap;\r\n\r\n                            totalGap -= singleGap;\r\n                            subtreeMoveAux = subtreeMoveAux.leftSibling();\r\n                        }\r\n                    }\r\n                }\r\n\r\n                compareDepth++;\r\n\r\n                firstChild = ( firstChild.childrenCount() === 0 )?\r\n                    node.leftMost(0, compareDepth):\r\n                    firstChild = firstChild.firstChild();\r\n\r\n                if ( firstChild ) {\r\n                    firstChildLeftNeighbor = firstChild.leftNeighbor();\r\n                }\r\n            }\r\n        },\r\n\r\n        /*\r\n         * During a second pre-order walk, each node is given a\r\n         * final x-coordinate by summing its preliminary\r\n         * x-coordinate and the modifiers of all the node's\r\n         * ancestors.  The y-coordinate depends on the height of\r\n         * the tree.  (The roles of x and y are reversed for\r\n         * RootOrientations of EAST or WEST.)\r\n         */\r\n        secondWalk: function( node, level, X, Y ) {\r\n            if ( level <= this.CONFIG.maxDepth ) {\r\n                var xTmp = node.prelim + X,\r\n                    yTmp = Y, align = this.CONFIG.nodeAlign,\r\n                    orient = this.CONFIG.rootOrientation,\r\n                    levelHeight, nodesizeTmp;\r\n\r\n                if (orient === 'NORTH' || orient === 'SOUTH') {\r\n                    levelHeight = this.levelMaxDim[level].height;\r\n                    nodesizeTmp = node.height;\r\n                    if (node.pseudo) {\r\n                        node.height = levelHeight;\r\n                    } // assign a new size to pseudo nodes\r\n                }\r\n                else if (orient === 'WEST' || orient === 'EAST') {\r\n                    levelHeight = this.levelMaxDim[level].width;\r\n                    nodesizeTmp = node.width;\r\n                    if (node.pseudo) {\r\n                        node.width = levelHeight;\r\n                    } // assign a new size to pseudo nodes\r\n                }\r\n\r\n                node.X = xTmp;\r\n\r\n                if (node.pseudo) { // pseudo nodes need to be properly aligned, otherwise position is not correct in some examples\r\n                    if (orient === 'NORTH' || orient === 'WEST') {\r\n                        node.Y = yTmp; // align \"BOTTOM\"\r\n                    }\r\n                    else if (orient === 'SOUTH' || orient === 'EAST') {\r\n                        node.Y = (yTmp + (levelHeight - nodesizeTmp)); // align \"TOP\"\r\n                    }\r\n\r\n                } else {\r\n                    node.Y = ( align === 'CENTER' ) ? (yTmp + (levelHeight - nodesizeTmp) / 2) :\r\n                        ( align === 'TOP' )  ? (yTmp + (levelHeight - nodesizeTmp)) :\r\n                            yTmp;\r\n                }\r\n\r\n                if ( orient === 'WEST' || orient === 'EAST' ) {\r\n                    var swapTmp = node.X;\r\n                    node.X = node.Y;\r\n                    node.Y = swapTmp;\r\n                }\r\n\r\n                if (orient === 'SOUTH' ) {\r\n                    node.Y = -node.Y - nodesizeTmp;\r\n                }\r\n                else if ( orient === 'EAST' ) {\r\n                    node.X = -node.X - nodesizeTmp;\r\n                }\r\n\r\n                if ( node.childrenCount() !== 0 ) {\r\n                    if ( node.id === 0 && this.CONFIG.hideRootNode ) {\r\n                        // ako je root node Hiden onda nemoj njegovu dijecu pomaknut po Y osi za Level separation, neka ona budu na vrhu\r\n                        this.secondWalk(node.firstChild(), level + 1, X + node.modifier, Y);\r\n                    }\r\n                    else {\r\n                        this.secondWalk(node.firstChild(), level + 1, X + node.modifier, Y + levelHeight + this.CONFIG.levelSeparation);\r\n                    }\r\n                }\r\n\r\n                if ( node.rightSibling() ) {\r\n                    this.secondWalk( node.rightSibling(), level, X, Y );\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * position all the nodes, center the tree in center of its container\r\n         * 0,0 coordinate is in the upper left corner\r\n         * @returns {Tree}\r\n         */\r\n        positionNodes: function() {\r\n            var self = this,\r\n                treeSize = {\r\n                    x: self.nodeDB.getMinMaxCoord('X', null, null),\r\n                    y: self.nodeDB.getMinMaxCoord('Y', null, null)\r\n                },\r\n\r\n                treeWidth = treeSize.x.max - treeSize.x.min,\r\n                treeHeight = treeSize.y.max - treeSize.y.min,\r\n\r\n                treeCenter = {\r\n                    x: treeSize.x.max - treeWidth/2,\r\n                    y: treeSize.y.max - treeHeight/2\r\n                };\r\n\r\n            this.handleOverflow(treeWidth, treeHeight);\r\n\r\n            var\r\n                containerCenter = {\r\n                    x: self.drawArea.clientWidth/2,\r\n                    y: self.drawArea.clientHeight/2\r\n                },\r\n\r\n                deltaX = containerCenter.x - treeCenter.x,\r\n                deltaY = containerCenter.y - treeCenter.y,\r\n\r\n                // all nodes must have positive X or Y coordinates, handle this with offsets\r\n                negOffsetX = ((treeSize.x.min + deltaX) <= 0) ? Math.abs(treeSize.x.min) : 0,\r\n                negOffsetY = ((treeSize.y.min + deltaY) <= 0) ? Math.abs(treeSize.y.min) : 0,\r\n                i, len, node;\r\n\r\n            // position all the nodes\r\n            for ( i = 0, len = this.nodeDB.db.length; i < len; i++ ) {\r\n\r\n                node = this.nodeDB.get(i);\r\n\r\n                self.CONFIG.callback.onBeforePositionNode.apply( self, [node, i, containerCenter, treeCenter] );\r\n\r\n                if ( node.id === 0 && this.CONFIG.hideRootNode ) {\r\n                    self.CONFIG.callback.onAfterPositionNode.apply( self, [node, i, containerCenter, treeCenter] );\r\n                    continue;\r\n                }\r\n\r\n                // if the tree is smaller than the draw area, then center the tree within drawing area\r\n                node.X += negOffsetX + ((treeWidth < this.drawArea.clientWidth) ? deltaX : this.CONFIG.padding);\r\n                node.Y += negOffsetY + ((treeHeight < this.drawArea.clientHeight) ? deltaY : this.CONFIG.padding);\r\n\r\n                var collapsedParent = node.collapsedParent(),\r\n                    hidePoint = null;\r\n\r\n                if (collapsedParent) {\r\n                    // position the node behind the connector point of the parent, so future animations can be visible\r\n                    hidePoint = collapsedParent.connectorPoint( true );\r\n                    node.hide(hidePoint);\r\n\r\n                }\r\n                else if (node.positioned) {\r\n                    // node is already positioned,\r\n                    node.show();\r\n                }\r\n                else { // inicijalno stvaranje nodeova, postavi lokaciju\r\n                    node.nodeDOM.style.left = node.X + 'px';\r\n                    node.nodeDOM.style.top = node.Y + 'px';\r\n                    node.positioned = true;\r\n                }\r\n\r\n                if (node.id !== 0 && !(node.parent().id === 0 && this.CONFIG.hideRootNode)) {\r\n                    this.setConnectionToParent(node, hidePoint); // skip the root node\r\n                }\r\n                else if (!this.CONFIG.hideRootNode && node.drawLineThrough) {\r\n                    // drawlinethrough is performed for for the root node also\r\n                    node.drawLineThroughMe();\r\n                }\r\n\r\n                self.CONFIG.callback.onAfterPositionNode.apply( self, [node, i, containerCenter, treeCenter] );\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Create Raphael instance, (optionally set scroll bars if necessary)\r\n         * @param {number} treeWidth\r\n         * @param {number} treeHeight\r\n         * @returns {Tree}\r\n         */\r\n        handleOverflow: function( treeWidth, treeHeight ) {\r\n            var viewWidth = (treeWidth < this.drawArea.clientWidth) ? this.drawArea.clientWidth : treeWidth + this.CONFIG.padding*2,\r\n                viewHeight = (treeHeight < this.drawArea.clientHeight) ? this.drawArea.clientHeight : treeHeight + this.CONFIG.padding*2;\r\n\r\n            this._R.setSize( viewWidth, viewHeight );\r\n\r\n            if ( this.CONFIG.scrollbar === 'resize') {\r\n                UTIL.setDimensions( this.drawArea, viewWidth, viewHeight );\r\n            }\r\n            else if ( !UTIL.isjQueryAvailable() || this.CONFIG.scrollbar === 'native' ) {\r\n\r\n                if ( this.drawArea.clientWidth < treeWidth ) { // is overflow-x necessary\r\n                    this.drawArea.style.overflowX = \"auto\";\r\n                }\r\n\r\n                if ( this.drawArea.clientHeight < treeHeight ) { // is overflow-y necessary\r\n                    this.drawArea.style.overflowY = \"auto\";\r\n                }\r\n            }\r\n            // Fancy scrollbar relies heavily on jQuery, so guarding with if ( $ )\r\n            else if ( this.CONFIG.scrollbar === 'fancy') {\r\n                var jq_drawArea = $( this.drawArea );\r\n                if (jq_drawArea.hasClass('ps-container')) { // znaci da je 'fancy' vec inicijaliziran, treba updateat\r\n                    jq_drawArea.find('.Treant').css({\r\n                        width: viewWidth,\r\n                        height: viewHeight\r\n                    });\r\n\r\n                    jq_drawArea.perfectScrollbar('update');\r\n                }\r\n                else {\r\n                    var mainContainer = jq_drawArea.wrapInner('<div class=\"Treant\"/>'),\r\n                        child = mainContainer.find('.Treant');\r\n\r\n                    child.css({\r\n                        width: viewWidth,\r\n                        height: viewHeight\r\n                    });\r\n\r\n                    mainContainer.perfectScrollbar();\r\n                }\r\n            } // else this.CONFIG.scrollbar == 'None'\r\n\r\n            return this;\r\n        },        \r\n        /**\r\n         * @param {TreeNode} treeNode\r\n         * @param {boolean} hidePoint\r\n         * @returns {Tree}\r\n         */\r\n        setConnectionToParent: function( treeNode, hidePoint ) {\r\n            var stacked = treeNode.stackParentId,\r\n                connLine,\r\n                parent = ( stacked? this.nodeDB.get( stacked ): treeNode.parent() ),\r\n\r\n                pathString = hidePoint?\r\n                    this.getPointPathString(hidePoint):\r\n                    this.getPathString(parent, treeNode, stacked);\r\n\r\n            if ( this.connectionStore[treeNode.id] ) {\r\n                // connector already exists, update the connector geometry\r\n                connLine = this.connectionStore[treeNode.id];\r\n                this.animatePath( connLine, pathString );\r\n            }\r\n            else {\r\n                connLine = this._R.path( pathString );\r\n                this.connectionStore[treeNode.id] = connLine;\r\n\r\n                // don't show connector arrows por pseudo nodes\r\n                if ( treeNode.pseudo ) {\r\n                    delete parent.connStyle.style['arrow-end'];\r\n                }\r\n                if ( parent.pseudo ) {\r\n                    delete parent.connStyle.style['arrow-start'];\r\n                }\r\n\r\n                connLine.attr( parent.connStyle.style );\r\n\r\n                if ( treeNode.drawLineThrough || treeNode.pseudo ) {\r\n                    treeNode.drawLineThroughMe( hidePoint );\r\n                }\r\n            }\r\n            treeNode.connector = connLine;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Create the path which is represented as a point, used for hiding the connection\r\n         * A path with a leading \"_\" indicates the path will be hidden\r\n         * See: http://dmitrybaranovskiy.github.io/raphael/reference.html#Paper.path\r\n         * @param {object} hidePoint\r\n         * @returns {string}\r\n         */\r\n        getPointPathString: function( hidePoint ) {\r\n            return [\"_M\", hidePoint.x, \",\", hidePoint.y, 'L', hidePoint.x, \",\", hidePoint.y, hidePoint.x, \",\", hidePoint.y].join(' ');\r\n        },\r\n\r\n        /**\r\n         * This method relied on receiving a valid Raphael Paper.path.\r\n         * See: http://dmitrybaranovskiy.github.io/raphael/reference.html#Paper.path\r\n         * A pathString is typically in the format of \"M10,20L30,40\"\r\n         * @param path\r\n         * @param {string} pathString\r\n         * @returns {Tree}\r\n         */\r\n        animatePath: function( path, pathString ) {\r\n            if (path.hidden && pathString.charAt(0) !== \"_\") { // path will be shown, so show it\r\n                path.show();\r\n                path.hidden = false;\r\n            }\r\n\r\n            // See: http://dmitrybaranovskiy.github.io/raphael/reference.html#Element.animate\r\n            path.animate(\r\n                {\r\n                    path: pathString.charAt(0) === \"_\"?\r\n                        pathString.substring(1):\r\n                        pathString // remove the \"_\" prefix if it exists\r\n                },\r\n                this.CONFIG.animation.connectorsSpeed,\r\n                this.CONFIG.animation.connectorsAnimation,\r\n                function() {\r\n                    if ( pathString.charAt(0) === \"_\" ) { // animation is hiding the path, hide it at the and of animation\r\n                        path.hide();\r\n                        path.hidden = true;\r\n                    }\r\n                }\r\n            );\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *\r\n         * @param {TreeNode} from_node\r\n         * @param {TreeNode} to_node\r\n         * @param {boolean} stacked\r\n         * @returns {string}\r\n         */\r\n        getPathString: function( from_node, to_node, stacked ) {\r\n            var startPoint = from_node.connectorPoint( true ),\r\n                endPoint = to_node.connectorPoint( false ),\r\n                orientation = this.CONFIG.rootOrientation,\r\n                connType = from_node.connStyle.type,\r\n                P1 = {}, P2 = {};\r\n\r\n            if ( orientation === 'NORTH' || orientation === 'SOUTH' ) {\r\n                P1.y = P2.y = (startPoint.y + endPoint.y) / 2;\r\n\r\n                P1.x = startPoint.x;\r\n                P2.x = endPoint.x;\r\n            }\r\n            else if ( orientation === 'EAST' || orientation === 'WEST' ) {\r\n                P1.x = P2.x = (startPoint.x + endPoint.x) / 2;\r\n\r\n                P1.y = startPoint.y;\r\n                P2.y = endPoint.y;\r\n            }\r\n\r\n            // sp, p1, pm, p2, ep == \"x,y\"\r\n            var sp = startPoint.x+','+startPoint.y, p1 = P1.x+','+P1.y, p2 = P2.x+','+P2.y, ep = endPoint.x+','+endPoint.y,\r\n                pm = (P1.x + P2.x)/2 +','+ (P1.y + P2.y)/2, pathString, stackPoint;\r\n\r\n            if ( stacked ) { // STACKED CHILDREN\r\n\r\n                stackPoint = (orientation === 'EAST' || orientation === 'WEST')?\r\n                endPoint.x+','+startPoint.y:\r\n                startPoint.x+','+endPoint.y;\r\n\r\n                if ( connType === \"step\" || connType === \"straight\" ) {\r\n                    pathString = [\"M\", sp, 'L', stackPoint, 'L', ep];\r\n                }\r\n                else if ( connType === \"curve\" || connType === \"bCurve\" ) {\r\n                    var helpPoint, // used for nicer curve lines\r\n                        indent = from_node.connStyle.stackIndent;\r\n\r\n                    if ( orientation === 'NORTH' ) {\r\n                        helpPoint = (endPoint.x - indent)+','+(endPoint.y - indent);\r\n                    }\r\n                    else if ( orientation === 'SOUTH' ) {\r\n                        helpPoint = (endPoint.x - indent)+','+(endPoint.y + indent);\r\n                    }\r\n                    else if ( orientation === 'EAST' ) {\r\n                        helpPoint = (endPoint.x + indent) +','+startPoint.y;\r\n                    }\r\n                    else if ( orientation === 'WEST' ) {\r\n                        helpPoint = (endPoint.x - indent) +','+startPoint.y;\r\n                    }\r\n                    pathString = [\"M\", sp, 'L', helpPoint, 'S', stackPoint, ep];\r\n                }\r\n\r\n            }\r\n            else {  // NORMAL CHILDREN\r\n                if ( connType === \"step\" ) {\r\n                    pathString = [\"M\", sp, 'L', p1, 'L', p2, 'L', ep];\r\n                }\r\n                else if ( connType === \"curve\" ) {\r\n                    pathString = [\"M\", sp, 'C', p1, p2, ep ];\r\n                }\r\n                else if ( connType === \"bCurve\" ) {\r\n                    pathString = [\"M\", sp, 'Q', p1, pm, 'T', ep];\r\n                }\r\n                else if (connType === \"straight\" ) {\r\n                    pathString = [\"M\", sp, 'L', sp, ep];\r\n                }\r\n            }\r\n\r\n            return pathString.join(\" \");\r\n        },\r\n\r\n        /**\r\n         * Algorithm works from left to right, so previous processed node will be left neighbour of the next node\r\n         * @param {TreeNode} node\r\n         * @param {number} level\r\n         * @returns {Tree}\r\n         */\r\n        setNeighbors: function( node, level ) {\r\n            node.leftNeighborId = this.lastNodeOnLevel[level];\r\n            if ( node.leftNeighborId ) {\r\n                node.leftNeighbor().rightNeighborId = node.id;\r\n            }\r\n            this.lastNodeOnLevel[level] = node.id;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Used for calculation of height and width of a level (level dimensions)\r\n         * @param {TreeNode} node\r\n         * @param {number} level\r\n         * @returns {Tree}\r\n         */\r\n        calcLevelDim: function( node, level ) { // root node is on level 0\r\n            this.levelMaxDim[level] = {\r\n                width: Math.max( this.levelMaxDim[level]? this.levelMaxDim[level].width: 0, node.width ),\r\n                height: Math.max( this.levelMaxDim[level]? this.levelMaxDim[level].height: 0, node.height )\r\n            };\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @returns {Tree}\r\n         */\r\n        resetLevelData: function() {\r\n            this.lastNodeOnLevel = [];\r\n            this.levelMaxDim = [];\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        root: function() {\r\n            return this.nodeDB.get( 0 );\r\n        }\r\n    };\r\n\r\n    /**\r\n     * NodeDB is used for storing the nodes. Each tree has its own NodeDB.\r\n     * @param {object} nodeStructure\r\n     * @param {Tree} tree\r\n     * @constructor\r\n     */\r\n    var NodeDB = function ( nodeStructure, tree ) {\r\n        this.reset( nodeStructure, tree );\r\n    };\r\n\r\n    NodeDB.prototype = {\r\n\r\n        /**\r\n         * @param {object} nodeStructure\r\n         * @param {Tree} tree\r\n         * @returns {NodeDB}\r\n         */\r\n        reset: function( nodeStructure, tree ) {\r\n\r\n            this.db = [];\r\n\r\n            var self = this;\r\n\r\n            /**\r\n             * @param {object} node\r\n             * @param {number} parentId\r\n             */\r\n            function iterateChildren( node, parentId ) {\r\n                var newNode = self.createNode( node, parentId, tree, null );\r\n\r\n                if ( node.children ) {\r\n                    // pseudo node is used for descending children to the next level\r\n                    if ( node.childrenDropLevel && node.childrenDropLevel > 0 ) {\r\n                        while ( node.childrenDropLevel-- ) {\r\n                            // pseudo node needs to inherit the connection style from its parent for continuous connectors\r\n                            var connStyle = UTIL.cloneObj( newNode.connStyle );\r\n                            newNode = self.createNode( 'pseudo', newNode.id, tree, null );\r\n                            newNode.connStyle = connStyle;\r\n                            newNode.children = [];\r\n                        }\r\n                    }\r\n\r\n                    var stack = ( node.stackChildren && !self.hasGrandChildren( node ) )? newNode.id: null;\r\n\r\n                    // children are positioned on separate levels, one beneath the other\r\n                    if ( stack !== null ) {\r\n                        newNode.stackChildren = [];\r\n                    }\r\n\r\n                    for ( var i = 0, len = node.children.length; i < len ; i++ ) {\r\n                        if ( stack !== null ) {\r\n                            newNode =  self.createNode( node.children[i], newNode.id, tree, stack );\r\n                            if ( ( i + 1 ) < len ) {\r\n                                // last node cant have children\r\n                                newNode.children = [];\r\n                            }\r\n                        }\r\n                        else {\r\n                            iterateChildren( node.children[i], newNode.id );\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if ( tree.CONFIG.animateOnInit ) {\r\n                nodeStructure.collapsed = true;\r\n            }\r\n\r\n            iterateChildren( nodeStructure, -1 ); // root node\r\n\r\n            this.createGeometries( tree );\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @param {Tree} tree\r\n         * @returns {NodeDB}\r\n         */\r\n        createGeometries: function( tree ) {\r\n            var i = this.db.length;\r\n\r\n            while ( i-- ) {\r\n                this.get( i ).createGeometry( tree );\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @param {number} nodeId\r\n         * @returns {TreeNode}\r\n         */\r\n        get: function ( nodeId ) {\r\n            return this.db[nodeId]; // get TreeNode by ID\r\n        },\r\n\r\n        /**\r\n         * @param {function} callback\r\n         * @returns {NodeDB}\r\n         */\r\n        walk: function( callback ) {\r\n            var i = this.db.length;\r\n\r\n            while ( i-- ) {\r\n                callback.apply( this, [ this.get( i ) ] );\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *\r\n         * @param {object} nodeStructure\r\n         * @param {number} parentId\r\n         * @param {Tree} tree\r\n         * @param {number} stackParentId\r\n         * @returns {TreeNode}\r\n         */\r\n        createNode: function( nodeStructure, parentId, tree, stackParentId ) {\r\n            var node = new TreeNode( nodeStructure, this.db.length, parentId, tree, stackParentId );\r\n\r\n            this.db.push( node );\r\n\r\n            // skip root node (0)\r\n            if ( parentId >= 0 ) {\r\n                var parent = this.get( parentId );\r\n\r\n                // todo: refactor into separate private method\r\n                if ( nodeStructure.position ) {\r\n                    if ( nodeStructure.position === 'left' ) {\r\n                        parent.children.push( node.id );\r\n                    }\r\n                    else if ( nodeStructure.position === 'right' ) {\r\n                        parent.children.splice( 0, 0, node.id );\r\n                    }\r\n                    else if ( nodeStructure.position === 'center' ) {\r\n                        parent.children.splice( Math.floor( parent.children.length / 2 ), 0, node.id );\r\n                    }\r\n                    else {\r\n                        // edge case when there's only 1 child\r\n                        var position = parseInt( nodeStructure.position );\r\n                        if ( parent.children.length === 1 && position > 0 ) {\r\n                            parent.children.splice( 0, 0, node.id );\r\n                        }\r\n                        else {\r\n                            parent.children.splice(\r\n                                Math.max( position, parent.children.length - 1 ),\r\n                                0, node.id\r\n                            );\r\n                        }\r\n                    }\r\n                }\r\n                else {\r\n                    parent.children.push( node.id );\r\n                }\r\n            }\r\n\r\n            if ( stackParentId ) {\r\n                this.get( stackParentId ).stackParent = true;\r\n                this.get( stackParentId ).stackChildren.push( node.id );\r\n            }\r\n\r\n            return node;\r\n        },\r\n\r\n        getMinMaxCoord: function( dim, parent, MinMax ) { // used for getting the dimensions of the tree, dim = 'X' || 'Y'\r\n            // looks for min and max (X and Y) within the set of nodes\r\n            parent = parent || this.get(0);\r\n\r\n            MinMax = MinMax || { // start with root node dimensions\r\n                    min: parent[dim],\r\n                    max: parent[dim] + ( ( dim === 'X' )? parent.width: parent.height )\r\n                };\r\n\r\n            var i = parent.childrenCount();\r\n\r\n            while ( i-- ) {\r\n                var node = parent.childAt( i ),\r\n                    maxTest = node[dim] + ( ( dim === 'X' )? node.width: node.height ),\r\n                    minTest = node[dim];\r\n\r\n                if ( maxTest > MinMax.max ) {\r\n                    MinMax.max = maxTest;\r\n                }\r\n                if ( minTest < MinMax.min ) {\r\n                    MinMax.min = minTest;\r\n                }\r\n\r\n                this.getMinMaxCoord( dim, node, MinMax );\r\n            }\r\n            return MinMax;\r\n        },\r\n\r\n        /**\r\n         * @param {object} nodeStructure\r\n         * @returns {boolean}\r\n         */\r\n        hasGrandChildren: function( nodeStructure ) {\r\n            var i = nodeStructure.children.length;\r\n            while ( i-- ) {\r\n                if ( nodeStructure.children[i].children ) {\r\n                    return true;\r\n                }\r\n            }\r\n            return false;\r\n        }\r\n    };\r\n\r\n    /**\r\n     * TreeNode constructor.\r\n     * @param {object} nodeStructure\r\n     * @param {number} id\r\n     * @param {number} parentId\r\n     * @param {Tree} tree\r\n     * @param {number} stackParentId\r\n     * @constructor\r\n     */\r\n    var TreeNode = function( nodeStructure, id, parentId, tree, stackParentId ) {\r\n        this.reset( nodeStructure, id, parentId, tree, stackParentId );\r\n    };\r\n\r\n    TreeNode.prototype = {\r\n\r\n        /**\r\n         * @param {object} nodeStructure\r\n         * @param {number} id\r\n         * @param {number} parentId\r\n         * @param {Tree} tree\r\n         * @param {number} stackParentId\r\n         * @returns {TreeNode}\r\n         */\r\n        reset: function( nodeStructure, id, parentId, tree, stackParentId ) {\r\n            this.id = id;\r\n            this.parentId = parentId;\r\n            this.treeId = tree.id;\r\n\r\n            this.prelim = 0;\r\n            this.modifier = 0;\r\n            this.leftNeighborId = null;\r\n\r\n            this.stackParentId = stackParentId;\r\n\r\n            // pseudo node is a node with width=height=0, it is invisible, but necessary for the correct positioning of the tree\r\n            this.pseudo = nodeStructure === 'pseudo' || nodeStructure['pseudo']; // todo: surely if nodeStructure is a scalar then the rest will error:\r\n\r\n            this.meta = nodeStructure.meta || {};\r\n            this.image = nodeStructure.image || null;\r\n\r\n            this.link = UTIL.createMerge( tree.CONFIG.node.link,  nodeStructure.link );\r\n\r\n            this.connStyle = UTIL.createMerge( tree.CONFIG.connectors, nodeStructure.connectors );\r\n            this.connector = null;\r\n\r\n            this.drawLineThrough = nodeStructure.drawLineThrough === false ? false : ( nodeStructure.drawLineThrough || tree.CONFIG.node.drawLineThrough );\r\n\r\n            this.collapsable = nodeStructure.collapsable === false ? false : ( nodeStructure.collapsable || tree.CONFIG.node.collapsable );\r\n            this.collapsed = nodeStructure.collapsed;\r\n\r\n            this.text = nodeStructure.text;\r\n\r\n            // '.node' DIV\r\n            this.nodeInnerHTML = nodeStructure.innerHTML;\r\n            this.nodeHTMLclass = (tree.CONFIG.node.HTMLclass ? tree.CONFIG.node.HTMLclass : '') + // globally defined class for the nodex\r\n                (nodeStructure.HTMLclass ? (' ' + nodeStructure.HTMLclass) : '');       // + specific node class\r\n\r\n            this.nodeHTMLid = nodeStructure.HTMLid;\r\n\r\n            this.children = [];\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @returns {Tree}\r\n         */\r\n        getTree: function() {\r\n            return TreeStore.get( this.treeId );\r\n        },\r\n\r\n        /**\r\n         * @returns {object}\r\n         */\r\n        getTreeConfig: function() {\r\n            return this.getTree().CONFIG;\r\n        },\r\n\r\n        /**\r\n         * @returns {NodeDB}\r\n         */\r\n        getTreeNodeDb: function() {\r\n            return this.getTree().getNodeDb();\r\n        },\r\n\r\n        /**\r\n         * @param {number} nodeId\r\n         * @returns {TreeNode}\r\n         */\r\n        lookupNode: function( nodeId ) {\r\n            return this.getTreeNodeDb().get( nodeId );\r\n        },\r\n\r\n        /**\r\n         * @returns {Tree}\r\n         */\r\n        Tree: function() {\r\n            return TreeStore.get( this.treeId );\r\n        },\r\n\r\n        /**\r\n         * @param {number} nodeId\r\n         * @returns {TreeNode}\r\n         */\r\n        dbGet: function( nodeId ) {\r\n            return this.getTreeNodeDb().get( nodeId );\r\n        },\r\n\r\n        /**\r\n         * Returns the width of the node\r\n         * @returns {float}\r\n         */\r\n        size: function() {\r\n            var orientation = this.getTreeConfig().rootOrientation;\r\n\r\n            if ( this.pseudo ) {\r\n                // prevents separating the subtrees\r\n                return ( -this.getTreeConfig().subTeeSeparation );\r\n            }\r\n\r\n            if ( orientation === 'NORTH' || orientation === 'SOUTH' ) {\r\n                return this.width;\r\n            }\r\n            else if ( orientation === 'WEST' || orientation === 'EAST' ) {\r\n                return this.height;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @returns {number}\r\n         */\r\n        childrenCount: function () {\r\n            return ( ( this.collapsed || !this.children)? 0: this.children.length );\r\n        },\r\n\r\n        /**\r\n         * @param {number} index\r\n         * @returns {TreeNode}\r\n         */\r\n        childAt: function( index ) {\r\n            return this.dbGet( this.children[index] );\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        firstChild: function() {\r\n            return this.childAt( 0 );\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        lastChild: function() {\r\n            return this.childAt( this.children.length - 1 );\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        parent: function() {\r\n            return this.lookupNode( this.parentId );\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        leftNeighbor: function() {\r\n            if ( this.leftNeighborId ) {\r\n                return this.lookupNode( this.leftNeighborId );\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        rightNeighbor: function() {\r\n            if ( this.rightNeighborId ) {\r\n                return this.lookupNode( this.rightNeighborId );\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        leftSibling: function () {\r\n            var leftNeighbor = this.leftNeighbor();\r\n\r\n            if ( leftNeighbor && leftNeighbor.parentId === this.parentId ){\r\n                return leftNeighbor;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        rightSibling: function () {\r\n            var rightNeighbor = this.rightNeighbor();\r\n\r\n            if ( rightNeighbor && rightNeighbor.parentId === this.parentId ) {\r\n                return rightNeighbor;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @returns {number}\r\n         */\r\n        childrenCenter: function () {\r\n            var first = this.firstChild(),\r\n                last = this.lastChild();\r\n\r\n            return ( first.prelim + ((last.prelim - first.prelim) + last.size()) / 2 );\r\n        },\r\n\r\n        /**\r\n         * Find out if one of the node ancestors is collapsed\r\n         * @returns {*}\r\n         */\r\n        collapsedParent: function() {\r\n            var parent = this.parent();\r\n            if ( !parent ) {\r\n                return false;\r\n            }\r\n            if ( parent.collapsed ) {\r\n                return parent;\r\n            }\r\n            return parent.collapsedParent();\r\n        },\r\n\r\n        /**\r\n         * Returns the leftmost child at specific level, (initial level = 0)\r\n         * @param level\r\n         * @param depth\r\n         * @returns {*}\r\n         */\r\n        leftMost: function ( level, depth ) {\r\n            if ( level >= depth ) {\r\n                return this;\r\n            }\r\n            if ( this.childrenCount() === 0 ) {\r\n                return;\r\n            }\r\n\r\n            for ( var i = 0, n = this.childrenCount(); i < n; i++ ) {\r\n                var leftmostDescendant = this.childAt( i ).leftMost( level + 1, depth );\r\n                if ( leftmostDescendant ) {\r\n                    return leftmostDescendant;\r\n                }\r\n            }\r\n        },\r\n\r\n        // returns start or the end point of the connector line, origin is upper-left\r\n        connectorPoint: function(startPoint) {\r\n            var orient = this.Tree().CONFIG.rootOrientation, point = {};\r\n\r\n            if ( this.stackParentId ) { // return different end point if node is a stacked child\r\n                if ( orient === 'NORTH' || orient === 'SOUTH' ) {\r\n                    orient = 'WEST';\r\n                }\r\n                else if ( orient === 'EAST' || orient === 'WEST' ) {\r\n                    orient = 'NORTH';\r\n                }\r\n            }\r\n\r\n            // if pseudo, a virtual center is used\r\n            if ( orient === 'NORTH' ) {\r\n                point.x = (this.pseudo) ? this.X - this.Tree().CONFIG.subTeeSeparation/2 : this.X + this.width/2;\r\n                point.y = (startPoint) ? this.Y + this.height : this.Y;\r\n            }\r\n            else if (orient === 'SOUTH') {\r\n                point.x = (this.pseudo) ? this.X - this.Tree().CONFIG.subTeeSeparation/2 : this.X + this.width/2;\r\n                point.y = (startPoint) ? this.Y : this.Y + this.height;\r\n            }\r\n            else if (orient === 'EAST') {\r\n                point.x = (startPoint) ? this.X : this.X + this.width;\r\n                point.y = (this.pseudo) ? this.Y - this.Tree().CONFIG.subTeeSeparation/2 : this.Y + this.height/2;\r\n            }\r\n            else if (orient === 'WEST') {\r\n                point.x = (startPoint) ? this.X + this.width : this.X;\r\n                point.y =  (this.pseudo) ? this.Y - this.Tree().CONFIG.subTeeSeparation/2 : this.Y + this.height/2;\r\n            }\r\n            return point;\r\n        },\r\n\r\n        /**\r\n         * @returns {string}\r\n         */\r\n        pathStringThrough: function() { // get the geometry of a path going through the node\r\n            var startPoint = this.connectorPoint( true ),\r\n                endPoint = this.connectorPoint( false );\r\n\r\n            return [\"M\", startPoint.x+\",\"+startPoint.y, 'L', endPoint.x+\",\"+endPoint.y].join(\" \");\r\n        },\r\n\r\n        /**\r\n         * @param {object} hidePoint\r\n         */\r\n        drawLineThroughMe: function( hidePoint ) { // hidepoint se proslijedjuje ako je node sakriven zbog collapsed\r\n            var pathString = hidePoint?\r\n                this.Tree().getPointPathString( hidePoint ):\r\n                this.pathStringThrough();\r\n\r\n            this.lineThroughMe = this.lineThroughMe || this.Tree()._R.path(pathString);\r\n\r\n            var line_style = UTIL.cloneObj( this.connStyle.style );\r\n\r\n            delete line_style['arrow-start'];\r\n            delete line_style['arrow-end'];\r\n\r\n            this.lineThroughMe.attr( line_style );\r\n\r\n            if ( hidePoint ) {\r\n                this.lineThroughMe.hide();\r\n                this.lineThroughMe.hidden = true;\r\n            }\r\n        },\r\n\r\n        addSwitchEvent: function( nodeSwitch ) {\r\n            var self = this;\r\n            UTIL.addEvent( nodeSwitch, 'click',\r\n                function( e ) {\r\n                    e.preventDefault();\r\n                    if ( self.getTreeConfig().callback.onBeforeClickCollapseSwitch.apply( self, [ nodeSwitch, e ] ) === false ) {\r\n                        return false;\r\n                    }\r\n\r\n                    self.toggleCollapse();\r\n\r\n                    self.getTreeConfig().callback.onAfterClickCollapseSwitch.apply( self, [ nodeSwitch, e ] );\r\n                }\r\n            );\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        collapse: function() {\r\n            if ( !this.collapsed ) {\r\n                this.toggleCollapse();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        expand: function() {\r\n            if ( this.collapsed ) {\r\n                this.toggleCollapse();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        toggleCollapse: function() {\r\n            var oTree = this.getTree();\r\n\r\n            if ( !oTree.inAnimation ) {\r\n                oTree.inAnimation = true;\r\n\r\n                this.collapsed = !this.collapsed; // toggle the collapse at each click\r\n                UTIL.toggleClass( this.nodeDOM, 'collapsed', this.collapsed );\r\n\r\n                oTree.positionTree();\r\n\r\n                var self = this;\r\n\r\n                setTimeout(\r\n                    function() { // set the flag after the animation\r\n                        oTree.inAnimation = false;\r\n                        oTree.CONFIG.callback.onToggleCollapseFinished.apply( oTree, [ self, self.collapsed ] );\r\n                    },\r\n                    ( oTree.CONFIG.animation.nodeSpeed > oTree.CONFIG.animation.connectorsSpeed )?\r\n                        oTree.CONFIG.animation.nodeSpeed:\r\n                        oTree.CONFIG.animation.connectorsSpeed\r\n                );\r\n            }\r\n            return this;\r\n        },\r\n\r\n        hide: function( collapse_to_point ) {\r\n            collapse_to_point = collapse_to_point || false;\r\n\r\n            var bCurrentState = this.hidden;\r\n            this.hidden = true;\r\n\r\n            this.nodeDOM.style.overflow = 'hidden';\r\n\r\n            var tree = this.getTree(),\r\n                config = this.getTreeConfig(),\r\n                oNewState = {\r\n                    opacity: 0\r\n                };\r\n\r\n            if ( collapse_to_point ) {\r\n                oNewState.left = collapse_to_point.x;\r\n                oNewState.top = collapse_to_point.y;\r\n            }\r\n\r\n            // if parent was hidden in initial configuration, position the node behind the parent without animations\r\n            if ( !this.positioned || bCurrentState ) {\r\n                this.nodeDOM.style.visibility = 'hidden';\r\n                if ( $ ) {\r\n                    $( this.nodeDOM ).css( oNewState );\r\n                }\r\n                else {\r\n                    this.nodeDOM.style.left = oNewState.left + 'px';\r\n                    this.nodeDOM.style.top = oNewState.top + 'px';\r\n                }\r\n                this.positioned = true;\r\n            }\r\n            else {\r\n                // todo: fix flashy bug when a node is manually hidden and tree.redraw is called.\r\n                if ( $ ) {\r\n                    $( this.nodeDOM ).animate(\r\n                        oNewState, config.animation.nodeSpeed, config.animation.nodeAnimation,\r\n                        function () {\r\n                            this.style.visibility = 'hidden';\r\n                        }\r\n                    );\r\n                }\r\n                else {\r\n                    this.nodeDOM.style.transition = 'all '+config.animation.nodeSpeed+'ms ease';\r\n                    this.nodeDOM.style.transitionProperty = 'opacity, left, top';\r\n                    this.nodeDOM.style.opacity = oNewState.opacity;\r\n                    this.nodeDOM.style.left = oNewState.left + 'px';\r\n                    this.nodeDOM.style.top = oNewState.top + 'px';\r\n                    this.nodeDOM.style.visibility = 'hidden';\r\n                }\r\n            }\r\n\r\n            // animate the line through node if the line exists\r\n            if ( this.lineThroughMe ) {\r\n                var new_path = tree.getPointPathString( collapse_to_point );\r\n                if ( bCurrentState ) {\r\n                    // update without animations\r\n                    this.lineThroughMe.attr( { path: new_path } );\r\n                }\r\n                else {\r\n                    // update with animations\r\n                    tree.animatePath( this.lineThroughMe, tree.getPointPathString( collapse_to_point ) );\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        hideConnector: function() {\r\n            var oTree = this.Tree();\r\n            var oPath = oTree.connectionStore[this.id];\r\n            if ( oPath ) {\r\n                oPath.animate(\r\n                    { 'opacity': 0 },\r\n                    oTree.CONFIG.animation.connectorsSpeed,\r\n                    oTree.CONFIG.animation.connectorsAnimation\r\n                );\r\n            }\r\n            return this;\r\n        },\r\n\r\n        show: function() {\r\n            var bCurrentState = this.hidden;\r\n            this.hidden = false;\r\n\r\n            this.nodeDOM.style.visibility = 'visible';\r\n\r\n            var oTree = this.Tree();\r\n\r\n            var oNewState = {\r\n                    left: this.X,\r\n                    top: this.Y,\r\n                    opacity: 1\r\n                },\r\n                config = this.getTreeConfig();\r\n\r\n            // if the node was hidden, update opacity and position\r\n            if ( $ ) {\r\n                $( this.nodeDOM ).animate(\r\n                    oNewState,\r\n                    config.animation.nodeSpeed, config.animation.nodeAnimation,\r\n                    function () {\r\n                        // $.animate applies \"overflow:hidden\" to the node, remove it to avoid visual problems\r\n                        this.style.overflow = \"\";\r\n                    }\r\n                );\r\n            }\r\n            else {\r\n                this.nodeDOM.style.transition = 'all '+config.animation.nodeSpeed+'ms ease';\r\n                this.nodeDOM.style.transitionProperty = 'opacity, left, top';\r\n                this.nodeDOM.style.left = oNewState.left + 'px';\r\n                this.nodeDOM.style.top = oNewState.top + 'px';\r\n                this.nodeDOM.style.opacity = oNewState.opacity;\r\n                this.nodeDOM.style.overflow = '';\r\n            }\r\n\r\n            if ( this.lineThroughMe ) {\r\n                this.getTree().animatePath( this.lineThroughMe, this.pathStringThrough() );\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @returns {TreeNode}\r\n         */\r\n        showConnector: function() {\r\n            var oTree = this.Tree();\r\n            var oPath = oTree.connectionStore[this.id];\r\n            if ( oPath ) {\r\n                oPath.animate(\r\n                    { 'opacity': 1 },\r\n                    oTree.CONFIG.animation.connectorsSpeed,\r\n                    oTree.CONFIG.animation.connectorsAnimation\r\n                );\r\n            }\r\n            return this;\r\n        }\r\n    };\r\n\r\n\r\n    /**\r\n     * Build a node from the 'text' and 'img' property and return with it.\r\n     *\r\n     * The node will contain all the fields that present under the 'text' property\r\n     * Each field will refer to a css class with name defined as node-{$property_name}\r\n     *\r\n     * Example:\r\n     * The definition:\r\n     *\r\n     *   text: {\r\n     *     desc: \"some description\",\r\n     *     paragraph: \"some text\"\r\n     *   }\r\n     *\r\n     * will generate the following elements:\r\n     *\r\n     *   <p class=\"node-desc\">some description</p>\r\n     *   <p class=\"node-paragraph\">some text</p>\r\n     *\r\n     * @Returns the configured node\r\n     */\r\n    TreeNode.prototype.buildNodeFromText = function (node) {\r\n        // IMAGE\r\n        if (this.image) {\r\n            image = document.createElement('img');\r\n            image.src = this.image;\r\n            node.appendChild(image);\r\n        }\r\n\r\n        // TEXT\r\n        if (this.text) {\r\n            for (var key in this.text) {\r\n                // adding DATA Attributes to the node\r\n                if (key.startsWith(\"data-\")) {\r\n                    node.setAttribute(key, this.text[key]);\r\n                } else {\r\n                    \r\n                    var textElement = document.createElement(this.text[key].href ? 'a' : 'p');\r\n                    \r\n                    // make an <a> element if required\r\n                    if (this.text[key].href) {\r\n                        textElement.href = this.text[key].href;\r\n                        if (this.text[key].target) {\r\n                            textElement.target = this.text[key].target;\r\n                        }\r\n                    }\r\n                    \r\n                    textElement.className =  \"node-\"+key;\r\n                    textElement.appendChild(document.createTextNode(\r\n                        this.text[key].val ? this.text[key].val :\r\n                        this.text[key] instanceof Object ? \"'val' param missing!\" : this.text[key]\r\n                    )\r\n                    );\r\n                    \r\n                    node.appendChild(textElement);\r\n                }\r\n            }\r\n        }\r\n        return node;\r\n    };\r\n\r\n    /**\r\n     * Build a node from  'nodeInnerHTML' property that defines an existing HTML element, referenced by it's id, e.g: #someElement\r\n     * Change the text in the passed node to 'Wrong ID selector' if the referenced element does ot exist,\r\n     * return with a cloned and configured node otherwise\r\n     *\r\n     * @Returns node the configured node\r\n     */\r\n    TreeNode.prototype.buildNodeFromHtml = function(node) {\r\n        // get some element by ID and clone its structure into a node\r\n        if (this.nodeInnerHTML.charAt(0) === \"#\") {\r\n            var elem = document.getElementById(this.nodeInnerHTML.substring(1));\r\n            if (elem) {\r\n                node = elem.cloneNode(true);\r\n                node.id += \"-clone\";\r\n                node.className += \" node\";\r\n            }\r\n            else {\r\n                node.innerHTML = \"<b> Wrong ID selector </b>\";\r\n            }\r\n        }\r\n        else {\r\n            // insert your custom HTML into a node\r\n            node.innerHTML = this.nodeInnerHTML;\r\n        }\r\n        return node;\r\n    };\r\n\r\n    /**\r\n     * @param {Tree} tree\r\n     */\r\n    TreeNode.prototype.createGeometry = function( tree ) {\r\n        if ( this.id === 0 && tree.CONFIG.hideRootNode ) {\r\n            this.width = 0;\r\n            this.height = 0;\r\n            return;\r\n        }\r\n\r\n        var drawArea = tree.drawArea,\r\n            image,\r\n\r\n            /////////// CREATE NODE //////////////\r\n            node = document.createElement( this.link.href? 'a': 'div' );\r\n\r\n        node.className = ( !this.pseudo )? TreeNode.CONFIG.nodeHTMLclass: 'pseudo';\r\n        if ( this.nodeHTMLclass && !this.pseudo ) {\r\n            node.className += ' ' + this.nodeHTMLclass;\r\n        }\r\n\r\n        if ( this.nodeHTMLid ) {\r\n            node.id = this.nodeHTMLid;\r\n        }\r\n\r\n        if ( this.link.href ) {\r\n            node.href = this.link.href;\r\n            node.target = this.link.target;\r\n        }\r\n\r\n        if ( $ ) {\r\n            $( node ).data( 'treenode', this );\r\n        }\r\n        else {\r\n            node.data = {\r\n                'treenode': this\r\n            };\r\n        }\r\n\r\n        /////////// BUILD NODE CONTENT //////////////\r\n        if ( !this.pseudo ) {\r\n            node = this.nodeInnerHTML? this.buildNodeFromHtml(node) : this.buildNodeFromText(node)\r\n\r\n            // handle collapse switch\r\n            if ( this.collapsed || (this.collapsable && this.childrenCount() && !this.stackParentId) ) {\r\n                this.createSwitchGeometry( tree, node );\r\n            }\r\n        }\r\n\r\n        tree.CONFIG.callback.onCreateNode.apply( tree, [this, node] );\r\n\r\n        /////////// APPEND all //////////////\r\n        drawArea.appendChild(node);\r\n\r\n        this.width = node.offsetWidth;\r\n        this.height = node.offsetHeight;\r\n\r\n        this.nodeDOM = node;\r\n\r\n        tree.imageLoader.processNode(this);\r\n    };\r\n\r\n    /**\r\n     * @param {Tree} tree\r\n     * @param {Element} nodeEl\r\n     */\r\n    TreeNode.prototype.createSwitchGeometry = function( tree, nodeEl ) {\r\n        nodeEl = nodeEl || this.nodeDOM;\r\n\r\n        // safe guard and check to see if it has a collapse switch\r\n        var nodeSwitchEl = UTIL.findEl( '.collapse-switch', true, nodeEl );\r\n        if ( !nodeSwitchEl ) {\r\n            nodeSwitchEl = document.createElement( 'a' );\r\n            nodeSwitchEl.className = \"collapse-switch\";\r\n\r\n            nodeEl.appendChild( nodeSwitchEl );\r\n            this.addSwitchEvent( nodeSwitchEl );\r\n            if ( this.collapsed ) {\r\n                nodeEl.className += \" collapsed\";\r\n            }\r\n\r\n            tree.CONFIG.callback.onCreateNodeCollapseSwitch.apply( tree, [this, nodeEl, nodeSwitchEl] );\r\n        }\r\n        return nodeSwitchEl;\r\n    };\r\n\r\n\r\n    // ###########################################\r\n    //      Expose global + default CONFIG params\r\n    // ###########################################\r\n\r\n\r\n    Tree.CONFIG = {\r\n        maxDepth: 100,\r\n        rootOrientation: 'NORTH', // NORTH || EAST || WEST || SOUTH\r\n        nodeAlign: 'CENTER', // CENTER || TOP || BOTTOM\r\n        levelSeparation: 30,\r\n        siblingSeparation: 30,\r\n        subTeeSeparation: 30,\r\n\r\n        hideRootNode: false,\r\n\r\n        animateOnInit: false,\r\n        animateOnInitDelay: 500,\r\n\r\n        padding: 15, // the difference is seen only when the scrollbar is shown\r\n        scrollbar: 'native', // \"native\" || \"fancy\" || \"None\" (PS: \"fancy\" requires jquery and perfect-scrollbar)\r\n\r\n        connectors: {\r\n            type: 'curve', // 'curve' || 'step' || 'straight' || 'bCurve'\r\n            style: {\r\n                stroke: 'black'\r\n            },\r\n            stackIndent: 15\r\n        },\r\n\r\n        node: { // each node inherits this, it can all be overridden in node config\r\n\r\n            // HTMLclass: 'node',\r\n            // drawLineThrough: false,\r\n            // collapsable: false,\r\n            link: {\r\n                target: '_self'\r\n            }\r\n        },\r\n\r\n        animation: { // each node inherits this, it can all be overridden in node config\r\n            nodeSpeed: 450,\r\n            nodeAnimation: 'linear',\r\n            connectorsSpeed: 450,\r\n            connectorsAnimation: 'linear'\r\n        },\r\n\r\n        callback: {\r\n            onCreateNode: function( treeNode, treeNodeDom ) {}, // this = Tree\r\n            onCreateNodeCollapseSwitch: function( treeNode, treeNodeDom, switchDom ) {}, // this = Tree\r\n            onAfterAddNode: function( newTreeNode, parentTreeNode, nodeStructure ) {}, // this = Tree\r\n            onBeforeAddNode: function( parentTreeNode, nodeStructure ) {}, // this = Tree\r\n            onAfterPositionNode: function( treeNode, nodeDbIndex, containerCenter, treeCenter) {}, // this = Tree\r\n            onBeforePositionNode: function( treeNode, nodeDbIndex, containerCenter, treeCenter) {}, // this = Tree\r\n            onToggleCollapseFinished: function ( treeNode, bIsCollapsed ) {}, // this = Tree\r\n            onAfterClickCollapseSwitch: function( nodeSwitch, event ) {}, // this = TreeNode\r\n            onBeforeClickCollapseSwitch: function( nodeSwitch, event ) {}, // this = TreeNode\r\n            onTreeLoaded: function( rootTreeNode ) {} // this = Tree\r\n        }\r\n    };\r\n\r\n    TreeNode.CONFIG = {\r\n        nodeHTMLclass: 'node'\r\n    };\r\n\r\n    // #############################################\r\n    // Makes a JSON chart config out of Array config\r\n    // #############################################\r\n\r\n    var JSONconfig = {\r\n        make: function( configArray ) {\r\n\r\n            var i = configArray.length, node;\r\n\r\n            this.jsonStructure = {\r\n                chart: null,\r\n                nodeStructure: null\r\n            };\r\n            //fist loop: find config, find root;\r\n            while(i--) {\r\n                node = configArray[i];\r\n                if (node.hasOwnProperty('container')) {\r\n                    this.jsonStructure.chart = node;\r\n                    continue;\r\n                }\r\n\r\n                if (!node.hasOwnProperty('parent') && ! node.hasOwnProperty('container')) {\r\n                    this.jsonStructure.nodeStructure = node;\r\n                    node._json_id = 0;\r\n                }\r\n            }\r\n\r\n            this.findChildren(configArray);\r\n\r\n            return this.jsonStructure;\r\n        },\r\n\r\n        findChildren: function(nodes) {\r\n            var parents = [0]; // start with a a root node\r\n\r\n            while(parents.length) {\r\n                var parentId = parents.pop(),\r\n                    parent = this.findNode(this.jsonStructure.nodeStructure, parentId),\r\n                    i = 0, len = nodes.length,\r\n                    children = [];\r\n\r\n                for(;i<len;i++) {\r\n                    var node = nodes[i];\r\n                    if(node.parent && (node.parent._json_id === parentId)) { // skip config and root nodes\r\n\r\n                        node._json_id = this.getID();\r\n\r\n                        delete node.parent;\r\n\r\n                        children.push(node);\r\n                        parents.push(node._json_id);\r\n                    }\r\n                }\r\n\r\n                if (children.length) {\r\n                    parent.children = children;\r\n                }\r\n            }\r\n        },\r\n\r\n        findNode: function( node, nodeId ) {\r\n            var childrenLen, found;\r\n\r\n            if (node._json_id === nodeId) {\r\n                return node;\r\n            }\r\n            else if ( node.children ) {\r\n                childrenLen = node.children.length;\r\n                while ( childrenLen-- ) {\r\n                    found = this.findNode(node.children[childrenLen], nodeId);\r\n                    if ( found ) {\r\n                        return found;\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        getID: (\r\n            function() {\r\n                var i = 1;\r\n                return function() {\r\n                    return i++;\r\n                };\r\n            }\r\n        )()\r\n    };\r\n\r\n    /**\r\n     * Chart constructor.\r\n     */\r\n    var Treant = function( jsonConfig, callback, jQuery ) {\r\n        if ( jsonConfig instanceof Array ) {\r\n            jsonConfig = JSONconfig.make( jsonConfig );\r\n        }\r\n\r\n        // optional\r\n        if ( jQuery ) {\r\n            $ = jQuery;\r\n        }\r\n\r\n        this.tree = TreeStore.createTree( jsonConfig );\r\n        this.tree.positionTree( callback );\r\n    };\r\n\r\n    Treant.prototype.destroy = function() {\r\n        TreeStore.destroy( this.tree.id );\r\n    };\r\n\r\n    /* expose constructor globaly */\r\n    exports.Treant = Treant;\r\n\r\n})( this.hasOwnProperty('window') ? window: module.exports );"]}