/*
    NAME: 
    DESCRIPTION: 客户数据分析
    PARAMETER:
	[
		{
			name : 'step_filter',
			title : 'Step过滤',
			type : 'LineEdit',
			property : {tool_tip : '过滤step信息'}
        },
        {
            name : 'erf',
			title : 'erf名称',
			type : 'LineEdit',
			property : {tool_tip : ''}
        },
        {
            name : 'auto_save',
			title : '自动保存',
            type : 'RadioBox',
            property : {
				item_list:[
					{name:'yes',text:'YES'},
					{name:'no',text:'NO'},
				],
				tool_tip:'是否自动保存料号开关'
			}
        }
    ]

    VERSION_HISTORY:
	V1.00 2020 3-30 Scott
	
    HELP:
	<html><body bgcolor="#DDECFE">
		<font size="3" color="#003DB2"><p>功能简介</p></font>
		  <p> 客户数据分析</p>
		  <br>
		<font size="3" color="#003DB2"><p>参数配置</p></font>
		 <p> 客户参数 </p>
		<font size="3" color="#003DB2"><p>注意事项</p></font>
		  <p> ● 无 </p>
		  <br>
	</body></html>	
*/

// 引入模块 包
var $ = require('topcam.scriptfunc').argv();
var fs = require('fs');
var _ = require('lodash');
var IKM = $.ikm;
var GEN = $.gen;
var GUI = $.gui;
var Job = $.job;
var JobId = $.job_id;

var mode = "develop"   // 运行模式  develop 开发模式 方便调试

