(function(){
	function Graph(settings){
		this.opt = $.extend({
			con:"",     //画布的容器id
			width:"",   //画布的宽度
			height:"",   //画布的高度
			linkDistance:100,
			charge: -2000, //正数为引力，负数为斥力
		},settings);
	}
	Graph.prototype = {
		para:{
			svg:null,
			graph:null,
			simulation:null, //引力布局
			zoomFactor:{k:1,tx:0,ty:0},
			data:null,
			loop:[],
			isHover:false,
			type:""
		},
		option:{
			type:{
				company:"C",
				people:"P"
			},
			line:{
				straight:{
					solid:{
						dashArray:"1,0"
					},
					dotted:{
						dashArray:"2,2"
					}
				}
			},
			arrow:[
		        {
					type:"C",
					fill:"#00b591"
				},
				{
					type:"P",
					fill:"#00b591"
				},
				{
					type:"CDB",
					fill:"#00BFFF"
				}
			],
			opcaity:{
				nodes:{
					weak:0.3,
					strong:1
				},
				links:{
					weak:0.1,
					strong:1
				}
			}
		},
		constructor:Graph,
		/*
		 *  初始化
		 */
		init:function(){
			var self = this;
			//初始化svg画布
			self.para.svg = d3.select("#"+self.opt.con)
			             .append("svg")
			             .attr("viewBox", "0 0 " + self.opt.width + " " + self.opt.height )
			             .attr("width",self.opt.width)
			             .attr("height",self.opt.height);
			//设置node，link，linkText的group
			self.para.graph = self.para.svg.append("g").attr("class","graph");
			self.para.graph.append("g").attr("class","links");
			self.para.graph.append("g").attr("class","nodes");
			self.para.graph.append("g").attr("class","linkTexts");
			self.para.graph.append("g").attr("class","nodeLabels");
			//初始化引力布局
			self.para.simulation = d3.forceSimulation()
									 //.alphaDecay([0.01])							     
								     .force("charge", d3.forceManyBody().strength(function(d){
										return self.opt.charge;
								     }))
								     .force("center", d3.forceCenter(self.opt.width / 2, self.opt.height / 2));
			//定义箭头,分为三种类型，实线、虚线、自连接
			self.para.svg.append("defs").selectAll("marker")
					    .data(self.option.arrow)
					    .enter().append("marker")
					    .attr("id", function(d) { return d.type; })
					    .attr("viewBox", "-1 -6 12 12")
					    .attr("refX", function(d){
					    	if(d.type=="C" || d.type=="CDB"){
					    		return 48;
					    	}else{
					    		return 32;
					    	}
					    })
					    //.attr("refY", -1.5)
					    .attr("markerWidth", 8)
					    .attr("markerHeight", 8)
					    .attr("orient", "auto")
					    .append("path")
					    .attr("d", "M10,0L0,5L0,-5L10,0")
					    .attr("fill", function(d){
					    	return d.fill;
					    })
					    .attr("stroke-width", 1)
					    .attr("stroke",function(d){
					    	return d.fill
					    });
			self.zoom(true);
			self.bind();
		},
		bind:function(){
			var self = this;
			_.MessageManager.on("hoverLoop",function($ev,data){
				self.hoverLoop(data);
			});
			self.para.svg.on("click",function(){
				if(self.para.isHover){
					self.para.graph.selectAll(".node").attr("opacity",1);
					self.para.graph.selectAll(".node").select("circle").attr("fill",function(d){
						if(d.type==self.option.type.company){
							if(d.isDB==0){
								return "#CCEEFF";
							}else if(d.isDB==1){
								return "#00BFFF";
							}
						}else if(d.type==self.option.type.people){
							return "#CCEEFF";
						}else{ 
							return "#CCEEFF";
						}
					});
					self.para.graph.selectAll(".link").attr("opacity",1);
					self.para.isHover = false;
					_.MessageManager.fire("clearSelect");
				}
			})
		},
		hoverLoop:function(data){
			var self = this;
			self.para.isHover = true;
			/*
			var originData = self.clone(self.para.data);
			var loopData = originData[data.name];
			var nodeIds = [], linkIds = [];
			var index = [];
			for(var i=0;i<loopData.length;i++){
				for(var j=0;j<loopData[i].length;j++){
					if(data.id==loopData[i][j].id){
						index.push(i);
						break;
					}
				}
			}
			for(var i=0;i<loopData.length;i++){
				if(index.indexOf(i)>=0){
					for(var j=0;j<loopData[i].length-1;j++){
						if(nodeIds.indexOf(loopData[i][j].id)<0){
							nodeIds.push(loopData[i][j].id);
						}
						var linkId;
						if(j==loopData[i].length-1){
							linkId = loopData[i][j].id+loopData[i][0].id;
						}else{
							linkId = loopData[i][j].id+loopData[i][j+1].id;
						}
						if(linkIds.indexOf(linkId)<0){
							linkIds.push(linkId);
						}
					}
				}
			}
			*/
			var linkIds = ["21","1","88","7","6","2"];
			var nodeIds = ["25","34","15","1","2","6","7","8"];
			self.para.graph.selectAll(".node").attr("opacity",function(d){
				if(nodeIds.indexOf(d.id)>=0){
					return 1;
				}else{
					return 0.2;
				}
			});
			/*
			self.para.graph.selectAll(".node").select("circle").attr("fill",function(d){
				if(d.id==data.id){
					return "#3f51b5";
				}else if(d.type==self.option.type.company){
					if(d.isDB==0){
						return "#00b591";
					}else if(d.isDB==1){
						return "#00BFFF";
					}
				}else if(d.type==self.option.type.people){
					return "#f66800";
				}else{ 
					return "#f66800";
				}
			});
				*/
			self.para.graph.selectAll(".link").attr("opacity",function(d){
				/*
				if(linkIds.indexOf(d.id)>=0){
					return 1;
				}else{
					return 0.05;
				}
				*/
				console.log(d.source);
				if(d.id == "7111"){
					return 0.05;
				}
				if(nodeIds.indexOf(d.source.id)>=0&&nodeIds.indexOf(d.target.id)>=0){
					return 1;
				}else{
					return 0.05;
				}
			});
		},
		/*
		 *  初始化关系图缩放功能
		 *  
		 *  放大原理：<x*k + tx , y*k + ty>
		 *  初始值为： k = 1, tx = ty = 0.
		 *  每次放大通过改变k,tx,ty的数值实现元素的缩放，位置改变
		 *  
		 */
		zoom:function(isZoom){
			var self = this;
			if(isZoom == true){
				self.para.svg.call(d3.zoom().scaleExtent([1/10,8]).on("zoom",function(){
					self.para.graph.attr("transform",d3.event.transform);
					//保存放大参数
					self.para.zoomFactor.k = d3.event.transform.k;
					self.para.zoomFactor.tx = d3.event.transform.x;
					self.para.zoomFactor.ty = d3.event.transform.y;
				}))
				.on("dblclick.zoom", null);
			}else{
				self.para.svg.on(".zoom", null);
			}
		},
		/*
		 *  读取数据
		 *  @param url 后台接口地址
		 */
		loadData:function(url,num,type){
			var self = this;
			self.para.type = type;
			//$.post(url,{num:num,DB:type},function(result){
			var result = {data:null};
			result.data = [
			     {
			    	 order:"001",
			    	 data:{
			    	       node:[
			    	               {id:"1",name:"刘员工",type:"P"},
					               {id:"2",name:"C013",type:"Order"},
					               {id:"3",name:"car1",type:"Car"},
					               {id:"4",name:"card1",type:"Card"},
					               {id:"5",name:"13310131101",type:"Phone"}
			    	             ],
			     		   link:[
			     		         
			     		         ]
			    	 }
			     }
	        ];
				console.log(result);
				if(type=="gsdb"){
					$.post(url,{num:num,DB:"db"},function(dbData){
						console.log(result);
						console.log(dbData);
						var dbNodesId = [];
						for(var i=0;i<dbData.data.length;i++){
							for(var j=0;j<dbData.data[i].length;j++){
								for(var k=0;k<dbData.data[i][j].length;k++){
									var dbNodeId = dbData.data[i][j][k].id;
									if(dbNodesId.indexOf(dbNodeId)<0){
										dbNodesId.push(dbNodeId);
									}
								}
							}
						}
						console.log(dbNodesId);
						for(var i=0;i<result.data.length;i++){
							for(var j=0;j<result.data[i].length;j++){
								for(var k=0;k<result.data[i][j].length;k++){
									var dbNodeId = result.data[i][j][k].id;
									if(dbNodesId.indexOf(dbNodeId)>=0){
										result.data[i][j][k].isDB = 1;
									}else{
										result.data[i][j][k].isDB = 0;
									}
								}
							}
						}
						console.log(result);
						self.preProcess(result);
					});
				}else{
					for(var i=0;i<result.data.length;i++){
						for(var j=0;j<result.data[i].length;j++){
							for(var k=0;k<result.data[i][j].length;k++){
								if(type == "gs"){
									result.data[i][j][k].isDB = 0;
								}else if(type == "db"){ 
									result.data[i][j][k].isDB = 1;
								}
							}
						}
					}
					self.preProcess(result);
				}
			//},"json");
		},
		preProcess:function(list){
			var self = this;
			var data = new Object();
			for(var i=0;i<list.data.length;i++){
				data["Group"+(i+1)] = self.clone(list.data[i]);
				self.para.loop.push("Group"+(i+1));
			}			
			self.para.data = self.clone(data);
			self.updateData(self.para.loop);
			
			var json = {
					data:self.clone(data),
					list:list.tableList
			}
			
			_.MessageManager.fire("addInfoList",json);
		},
		clear:function(){
			var self = this;
			self.para.graph.select(".links").selectAll("*").remove();
			self.para.graph.select(".nodes").selectAll("*").remove();
			self.para.loop.splice(0,self.para.loop.length);
			self.para.isHover = false;
			self.para.data = null;
			self.para.type = "";
		},
		updateData:function(list){
			var self = this;
			var graph = {nodes:[],links:[]};
			
			var nodeIds = [],linkIds = [];//node和link的集合，用来去重
			var data = self.clone(self.para.data);
			for(var prop in data){
				if(list.indexOf(prop)>=0){//选择需要画出的group
					for(var i=0;i<data[prop].length;i++){
						var oneList = data[prop][i];//一个loop
						for(var j=0;j<oneList.length-1;j++){
							//添加node
							if(nodeIds.indexOf(oneList[j].id)<0){//去重
								nodeIds.push(oneList[j].id);
								var oneNode = self.clone(oneList[j]);
								oneNode.group = prop;
								graph.nodes.push(oneNode);
							}
							//添加link
							var source = oneList[j].id;
							var target = "";
							if(j==oneList.length-1){
								target = oneList[0].id;
							}else{
								target = oneList[j+1].id;
							}
							if(linkIds.indexOf(source+target)<0){//去重
								graph.links.push({
									id:source+target,
									source:source,
									target:target,
									rel:[]
								});
								linkIds.push(source+target);
							}
						}
					}
				}
			}
			
		
			graph.nodes = [
			               	{id:"1",name:"袁弘",type:"P"},
			               	{id:"2",name:"C056",type:"Order"},
			               	{id:"3",name:"car1",type:"Car"},
			               	{id:"4",name:"C087",type:"Order"},
			               	{id:"5",name:"C095",type:"Order"},
			               ];
			graph.links = [
			               {id:"12",source:"1",target:"2"},
			               {id:"32",source:"3",target:"2"},
			               {id:"34",source:"4",target:"3"},
			               {id:"45",source:"5",target:"3"}
			               ];
/*
			graph.nodes = [
			               {id:"1",name:"刘员奕",type:"P"},
			               {id:"2",name:"C013",type:"Order"},
			               {id:"6",name:"C053",type:"Order"},
                           {id:"7",name:"C063",type:"Order"},
                           {id:"8",name:"C092",type:"Order"},
			               {id:"3",name:"car1",type:"Car"},
			               {id:"21",name:"car1",type:"Car"},
			               //{id:"22",name:"car2",type:"Car"},
			              // {id:"23",name:"car3",type:"Car"},
			               {id:"24",name:"car4",type:"Car"},
			               {id:"25",name:"car5",type:"Car"},
			               {id:"26",name:"car6",type:"Car"},
			               {id:"4",name:"card1",type:"Card"},
			               {id:"18",name:"card2",type:"Card"},
			               {id:"19",name:"card3",type:"Card"},
			               {id:"31",name:"黄建华",type:"P"},
			               {id:"32",name:"黄会将",type:"P"},
			               {id:"33",name:"张靠生",type:"P"},
			               {id:"34",name:"刘楠",type:"P"},
			               {id:"35",name:"方雷",type:"P"},
			               {id:"36",name:"王欧普",type:"P"},
			               {id:"5",name:"13310131101",type:"Phone"},
			               {id:"15",name:"15510231203",type:"Phone"},
			               {id:"16",name:"13990124501",type:"Phone"},
			               {id:"88",name:"XL1",type:"XL"}
			               ];
			
graph.links = [
			               {id:"12",source:"1",target:"2"},
			               {id:"83",source:"3",target:"2"},
			               {id:"61",source:"1",target:"6"},
			               {id:"82",source:"4",target:"2"},
			               {id:"24",source:"4",target:"2"},
			               {id:"41",source:"5",target:"2"},
			               {id:"7111",source:"1",target:"7"},
			               {id:"43",source:"15",target:"6"},
			               {id:"44",source:"15",target:"7"},
			               {id:"45",source:"16",target:"8"},
			               {id:"46",source:"18",target:"6"},
			               {id:"47",source:"19",target:"7"},
			               {id:"42",source:"4",target:"2"},
			               {id:"52",source:"25",target:"2"},
			               {id:"53",source:"21",target:"6"},
			               {id:"55",source:"26",target:"7"},
			               {id:"56",source:"24",target:"8"},
			               {id:"57",source:"25",target:"8"},
			               {id:"62",source:"31",target:"2"},
			               {id:"64",source:"32",target:"7"},
			               {id:"67",source:"35",target:"8"},
			               {id:"68",source:"36",target:"7"},
			               {id:"72",source:"33",target:"2"},
			               {id:"881",source:"88",target:"2"},
			               {id:"881",source:"34",target:"7"},
			               {id:"881",source:"34",target:"8"}
			               ];
			               */
							//			               var hoverNode = ["25","34","15","1"];
							var hoverNode = ["16","9","34"];
							for(var i=0;i<graph.nodes.length;i++){
								if(hoverNode.indexOf(graph.nodes[i].id)>=0){
									graph.nodes[i].enable = 1;
								}else{
									graph.nodes[i].enable = 0;
								}
							}
			console.log(self.clone(graph));
			self.draw(graph);
		},
		createNode:function(item,nodesData){
			var self = this;
			item.selectAll(".node").remove();//删除已有的线段
			var nodes = item.selectAll(".node").data(nodesData)
							.enter().append("g").attr("class","node")
							.attr("opacity",1).attr("cursor","pointer")
							.attr("data-id",function(d){return d.id;});
			//鼠标移入节点虚化其他节点
			nodes.on("mouseover",function(d){
				//self.mouseoverNode(d);
			}).on("mouseout",function(d){
				//self.mouseoutNode(d);
			}).on("dblclick",function(d){
				
			}).on("click",function(d){
				d3.event.stopPropagation();
				var data = {
						id:d.id,
						name:d.group
				};
				self.hoverLoop(data);
				//_.MessageManager.fire("listChange",data);
			});

			
			nodes.append("circle").attr("r",function(d){
				if(d.type==self.option.type.company){
					return 50;
				}else if(d.type==self.option.type.people){
					return 30; 
				}else{ 
					return 50;
				}
			}).attr("fill",function(d){
				if(d.type==self.option.type.company){
					if(d.isDB==0){
						return "#CCEEFF";
					}else if(d.isDB==1){
						return "#00BFFF";
					}
				}else if(d.type==self.option.type.people){
					return "#CCEEFF";
				}else{ 
					return "#CCEEFF";
				}
			});
			
			nodes.selectAll("circle").each(function(d){
				var nodeThis = d3.select(this);
				if(d.enable==1){
					nodeThis.attr("stroke","red").attr("stroke-width",4).attr("stroke-opacity",1);
				}
			});
			
			nodes.append("image")  
	            .attr("x",-20)  
	            .attr("y",-20)  
	            .attr("width",40)  
	            .attr("height",40)  
	            .attr("xlink:href",function(d){  
	            	var enable = "";
	            	console.log(d.enable);
	            	if(d.enable==1){
	            		enable = "2";
	            	}
	            	if(d.type=="P"){
	            		return "/EGraphPlaform-web/images/graph/people.png";  
	            	}else if(d.type=="Order"){
	            		return "/EGraphPlaform-web/images/graph/order.png"; 
	            	}else if(d.type=="Car"){
	            		return "/EGraphPlaform-web/images/graph/car3.png"; 
	            	}else if(d.type=="Phone"){
	            		return "/EGraphPlaform-web/images/graph/phone.png"; 
	            	}else if(d.type=="Card"){
	            		return "/EGraphPlaform-web/images/graph/card.png"; 
	            	}else if(d.type=="XL"){
	            		return "/EGraphPlaform-web/images/graph/4S.png"; 
	            	}else{
	            		// return "/EGraphPlaform-web/images/graph/null.png";
	            	}
	                
	            });  
			
			nodes.append("text").text(function(d){
					if(d.type == "Order"){
						return d.name;
					}else{
						return "";
					}
				 })
				 .attr("fill","#FFFFFF")
				 .attr("font-size",16)
				 .attr("x",-20).attr("y",70);
					
			/*
			nodes.append("circle").attr("r",function(d){
				if(d.type==self.option.type.company){
					return 50;
				}else if(d.type==self.option.type.people){
					return 30; 
				}else{ 
					return 30;
				}
			}).attr("fill",function(d){
				if(d.type==self.option.type.company){
					if(d.isDB==0){
						return "#00b591";
					}else if(d.isDB==1){
						return "#00BFFF";
					}
				}else if(d.type==self.option.type.people){
					return "#f66800";
				}else{ 
					return "#f66800";
				}
			});
			nodes.selectAll("circle").each(function(d){
				var nodeThis = d3.select(this);
				if(d.badNewNum>0 || d.badAsset==true ){
					nodeThis.attr("stroke","red").attr("stroke-width",4).attr("stroke-opacity",0.7);
				}
			});
			nodes.append("title").text(function(d){return d.name;});
			nodes.append("text").attr("font-size",function(d){
									if(d.badNewNum>0 || d.badAsset==true || d.casesNum>0){
										return 16;
									}else{
										return 14;
									}
								})
								.attr("fill",function(d){
									//|| d.casesNum>0
									if(d.badNewNum>0 || d.badAsset==true ){
										return "#FFFFFF";
									}else{
										return "#FFFFFF";
									}
								})
								.style("cursor","pointer")
								.each(function(d){
									var title = d.name;
									var titleLen = title.length;
									title = title.length>12?title.substring(0,10)+"..":title;
									titleLen = title.length;
									var oneRowNum = 4;
									var spanNum = Math.ceil(titleLen/oneRowNum);
									var spanValue = [];
									for(var i=0;i<spanNum;i++){
										if(i==spanNum){
											spanValue.push(title.substring(i*4,titleLen));
										}else{
											spanValue.push(title.substring(i*4,(i+1)*4));
										}
									}
									d3.select(this).selectAll("tspan").data(spanValue).enter()
										.append("tspan")
										.attr("x",function(innerd,i){
											return 0;
										})
										.attr("y",function(d,i){
											if(spanNum==3){
												return -10+i*15;
											}else if(spanNum==2){
												return -4+i*16;
											}else{
												return 4;
											}
										})
										.attr("text-anchor","middle")
										.text(function(d){  
											return d;  
										});
								});
								*/
			return item;			
		},
		createLink:function(item,linksData){
			var self = this;
			item.selectAll(".line").remove();//删除已有的线段
			var links = item.selectAll(".line").data(linksData)
							.enter().append("line")
							.attr("class","line")
							.attr("data-id",function(d){
								return d.id;
							})
							.attr("opacity",0)
							.attr("stroke-width",2)
							.attr("stroke","#5ce2c7");
			/*
			 * 如果是多实体查询着重显示相交的部分
			 * */
			if(false){
				links.attr("opacity",function(d){//marker
					var sourceId = self.getLinkSourceId(d);
					var targetId = self.getLinkTargetId(d);
					if(self.para.ids.indexOf(sourceId)>=0 && self.para.ids.indexOf(targetId)>=0){
						d.originOpacity=1;
						return 1;
					}else{
						d.originOpacity=0.1;
						return 0.1;
					}
				});
			}else{
				links.attr("opacity",function(d){
					d.originOpacity=1;
					return 1;
				});
			}
			return item;
		},
		draw:function(graph){
			var self = this;
			//添加节点
			var nodes = self.createNode(self.para.graph.select(".nodes"),graph.nodes);
			//添加连线
			var links = self.para.graph.select(".links");
			links.selectAll(".link").remove();
			var oneLink = links.selectAll(".link").data(graph.links)
								.enter().append("line")
								.attr("class","link")
								.attr("stroke-width",2)
								.attr("stroke",function(d){
									if(self.getNodeDetail(graph.nodes, d.source, "isDB")==1 &&
										self.getNodeDetail(graph.nodes, d.target, "isDB")==1
											){
										return "#00BFFF";
									}else{
										return "#00b591";
									}
								})
								/*
								.attr("data-id",function(d){return d.id})
								.attr("data-source",function(d){return d.source})
								.attr("data-target",function(d){return d.target})
								*/
								.attr("opacity",function(d){
										return 1;
								})
								.attr("marker-end", function(d) { 
									if(self.getNodeDetail(graph.nodes, d.target, "type")=="P"){
										return "url(#P)"; 
									}else{
										if(self.getNodeDetail(graph.nodes, d.target, "isDB")==1 && self.getNodeDetail(graph.nodes, d.source, "isDB")==1){
											return "url(#CDB)"; 
										}else{
											return "url(#C)"; 
										}
									}
								});
			//force布局
			self.para.simulation.alpha(0.8).restart();	
			self.para.simulation.nodes(graph.nodes).on("tick",ticked);
			
			self.para.simulation.force("link",d3.forceLink().id(function(d,i) { 
		    	return d.id;
		     }).links(graph.links).distance(function(d){
		    	 return 200;
			}).iterations(3));
			self.para.simulation.force("collide", d3.forceCollide().radius(80).iterations(4));
			
			//node拖拽事件
			self.nodeDrag("node");
			console.log(graph);
			function ticked() {
				nodes.selectAll(".node").attr("transform",function(d){
					return "translate("+d.x+","+d.y+")";
				});
				
				//调整link位置
				links.selectAll(".link").attr("x1", function(d) { 
						return d.source.x; 
					})
					.attr("y1", function(d) { 
						return d.source.y; 
					})
					.attr("x2", function(d) {
						return d.target.x; 
					})
					.attr("y2", function(d) { 
						return d.target.y; 
					});
					
				/*
				//调整link标签位置
				linkTextG.attr("transform",function(d){ return "translate("+((d.source.x + d.target.x)/2)+"," +((d.source.y + d.target.y)/2)+")";});
				*/
			}
			function findNodePoi(id){
				var node=null;
				for(var i=0;i<graph.nodes.length;i++){
					if(graph.nodes[i].id==id){
						node = graph.nodes[i];
						break;
					}
				}
				return node;
			}
		},
		/*
		 * 返回node的指定字段
		 * */
		getNodeDetail:function(nodeArr,id,key){
			for(var i=0;i<nodeArr.length;i++){
				if(nodeArr[i].id==id){
					return nodeArr[i][key];
				}
			}
			return null;
		},
		/*
		 *  实现、取消node拖拽
		 */
		nodeDrag:function(className){
			var self = this;
			var isDrag = true;
			var nodes = self.para.graph.select(".nodes").selectAll("."+className);
			//var nodes = self.para.graph.select(".nodes").selectAll(".node");
			if(isDrag==true){
				nodes.call(
					d3.drag().on("start",dragStart)
							 .on("drag",dragged)
							 .on("end",dragEnd)
				);
			}else{
				nodes.on(".start", null);
				nodes.on(".drag", null);
				nodes.on(".end", null);
			}
			function dragStart(d) {		
				if (!d3.event.active){
					self.para.simulation.alpha(0.02).restart();  
					//self.para.simulation
				} 
				d.fx = d.x;
				d.fy = d.y;
			}
			function dragged(d){
				d.fx = d3.event.x;
				d.fy = d3.event.y;
			}
			function dragEnd(d) {
				if(!d3.event.active){
					self.para.simulation.alpha(0.02);
					//self.para.simulation.stop();
				}
				d.fx = null;
				d.fy = null;
			}
		},
		/*
		 * 复制
		 * */
		clone:function(obj){
			var o,i,j,k;
			if(typeof(obj)!="object" || obj===null)return obj;
			if(obj instanceof(Array))
			{
				o=[];
				i=0;j=obj.length;
				for(;i<j;i++)
				{
					if(typeof(obj[i])=="object" && obj[i]!=null)
					{
						o[i]=arguments.callee(obj[i]);
					}
					else
					{
						o[i]=obj[i];
					}
				}
			}
			else
			{
				o={};
				for(i in obj)
				{
					if(typeof(obj[i])=="object" && obj[i]!=null)
					{
						o[i]=arguments.callee(obj[i]);
					}
					else
					{
						o[i]=obj[i];
					}
				}
			}
			return o;
		}
	};
	window.Graph=Graph;
})()