diff --git a/ats/analysis/ATS_AIM_customer_data_analysis.js b/ats/analysis/ATS_AIM_customer_data_analysis.js
index f382a0de3525043c7592c074cd58529046b35723..2bb9afc3ce3239400af322084b5f6f61c121a988 100644
--- a/ats/analysis/ATS_AIM_customer_data_analysis.js
+++ b/ats/analysis/ATS_AIM_customer_data_analysis.js
@@ -100,7 +100,6 @@ try {
     }
     var matrix = UPLOAD_LAYER_MATRIX({job:job})  // 分析matrix 获得分析后的matrix信息
     GEN.openStep({job:job, name:pcs_step})
-    GEN.units({type:"mm"})
     _.values(matrix).forEach(function(v){
         if(v.context == "board" && v.layer_type == "drill"){
             if(v.type == "laser_drill"){
@@ -306,6 +305,8 @@ try {
         })
     })
 
+    
+
     console.log("=============================> 6 set smd bga")
     var allStep = GEN.getStepList({job:job})
     allStep.forEach(function(step){
@@ -459,6 +460,7 @@ try {
         // signal层分析结果
         var res = analysisChkAttr({layers:signalLayers, info:info, step:step, job:job, oChecklistName:oChecklistName})
         
+        console.log("==================================> Drill analysis")
         // 钻孔
         var drillToSignals = drillLayers.map(function(v){  // 获取到钻孔层对应的顶层和底层
             var simbols = GEN.getLayerSymsHist({job:job,step:step,layer:v})
@@ -469,24 +471,12 @@ try {
                 }
                 return a
             },[])[0]
-            return {layer:v,symbol:symbol,start:matrix[v]["drl_start"],end:matrix[v]["drl_end"]}
+            return {layer:v,symbol:symbol,start:tmp_matrix[v]["drl_start"],end:tmp_matrix[v]["drl_end"]}
         })
         console.log("==================================> 12 Drill analysis")
         var drillRes = analysisDrill(drillToSignals,step) // 钻孔分析结果
 
-        console.log("================drillRes:" + _.toString(drillRes));
-        
-        throw "tmp"
-
-        //  数据入库 
-        Object.keys(res).forEach(function(key){
-            var val = res[key]
-            save_layerinfo({
-                jobid: JobId,
-                layer: key,
-                layerinfohash: val
-            })
-        })
+        console.log("===========  =====drillRes:" + _.toString(drillRes));
         drillRes.forEach(function(item){
             save_layerinfo({
                 jobid: JobId,
@@ -497,6 +487,17 @@ try {
                 }
             })
         })
+        throw "tmp"
+        //  数据入库 
+        Object.keys(res).forEach(function(key){
+            var val = res[key]
+            save_layerinfo({
+                jobid: JobId,
+                layer: key,
+                layerinfohash: val
+            })
+        })
+        
         // 铜面积
         console.log("=============================> 13 save copper_percent")
         var copper_percent_pcs = signalLayers.map(function(v){
@@ -1054,7 +1055,7 @@ function smdAnalysis(props){
     var layers = props.layers
     var res = {}
     steplist.forEach(function(step){
-        GEN.openStep({job:job,step:step})
+        GEN.openStep({job:job,name:step})
         layers.forEach(function(layer){
             // 计算开窗 数量 
             if(layer.solderL){
@@ -1257,7 +1258,6 @@ function analysisChkAttr(par) {
                     job: job,
                     step: par.step,
                     checklist: oChecklistName,
-                    units:"mm",
                     nact: 1,
                     attr: v + "_min_" + type
                 })
@@ -1279,12 +1279,13 @@ function analysisDrill(par, step){
     // {"layer":"d1-2","symbol":"r3.937","start":"top","end":"isl2"}
     // {"layer":"d1-2","symbol":"r35.0394","start":"top","end":"bottom"}
     var job = Job.toLowerCase()
+    GEN.affectedLayer({affected:'no',mode:'all'})
     var res = par.map(function(drill){
-		GEN.affectedLayer({affected:'no',mode:'all'})
-		GEN.affectedLayer({affected:'yes',layer:drill.layer})
+        GEN.workLayer({name:drill.layer,display_number:2,clear_before:'yes'})
         GEN.selClearFeature()
-		GEN.selectByFilter({feat_types:"pad",include_syms:drill.symbol})
+        GEN.selectByFilter({feat_types:'pad', include_syms:drill.symbol})
 		if(GEN.getSelectCount()>0){
+            console.log("==========================>jinru 111111111")
 			// 拷贝到_tmp
 			var tmplayer = drill.layer + "_tmp"
 			if(GEN.isLayerExists({job:job,layer:tmplayer})){GEN.deleteLayer({job:job,step:step,layer:tmplayer})}
@@ -1336,7 +1337,7 @@ function bgaAnalysis(props){
     }
     var res = {}
     steplist.forEach(function(step){
-        GEN.openStep({job:job,step:step})
+        GEN.openStep({job:job,name:step})
         layers.forEach(function(layer){
             // 找出bga 拷贝到辅助层
             GEN.workLayer({name:layer.signalL,display_number:2,clear_before:'yes'})
diff --git a/ats/analysis/backup.js b/ats/analysis/backup.js
index 994035c3d323dfd3a02aff29af73a20fc3edf20a..d7b9c32814d7deb78fc8c3bc72df578957b8dbda 100644
--- a/ats/analysis/backup.js
+++ b/ats/analysis/backup.js
@@ -100,8 +100,8 @@ try {
     }
     var matrix = UPLOAD_LAYER_MATRIX({job:job})  // 分析matrix 获得分析后的matrix信息
     GEN.openStep({job:job, name:pcs_step})
+    GEN.units({type:"mm"})
     _.values(matrix).forEach(function(v){
-        
         if(v.context == "board" && v.layer_type == "drill"){
             if(v.type == "laser_drill"){
                 GEN.affectedLayer({affected:'no',mode:'all'})
@@ -137,7 +137,7 @@ try {
     console.log("===================>steplist:"+_.toString(step_list))
     if(step_list.indexOf(pcs_step)<0){throw "can not find pcsstep"}
     if(step_list.indexOf(array_step)<0){array_step = false}
-    console.log("===================================> 1matrix")
+    console.log("=============== ====================> 1matrix")
     var analysis_obj = analysis({job:job,jobId:JobId,pcs_step:pcs_step,array_step:array_step,matrix:matrix})
     // 创建profile
     var tmp_matrix = GEN.getMatrix({job:job})
@@ -149,25 +149,15 @@ try {
     console.log("profile:===============>"+now_profile);
     console.log(now_profile.match(/\n/ig).length);
     if(now_profile.match(/\n/ig).length == 1){  // 如果没有profile
-        var alllayers = Object.keys(matrix)
-        if (alllayers.indexOf("outline") >= 0){  // 如果有outline层
-            GEN.affectedLayer({ affected: 'no', mode: 'all' })
-            GEN.clearLayers()
-            GEN.workLayer({name:'outline',display_number:2,clear_before:'yes'})
-            GEN.selectByFilter({feat_types:'line\;arc'})
-            var count = GEN.getSelectCount()
-            if(count > 0) {
-                GEN.selCreateProfile()
-            }
-            GEN.clearLayers()
-            console.log("create profile ok");
+        createOutline({job:job, step:pcs_step, matrix: tmp_matrix})
+    } else {
+        GEN.affectedLayer({affected:'yes',layer: board_layer, clear_before:"yes"})
+        GEN.selectByFilter({profile:"out"})
+        if(GEN.getSelectCount() > 0){
+            GEN.selDelete()
         }
     }
-    GEN.affectedLayer({affected:'yes',layer: board_layer, clear_before:"yes"})
-    GEN.selectByFilter({profile:"out"})
-    if(GEN.getSelectCount() > 0){
-        GEN.selDelete()
-    }
+    
     GEN.closeStep()
     var config = {
         jobInfo: {
@@ -203,7 +193,7 @@ try {
             max_spec_slot_drl_length: true, // todo  3.0mm 最大异形槽孔
         }
     }
-    console.log("================== ================> 2analysis_obj")
+    console.log("===============================> 2analysis_obj")
 
     // 分析料号info
     var jobInfo = {}
@@ -316,22 +306,43 @@ try {
         })
     })
 
-    console.log("=========== ===================> 6 set smd bga")
-    
-
-    var hasattrs = [".smd",".bga"]
-    var ishasattrs = hasattrs.reduce(function(a,b){  // 判断是否含有.smd属性
-        if(!hasAttr({job:job,step:pcs_step,attr:b,layers:analysis_obj.matrixInfo.mOuters})){ a = false }
-        return a
-    },true)
-    if(!ishasattrs){ // 如果找不到.smd 分析.smd
-        GEN.COM("chklist_single,action=valor_cleanup_set_smd,show=yes")
+    console.log("=============================> 6 set smd bga")
+    var allStep = GEN.getStepList({job:job})
+    allStep.forEach(function(step){
+        GEN.openStep({job:job,name:step})
+        console.log(3)
+        GEN.COM("chklist_single,show=yes,action=valor_cleanup_set_smd")
+        console.log(4)
         GEN.COM("chklist_cupd,chklist=valor_cleanup_set_smd,nact=1,params=((pp_layer=.type=signal|mixed&side=top|bottom)(pp_work_on=SMD\;BGA)(pp_delete=No)(pp_types=Square\;Rect\;Oval)(pp_other_smd=)(pp_sm=No)(pp_drill=)(pp_rotate=No)(pp_ignore_covered=Yes)(pp_bga_types=Round)(pp_other_bga=)(pp_sm_bga=No)(pp_bga_max_pitch=70)(pp_bga_actions=Set attribute)(pp_bga_suffix=_bga)(pp_identify_gf=)),mode=regular")
+        console.log(5)
+        GEN.COM("get_user_name")
+        console.log(6)
+        GEN.COM("get_job_path,job="+job)
+        console.log(7)
+        GEN.COM("disp_on")
+        console.log(8)
+        GEN.COM("origin_on")
+        console.log(9)
+        GEN.COM("chklist_cnf_act,chklist=valor_cleanup_set_smd,nact=1,cnf=no")
+        console.log(10)
         GEN.COM("chklist_run,chklist=valor_cleanup_set_smd,nact=1,area=profile")
-        GEN.COM("chklist_close,chklist=valor_cleanup_set_smd,mode=hide")
-    }
-
-
+        console.log(11)
+        GEN.COM("skip_next_pre_hook")
+        console.log(12)
+        GEN.COM("chklist_run,chklist=valor_cleanup_set_smd,nact=1,area=profile")
+        console.log(13)
+        GEN.COM("get_user_name")
+        console.log(14)
+        GEN.COM("skip_current_command")
+        console.log(15)
+        GEN.COM("disp_on")
+        console.log(16)
+        GEN.COM("origin_on")
+        console.log(17)
+        GEN.COM("show_tab,tab=Checklists,show=no")
+        GEN.closeStep()
+    })
+    
     // GEN.createChklist()
 
     console.log("============= ===============> 6 analysis smd")
@@ -386,6 +397,10 @@ try {
         min_pad2pad: ["p2p", "smd2smd", "smd2pad"],
         min_ar: ["ar","pth_ar"]
     }
+    save_job_info({
+        jobid: JobId,
+        jobinfohash: {ATS_surface_area_base_on:"Card"}
+    })
     stepList.forEach(function(step){
         GEN.openStep({ job: job, name: step })
          // 曝光
@@ -394,13 +409,18 @@ try {
                 var tmp_info = GEN.exposedArea({layer1:item.signalL,mask1:item.solderL})
                 // {"area":"0.73817","percent":"8.986"}
                 var tmp_area =  tmp_info.area
-                var tmp_percent =  tmp_info.percent + "%"
+                var tmp_percent =  tmp_info.percent;
+                var tmp_data = /top/ig.test(item.signalL) ? {carbon_Area_front:tmp_area} : {carbon_Area_back:tmp_area}
+                save_job_info({
+                    jobid: JobId,
+                    jobinfohash: tmp_data
+                })
                 save_layerinfo({
                     jobid: JobId,
                     layer: item.signalL,
                     layerinfohash: {
                         ref_layer: item.solderL,
-                        exposed_area: tmp_area
+                        exposed_area: tmp_percent
                     }
                 })
             }
@@ -435,7 +455,7 @@ try {
             layers: signalLayers,
             items: [tmpitem]
         })
-        console.log("================== =================> 11 signals analysis")
+        console.log("==================================> 11 signals analysis")
         // signal层分析结果
         var res = analysisChkAttr({layers:signalLayers, info:info, step:step, job:job, oChecklistName:oChecklistName})
         
@@ -451,8 +471,13 @@ try {
             },[])[0]
             return {layer:v,symbol:symbol,start:matrix[v]["drl_start"],end:matrix[v]["drl_end"]}
         })
-        console.log("===================================> 12 Drill analysis")
+        console.log("==================================> 12 Drill analysis")
         var drillRes = analysisDrill(drillToSignals,step) // 钻孔分析结果
+
+        console.log("================drillRes:" + _.toString(drillRes));
+        
+        throw "tmp"
+
         //  数据入库 
         Object.keys(res).forEach(function(key){
             var val = res[key]
@@ -473,48 +498,24 @@ try {
             })
         })
         // 铜面积
-        console.log("===================================> 13 save copper_percent")
-        // 创建profile
-        var new_martix = GEN.getMatrix({job:job})
-        var profileLayer = Object.keys(new_martix).filter(function(v){
-            return new_martix[v].layer_type=="rout" && new_martix[v].context == "board"
+        console.log("=============================> 13 save copper_percent")
+        var copper_percent_pcs = signalLayers.map(function(v){
+            var tmp = {layer:v}
+            tmp.copper_percent = GEN.copperArea({layer1:v}).percent + "%"
+            return tmp
         })
-        if(profileLayer.length){
-            if(GEN.getProfile({job:job, step:pcs_step}).match(/\n/ig).length == 1){  // 如果没有profile
-                var tmp = profileLayer[0]
-                if(profileLayer.indexOf("outline")>=0){tmp = "outline"}
-                GEN.openStep({job:job,name:pcs_step})
-                GEN.workLayer({name:tmp,display_number:2,clear_before:'yes'})
-                GEN.selectByFilter({feat_types:'line\;arc'})
-                var count = GEN.getSelectCount()
-                if(count > 0){
-                    GEN.selCreateProfile()
-                    GEN.selClearFeature()
-                } else if(profileLayer.length > 1) {
-                    GEN.workLayer({name:"rout",display_number:2,clear_before:'yes'})
-                    GEN.selectByFilter({feat_types:'line\;arc'})
-                    if(GEN.getSelectCount() > 0){
-                        GEN.selCreateProfile()
-                        GEN.selClearFeature()
-                    }
+        console.log("================ ==signalLayers============"+_.toString(signalLayers));
+        console.log(_.toString(copper_percent_pcs));
+        GEN.closeStep()
+        copper_percent_pcs.forEach(function(item){
+            save_layerinfo({
+                jobid: JobId,
+                layer: item.layer,
+                layerinfohash: {
+                    copper_percent: item.copper_percent
                 }
-            }
-            var copper_percent_pcs = signalLayers.map(function(v){
-                var tmp = {layer:v}
-                tmp.copper_percent = GEN.copperArea({layer1:v}).percent + "%"
-                return tmp
             })
-            GEN.closeStep()
-            copper_percent_pcs.forEach(function(item){
-                save_layerinfo({
-                    jobid: JobId,
-                    layer: item.layer,
-                    layerinfohash: {
-                        copper_percent: item.copper_percent
-                    }
-                })
-            })
-        }
+        })
     })
 
     // 保存 
@@ -824,7 +825,10 @@ function analysis(props){
         this.jobId = props.jobId;
         if(props.pcs_step){ this.pcs_step = props.pcs_step; }
         if(props.matrix){ this.matrix = props.matrix; }
-        if(props.array_step){ this.array_step = props.array_step; }
+        if(props.array_step){ 
+            
+            this.array_step = props.array_step; 
+        }
         this.matrixInfo = getMatrixInfo({job:this.job})
         this.init();
     }
@@ -843,11 +847,11 @@ function analysis(props){
         return res.length
     }
     T_m_p.prototype.analysis_vc_card_size = function(props){   // card短边尺寸 string
-        return GEN.getProfileLimits({job:this.job,step:this.pcs_step})[props].toFixed(3)
+        return GEN.getProfileLimits({job:this.job,step:this.pcs_step,units:"mm"})[props].toFixed(2)
     }
     T_m_p.prototype.analysis_vc_array_size = function(props){   // array长边尺寸 string
         if(!this.array_step){return "_error"}
-        return GEN.getProfileLimits({job:this.job,step:this.array_step})[props].toFixed(3)
+        return GEN.getProfileLimits({job:this.job,step:this.array_step,units:"mm"})[props].toFixed(2)
     }
     T_m_p.prototype.analysis_vc_pcs_count_on_panel = function(props){  // 
         return "_todo"
@@ -1085,7 +1089,7 @@ function smdAnalysis(props){
                 // 分析最小smd间距
                 // 创建一个checklist并且分析
                 var min_smd_pitch = smdPitch({job:job,step:step,layer:tmp_layer})  // min_smd_pitch
-                // console.log('========================min_smd_pitch:' + min_smd_pitch);
+                // console.log('=================  =======min_smd_pitch:' + min_smd_pitch);
                 
                 res[layer.signalL]["min_smd_pitch"] = min_smd_pitch
                 // 分析开窗宽高
@@ -1253,14 +1257,17 @@ function analysisChkAttr(par) {
                     job: job,
                     step: par.step,
                     checklist: oChecklistName,
+                    units:"mm",
                     nact: 1,
                     attr: v + "_min_" + type
                 })
                 if (a === "N/A" && /\d+/.test(tmp)) {
-                    a = tmp
+                    tmp = Number(tmp)
+                    a = tmp.toFixed(2)
                 }
                 if (/\d+/.test(a) && /\d+/.test(tmp) && Number(tmp) < Number(a)) {
-                    a = tmp
+                    tmp = Number(tmp)
+                    a = tmp.toFixed(2)
                 }
                 return a
             }, "N/A")
@@ -1273,49 +1280,43 @@ function analysisDrill(par, step){
     // {"layer":"d1-2","symbol":"r35.0394","start":"top","end":"bottom"}
     var job = Job.toLowerCase()
     var res = par.map(function(drill){
-        GEN.affectedLayer({affected:"yes",layer:drill.layer,clear_before:"yes",mode:"all"})
+		GEN.affectedLayer({affected:'no',mode:'all'})
+		GEN.affectedLayer({affected:'yes',layer:drill.layer})
         GEN.selClearFeature()
-        GEN.selectByFilter({feat_types:"pad",include_syms:drill.symbol})
-        // 拷贝到_tmp
-        var tmplayer = drill.layer + "_tmp"
-        if(GEN.isLayerExists({job:job,layer:tmplayer})){GEN.deleteLayer({job:job,step:step,layer:tmplayer})}
-        GEN.selCopyOther({dest:"layer_name",target_layer:tmplayer})
-        GEN.affectedLayer({affected:"no",mode:"all"})
-        GEN.selClearFeature();
-        [drill.start,drill.end].forEach(function(item, i){
-            GEN.workLayer({name:item,display_number:1,clear_before:"yes"})
-            // GEN.selRefFeat({
-            //     layers: tmplayer,
-            //     use: "filter",
-            //     mode: "touch",
-            //     f_types: "pad",
-            //     pads_as:"shape",
-            //     polarity:"positive",
-            //     include_syms:drill.symbol,
-            //     filter: {
-            //         feat_types:'pad'
-            //     }
-            // })
-            GEN.COM("sel_ref_feat",
-            {layers:tmplayer,use:"filter",mode:"touch",pads_as:"shape",f_types:"pad",polarity:"positive\;negative",include_syms:drill.symbol})
-            var res = ""
-            var pads = GEN.getFeatures({job:job,step:step,layer:item,options:"select"})
-            if(pads && pads.length) {
-                pads = pads.filter(function(item){
-                    return /^r\d+/.test(item.symbol)
-                })
-                pads = pads.sort(function(a,b){
-                    return parseInt(a.symbol) - parseInt(b.symbol) 
-                })
-                res = pads[0].symbol.slice(1)
-            }
-            if ( i == 0) {
-                drill.drl_pad_top = res
-            } else if (i==1){
-                drill.drl_pad_bot = res
-            }
-        })
-        GEN.deleteLayer({job:job,step:step,layer:tmplayer})
+		GEN.selectByFilter({feat_types:"pad",include_syms:drill.symbol})
+		if(GEN.getSelectCount()>0){
+            console.log("==========================>jinru 111111111")
+			// 拷贝到_tmp
+			var tmplayer = drill.layer + "_tmp"
+			if(GEN.isLayerExists({job:job,layer:tmplayer})){GEN.deleteLayer({job:job,step:step,layer:tmplayer})}
+			GEN.selCopyOther({dest:"layer_name",target_layer:tmplayer})
+			GEN.affectedLayer({affected:"no",mode:"all"})
+			GEN.selClearFeature();
+			[drill.start,drill.end].forEach(function(item, i){
+				GEN.workLayer({name:item,display_number:1,clear_before:"yes"})
+				GEN.COM("sel_ref_feat",
+				{layers:tmplayer,use:"filter",mode:"touch",pads_as:"shape",f_types:"pad",polarity:"positive\;negative",include_syms:drill.symbol})
+				if(GEN.getSelectCount()>0){
+					var res = ""
+					var pads = GEN.getFeatures({job:job,step:step,layer:item,options:"select"})
+					if(pads && pads.length) {
+						pads = pads.filter(function(item){
+							return /^r\d+/.test(item.symbol)
+						})
+						pads = pads.sort(function(a,b){
+							return parseInt(a.symbol) - parseInt(b.symbol) 
+						})
+						res = pads[0].symbol.slice(1)
+					}
+					if ( i == 0) {
+						drill.drl_pad_top = res
+					} else if (i==1){
+						drill.drl_pad_bot = res
+					}
+				}
+			})
+			GEN.deleteLayer({job:job,step:step,layer:tmplayer})
+		}
         return drill
     })
     return res
@@ -1361,14 +1362,14 @@ function bgaAnalysis(props){
                 if (!res.hasOwnProperty(layer.signalL)){
                     res[layer.signalL] = {}
                 }
-                res[layer.signalL].min_bga_size = min_symbols_info["min_bga_size"]
-                res[layer.signalL].min_bga_openging_size = min_symbols_info["min_bga_openging_size"]
-                res[layer.signalL].min_bga_pitch = min_symbols_info["min_bga_pitch"]
+                res[layer.signalL].min1_bga_dia = myFixed(min_symbols_info["min_bga_size"],2) 
+                res[layer.signalL].min1_bga_sm_dia = myFixed(min_symbols_info["min_bga_openging_size"],2) 
+                res[layer.signalL].min1_bga_grid = myFixed(min_symbols_info["min_bga_pitch"],2) 
                 // 分析所有BGA
                 var all_bga_min_pitch_info = all_bga_min_pitch_anal({job:job, step:step, layer:tmp_layer,solderLayer:layer.solderL})
-                res[layer.signalL].bga_min_pitch = all_bga_min_pitch_info["bga_min_pitch"]
-                res[layer.signalL].bga_min_pitch_pad_size = all_bga_min_pitch_info["bga_min_pitch_pad_size"]
-                res[layer.signalL].bga_min_pitch_openging_size = all_bga_min_pitch_info["bga_min_pitch_openging_size"]
+                res[layer.signalL].min2_bga_grid = myFixed(all_bga_min_pitch_info["bga_min_pitch"],2) 
+                res[layer.signalL].min2_bga_dia = myFixed(all_bga_min_pitch_info["bga_min_pitch_pad_size"],2) 
+                res[layer.signalL].min2_bga_sm_dia = myFixed(all_bga_min_pitch_info["bga_min_pitch_openging_size"],2) 
                 GEN.deleteLayer({job:job,layer:tmp_layer})
             } 
         })
@@ -1625,527 +1626,60 @@ function hasAttr(props){  // 判断层 有没有部分属性
     }
     return res
 }
-function tmp(){
-    return {
-        "sst": {
-            "row": "1","type": "solder_paste","name": "sp_fr","context": "board","layer_type": "solder_paste","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": -1000,"tl_name": "sp_fr","tl_type": "solder_paste","odb_name": "sst","odb_context": "board","odb_type": "solder_paste","odb_polarity": "positive","odb_side": "top",
-            "row_num": -1000,"odb_row_num": "1"
-        },
-        "spt": {
-            "row": "2","type": "solder_paste","name": "sp_fr(2)","context": "board","layer_type": "solder_paste","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": -999,"tl_name": "sp_fr(2)","tl_type": "solder_paste","odb_name": "spt","odb_context": "board","odb_type": "solder_paste","odb_polarity": "positive","odb_side": "top",
-            "row_num": -999,"odb_row_num": "2"
-        },
-        "smt": {
-            "row": "3","type": "solder_mask","name": "sm_fr","context": "board","layer_type": "solder_mask","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": -998,"tl_name": "sm_fr","tl_type": "solder_mask","odb_name": "smt","odb_context": "board","odb_type": "solder_mask","odb_polarity": "positive","odb_side": "top",
-            "row_num": -998,"odb_row_num": "3"
-        },
-        "top": {
-            "row": "4","type": "outer","name": "top","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 1,"tl_name": "top","tl_type": "outer","odb_name": "top","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "top",
-            "row_num": 1,"odb_row_num": "4"
-        },
-        "isl2": {
-            "row": "5","type": "inner","name": "l2","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 2,"tl_name": "l2","tl_type": "inner","odb_name": "isl2","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner",
-            "row_num": 2,"odb_row_num": "5"
-        },
-        "isl3": {
-            "row": "6","type": "inner","name": "l3","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 3,"tl_name": "l3","tl_type": "inner","odb_name": "isl3","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner",
-            "row_num": 3,"odb_row_num": "6"
-        },
-        "isl4": {
-            "row": "7","type": "inner","name": "l4","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 4,"tl_name": "l4","tl_type": "inner","odb_name": "isl4","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner",
-            "row_num": 4,"odb_row_num": "7"
-        },
-        "isl5": {
-            "row": "8","type": "inner","name": "l5","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 5,"tl_name": "l5","tl_type": "inner","odb_name": "isl5","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner",
-            "row_num": 5,"odb_row_num": "8"
-        },
-        "isl6": {
-            "row": "9","type": "inner","name": "l6","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 6,"tl_name": "l6","tl_type": "inner","odb_name": "isl6","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner",
-            "row_num": 6,"odb_row_num": "9"
-        },
-        "isl7": {
-            "row": "10","type": "inner","name": "l7","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 7,"tl_name": "l7","tl_type": "inner","odb_name": "isl7","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner",
-            "row_num": 7,"odb_row_num": "10"
-        },
-        "isl8": {
-            "row": "11","type": "inner","name": "l8","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 8,"tl_name": "l8","tl_type": "inner","odb_name": "isl8","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner",
-            "row_num": 8,"odb_row_num": "11"
-        },
-        "isl9": {
-            "row": "12","type": "inner","name": "l9","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 9,"tl_name": "l9","tl_type": "inner","odb_name": "isl9","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "inner",
-            "row_num": 9,"odb_row_num": "12"
-        },
-        "bottom": {
-            "row": "13","type": "outer","name": "bottom","context": "board","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 10,"tl_name": "bottom","tl_type": "outer","odb_name": "bottom","odb_context": "board","odb_type": "signal","odb_polarity": "positive","odb_side": "bottom",
-            "row_num": 10,"odb_row_num": "13"
-        },
-        "smb": {
-            "row": "14","type": "solder_mask","name": "sm_ba","context": "board","layer_type": "solder_mask","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 1013,"tl_name": "sm_ba","tl_type": "solder_mask","odb_name": "smb","odb_context": "board","odb_type": "solder_mask","odb_polarity": "positive","odb_side": "bottom",
-            "row_num": 1013,"odb_row_num": "14"
-        },
-        "spb": {
-            "row": "15","type": "solder_paste","name": "sp_ba","context": "board","layer_type": "solder_paste","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 1014,"tl_name": "sp_ba","tl_type": "solder_paste","odb_name": "spb","odb_context": "board","odb_type": "solder_paste","odb_polarity": "positive","odb_side": "bottom",
-            "row_num": 1014,"odb_row_num": "15"
-        },
-        "ssb": {
-            "row": "16","type": "solder_paste","name": "sp_ba(2)","context": "board","layer_type": "solder_paste","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 1015,"tl_name": "sp_ba(2)","tl_type": "solder_paste","odb_name": "ssb","odb_context": "board","odb_type": "solder_paste","odb_polarity": "positive","odb_side": "bottom",
-            "row_num": 1015,"odb_row_num": "16"
-        },
-        "d1-2": {
-            "row": "17","type": "laser_drill","name": "d1-2","context": "board","layer_type": "drill","polarity": "positive","drl_start": "top",
-            "drl_end": "isl2","gdrl_start": "top","gdrl_end": "isl2","drl_start_num": "1","drl_end_num": "2","tl_name": "drill1-2","tl_type": "drill",
-            "tl_num": 10016,"odb_name": "d1-2","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10016,"odb_row_num": "17","drl_from_num": "1","drl_to_num": "2"
-        },
-        "d2-3": {
-            "row": "18","type": "laser_drill","name": "d2-3","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl2","drl_end": "isl3","gdrl_start": "isl2","gdrl_end": "isl3","drl_start_num": "2","drl_end_num": "3","tl_name": "drill2-3","tl_type": "drill",
-            "tl_num": 10017,"odb_name": "d2-3","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10017,"odb_row_num": "18","drl_from_num": "2","drl_to_num": "3"
-        },
-        "d3-4": {
-            "row": "19","type": "laser_drill","name": "d3-4","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl3","drl_end": "isl4","gdrl_start": "isl3","gdrl_end": "isl4","drl_start_num": "3","drl_end_num": "4","tl_name": "drill3-4","tl_type": "drill",
-            "tl_num": 10018,"odb_name": "d3-4","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10018,"odb_row_num": "19","drl_from_num": "3","drl_to_num": "4"
-        },
-        "d4-5": {
-            "row": "20","type": "laser_drill","name": "d4-5","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl4","drl_end": "isl5","gdrl_start": "isl4","gdrl_end": "isl5","drl_start_num": "4","drl_end_num": "5","tl_name": "drill4-5","tl_type": "drill",
-            "tl_num": 10019,"odb_name": "d4-5","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10019,"odb_row_num": "20","drl_from_num": "4","drl_to_num": "5"
-        },
-        "d5-6": {
-            "row": "21","type": "laser_drill","name": "d5-6","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl5","drl_end": "isl6","gdrl_start": "isl5","gdrl_end": "isl6","drl_start_num": "5","drl_end_num": "6","tl_name": "drill5-6","tl_type": "drill",
-            "tl_num": 10020,"odb_name": "d5-6","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10020,"odb_row_num": "21","drl_from_num": "5","drl_to_num": "6"
-        },
-        "d6-7": {
-            "row": "22","type": "laser_drill","name": "d6-7","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl6","drl_end": "isl7","gdrl_start": "isl6","gdrl_end": "isl7","drl_start_num": "6","drl_end_num": "7","tl_name": "drill6-7","tl_type": "drill",
-            "tl_num": 10021,"odb_name": "d6-7","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10021,"odb_row_num": "22","drl_from_num": "6","drl_to_num": "7"
-        },
-        "d7-8": {
-            "row": "23","type": "laser_drill","name": "d7-8","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl7","drl_end": "isl8","gdrl_start": "isl7","gdrl_end": "isl8","drl_start_num": "7","drl_end_num": "8","tl_name": "drill7-8","tl_type": "drill",
-            "tl_num": 10022,"odb_name": "d7-8","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10022,"odb_row_num": "23","drl_from_num": "7","drl_to_num": "8"
-        },
-        "d8-9": {
-            "row": "24","type": "laser_drill","name": "d8-9","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl8","drl_end": "isl9","gdrl_start": "isl8","gdrl_end": "isl9","drl_start_num": "8","drl_end_num": "9","tl_name": "drill8-9","tl_type": "drill",
-            "tl_num": 10023,"odb_name": "d8-9","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10023,"odb_row_num": "24","drl_from_num": "8","drl_to_num": "9"
-        },
-        "d9-10": {
-            "row": "25","type": "laser_drill","name": "d9-10","context": "board","layer_type": "drill","polarity": "positive","drl_start": "isl9","drl_end": "bottom","gdrl_start": "isl9","gdrl_end": "bottom","drl_start_num": "9","drl_end_num": "10","tl_name": "drill9-10","tl_type": "drill",
-            "tl_num": 10024,"odb_name": "d9-10","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10024,"odb_row_num": "25","drl_from_num": "9","drl_to_num": "10"
-        },
-        "drill": {
-            "row": "26","type": "main_drill","name": "drill","context": "board","layer_type": "drill","polarity": "positive","drl_start": "top","drl_end": "bottom","gdrl_start": "top","gdrl_end": "bottom","drl_start_num": 1,"drl_end_num": 10,"tl_name": "drill","tl_type": "drill",
-            "tl_num": 10025,"odb_name": "drill","odb_context": "board","odb_type": "drill","odb_polarity": "positive","odb_side": "none",
-            "row_num": 10025,"odb_row_num": "26","drl_from_num": 1,"drl_to_num": 10
-        },
-        "rout": {
-            "row": "27","type": "other","name": "__rout__","context": "board","layer_type": "rout","polarity": "positive","drl_start": "top","drl_end": "bottom","gdrl_start": "top","gdrl_end": "bottom","odb_name": "rout","odb_context": "board","odb_type": "rout","odb_polarity": "positive","odb_side": "none","odb_row_num": "27"
-        },
-        "nclegend-1-2": {
-            "row": "28","type": "other","name": "__nclegend-1-2__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110027,"odb_name": "nclegend-1-2","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110027,"odb_row_num": "28"
-        },
-        "nclegend-2-3": {
-            "row": "29","type": "other","name": "__nclegend-2-3__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110028,"odb_name": "nclegend-2-3","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110028,"odb_row_num": "29"
-        },
-        "nclegend-3-4": {
-            "row": "30","type": "other","name": "__nclegend-3-4__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110029,"odb_name": "nclegend-3-4","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110029,"odb_row_num": "30"
-        },
-        "nclegend-4-5": {
-            "row": "31","type": "other","name": "__nclegend-4-5__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110030,"odb_name": "nclegend-4-5","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110030,"odb_row_num": "31"
-        },
-        "nclegend-5-6": {
-            "row": "32","type": "other","name": "__nclegend-5-6__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110031,"odb_name": "nclegend-5-6","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110031,"odb_row_num": "32"
-        },
-        "nclegend-6-7": {
-            "row": "33","type": "other","name": "__nclegend-6-7__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110032,"odb_name": "nclegend-6-7","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110032,"odb_row_num": "33"
-        },
-        "nclegend-7-8": {
-            "row": "34","type": "other","name": "__nclegend-7-8__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110033,"odb_name": "nclegend-7-8","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110033,"odb_row_num": "34"
-        },
-        "nclegend-8-9": {
-            "row": "35","type": "other","name": "__nclegend-8-9__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110034,"odb_name": "nclegend-8-9","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110034,"odb_row_num": "35"
-        },
-        "nclegend-9-10": {
-            "row": "36","type": "other","name": "__nclegend-9-10__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110035,"odb_name": "nclegend-9-10","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110035,"odb_row_num": "36"
-        },
-        "nclegend-1-10": {
-            "row": "37","type": "other","name": "__nclegend-1-10__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110036,"odb_name": "nclegend-1-10","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110036,"odb_row_num": "37"
-        },
-        "outline": {
-            "row": "38","type": "other","name": "__outline__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110037,"odb_name": "outline","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110037,"odb_row_num": "38"
-        },
-        "top_assem": {
-            "row": "39","type": "other","name": "__top_assem__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110038,"odb_name": "top_assem","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110038,"odb_row_num": "39"
-        },
-        "bot_assem": {
-            "row": "40","type": "other","name": "__bot_assem__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110039,"odb_name": "bot_assem","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110039,"odb_row_num": "40"
-        },
-        "top_testpoint": {
-            "row": "41","type": "other","name": "__top_testpoint__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110040,"odb_name": "top_testpoint","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110040,"odb_row_num": "41"
-        },
-        "bot_testpoint": {
-            "row": "42","type": "other","name": "__bot_testpoint__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110041,"odb_name": "bot_testpoint","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110041,"odb_row_num": "42"
-        },
-        "top_osp": {
-            "row": "43","type": "other","name": "__top_osp__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110042,"odb_name": "top_osp","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110042,"odb_row_num": "43"
-        },
-        "bot_osp": {
-            "row": "44","type": "other","name": "__bot_osp__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110043,"odb_name": "bot_osp","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110043,"odb_row_num": "44"
-        },
-        "top_enig": {
-            "row": "45","type": "other","name": "__top_enig__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110044,"odb_name": "top_enig","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110044,"odb_row_num": "45"
-        },
-        "bot_enig": {
-            "row": "46","type": "other","name": "__bot_enig__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110045,"odb_name": "bot_enig","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110045,"odb_row_num": "46"
-        },
-        "fab_page2": {
-            "row": "47","type": "other","name": "__fab_page2__","context": "misc","layer_type": "document","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110046,"odb_name": "fab_page2","odb_context": "misc","odb_type": "document","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110046,"odb_row_num": "47"
-        },
-        "tmp_top_shorts": {
-            "row": "48","type": "other","name": "__tmp_top_shorts__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110047,"odb_name": "tmp_top_shorts","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110047,"odb_row_num": "48"
-        },
-        "tmp_bot_shorts": {
-            "row": "49","type": "other","name": "__tmp_bot_shorts__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110048,"odb_name": "tmp_bot_shorts","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110048,"odb_row_num": "49"
-        },
-        "bot_assy_mate": {
-            "row": "50","type": "other","name": "__bot_assy_mate__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110049,"odb_name": "bot_assy_mate","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110049,"odb_row_num": "50"
-        },
-        "outline+1": {
-            "row": "51","type": "other","name": "__outline+1__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110050,"odb_name": "outline+1","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110050,"odb_row_num": "51"
-        },
-        "top_assy_mate": {
-            "row": "52","type": "other","name": "__top_assy_mate__","context": "misc","layer_type": "signal","polarity": "positive","drl_start": "","drl_end": "","gdrl_start": "","gdrl_end": "",
-            "tl_num": 110051,"odb_name": "top_assy_mate","odb_context": "misc","odb_type": "signal","odb_polarity": "positive","odb_side": "none",
-            "row_num": 110051,"odb_row_num": "52"
-        }
-    }
+function myFixed(str, num) {
+	if(/^[1-9][0-9]*([.][0-9]+)?$/.test(str)){
+		return Number(str).toFixed(num)
+	} else {
+		return str
+	}
 }
 
-function tmp_2(){
-    return {
-        "cad": {
-            "d1-2": {
-                "1": {
-                    "count": "06896",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "d2-3": {
-                "1": {
-                    "count": "07430",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "d3-4": {
-                "1": {
-                    "count": "06866",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "d4-5": {
-                "1": {
-                    "count": "06413",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "d5-6": {
-                "1": {
-                    "count": "08938",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "d6-7": {
-                "1": {
-                    "count": "09057",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "d7-8": {
-                "1": {
-                    "count": "07818",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "d8-9": {
-                "1": {
-                    "count": "09126",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "d9-10": {
-                "1": {
-                    "count": "08498",
-                    "num": "1",
-                    "type": "via",
-                    "min_tol": "2.756",
-                    "max_tol": "0.984",
-                    "finish_size": "2.756",
-                    "drill_size": "2.756",
-                    "slot_len": "0",
-                    "type2": "laser",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            },
-            "drill": {
-                "1": {
-                    "count": "05",
-                    "num": "1",
-                    "type": "non_plated",
-                    "min_tol": "3.15",
-                    "max_tol": "3.15",
-                    "finish_size": "15.748",
-                    "drill_size": "15.748",
-                    "slot_len": "0",
-                    "type2": "standard",
-                    "shape": "hole",
-                    "bit": 0
-                },
-                "2": {
-                    "count": "01",
-                    "num": "2",
-                    "type": "non_plated",
-                    "min_tol": "0",
-                    "max_tol": "1.969",
-                    "finish_size": "35.039",
-                    "drill_size": "35.039",
-                    "slot_len": "0",
-                    "type2": "standard",
-                    "shape": "hole",
-                    "bit": 0
-                },
-                "3": {
-                    "count": "01",
-                    "num": "3",
-                    "type": "non_plated",
-                    "min_tol": "3.15",
-                    "max_tol": "3.15",
-                    "finish_size": "35.039",
-                    "drill_size": "35.039",
-                    "slot_len": "0",
-                    "type2": "standard",
-                    "shape": "hole",
-                    "bit": 0
-                },
-                "4": {
-                    "count": "01",
-                    "num": "4",
-                    "type": "non_plated",
-                    "min_tol": "1.969",
-                    "max_tol": "1.969",
-                    "finish_size": "47.244",
-                    "drill_size": "47.244",
-                    "slot_len": "0",
-                    "type2": "standard",
-                    "shape": "hole",
-                    "bit": 0
-                },
-                "5": {
-                    "count": "05",
-                    "num": "5",
-                    "type": "non_plated",
-                    "min_tol": "1.969",
-                    "max_tol": "1.969",
-                    "finish_size": "59.055",
-                    "drill_size": "59.055",
-                    "slot_len": "0",
-                    "type2": "standard",
-                    "shape": "hole",
-                    "bit": 0
-                },
-                "6": {
-                    "count": "01",
-                    "num": "6",
-                    "type": "non_plated",
-                    "min_tol": "1.969",
-                    "max_tol": "1.969",
-                    "finish_size": "70.866",
-                    "drill_size": "70.866",
-                    "slot_len": "0",
-                    "type2": "standard",
-                    "shape": "hole",
-                    "bit": 0
-                },
-                "7": {
-                    "count": "01",
-                    "num": "7",
-                    "type": "non_plated",
-                    "min_tol": "1.969",
-                    "max_tol": "1.969",
-                    "finish_size": "74.803",
-                    "drill_size": "74.803",
-                    "slot_len": "0",
-                    "type2": "standard",
-                    "shape": "hole",
-                    "bit": 0
-                }
-            }
-        },
-        "stp": {
-            "d1-2": {},
-            "d2-3": {},
-            "d3-4": {},
-            "d4-5": {},
-            "d5-6": {},
-            "d6-7": {},
-            "d7-8": {},
-            "d8-9": {},
-            "d9-10": {},
-            "drill": {
-                "1": {
-                    "count": "08",
-                    "num": "1",
-                    "type": "non_plated",
-                    "min_tol": "0",
-                    "max_tol": "1.969",
-                    "finish_size": "118.11",
-                    "drill_size": "118.11",
-                    "slot_len": "0",
-                    "type2": "standard",
-                    "shape": "hole",
-                    "bit": 0
-                }
+function createOutline(props){
+    var job = props.job
+    var step = props.step
+    var matrix = props.matrix
+    var outlines = Object.keys(matrix).filter(function(v){return /^outline$|^rout$/ig.test(v)})
+    var drill_layer = Object.keys(matrix).filter(function(v){return matrix[v].layer_type=="drill" && matrix[v].context == "board"})
+    var tmp_outline
+    if(outlines.length){
+        if( outlines.length > 1 && outlines.indexOf("outline")>=0){
+            tmp_outline = "outline"
+            if(cl(tmp_outline)) {
+                return true
+            }else{
+                return cl("rout")
             }
+        } else {
+            return cl(outlines[0])
+        }
+    }else{return false}
+    function cl(l){
+        GEN.openStep({job:job, name:step})
+        GEN.affectedLayer({affected:'no',mode:'all'})
+        GEN.workLayer({name:l,display_number:2,clear_before:"yes"})
+        GEN.selClearFeature()
+        GEN.COM("sel_cut_data,det_tol=1,con_tol=1,rad_tol=0.1,filter_overlaps=no,delete_doubles=no,use_order=yes,ignore_width=yes,ignore_holes=none,start_positive=yes,polarity_of_touching=same")
+        var tmp_layer = l+"+++"
+        GEN.selRefFeat({layers:drill_layer[0],use:'filter',mode:'touch'})
+        if(GEN.getSelectCount() > 0){
+            var tmp_outline = l + "_tmp"
+            selCopyLayer({job:job,layer:tmp_outline})
+            GEN.workLayer({name:l,display_number:2,clear_before:"yes"})
+            GEN.selAllFeat()
+            GEN.selDelete()
+            GEN.workLayer({name:tmp_outline,display_number:2,clear_before:"yes"})
+            GEN.COM("sel_surf2outline,width=15")
+            GEN.selAllFeat()
+            selCopyLayer({job:job,layer:l})
+            GEN.workLayer({name:l,display_number:2,clear_before:"yes"})
+            GEN.selClearFeature()
+            GEN.selCreateProfile()
+            GEN.deleteLayer({job:job, layer:tmp_layer})
+            GEN.deleteLayer({job:job, layer:tmp_outline})
+            return true
         }
+        GEN.deleteLayer({job:job, layer:tmp_layer})
+        return false
     }
+    
 }
\ No newline at end of file
diff --git a/test/scott_test.js b/test/scott_test.js
index e3d99266556280b8fe615c3ad26bb67762763184..4836a73e1337ddaec5eeded06559d1b192d36643 100644
--- a/test/scott_test.js
+++ b/test/scott_test.js
@@ -80,11 +80,11 @@ try {
         },[])[0]
         return {layer:v,symbol:symbol,start:matrix[v]["drl_start"],end:matrix[v]["drl_end"]}
     })
-    console.log("==================================>drillToSignals:"+_.toString(drillToSignals))
+    console.log("===============================>drillToSignals:"+_.toString(drillToSignals))
 
-	var drillRes = analysisDrill(drillToSignals,step) // 钻孔分析结果
+	// var drillRes = analysisDrill(drillToSignals,step) // 钻孔分析结果
 
-    console.log("==================================>drillRes:"+_.toString(drillRes))
+    // console.log("==================================>drillRes:"+_.toString(drillRes))