try {
    var job = "1"
    var pcs_step = "cad", array_step = "stp";
    var matrix = UPLOAD_LAYER_MATRIX({job:job})  // 分析matrix 获得分析后的matrix信息

    var analysis_obj = analysis({job:job,jobId:JobId,pcs_step:pcs_step,array_step:array_step,matrix:matrix})
    var config = {
        jobInfo: {
            layer_count: ["signal","power_ground"],  // Board属性的signal或者power_ground层
            vc_card_size_w: {api:"vc_card_size", props:"xsize"},       // card短边尺寸   // ? 保留小数
            vc_card_size_l: {api:"vc_card_size", props:"ysize"},       // card长边尺寸     // ? 保留小数
            vc_array_size_w: {api:"vc_array_size", props:"xsize"},       // ! array短边尺寸 需要arr_step   // ? 保留小数
            vc_array_size_l: {api:"vc_array_size", props:"ysize"},       // ! array长边尺寸 需要arr_step   // ? 保留小数
            vc_pcs_count_on_panel: true,  // todo array中pcs的数量 ! 需要arr_step
            stack_vias_number: true,    // via孔连续叠加的层数
            stack_vias_more: {only_value:true},   // yes|no : 14层板以上时，Stack Vias >=12时,存yes   // ! 需要分析完via连续叠加层数
            depth_drilling: {api:"layer_exist", props:"depth_drill"},  // yes|no :存在depth_drill 层时 ,存yes
            depth_routing: {api:"layer_exist", props:"depth_routing"},  // tmp yes|no :存在depth_routing 层时，,存yes
            laser_via_on_buried_hole: true,  // todo via孔在埋孔上时，存yes
            milling_bit_size: true,  // todo 检查array中pcs的最小间距值
            milling_length: true,  // todo 检查array中铣切长度
            vc_src_01005_pad_result: {api:"board_has_attr", props:".smd"},  // * yes|no：board 层中检查存在01005属性物件时，存yes 这里先拿.smd代替了
            ATS_technology_25dc: {api:"layer_exist", props:"cavity"},  // yes|no：存在cavity层别时存yes
            ATS_technology_25dr: {api:"layer_exist", props:"cavity"},  // yes|no：存在cavity层别时存yes
            vc_src_EDGE_PLATING: true,  // yes|no：检查线路外形是否存在物件，存在则存yes  // !料号需要有rout层
            edge_plating_length: true,  // todo 检查线路外形处物件的长度
            glod_finger: true,  // todo yes|no：暂无逻辑
            glod_finger_area: true,  // todo 暂无逻辑
            solder_mask_side: true, // top|bot|both:检查防焊层所在面次
            silk_screen_side: true, // top|bot|both:检查文字层所在面次
            min_drl_size: true, // todo  0.5mm 最小圆孔
            max_pth_drl_size: true, // todo  3.5mm 最大pth圆孔
            max_npth_drl_size: true, // todo  6.0mm 最大npth圆孔
            min_slot_drl_size: true, // todo  0.8mm 最小槽孔
            max_slot_drl_size: true, // todo  1.2mm 最大槽孔
            max_slot_drl_length: true, // todo  2.0mm 最大槽孔
            max_spec_slot_drl_size: true, // todo  2.1mm 最大异形槽孔
            max_spec_slot_drl_length: true, // todo  3.0mm 最大异形槽孔
        }
    }

    // 分析料号info
    var jobInfo = {}
    Object.keys(config.jobInfo).forEach(function(key){
        var props = config.jobInfo[key];
        if(props){
            try {
                if(props.hasOwnProperty("api") && props.hasOwnProperty("props")){
                    jobInfo[key] = analysis_obj["analysis_"+props.api](props.props)
                } else if(props.only_value){
                    jobInfo[key] = analysis_obj[key]
                } else {
                    jobInfo[key] = analysis_obj["analysis_"+key](props)
                }
            } catch (e) {
                console.log(e);
                jobInfo[key] = "_error"
            }
        }
    })
    // 过滤掉料号信息的 _todo 和 _error
    for (var key in jobInfo) {
        if(jobInfo[key] === "_todo" || jobInfo[key] === "_error"){
            delete jobInfo[key]
        }
    }
    // 上传jobInfo  IKM版本
    IKM.save_job_info({
        jobid: JobId,
        jobinfohash:jobInfo
    })
    // todo 上传jobInfo  topjs3版本
    // save_job_info({
    //     jobid: JobId,
    //     jobinfohash: jobInfo
    // })
    
    // todo 设置钻孔层孔属性，镭射孔via，无铜孔npth，其余孔pth
    
    // todo 上传钻孔信息
    // 获取pcs_step 和 array_step的钻孔信息
    var drill_info = {}; 
    var drillLayers = analysis_obj.matrixInfo.mDrills;
    [pcs_step, array_step].forEach(function(step){
        drill_info[step] = drill_info[step] || {};
        drillLayers.forEach(function(layer){
            var layer_tool_manager = GEN.getTool({job:job, step:step,layer:layer.name})
            drill_info[step][layer.name] = layer_tool_manager
        })
    })
    var pcs_tool_manager = drill_info[pcs_step];
    var array_tool_manager = drill_info[array_step];
    Object.keys(pcs_tool_manager).forEach(function(layer){
        Object.keys(pcs_tool_manager[layer]).forEach(function(key){
            var tool = pcs_tool_manager[layer][key];
            var array_count;
            if(array_tool_manager && array_tool_manager[layer] && array_tool_manager[layer][key]){array_count = array_tool_manager[layer][key].count}
            var data = {
                job_id: JobId,
                layer_name: layer,
                tool_num: key,
                tool_flag: key,
                tool_type: tool.shape,
                drill_type:tool.type,
                drill_size : tool.drill_size,
                drill_slot_length: tool.slot_len,
                finish_size : tool.finish_size,
                finish_slot_length: tool.slot_len,
                size_tol_lower: tool.min_tol,
                size_tol_upper: tool.max_tol,
                pcs_count: tool.count,
                array_count: array_count,    // todo
                attr_data: {}   // {"allowance": 2, "org_layer_name": "hhhh"}
            }
            if(!array_count){delete data.array_count}
            var id = IKM.crud("selectValue",{
                table:'pdm_job_cam_drill',
                field:"id",
                where:{job_id:JobId, layer_name: layer,tool_num: key}
            })
            if(/done/ig.test(id)){
                IKM.crud("insertRow",{
                    table:'pdm_job_cam_drill',
                    data:data,
                    return_field:'id',
                })
            }else{
                IKM.crud("updateRow",{
                    table:'pdm_job_cam_drill',
                    where: {id:id},
                    data:data,
                    update_policy:{tags:'array_append', attr_data:'json_merge'}
                })
            }
        })
    })
    
    GUI.msg("Done")
    return 'Done';
}
catch (error) {
    GUI.msg(error);
    return 'Error';
}

