|
|
using connor_zwcadm.dialog;
|
|
|
using connor_zwcadm.model;
|
|
|
using connor_zwcadm.util;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.ComponentModel;
|
|
|
using System.IO;
|
|
|
using System.Text;
|
|
|
using System.Windows.Forms;
|
|
|
using ZwSoft.ZwCAD.ApplicationServices;
|
|
|
using ZwSoft.ZwCAD.DatabaseServices;
|
|
|
using Application = ZwSoft.ZwCAD.ApplicationServices.Application;
|
|
|
|
|
|
namespace connor_zwcadm.commands {
|
|
|
public class SaveCommand : AbstractCADCommand {
|
|
|
|
|
|
public const bool IS_PACK = true;
|
|
|
|
|
|
public SaveCommand(string file_path, bool isBatchSave) : base(file_path) {
|
|
|
bgWorker = new KBackgroundWorker();
|
|
|
if (isBatchSave) {
|
|
|
bgWorker.backgroundWorker.DoWork += DoBatchSave;
|
|
|
}
|
|
|
else {
|
|
|
bgWorker.backgroundWorker.DoWork += DoSave;
|
|
|
}
|
|
|
TCUtil = new TCUtil(bgWorker);
|
|
|
}
|
|
|
|
|
|
private string[] uploadFileConfig; // 关系 数据集类型 数据集引用 fms地址
|
|
|
|
|
|
private string fmsUrl;
|
|
|
private KBackgroundWorker bgWorker { get; }
|
|
|
public TCUtil TCUtil { get; }
|
|
|
|
|
|
public void CycleBom(TCData parentData, Dictionary<string, TCData> docDatas, List<string> savedDocs, List<TCData> docsToSave, List<string> checkedIds,List<string> fuIds) {
|
|
|
if (parentData == null) {
|
|
|
return;
|
|
|
}
|
|
|
List<TCData> childDatas = parentData.BomLineDatas;
|
|
|
int childCnt = childDatas == null ? 0 : childDatas.Count;
|
|
|
List<string> currentLevelIds = new List<string>();
|
|
|
string itemId = parentData.Item_id;
|
|
|
for (int i = 0; i < childCnt; i++) {
|
|
|
string childId = childDatas[i].Item_id;
|
|
|
if (fuIds.Contains(childId))
|
|
|
{
|
|
|
throw new Exception("图纸存在循环结构,请检查。子件ID为:" + childId+ ",母件ID为:"+ itemId);
|
|
|
}
|
|
|
if (!currentLevelIds.Contains(childId)) {
|
|
|
currentLevelIds.Add(childId);
|
|
|
}
|
|
|
}
|
|
|
/* if (childCnt > 0)
|
|
|
{
|
|
|
fuIds.Add(itemId);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
string topID = fuIds[0];
|
|
|
fuIds = new List<string>();
|
|
|
fuIds.Add(topID);
|
|
|
}*/
|
|
|
|
|
|
childCnt = currentLevelIds.Count;
|
|
|
for (int i = 0; i < childCnt; i++) {
|
|
|
string childId = currentLevelIds[i];
|
|
|
if (!checkedIds.Contains(childId)) {
|
|
|
checkedIds.Add(childId);
|
|
|
}
|
|
|
else {
|
|
|
//throw new Exception("图纸存在循环结构,请检查。问题ID为:" + childId);
|
|
|
}
|
|
|
if (!docDatas.ContainsKey(childId)) {
|
|
|
KUtil.Log("图纸中子件ID为\"" + childId + "\"的图纸不存在:" + parentData.DocFileName);
|
|
|
continue;
|
|
|
}
|
|
|
List<TCData> childDatas2 = docDatas[childId].BomLineDatas;
|
|
|
string itemId2 = docDatas[childId].Item_id;
|
|
|
if (childDatas2.Count > 0)
|
|
|
{
|
|
|
fuIds.Add(itemId2);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
string topID = fuIds[0];
|
|
|
fuIds.Clear();
|
|
|
fuIds.Add(topID);
|
|
|
}
|
|
|
KUtil.Log("fuID.count:" + fuIds.Count);
|
|
|
CycleBom(docDatas[childId], docDatas, savedDocs, docsToSave, checkedIds, fuIds);
|
|
|
}
|
|
|
|
|
|
if (savedDocs.Contains(itemId)) {
|
|
|
return;
|
|
|
}
|
|
|
savedDocs.Add(itemId);
|
|
|
docsToSave.Add(parentData);
|
|
|
}
|
|
|
|
|
|
//批量保存
|
|
|
public void DoBatchSave(object sender, DoWorkEventArgs e) {
|
|
|
|
|
|
bgWorker.Progress("初始化","", 0);
|
|
|
bgWorker.Progress("读取图纸数据", 0);
|
|
|
TCData titleData = KCADUtil.ReadDocData(true, TCUtil);
|
|
|
string currentDocId = titleData.Item_id;
|
|
|
string currentDocPath = File_Path;
|
|
|
KUtil.Log("当前图纸路径:" + currentDocPath);
|
|
|
string folderName = System.IO.Path.GetDirectoryName(currentDocPath);
|
|
|
KUtil.Log("查询文件夹中的图纸: " + folderName);
|
|
|
string[] filePaths = System.IO.Directory.GetFiles(folderName, "*.dwg");
|
|
|
int fileCnt = KUtil.GetLen(filePaths);
|
|
|
KUtil.Log("找到图纸数量:" + fileCnt);
|
|
|
Dictionary<string, TCData> docDatas = new Dictionary<string, TCData>();
|
|
|
docDatas.Add(currentDocId, titleData);
|
|
|
for (int i = 0; i < fileCnt; i++) {
|
|
|
string filePath = filePaths[i];
|
|
|
|
|
|
bgWorker.Progress("读取文件夹中的图纸数据 ( " + (i + 1) + " / " + fileCnt + " )", 0);
|
|
|
KUtil.Log((i + 1) + ". 加载文件" + filePath);
|
|
|
if (currentDocPath.Equals(filePath)) {
|
|
|
KUtil.Log("跳过当前图纸");
|
|
|
continue;
|
|
|
}
|
|
|
TCData docData;
|
|
|
KCADUtil kCADUtil = new KCADUtil(filePath);
|
|
|
try {
|
|
|
docData = kCADUtil.ReadDocData(true, TCUtil);
|
|
|
} catch (Exception ex) {
|
|
|
KUtil.Log("读取图纸数据失败:" + ex.Message);
|
|
|
continue;
|
|
|
}
|
|
|
finally {
|
|
|
kCADUtil.CloseDatabse();
|
|
|
}
|
|
|
string docId = docData.Item_id;
|
|
|
if (docDatas.ContainsKey(docId)) {
|
|
|
throw new Exception("存在对象ID重复的图纸[" + docId + "]:\r\n" + docData.DocFileName + "\r\n" + docDatas[docId].DocFileName);
|
|
|
}
|
|
|
docDatas.Add(docId, docData);
|
|
|
}
|
|
|
|
|
|
KUtil.Log("找到文件夹中的标题栏对象:"+string.Join(", ", docDatas.Keys));
|
|
|
List<TCData> docsToSave = new List<TCData>();
|
|
|
List<string> docIdsToSave = new List<string>();
|
|
|
List<string> fuIDs = new List<string>();
|
|
|
fuIDs.Add(titleData.Item_id);
|
|
|
CycleBom(titleData, docDatas, docIdsToSave, docsToSave, new List<string>(), fuIDs);
|
|
|
KUtil.Log("将按顺序保存以下图纸\r\n"+string.Join(" > ", docIdsToSave)+"\r\n"+string.Join("\r\n", docsToSave));
|
|
|
int docCnt = docsToSave.Count;
|
|
|
//检查所有图纸
|
|
|
List<string> idsToCreate = new List<string>();
|
|
|
StringBuilder propertyInfo = new StringBuilder();
|
|
|
for (int i=0; i<docCnt; i++) {
|
|
|
TCData parentData = docsToSave[i];
|
|
|
string itemId = parentData.Item_id;
|
|
|
bgWorker.Progress("检查图纸:" + itemId, "检查标题栏数据", (i * 100) / docCnt);
|
|
|
//检查ID
|
|
|
// CheckIdInTitle(itemId, idsToCreate, parentData.ItemTypeName);
|
|
|
// 检查BOM
|
|
|
List<TCData> bomlineDatas = parentData.BomLineDatas;
|
|
|
int bomlineCnt = bomlineDatas == null ? 0 : bomlineDatas.Count;
|
|
|
for (int j = 0; j < bomlineCnt; j++) {
|
|
|
bgWorker.ProgressDetail("检查明细栏数据 ( " + (j + 1) + " / " + bomlineCnt + " )");
|
|
|
TCData bomlineData = bomlineDatas[j];
|
|
|
CheckIdInBom(bomlineData, propertyInfo, idsToCreate);
|
|
|
}
|
|
|
}
|
|
|
if (propertyInfo.Length > 0) {
|
|
|
string msg = "下列图号的零组件存在属性与TC系统不一致的情况,是否同步图纸属性并继续?" + propertyInfo.ToString();
|
|
|
System.Windows.MessageBoxResult dialogResult = System.Windows.MessageBoxResult.No;
|
|
|
bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate {
|
|
|
dialogResult = System.Windows.MessageBox.Show(msg, "提示", System.Windows.MessageBoxButton.YesNo);
|
|
|
}));
|
|
|
if (dialogResult != System.Windows.MessageBoxResult.Yes) {
|
|
|
bgWorker.CompleteMessage = null;
|
|
|
KUtil.Log("取消批量保存");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
StringBuilder errSB = new StringBuilder();
|
|
|
for (int i = 0; i < docCnt; i++) {
|
|
|
TCData parentData = docsToSave[i];
|
|
|
string itemId = parentData.Item_id;
|
|
|
bgWorker.Progress("保存图纸:" + itemId, (i * 100) / docCnt);
|
|
|
KUtil.Log("-------------------------------------------------------------------");
|
|
|
KUtil.Log("开始保存图纸[" + itemId + "]:" + parentData.DocFileName);
|
|
|
//同步对象属性
|
|
|
Boolean iserr = TCUtil.CreateOrUpdateItem(parentData);
|
|
|
//更新BOM
|
|
|
TCUtil.GetProperties(parentData.Rev, "object_name");
|
|
|
TCUtil.GetProperties(parentData.Rev, "item_revision_id");
|
|
|
TCUtil.CreateOrUpdateBom(parentData, IS_PACK);
|
|
|
if (!iserr)
|
|
|
{
|
|
|
errSB.Append(parentData.Item_id);
|
|
|
errSB.Append("-");
|
|
|
errSB.Append(parentData.Rev.Item_revision_id);
|
|
|
errSB.Append("-");
|
|
|
errSB.Append(parentData.Rev.Object_name);
|
|
|
errSB.Append(";");
|
|
|
continue;
|
|
|
}
|
|
|
//上传文件
|
|
|
|
|
|
string dsName = itemId + "-" + parentData.Rev.Object_name;
|
|
|
|
|
|
|
|
|
List<string> tempFiles = new List<string>();
|
|
|
//DocumentLock m_DocumentLock = ZwSoft.ZwCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
|
|
|
TCUtil.UploadFile(parentData, uploadFileConfig[0], uploadFileConfig[1], uploadFileConfig[2], dsName, tempFiles, fmsUrl);
|
|
|
//m_DocumentLock.Dispose();
|
|
|
|
|
|
|
|
|
ConvertPDFAndUpload(parentData);
|
|
|
|
|
|
KUtil.Log("保存图纸完成:" + parentData.DocFileName);
|
|
|
// 清理缓存
|
|
|
foreach (string path in tempFiles)
|
|
|
{
|
|
|
File.Delete(path);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bgWorker.Progress("保存完成", "", 100);
|
|
|
if (!("".Equals(errSB.ToString())))
|
|
|
{
|
|
|
MessageBox.Show("数据保存成功,但"+errSB.ToString()+ "对象数据更新失败,请查看权限!!!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
|
|
|
|
|
|
}
|
|
|
System.Threading.Thread.Sleep(800);
|
|
|
}
|
|
|
//单个保存
|
|
|
public void DoSave(object sender, DoWorkEventArgs e) {
|
|
|
bgWorker.Progress("初始化", "",0);
|
|
|
//读取图纸数据
|
|
|
bgWorker.Progress("读取图纸数据", 10);
|
|
|
TCData titleData = KCADUtil.ReadDocData(true, TCUtil);
|
|
|
string itemId = titleData.Item_id;
|
|
|
List<TCData> bomlineDatas = titleData.BomLineDatas;
|
|
|
//检查ID
|
|
|
bgWorker.Progress("检查标题栏数据", 30);
|
|
|
CheckIdInTitle(itemId, null, titleData.ItemTypeName);
|
|
|
// 检查BOM
|
|
|
bgWorker.Progress("检查明细栏数据", 40);
|
|
|
int bomlineCnt = bomlineDatas == null ? 0 : bomlineDatas.Count;
|
|
|
StringBuilder propertyInfo = new StringBuilder();
|
|
|
for(int i = 0; i < bomlineCnt; i++) {
|
|
|
bgWorker.ProgressDetail("检查明细栏数据 ( " + (i + 1) + " / " + bomlineCnt + " )");
|
|
|
TCData bomlineData = bomlineDatas[i];
|
|
|
CheckIdInBom(bomlineData, propertyInfo, null);
|
|
|
}
|
|
|
if (propertyInfo.Length > 0) {
|
|
|
string msg = "下列图号的零组件存在属性与TC系统不一致的情况,是否同步图纸属性并继续?"+propertyInfo.ToString();
|
|
|
System.Windows.MessageBoxResult dialogResult = System.Windows.MessageBoxResult.No;
|
|
|
bgWorker.pbDialog.Dispatcher.Invoke(new Action(delegate {
|
|
|
dialogResult = System.Windows.MessageBox.Show(msg, "提示", System.Windows.MessageBoxButton.YesNo);
|
|
|
}));
|
|
|
if (dialogResult != System.Windows.MessageBoxResult.Yes) {
|
|
|
bgWorker.CompleteMessage = null;
|
|
|
KUtil.Log("取消保存");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
//同步对象属性
|
|
|
bgWorker.Progress("保存标题栏数据", 60);
|
|
|
Boolean iserr = TCUtil.CreateOrUpdateItem(titleData);
|
|
|
//更新BOM
|
|
|
bgWorker.Progress("保存明细栏数据", 80);
|
|
|
TCUtil.CreateOrUpdateBom(titleData, IS_PACK);
|
|
|
|
|
|
//上传文件
|
|
|
bgWorker.Progress("上传文件", 90);
|
|
|
|
|
|
TCUtil.GetProperties(titleData.Rev, "item_revision_id");
|
|
|
TCUtil.GetProperties(titleData.Rev, "object_name");
|
|
|
if (!iserr)
|
|
|
{
|
|
|
StringBuilder errSB = new StringBuilder();
|
|
|
errSB.Append(itemId);
|
|
|
errSB.Append("-");
|
|
|
errSB.Append(titleData.Rev.Item_revision_id);
|
|
|
errSB.Append("-");
|
|
|
errSB.Append(titleData.Rev.Object_name);
|
|
|
errSB.Append(":数据更新失败,请查看权限!!!");
|
|
|
throw new Exception(errSB.ToString());
|
|
|
}
|
|
|
string dsName = itemId + "-" + titleData.Rev.Object_name;
|
|
|
|
|
|
|
|
|
List<string> tempFiles = new List<string>();
|
|
|
//DocumentLock m_DocumentLock = ZwSoft.ZwCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
|
|
|
//TCUtil.UploadFile(titleData, uploadFileConfig[0], uploadFileConfig[1], uploadFileConfig[2], dsName,tempFiles, fmsUrl);
|
|
|
//m_DocumentLock.Dispose();
|
|
|
KCADUtil.saveData();
|
|
|
ConvertPDFAndUpload(titleData);
|
|
|
// 清理缓存
|
|
|
foreach (string path in tempFiles)
|
|
|
{
|
|
|
//File.Delete(path);
|
|
|
}
|
|
|
|
|
|
bgWorker.Progress("保存完成", "", 100);
|
|
|
System.Threading.Thread.Sleep(800);
|
|
|
}
|
|
|
|
|
|
|
|
|
public void CheckIdInBom(TCData bomlineData, StringBuilder propertyInfo, List<string> idsToCreate) {
|
|
|
string itemId = bomlineData.Item_id;
|
|
|
if (string.IsNullOrWhiteSpace(itemId)) {
|
|
|
throw new Exception("对象ID不可为空");
|
|
|
}
|
|
|
Teamcenter.Soa.Client.Model.Strong.Item item = TCUtil.QueryItem(itemId, bomlineData.ItemTypeName, true);
|
|
|
//if (itemId.StartsWith("M")) {
|
|
|
// if (item == null) {
|
|
|
// throw new Exception("[" + itemId + "]未查询到TC系统中ItemID是[图号]或[MDM编码]的零组件,请确认填写正确或TC系统中已存在该零组件。");
|
|
|
// }
|
|
|
//}
|
|
|
//if (item == null) {
|
|
|
// if (idsToCreate != null && idsToCreate.Contains(itemId)) {
|
|
|
// return;
|
|
|
// }
|
|
|
// throw new Exception("[" + itemId + "]未查询到TC系统中ItemID是[图号]或[MDM编码]的零组件,请确认填写正确或TC系统中已存在该零组件。");
|
|
|
//}
|
|
|
if (item != null) {
|
|
|
//检查属性
|
|
|
List<string> changedProps = TCUtil.ComparePropertiesInTC(bomlineData);
|
|
|
if (changedProps != null && changedProps.Count > 0) {
|
|
|
propertyInfo.Append(string.Format("\r\n[{0}]: {1}", itemId, string.Join(", ", changedProps)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void CheckIdInTitle(string itemId, List<string> idsToCreate, string itemTypeName) {
|
|
|
if (string.IsNullOrWhiteSpace(itemId)) {
|
|
|
throw new Exception("对象ID不可为空");
|
|
|
}
|
|
|
Teamcenter.Soa.Client.Model.Strong.Item item = TCUtil.QueryItem(itemId, itemTypeName);
|
|
|
//if (itemId.StartsWith("M")) {
|
|
|
// if (item == null) {
|
|
|
// throw new Exception("M开头编码需先在TC中申请后才能使用。");
|
|
|
// }
|
|
|
//}
|
|
|
if (item != null && !TCUtil.CheckCanWrite(item)) {
|
|
|
throw new Exception("当前用户无对应零组件编辑权限,无法保存。");
|
|
|
}
|
|
|
if (item == null && idsToCreate!=null) {
|
|
|
idsToCreate.Add(itemId);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
protected override void InitCommand() {
|
|
|
uploadFileConfig = TCUtil.GetPrefValues(KMain.PREF_UPLOAD_FILE);
|
|
|
KUtil.Log("文件上传配置:" + string.Join(", ", uploadFileConfig));
|
|
|
if (KUtil.GetLen(uploadFileConfig) < 3) {
|
|
|
throw new Exception("首选项配置错误:" + KMain.PREF_UPLOAD_FILE);
|
|
|
}
|
|
|
if (KUtil.GetLen(uploadFileConfig) > 3) {
|
|
|
fmsUrl = uploadFileConfig[3];
|
|
|
}
|
|
|
string[] titleBlockNames = ConfigUtil.GetValue("titles").Split(';');
|
|
|
string[] mediaNames = ConfigUtil.GetValue("media_names").Split(';');
|
|
|
string[] rotates = ConfigUtil.GetValue("rotates").Split(';');
|
|
|
int len = KUtil.GetLen(titleBlockNames);
|
|
|
for (int i = 0; i < len; i++)
|
|
|
{
|
|
|
PlotData plot = PlotData.Parse(i, titleBlockNames, mediaNames, rotates);
|
|
|
if (plot == null)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
KUtil.Log("添加打印信息: " + plot.TitleBlockName + "|" + plot.MediaName + "|" + plot.Rotate);
|
|
|
KUtil.Put(plotInfos, plot.TitleBlockName, plot);
|
|
|
}
|
|
|
if (plotInfos.Count == 0)
|
|
|
{
|
|
|
throw new System.Exception("未配置PDF转换数据");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
protected override void ExecuteCommand() {
|
|
|
bgWorker.Start(null);
|
|
|
}
|
|
|
private Dictionary<string, PlotData> plotInfos = new Dictionary<string, PlotData>();
|
|
|
public void ConvertPDFAndUpload(TCData data)
|
|
|
{
|
|
|
string itemId = data.Item_id;
|
|
|
TCUtil.GetProperties(data.Rev, "object_name");
|
|
|
TCUtil.GetProperties(data.Rev, "item_revision_id");
|
|
|
string dsName = itemId + "-" + data.Rev.Object_name;
|
|
|
string file = data.DocFileName;
|
|
|
KUtil.Log("file:" + file);
|
|
|
string path = itemId+ "-" + data.Rev.Item_revision_id + "-"+ data.Rev.Object_name+ ".pdf";
|
|
|
if (!System.IO.File.Exists(file))
|
|
|
{
|
|
|
throw new Exception("上传文件失败,文件不存在:" + file);
|
|
|
}
|
|
|
Document openDoc = GetOpenedDoc(file);
|
|
|
KUtil.Log("path:" + path);
|
|
|
bool close = openDoc == null;
|
|
|
KUtil.Log("close:" + close);
|
|
|
if (close)
|
|
|
{
|
|
|
DocumentCollection acDocMgr = ZwSoft.ZwCAD.ApplicationServices.Application.DocumentManager;
|
|
|
// DocumentLock m_lock = acDocMgr.MdiActiveDocument.LockDocument();
|
|
|
openDoc = acDocMgr.Open(file, false); //filepath打开的文件路径,false表示文件可改写
|
|
|
Database acDbNewDoc = openDoc.Database;
|
|
|
//acDocMgr.MdiActiveDocument = openDoc;
|
|
|
/* openDoc = Application.DocumentManager.Open(file, false);
|
|
|
// openDoc = Application.DocumentManager.Open(file);
|
|
|
Application.DocumentManager.MdiActiveDocument = openDoc;*/
|
|
|
}
|
|
|
try
|
|
|
{
|
|
|
using (openDoc.LockDocument())
|
|
|
{
|
|
|
KUtil.Log("开始转换PDF" );
|
|
|
string pdfFilePath = ConvertPDFCommand.ConvertPDF(openDoc, plotInfos,path);
|
|
|
if (pdfFilePath.Equals("OFF"))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
if (!System.IO.File.Exists(pdfFilePath))
|
|
|
{
|
|
|
throw new Exception("PDF转换失败:" + file);
|
|
|
}
|
|
|
data.DocFileName = pdfFilePath;
|
|
|
List<string> tempFiles = new List<string>();
|
|
|
TCUtil.UploadFile(data, uploadFileConfig[0], "PDF", "PDF_Reference", dsName, tempFiles, fmsUrl);
|
|
|
KUtil.Log("PDF上传完成:" + data.DocFileName);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
data.DocFileName = file;
|
|
|
if (close)
|
|
|
{
|
|
|
openDoc.CloseAndDiscard();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
public static Document GetOpenedDoc(string file)
|
|
|
{
|
|
|
foreach (object doc in Application.DocumentManager)
|
|
|
{
|
|
|
if (doc is Document)
|
|
|
{
|
|
|
if (file.Equals(((Document)doc).Name))
|
|
|
{
|
|
|
return doc as Document;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
}
|