using Hydro.CodeProvider;
|
using Hydro.CommonBase;
|
//using Hydro.CommonBase.Helper;
|
using Hydro.ConfigModel;
|
using Hydro.HydraulicModel;
|
using Hydro.ParrelControl;
|
|
using SolutionDBHelper_NS;
|
using System;
|
using System.CodeDom;
|
using System.Collections.Generic;
|
using System.Drawing;
|
using System.Linq;
|
using System.Text;
|
using System.Text.RegularExpressions;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using System.Xml.Linq;
|
//using WaterDistributioinManager;
|
using Hydro.ConfigModel;
|
|
using static System.Net.Mime.MediaTypeNames;
|
using System.Reflection;
|
|
namespace Hydro.HydraulicHelperNS
|
{
|
public partial class HydraulicHelper
|
{
|
/// <summary>
|
/// 初始化集合
|
/// </summary>
|
/// <param name="param"></param>
|
/// <returns></returns>
|
public string Init_Set( bool showSettingForm = false, WdnmoParam wParam = null)
|
{
|
|
#region 初始判断
|
|
//this.param = param;
|
|
string result = null;
|
int err = 0;
|
|
#endregion
|
int GetNodeOType(string txt)
|
{
|
switch(txt.ToUpper())
|
{
|
case "JUNCTION":
|
return 0;
|
case "METER":
|
return 1;
|
case "NOZZLE":
|
return 2;
|
default:return 0;
|
}
|
}
|
int GetLinkOType(string txt)
|
{
|
switch (txt)
|
{
|
default: return 0;
|
}
|
}
|
List<string> 节点属性 = new List<string>() { "EN_ELEVATION", "EN_BASEDEMAND", "EN_PATTERN", "EN_EMITTER", "EN_INITQUAL", "EN_SOURCEQUAL", "EN_SOURCEPAT", "EN_SOURCETYPE", "EN_TANKLEVEL", "EN_DEMAND", "EN_HEAD", "EN_PRESSURE", "EN_QUALITY", "EN_SOURCEMASS", "EN_INITVOLUME", "EN_MIXMODEL", "EN_MIXZONEVOL" };
|
List<string> 管线属性 = new List<string>() { "EN_DIAMETER", "EN_LENGTH", "EN_ROUGHNESS", "EN_MINORLOSS", "EN_INITSTATUS", "EN_INITSETTING", "EN_KBULK", "EN_KWALL", "EN_FLOW", "EN_VELOCITY", "EN_HEADLOSS", "EN_STATUS", "EN_SETTING", "EN_ENERGY" };
|
List<string> 节点类型 = new List<string>() { "JUNCTION", "RESERVOIR", "TANK" };
|
List<string> 管线类型 = new List<string>() { "CVPIPE", "PIPE", "PUMP", "PRV", "PSV", "PBV", "FCV", "TCV", "GPV" };
|
param.map_node = new dict<string, dict>();
|
param.map_link = new dict<string, dict>();
|
var map_node = param.map_node;
|
var map_link = param.map_link;
|
|
//获取所有管网\节点对象 {0=节点,1=水库水池,2=管段,3=模式,4=曲线,5=控制}
|
int nodeCount = 0;
|
List<string> repeatNodes = new List<string>();
|
List<string> repeatLinks = new List<string>();
|
|
err = epanet.getcount(0, ref nodeCount);
|
//BookMark :读取管网信息,初始化map_node,map_link
|
for (int i = 1; i <= nodeCount; i++)
|
{
|
StringBuilder id = new StringBuilder();
|
err = epanet.getnodeid(i, id);
|
string ID = id.ToString();
|
//Epanet.Const_class.Const_Node
|
//foreach (Epanet.Const_class.Const_Node j in Enum.GetValues(typeof(Epanet.Const_class.Const_Node)))
|
dict obj = new dict();
|
int typeIndex = -1;
|
err = epanet.getnodetype(i, ref typeIndex);
|
if (err > 9) { result = ReportQuestion(err); return result; }
|
obj.Add("type", typeIndex);
|
obj.Add("index",i);
|
obj.Add("isnode", 1);
|
for (int j = 0; j < 节点属性.Count; j++) //节点数值为16
|
{
|
float value = 0;
|
err = epanet.getnodevalue(i, j, ref value);
|
//if (err > 9) { result = ReportQuestion(err); return result; }
|
obj.Add(节点属性[j], value);
|
}
|
err=epanet.getnodecomment(i, id);
|
if (err > 9) { result = ReportQuestion(err); return result; }
|
Parts p = new Parts(id.ToString());
|
string oType = p.ToString(1, null);
|
if (oType != null) obj.Add("otype", GetNodeOType(oType)); else obj.Add("otype", typeIndex);
|
|
if (!map_node.ContainsKey(ID))
|
{
|
map_node.Add(ID, obj);
|
}
|
else
|
{
|
repeatNodes.Add(ID);
|
}
|
}
|
|
//获取所有管网\节点对象 {0=节点,1=水库水池,2=管段,3=模式,4=曲线,5=控制}
|
int linkCount = 0;
|
err = epanet.getcount(2, ref linkCount);
|
|
for (int i = 1; i <= linkCount; i++)
|
{
|
StringBuilder id = new StringBuilder();
|
err = epanet.getlinkid(i, id);
|
string ID = id.ToString();
|
//Epanet.Const_class.Const_Node
|
//foreach (Epanet.Const_class.Const_Node j in Enum.GetValues(typeof(Epanet.Const_class.Const_Node)))
|
dict obj = new dict();
|
int typeIndex = -1;
|
err = epanet.getlinktype(i, ref typeIndex);
|
if (err > 9) { result = ReportQuestion(err); return result; }
|
obj.Add("type", typeIndex);
|
obj.Add("index", i);
|
obj.Add("isnode",0);
|
for (int j = 0; j < 管线属性.Count; j++) //节点数值为16
|
{
|
float value = 0;
|
err = epanet.getlinkvalue(i, j, ref value);
|
obj.Add(管线属性[j], value);
|
}
|
Parts p = new Parts(id.ToString());
|
string oType = p.ToString(1, null);
|
if (oType != null) obj.Add("otype", GetLinkOType(oType)); else obj.Add("otype", typeIndex);
|
if (!map_link.ContainsKey(ID)) map_link.Add(ID, obj);
|
else { repeatLinks.Add(ID); }
|
}
|
|
|
//处理变量
|
bool flag = true;
|
|
if (!flag) return result;
|
|
|
if (repeatNodes.Count > 0)
|
{
|
result += $"重复节点清单:\r\n{string.Join("\r\n", repeatNodes)}";
|
}
|
if (repeatLinks.Count > 0)
|
{
|
result += $"重复链接清单:\r\n{string.Join("\r\n", repeatLinks)}";
|
}
|
|
if (result != null)
|
return result;
|
//处理变量
|
|
param.集合.ForEach(s =>
|
{
|
if (!flag) return;
|
//直接执行条件,获取集合合
|
s.Vars = new List<Ivariable>();
|
Eval val;
|
val = new Eval(s.modelObjectID, EvalTemplate.TempCode_Set);
|
if (val.errString != null) { result += $"集合[{s.Name}]表达式错误," + val.errString; flag = false; return; }
|
var contents = val.getResult(map_node, map_link);
|
foreach (var item in contents)
|
{
|
string id = item.Key;
|
dict<string, double> obj = item.Value;
|
var v = new VarSimple();
|
//v.isNode = obj["isnode"]==1;
|
//if (v.isNode!=s.isNode)
|
//{
|
// result += $"集合[{s.Name}]中元素[{id}]点线类型异常";
|
//}
|
//v.modelObjectID = id;
|
if (s.isNode)
|
{
|
v.modelIndex = (int)param.map_node[id]["index"];
|
}
|
else
|
{
|
v.modelIndex = (int)param.map_link[id]["index"];
|
}
|
|
//v.Type = s.Type;
|
|
//v.expressType = s.defineType;
|
s.Vars.Add(v);
|
}
|
if (s.Vars.Count == 0) { result += $"集合[{s.Name}]筛选后数量为0"; flag = false; return; }
|
});
|
|
if (!flag) return result;
|
|
//处理接口中的新增集合
|
if (wParam != null && wParam.VarSets_Import != null)
|
{
|
foreach(vSet S_import in wParam.VarSets_Import)
|
{
|
variable s = new variable();
|
s.ID= S_import.ID;
|
s.isNode = S_import.isNode;
|
s.Name = S_import.Name;
|
s.Tag= S_import.Tag;
|
s.Vars = new List<Ivariable>();
|
s.logicType = "集合";
|
s.modelIndex = 0;
|
s.defaultExpress = S_import.defaultExpress;
|
s.IndicatorType = S_import.IndicatorType;
|
s.expressType = "集合计算";
|
|
|
//var VarType = GlobalModel.dict_StringToType[S_import.IndicatorType];
|
|
//int ObjType = GlobalModel.dict_StringToObjType[S_import.ObjectType];
|
|
//bool isNode = GlobalModel.dict_StringToisNode[S_import.IndicatorType];
|
|
//int arrgFuncType = GlobalModel.dict_StringToFuncType[S_import.defaultExpress];
|
|
dynamic VarType = HydraulicInputType.None;
|
if (GlobalModel.dict_StringToType.TryGetValue(S_import.IndicatorType, out dynamic vartype))
|
VarType = vartype;
|
|
|
int ObjType = 0;
|
if (GlobalModel.dict_StringToObjType.TryGetValue(S_import.ObjectType, out int objType))
|
ObjType = objType;
|
|
|
bool isNode = true;
|
if (GlobalModel.dict_StringToisNode.TryGetValue(S_import.IndicatorType, out bool isnode))
|
isNode = isnode;
|
|
|
int arrgFuncType = -1;
|
if (GlobalModel.dict_StringToFuncType.TryGetValue(S_import.defaultExpress, out int FuncInt))
|
arrgFuncType = FuncInt;
|
|
|
s.Type = VarType;
|
s.arrgFuncType = arrgFuncType;
|
s.ObjType = (int)ObjType;
|
|
S_import.IDs.ForEach(id =>
|
{
|
var v = new VarSimple();
|
//v.isNode = id.isNode;
|
if (s.isNode)
|
{
|
v.modelIndex = (int)param.map_node[id]["index"];
|
}
|
else
|
{
|
v.modelIndex = (int)param.map_link[id]["index"];
|
}
|
s.Vars.Add(v);
|
});
|
if (s.Vars.Count == 0) { result += $"集合[{s.Name}]筛选后数量为0"; flag = false; }
|
param.集合.Add(s);
|
}
|
|
}
|
if (!flag) return result;
|
//处理wParam.Vars_Import
|
if (wParam != null && wParam.Vars_Import != null)
|
{
|
foreach (var v in wParam.Vars_Import)
|
{
|
//根据v的LogicType,添加到对应的变量列表中
|
if (v.logicType == "初始条件")
|
{
|
param.初始条件.Add(v);
|
}
|
else if (v.logicType == "下阶段条件")
|
{
|
param.下阶段条件.Add(v);
|
}
|
else if (v.logicType == "试算变量")
|
{
|
param.试算变量.Add(v);
|
}
|
else if (v.logicType == "约束变量")
|
{
|
param.约束变量.Add(v);
|
}
|
else if (v.logicType == "变量")
|
{
|
param.变量.Add(v);
|
}
|
else if (v.logicType == "水量分配")
|
{
|
param.水量分配变量.Add(v);
|
}
|
}
|
}
|
param.buildDict();
|
|
|
#region 初始条件和下阶段条件
|
/*
|
*[Cloudflight修改]2024-5-15
|
* 初始条件和下阶段条件,不再使用集合变量来批量增加初始条件,而是在初始条件赋值时,直接调用集合变量的子变量来进行赋值
|
*/
|
param.初始条件.ToList().ForEach(v =>
|
{
|
if (result != null) return;
|
v.modelIndex = GetIndex(v);
|
//如果初始条件是集合变量
|
if (v.modelIndex == 0)
|
{
|
var ss = param.dict_Name.Get(v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
if (ss == null || ss.logicType != "集合")
|
{
|
result = $"{v.logicType}[{v.Name}]中设置了不存在的集合名称[{v.modelObjectID.Trim('{').Trim('}').Trim('|')}]";
|
return;
|
}
|
v.Vars = ss.Vars;
|
}
|
});
|
if (result != null) return result;
|
//List<variable> Vset;
|
//List<variable> Vset_del;
|
//Vset = new List<variable>();
|
//Vset_del = new List<variable>();
|
|
//param.初始条件.ToList().ForEach(v =>
|
//{
|
// if (result != null) return;
|
// v.modelIndex = GetIndex(v);
|
// //如果初始条件是集合变量
|
// if (v.modelIndex == 0)
|
// {
|
// var ss = param.dict_Name.Get(v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
// if (ss == null || ss.logicType!="集合")
|
// {
|
// result = $"{v.logicType}[{v.Name}]中设置了不存在的集合名称[{v.modelObjectID.Trim('{').Trim('}').Trim('|')}]";
|
// return;
|
// }
|
// //[Cloudflight修改]2023-12-29
|
// var Vset_copy = ss.Vars.DeepCopyByBin<List<Ivariable>>();
|
// //var Vset_copy = ss.Vars.ToList();
|
// Vset_copy.ForEach(c => SetVarByVset(c, v));
|
// Vset.AddRange(Vset_copy);
|
// Vset_del.Add(v);
|
// }
|
//});
|
//if (result != null) return result;
|
//param.初始条件.AddRange(Vset);
|
|
|
param.下阶段条件.ToList().ForEach(v =>
|
{
|
if (result != null) return;
|
v.modelIndex = GetIndex(v);
|
if (v.modelIndex == 0)
|
{
|
var ss = param.dict_Name.Get(v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
if (ss == null || ss.logicType != "集合")
|
{
|
result = $"{v.logicType}[{v.Name}]中设置了不存在的集合名称[{v.modelObjectID.Trim('{').Trim('}').Trim('|')}]";
|
return;
|
}
|
v.Vars = ss.Vars;
|
}
|
});
|
//Vset = new List<variable>();
|
//Vset_del = new List<variable>();
|
//param.下阶段条件.ToList().ForEach(v =>
|
//{
|
// if (result != null) return;
|
// v.modelIndex = GetIndex(v);
|
// if (v.modelIndex == 0)
|
// {
|
// var ss = param.dict_Name.Get(v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
// if (ss == null || ss.logicType != "集合")
|
// {
|
// result = $"{v.logicType}[{v.Name}]中设置了不存在的集合名称[{v.modelObjectID.Trim('{').Trim('}').Trim('|')}]";
|
// return;
|
// }
|
// //[Cloudflight修改]2023-12-29
|
// var Vset_copy = ss.Vars.DeepCopyByBin<List<variable>>();
|
// //var Vset_copy = ss.Vars.ToList();
|
// Vset_copy.ForEach(c => SetVarByVset(c, v));
|
// Vset.AddRange(Vset_copy);
|
// Vset_del.Add(v);
|
// }
|
//});
|
//if (result != null) return result;
|
//param.下阶段条件.AddRange(Vset);
|
#endregion
|
|
|
#region 试算变量
|
/*
|
*[Cloudflight修改]2024-5-15
|
* 试算变量不再支持集合变量,将集合中的子变量简化成Ivariable
|
*/
|
//Vset = new List<variable>();
|
//Vset_del = new List<variable>();
|
//param.试算变量.ToList().ForEach(v =>
|
//{
|
// if (result != null) return;
|
// v.modelIndex = GetIndex(v);
|
// if (v.modelIndex == 0)
|
// {
|
// var ss = param.dict_Name.Get(v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
// if (ss == null || ss.logicType != "集合")
|
// {
|
// result = $"{v.logicType}[{v.Name}]中设置了不存在的集合名称[{v.modelObjectID.Trim('{').Trim('}').Trim('|')}]";
|
// return;
|
// }
|
// //[Cloudflight修改]2023-12-29
|
// var Vset_copy = ss.Vars.DeepCopyByBin<List<variable>>();
|
// //var Vset_copy = ss.Vars.ToList();
|
// Vset_copy.ForEach(c => SetVarByVset(c, v));
|
// Vset.AddRange(Vset_copy);
|
// Vset_del.Add(v);
|
// }
|
//});
|
//if (result != null) return result;
|
//param.试算变量.AddRange(Vset);
|
//Vset_del.ForEach(v => param.试算变量.Remove(v));
|
|
//Vset = new List<variable>();
|
//Vset_del = new List<variable>();
|
|
|
|
param.试算变量.ToList().ForEach(v =>
|
{
|
if (result != null) return;
|
v.modelIndex = GetIndex(v);
|
if (v.modelIndex == 0)
|
{
|
var ss = param.dict_Name.Get(v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
if (ss == null || ss.logicType != "集合")
|
{
|
result = $"{v.logicType}[{v.Name}]中设置了不存在的集合名称[{v.modelObjectID.Trim('{').Trim('}').Trim('|')}]";
|
return;
|
}
|
v.Vars=ss.Vars;
|
|
}
|
});
|
#endregion
|
|
|
|
//if (param.水量分配变量.Count > 1) return "水量分配变量只允许设置一个";
|
|
param.水量分配变量.ToList().ForEach(v =>
|
{
|
//if (result != null) return;
|
v.modelIndex = GetIndex(v);
|
if (v.modelIndex == 0)
|
{
|
var ss = param.dict_Name.Get(v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
if (ss == null || ss.logicType != "集合")
|
{
|
result = $"{v.logicType}[{v.Name}]中设置了不存在的集合名称[{v.modelObjectID.Trim('{').Trim('}').Trim('|')}]";
|
return;
|
}
|
//[Cloudflight修改]2024-5-16
|
/*
|
* 水量分配变量,将集合中的子变量简化成Ivariable
|
*/
|
v.Vars = ss.Vars;
|
////[Cloudflight修改]2023-12-29
|
//var Vset_copy = ss.Vars.DeepCopyByBin<List<variable>>();
|
////var Vset_copy = ss.Vars.ToList();
|
//Vset_copy.ForEach(c =>
|
//{
|
// SetVarByVset(c, v);
|
// c.Type = HydraulicInputType.demand;
|
//});
|
//Vset.AddRange(Vset_copy);
|
//Vset_del.Add(v);
|
|
if (v.Vars.Count == 0) { result += $"水量分配变量[{v.Name}]的数量为0\r\n"; }
|
if (v.IndicatorType == "当量分配")
|
{
|
try
|
{
|
float disTotalDemand = float.Parse(v.expressString.Split(':')[0]);
|
var list = v.expressString.Split(':')[1].Split(',').ToList();
|
List<UvalueSetting> uvalueSettings=new List<UvalueSetting>();
|
for (int i = 0; i < list.Count; i += 3)
|
{
|
uvalueSettings.Add(new UvalueSetting(long.Parse(list[i]), float.Parse(list[i + 1]), float.Parse(list[i + 2])));
|
}
|
}
|
catch (Exception ex)
|
{
|
result += $@"水量分配变量[{v.Name}]的分配参数""{v.expressString}""解析错误\r\n";
|
}
|
}
|
|
|
|
}
|
});
|
if (result != null) return result;
|
|
/*[Cloudflight修改]2024-5-16
|
* 水量分配变量,读取v.Vars中的Ivar进行赋值,多线程的值存储在染色体中
|
*
|
*/
|
|
//param.水量分配集合.AddRange(Vset);
|
//Vset_del.ForEach(v => param.水量分配变量.Remove(v));
|
|
//param.水量分配集合.Sort(
|
// (a, b) => {
|
// return (a.modelIndex > b.modelIndex) ? 1 : -1;
|
// }
|
//);
|
|
//param.水量分配集合.ForEach(v =>
|
//{
|
// if (result != null) return;
|
// float tempValue = -1;
|
// err = epanet.getnodevalue(v.modelIndex, HydraulicCore.Const_class.Const_Node.EN_ELEVATION, ref tempValue);
|
// if (err > 9) result += "标高初始化错误:" + ReportQuestion(err) + "\r\n";
|
// v.elevation = tempValue;
|
//});
|
|
//BookMark :根据集合变量处理变量
|
/*[Cloudflight修改]2024-5-16
|
* 集合变量,将集合中的子变量简化成Ivariable,不再存储在param.变量中,而是直接存储在param.集合的Vars中
|
* 关于变量集合是否需要存值,变量集合只是一个中间变量,不需要存值,只需要存储在param.集合的Vars中
|
* 需要输出的时候,直接根据param.集合的Vars中的值进行输出
|
* 可以通过param.dict_OutPut来获取输出的变量,通过param.dict_OutPut的key来获取输出的变量
|
* dict_Output中存储的是Ivariable,需要getvalue方法支持Ivarible
|
*/
|
//Vset = new List<variable>();
|
//Vset_del = new List<variable>();
|
|
param.变量.ToList().ForEach(v =>
|
{
|
if (result != null) return;
|
v.modelIndex = GetIndex(v);
|
if (v.modelIndex == 0)
|
{
|
//if (v.IndicatorType == "总水量") return;
|
var ss = param.dict_Name.Get(v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
if (ss == null || ss.logicType != "集合")
|
{
|
result = $"{v.logicType}[{v.Name}]中设置了不存在的集合名称[{v.modelObjectID.Trim('{').Trim('}').Trim('|')}]";
|
return;
|
}
|
v.Vars = ss.Vars;
|
v.Vars.ForEach(vv =>
|
{
|
var modelObjectID =GetModelObjectID(vv,v.isNode);
|
var outputKey = v.expressString + "_" + modelObjectID;
|
if (!param.dict_OutPut.ContainsKey(outputKey))
|
param.dict_OutPut.Add(outputKey, new Ivariable[] { v,vv});
|
});
|
//[Cloudflight修改]2023-12-29
|
//var Vset_copy = ss.Vars.DeepCopyByBin<List<variable>>();
|
////var Vset_copy = ss.Vars.ToList();
|
//Vset_copy.ForEach(c =>
|
//{
|
// SetVarOutputByVset(c, v);
|
//});
|
//Vset.AddRange(Vset_copy);
|
//Vset_del.Add(v);
|
|
//如何保证这些变量的值,在多线程中计算时的正确性?所有的集合变量计算值的时候,都是通过Vars进行临时计算,不通过缓存值
|
//1、集合聚合方式包括:求和、计数、最大、最小、平均
|
//--集合聚合值本身存储在集合变量中,集合的子变量并不进行存储而是按需进行计算和输出
|
//2、集合衍生的使用方式包括:初始条件、下阶段条件、水量分配变量、变量
|
//--初始条件和下阶段条件,不再使用集合变量来批量增加初始条件,而是在初始条件赋值时,直接调用集合变量的子变量来进行赋值
|
//--试算变量不再支持集合变量,将集合中的子变量简化成Ivariable
|
//--水量分配变量,读取v.Vars中的Ivar进行赋值,多线程的值存储在染色体中
|
//--集合变量,将集合中的子变量简化成Ivariable,不再存储在param.变量中,而是直接存储在param.集合的Vars中
|
//source.expressString + "_" + v.modelObjectID;
|
}
|
});
|
if (result != null) return result;
|
|
|
//param.变量.AddRange(Vset);
|
//Vset.ForEach(vv =>
|
//{
|
// param.dict_OutPut.AddKey(vv.expressString, vv);
|
//});
|
return result;
|
}
|
|
|
public string GetModelObjectID(Ivariable vv,bool isNode)
|
{
|
return isNode ? param. map_node.GetKeys()[vv.modelIndex - 1] :param. map_link.GetKeys()[vv.modelIndex - 1];
|
}
|
/// <summary>
|
/// 初始化预处理器
|
/// </summary>
|
/// <param name="param"></param>
|
/// <returns></returns>
|
public string Init_PreTool()
|
{
|
|
#region 初始判断
|
|
//this.param = param;
|
|
string result = null;
|
int err = 0;
|
|
#endregion
|
//获取所有管网\节点对象 {0=节点,1=水库水池,2=管段,3=模式,4=曲线,5=控制}
|
int nodeCount = 0;
|
//处理变量
|
bool flag = true;
|
param.预处理插件.ForEach(v =>
|
{
|
if (!flag) return;
|
Eval val;
|
val = new Eval(v.modelObjectID, EvalTemplate.TempCode_preTool);
|
if (val.errString != null) { result += $"预处理插件[{v.Name}]函数编写错误," + val.errString; flag = false; return; }
|
v.Eval = val;
|
});
|
if (!flag) return result;
|
return result;
|
}
|
}
|
}
|