function UPLOAD_LAYER_MATRIX(props){
    var job = props.job
    props.jobcategory = props.jobcategory || "work"
	var matrix = ANALYSIS_STACKUP({job:job, jobcategory:props.jobcategory});
	var func = 'function(ARGV)\
	{\
		var jobId = ARGV["job_id"];\
		var tableName = "pdm_job_" + ARGV["jobcategory"] + "_layer";\
		//GUI.msgbox({text: TDataParse.variant2JsonStr(tableName)});\
		var db = new TSqlQueryV2(T_SQLCNT_POOL.getSqlDatabase());\
		db.begin();\
		try{\
			var oLayers = db.selectMapMap({table:tableName, field:["odb_name","release_status"], where:{job_id:jobId}, uniquefield:"odb_name"});\
			if (db.lastError().isValid()) throw db.lastError();\
			//GUI.msgbox({text: TDataParse.variant2JsonStr(oLayers)});\
			\
			db.deleteRow({table:tableName, where:{job_id:jobId}});\
			if (db.lastError().isValid()) throw db.lastError();\
			\
			var fieldLst = ["name", "odb_context", "odb_type", "odb_polarity", "odb_side", "drl_start", "drl_end",\
					 "row_num", "type", "drl_start_num", "drl_end_num", "drl_from_num", "drl_to_num", "drl_connect_to", \
					 "odb_name", "side", "stackup_num", "customer_field", "input_file_name", "odb_row_num"];\
			\
			for (var i=0;i<ARGV["layers"].length;i++)\
			{\
				layerName = ARGV["layers"][i];\
				var layerInfo = ARGV["matrix"][layerName];\
				var tmpData = {"job_id":jobId, "name": layerInfo["name"]};\
				if (ARGV["releasestatus"] != undefined && ARGV["releasestatus"] != null && ARGV["releasestatus"].length>0\
					&& ARGV["releasestatus"][layerInfo["odb_name"]] != undefined && ARGV["releasestatus"][layerInfo["odb_name"]] != null )\
				{\
					tmpData["release_status"] = ARGV["releasestatus"];\
				}\
				else\
				{\
					tmpData["release_status"] = oLayers.hasOwnProperty(layerInfo["odb_name"]) ? oLayers[layerInfo["odb_name"]]["release_status"] : null;\
				}\
				for (n = 0; n < fieldLst.length; n++)\
				{\
					tmpData[fieldLst[n]] = layerInfo[fieldLst[n]];\
				}\
				//GUI.msgbox({text: TDataParse.variant2JsonStr(tmpData)});\
				db.insertRow({table:tableName, data:tmpData});\
				if (db.lastError().isValid()) throw db.lastError();\
			}\
			db.commit();\
			return new TDataResponse();\
		}\
		catch (err)\
		{\
			print(err.text());\
			db.rollback();\
			return new TDataResponse(err, "");\
		}\
    }';
    // var ret = IKM.command( func,     // ?? =========================> tmp
    //     {   job_id :JobId, 
    //         matrix:matrix,
    //         layers: Object.keys(matrix).sort(function(a,b){return matrix[a]["row"] - matrix[b]["row"]}), 
    //         jobcategory:props.jobcategory}, 1);
	// if (ret.errText) {                    
	// 	return {
	// 		jobcategory:props.jobcategory,
	// 		errText :ret.errText,
	// 		errCode :ret.errCode,
	// 	};
    // }
    return matrix
}
function ANALYSIS_STACKUP(props){
    var job = props.job
    if(!props.hasOwnProperty("jobcategory")){ props.jobcategory = 'work' }
    var matrix = GEN.getMatrix({job:job})
	var layer_count = IKM.get_jobinfo({jobname:JobId,jobcategory:props.jobcategory,jobinfo:'layer_count'});
    if(!layer_count){
        layer_count = GEN.getLayerCount({job:job})
    }
	IKM.save_job_info({jobid:JobId,jobcategory:props.jobcategory,jobinfohash:{TL_layer_count:layer_count}});
	_.values(matrix).sort(function(a,b){return a.row-b.row}).forEach(function(layer){
        layer.odb_name = layer.name;
		layer.name = layer.tl_name;
		layer.odb_context = layer.context;
		layer.odb_type = layer.layer_type;
		layer.odb_polarity = layer.polarity;
		layer.odb_side = layer.side;
		layer.row_num = layer.tl_num;
		layer.type = layer.tl_type;
		layer.side = layer.enum_tl_side;
		layer.input_file_name = layer.file_name;
		layer.odb_row_num = layer.row;
		if (layer.odb_name == 'drill'){
			layer.name = 'drill';
			layer.drl_start_num = 1;
			layer.drl_end_num = layer_count;
			layer.drl_from_num = 1;
			layer.drl_to_num = layer_count;
			layer.type = 'main_drill';
		}
		else if (/^d_(\d+)\-(\d+)$/.test(layer.odb_name)){
            var tmp = /^d(\d+)\-(\d+)$/.exec(layer.odb_name)
			var drl_star = tmp[1];
			var drl_end = tmp[2];
			layer.name = 'drill' + drl_star + '-' + drl_end;
			layer.drl_start_num = drl_star;
			layer.drl_end_num = drl_end;
			layer.drl_from_num = drl_star;
			layer.drl_to_num = drl_end;
			if( drl_star == 1 || drl_end == layer_count ){
				layer.type = 'blind_drill';             // 埋孔
			}
			else{
				layer.type = 'bury_drill';              // 盲孔
			}
		}
		else if (/^d(\d+)\-(\d+)$/.test(layer.odb_name)){
            var tmp = /^d(\d+)\-(\d+)$/.exec(layer.odb_name)
			var drl_star = tmp[1];
			var drl_end = tmp[2];
			layer.name = 'd'+drl_star+'-'+drl_end;
			layer.drl_start_num = drl_star;
			layer.drl_end_num = drl_end;
			layer.drl_from_num = drl_star;
			layer.drl_to_num = drl_end;
			layer.type = 'laser_drill';   // 镭射孔
		}
		else if (/\-a$/.test(layer.odb_name)){
            layer.side = 'top';
            if(!layer.name){
                layer.name = '__'+layer.odb_name+'__'
            }
            if(!layer.type){
                layer.type = 'other'
            }
		}
		else if (/\-b$/.test(layer.odb_name)){
            layer.side = 'bottom';
            if(!layer.name){
                layer.name = '__'+layer.odb_name+'__'
            }
            if(!layer.type){
                layer.type = 'other'
            }
		}
		else{
            if(!layer.name){
                layer.name = '__'+layer.odb_name+'__'
            }
			if(!layer.type){
                layer.type = 'other'
            }
		}
    })
    return matrix;
}
function getMatrixInfo(props){  // 获取matrix各种信息
    var job = props.job
    var matrix = GEN.getMatrix({job:job})
    var res = {
        matrix: matrix,   // matrix
        matrixVal: [],   // matrix 的 value数组
        mSignal: {},   // board的signal层 {}
        mSignals: [],   // board的signal层  []
        mDrill: {},  // board的drill层
        mDrills: [],  // board的drill层
        mSolderMask: {},    // 防焊层
        mSolderMasks: [],   // 防焊层
        mOuters: [],    // 外层和对于的防旱
        mBoardLayer: []   // board层
    }
    for (var key in matrix) {
        var value = matrix[key]
        res.matrixVal.push(value)
        if(value.context == "board"){
            res.mBoardLayer.push(key)
            switch (value.layer_type) {
                case "signal":
                    res.mSignal[key] = value
                    res.mSignals.push(value)            
                    break;
                case "drill":
                    res.mDrill[key] = value
                    res.mDrills.push(value)        
                    break;
                case "solder_mask":
                    res.mSolderMask[key] = value
                    res.mSolderMasks.push(value)        
                    break;
            }
        }
    }
    res.matrixVal = res.matrixVal.sort(function(a,b){return Number(a.row) - Number(b.row)})
    res.mSignals = res.mSignals.sort(function(a,b){return Number(a.row) - Number(b.row)})
    res.mDrills = res.mDrills.sort(function(a,b){return Number(a.row) - Number(b.row)})
    // 找出外层  以及外层对应的防焊层 [{signalL:"top", solderL:"smt"}]
    res.mOuters = res.mSignals.reduce(function(a,b){
        if(b.tl_type == "outer"){
			var solderLayers = res.mSolderMasks.filter(function(v){
				return v.side == b.side
			})
           	a.push({
                signalL: b.name,
                solderL: solderLayers.length >0 ? solderLayers[0]["name"] : null
           	})
        }
        return a
    },[])
    return res
}
function selCopyLayer(props){  // 拷贝选择的到辅助层
    var layer = props.layer
    var job = props.job
    if(GEN.isLayerExists({job:job,layer:layer})){
        GEN.deleteLayer({job:job,layer:layer})
    }
    GEN.selCopyOther({dest:'layer_name',target_layer:layer})
}
function save_job_info(props){  // todo 保存料号信息

}
function analysis(props){
    var job = props.job || Job;
    var jobId = props.jobId || JobId;
    var pcs_step = props.pcs_step || false;
    var array_step = props.array_step || false;
    var matrix = props.matrix;
    function T_m_p(props){
        this.job = props.job;
        this.jobInfo = {};
        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; }
        this.matrixInfo = getMatrixInfo({job:this.job})
        this.init();
    }
    T_m_p.prototype.init = function(){
        var init_checking = ["job", "jobId", "pcs_step", "matrix"];
        var t = this;
        init_checking.forEach(function(v){ if(!t[v]){t.e(v+" is undefined")} })
    }
    T_m_p.prototype.e = function(e){  // 处理error
        console.log(e)
        throw e
    }
    T_m_p.prototype.analysis_layer_count = function(props){   // 分析board属性的层数量 []string
        var matrix = this.matrixInfo.matrixVal;
        var res = matrix.filter(function(v){return v.context == "board" && props.indexOf(v.layer_type) >= 0 })
        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)
    }
    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)
    }
    T_m_p.prototype.analysis_vc_pcs_count_on_panel = function(props){  // 
        return "_todo"
    }
    T_m_p.prototype.analysis_stack_vias_number = function(props){        // via孔连续叠加的层数 
        var t = this;
        var res;
        // 找出 镭射孔
        var laser_layers = []
        for (var key in t.matrix) {
            var val = t.matrix[key]
            if(val.type == "laser_drill"){
                laser_layers.push(val)
            }
        }
        if(laser_layers.length == 0){return "error"}
        GEN.openStep({job:t.job,name:t.pcs_step})
        laser_layers = laser_layers.sort(function(a,b){return Number(a.row)-Number(b.row)})
        var laser_info = {}
        for(var i = 0; i < laser_layers.length-1; i++){
            var start_layer = laser_layers[i].name
            var cover_layer = laser_layers[i+1].name
            GEN.workLayer({name:start_layer,display_number:2,clear_before:'yes'})
            GEN.selClearFeature()
            GEN.selRefFeat({layers:cover_layer,use:'filter',mode:'cover'})
            var count = GEN.getSelectCount()
            if(count>0){
                if(!laser_info[start_layer]){
                    laser_info[start_layer] = {}
                }
                laser_info[start_layer].drill_connect_layer = cover_layer
                laser_info[start_layer].drill_connect_point = count
            }
        }
        // via孔连续叠加的层数
        var via_vias_info = []
        function analysis_via_number(layers){
            if(layers.length < 2){return}
            var startlayer = layers[0].name + "_cover" 
            GEN.selClearFeature()
            GEN.workLayer({name:layers[0].name,display_number:2,clear_before:'yes'})
            GEN.selAllFeat()
            selCopyLayer({job:t.job,layer:startlayer})
            var end_index = start_cover_next(startlayer,layers,0)
            via_vias_info.push(end_index+1)
            analysis_via_number(layers.slice(end_index))
        }
        function start_cover_next(start, layers, end_index){
            if(layers.length < 2){
                GEN.deleteLayer({job:t.job,layer:start})
                return end_index
            }
            layers = layers.slice(1)
            GEN.workLayer({name:start,display_number:2,clear_before:'yes'})
            GEN.selClearFeature()
            GEN.selRefFeat({layers:layers[0].name,use:'filter',mode:'cover'})
            var count = GEN.getSelectCount()
            if (count < 1) {
                GEN.deleteLayer({job:t.job,layer:start})
                return ++end_index
            }
            var nextstartlayer = layers[0].name + "_cover" 
            selCopyLayer({job:t.job,layer:nextstartlayer})
            GEN.deleteLayer({job:t.job,layer:start})
            return start_cover_next(nextstartlayer,layers,++end_index)
        }
        analysis_via_number(laser_layers.slice())
        if (via_vias_info.length == 1){
            res = via_vias_info[0]
        }else{
            res = via_vias_info.reduce(function(a,b){return a-b>0?a :b})
        }
        t.jobInfo.stack_vias_more = "no"
        if(GEN.getLayerCount({job:t.job}) > 14 && res >= 12){
            t.jobInfo.stack_vias_more = "yes"
        }
        t.jobInfo.laser_info = laser_info;
        return res
    }
    T_m_p.prototype.analysis_layer_exist = function(props){        // 存在某某层？ string 
        return this.matrixInfo.matrix.hasOwnProperty(props) ? "yes" : "no"
    }
    T_m_p.prototype.analysis_laser_via_on_buried_hole = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_milling_bit_size = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_milling_length = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_board_has_attr = function(props){        //  board层中检查存在01005属性物件时
        GEN.openStep({job:this.job,name:this.pcs_step})
        GEN.clearLayers()
        GEN.affectedLayer({affected:'yes',layer:this.matrixInfo.mBoardLayer,clear_before:'yes'});
        GEN.selClearFeature()
        GEN.selectByFilter({attribute:props})
        var res = GEN.getSelectCount() > 0? "yes" : "no"
        GEN.affectedLayer({affected:'no',mode:'all'});
        GEN.selClearFeature()
        GEN.closeStep()
        return res
    }
    T_m_p.prototype.analysis_vc_src_EDGE_PLATING = function(props){        // ? 检查线路外形是否存在物件，存在则存yes
        var res = "no"
        var rout = this.matrixInfo.matrixVal.filter(function(v){return v.layer_type == "rout"})   // 找rout层
        if(rout.length == 0){
            return "error:cant find rout layer"
        }
        GEN.openStep({job:this.job, name:this.pcs_step})
        GEN.affectedLayer({affected:'no',mode:'all'})
        try {
            this.matrixInfo.mSignals.forEach(function(v){   // 用线路层逐层与rout层touch 找得到说明存在
                GEN.workLayer({name:v.name,display_number:2,clear_before:'yes'})
                GEN.selClearFeature()
                GEN.selRefFeat({layers:rout[0].name,mode:"touch",use:"filter"})
                if( GEN.getSelectCount()>0){
                    throw "yes"
                }
                GEN.clearLayers()
            })
        } catch (msg) {
            res = msg
            GEN.affectedLayer({affected:'no',mode:'all'})
            GEN.selClearFeature()
        }
        GEN.closeStep()
        return res
    }
    T_m_p.prototype.analysis_edge_plating_length = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_glod_finger = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_glod_finger_area = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_solder_mask_side = function(){        //  检查防焊层所在面次 
        var solder_paste_layers = this.matrixInfo.matrixVal.filter(function(v){return v.layer_type == "solder_paste"})
        var solder_paste_info= solder_paste_layers.map(function(v){return v.side}).reduce(function(a,b){
            if(a.indexOf(b)<0){ a.push(b) }
            return a
        },[])
        var res = "no"
        if(solder_paste_info.length == 0){
            res = "no"
        } else if (solder_paste_info.length == 1) {
            res = /top/ig.test(solder_paste_info[0]) ?  "top" : "bot"
        } else {
            res = "both"
        }
        return res
    }
    T_m_p.prototype.analysis_silk_screen_side = function(){        // 检查文字层所在面次 
        var solder_mask_layers = this.matrixInfo.matrixVal.filter(function(v){return v.layer_type == "solder_mask"})
        var solder_mask_info= solder_mask_layers.map(function(v){return v.side}).reduce(function(a,b){
            if(a.indexOf(b)<0){ a.push(b) }
            return a
        },[])
        var res = "no"
        if(solder_mask_info.length == 0){
            res = "no"
        } else if (solder_mask_info.length == 1) {
            res = /top/ig.test(solder_mask_info[0]) ?  "top" : "bot"
        } else {
            res = "both"
        }
        return res
    }
    T_m_p.prototype.analysis_min_drl_size = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_max_pth_drl_size = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_max_npth_drl_size = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_min_slot_drl_size = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_max_slot_drl_size = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_max_slot_drl_length = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_max_spec_slot_drl_size = function(){        // todo 
        return "_todo"
    }
    T_m_p.prototype.analysis_max_spec_slot_drl_length = function(){        // todo 
        return "_todo"
    }
    return new T_m_p({job:job, jobId:jobId, pcs_step:pcs_step, array_step:array_step,matrix:matrix})
}

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 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
                }
            }
        }
    }
}