From 3d55f1cebc6d9d4f0a3a25e22435d18df66595d8 Mon Sep 17 00:00:00 2001
From: huangxiaoqiang <huangxiaoqiang@hnkhzn.com>
Date: 星期二, 22 七月 2025 15:05:17 +0800
Subject: [PATCH] 1
---
Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob_GW/CommonConveyorLine_GWJob.cs | 242 +++++++++++++++++++++++++++++++++---------------
1 files changed, 166 insertions(+), 76 deletions(-)
diff --git a/Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob_GW/CommonConveyorLine_GWJob.cs b/Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob_GW/CommonConveyorLine_GWJob.cs
index 64ffdc4..b710291 100644
--- a/Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob_GW/CommonConveyorLine_GWJob.cs
+++ b/Code Management/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob_GW/CommonConveyorLine_GWJob.cs
@@ -25,6 +25,7 @@
using Newtonsoft.Json;
using Quartz;
using SqlSugar;
+using System.ComponentModel.Design;
using System.Reflection;
using WIDESEAWCS_BasicInfoRepository;
using WIDESEAWCS_Common;
@@ -65,6 +66,8 @@
private readonly INoticeService _noticeService;
private readonly IDt_needBarcodeRepository _needBarcodeRepository;
private readonly IDeviceInfoRepository _deviceInfoRepository;
+ private static List<string>? userTokenIds;
+ private static List<int>? userIds;
public CommonConveyorLine_GWJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper, ITaskRepository taskRepository, IPlatFormRepository platFormRepository, ISys_ConfigService sys_ConfigService, IDt_StationManagerRepository stationManagerRepository, ICacheService cacheService, INoticeService noticeService, IDt_needBarcodeRepository needBarcodeRepository, IDeviceInfoRepository deviceInfoRepository)
{
@@ -130,9 +133,9 @@
}
}
- if (childDeviceCode == "1670")
+ if (childDeviceCode == "1670" || childDeviceCode == "1666" || childDeviceCode == "1548" || childDeviceCode == "1448")
{
- Platform platform = _platFormRepository.QueryFirst(x => x.PLCCode == conveyorLine.DeviceCode && x.PlatCode == childDeviceCode && x.Status == "Active");
+ Platform platform = _platFormRepository.QueryFirst(x => x.DeviceCode == conveyorLine.DeviceCode && x.PlatCode == childDeviceCode && x.Status == "Active");
if (platform != null)
{
if (command.HasPallet != 1)
@@ -196,19 +199,33 @@
try
{
var task = _taskService.QueryBarCodeConveyorLineTask(command.ConveyorLineBarcode, childDeviceCode);
- //HandleTaskOut(conveyorLine, command, childDeviceCode, task);
- // && command.ConveyorLineBarcode != "NoRead" && !command.ConveyorLineBarcode.IsNotEmptyOrNull()
- ConsoleHelper.WriteSuccessLine($"銆恵conveyorLine.DeviceName}銆戞墭鐩樺彿锛氥�恵command.ConveyorLineBarcode}銆戣澶囩紪鐮侊細銆恵childDeviceCode}銆�");
+ var log = $"銆恵conveyorLine.DeviceName}銆戞墭鐩樺彿锛氥�恵command.ConveyorLineBarcode}銆戜换鍔″彿锛氥�恵command.ConveyorLineTaskNum}銆戣澶囩紪鐮侊細銆恵childDeviceCode}銆�";
+ ConsoleHelper.WriteSuccessLine(log);
+
+ _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = log, time = DateTime.Now.ToString("G"), color = "red" });
+ WriteInfo(conveyorLine.DeviceName, log);
+
if (task == null)
{
HandleNewTask(conveyorLine, command, childDeviceCode);
}
else
{
+ var GWTask = _taskRepository.QueryData(x => x.Roadway.Contains("GWSC2") && x.SourceAddress == "1039" && (x.TaskState == (int)TaskInStatusEnum.Line_InExecuting || x.TaskState == (int)TaskInStatusEnum.Line_InFinish)).ToList();
+ if (GWTask.Count >= 2 && childDeviceCode == "1039" && task.Roadway.Contains("GWSC2"))
+ {
+ ConsoleHelper.WriteErrorLine($"鎵樼洏鍙凤細銆恵command.ConveyorLineBarcode}銆戦珮娓╀簩宸插瓨鍦ㄣ�恵GWTask.Count}銆戜釜浠诲姟澶т簬2涓换鍔′笉鍙笅鍙�");
+ return;
+ }
ConveyorLineTaskCommand_After taskCommand = _mapper.Map<ConveyorLineTaskCommand_After>(task);
- conveyorLine.SendCommand(taskCommand, childDeviceCode);
- conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode);
- _taskService.UpdateTaskStatusToNext(task);
+ //conveyorLine.SendCommand(taskCommand, childDeviceCode);
+
+ bool sendFlag = SendCommand(taskCommand, conveyorLine, childDeviceCode);
+ if (sendFlag)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
+ _taskService.UpdateTaskStatusToNext(task);
+ }
}
}
catch (Exception ex)
@@ -225,28 +242,38 @@
/// <param name="childDeviceCode">瀛愯澶囩紪鍙�</param>
public void RequestInNextAddress(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode)
{
- Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode);
+ Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode, command.ConveyorLineBarcode);
if (task != null)
{
if (command.ConveyorLineBarcode != task.PalletCode)
{
- conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 2, childDeviceCode);
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
return;
}
Dt_Task? newTask = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress);
if (newTask != null)
{
-
- //conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTaskNum, newTask.TaskNum, childDeviceCode);
- //conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTargetAddress, newTask.NextAddress, childDeviceCode);
- //conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineBarcode, command.ConveyorLineBarcode, childDeviceCode);
ConveyorLineTaskCommand_After taskCommand = _mapper.Map<ConveyorLineTaskCommand_After>(newTask);
- //taskCommand.InteractiveSignal = command.InteractiveSignal;
- conveyorLine.SendCommand(taskCommand, childDeviceCode);
- conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode);
+ //conveyorLine.SendCommand(taskCommand, childDeviceCode);
+
+ bool sendFlag = SendCommand(taskCommand, conveyorLine, childDeviceCode);
+ if (sendFlag)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
+ _taskService.UpdateData(newTask);
+ }
}
}
+ //else
+ //{
+ // //褰撳墠鍦板潃璇锋眰 瀵绘壘褰撳墠鍦板潃鐨勬墭鐩樺彿 浠诲姟鍙风殑浠诲姟锛屽瀛樺湪浠诲姟鍒欓噸鏂板啀娆″啓鍏ユ柊鐩爣鍦板潃
+ // Dt_Task currentTask = _taskService.QueryExecutingCurrentConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode, command.ConveyorLineBarcode);
+ // if (currentTask != null)
+ // {
+ // conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTargetAddress, Convert.ToInt16(currentTask.TargetAddress), childDeviceCode);
+ // }
+ //}
}
/// <summary>
@@ -261,13 +288,11 @@
var task = _taskService.QueryExecutingTaskByBarcode(command.ConveyorLineBarcode, childDeviceCode);
if (task != null && task.TaskState != (int)TaskInStatusEnum.Line_InFinish)
{
- //ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true);
-
WebResponseContent content = _taskService.UpdateTaskStatusToNext(task);
if (content.Status)
{
- conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode);
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
}
Console.Out.WriteLine(content.Serialize());
@@ -287,14 +312,18 @@
if (task != null)
{
ConveyorLineTaskCommand_After taskCommand = _mapper.Map<ConveyorLineTaskCommand_After>(task);
- conveyorLine.SendCommand(taskCommand, childDeviceCode);
- conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode);
+ //conveyorLine.SendCommand(taskCommand, childDeviceCode);
- //ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true);
- _taskService.UpdateTaskStatusToNext(task);
- if (task.TaskType == (int)TaskOutboundTypeEnum.OutTray)
+ bool sendFlag = SendCommand(taskCommand, conveyorLine, childDeviceCode);
+ if (sendFlag)
{
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
+
_taskService.UpdateTaskStatusToNext(task);
+ if (task.TaskType == (int)TaskOutboundTypeEnum.OutTray)
+ {
+ _taskService.UpdateTaskStatusToNext(task);
+ }
}
}
}
@@ -307,7 +336,7 @@
/// <param name="childDeviceCode">瀛愯澶囩紪鍙�</param>
public void RequestOutNextAddress(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode)
{
- Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode);
+ Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode, command.ConveyorLineBarcode);
if (task != null)
{
var config = _sys_ConfigService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress);
@@ -342,19 +371,29 @@
if (newTask != null)
{
ConveyorLineTaskCommand_After taskCommand = _mapper.Map<ConveyorLineTaskCommand_After>(newTask);
- conveyorLine.SendCommand(taskCommand, childDeviceCode);
- conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode);
+ //conveyorLine.SendCommand(taskCommand, childDeviceCode);
+
+ bool sendFlag = SendCommand(taskCommand, conveyorLine, childDeviceCode);
+ if (sendFlag)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
+ _taskService.UpdateData(newTask);
+ }
}
}
else
{
ConveyorLineTaskCommand_After taskCommand = _mapper.Map<ConveyorLineTaskCommand_After>(task);
taskCommand.ConveyorLineTargetAddress = Convert.ToInt16(stationManager.stationNGChildCode);
- conveyorLine.SendCommand(taskCommand, childDeviceCode);
- conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode);
- _taskService.UpdateTaskStatusToNext(task);
- }
+ //conveyorLine.SendCommand(taskCommand, childDeviceCode);
+ bool sendFlag = SendCommand(taskCommand, conveyorLine, childDeviceCode);
+ if (sendFlag)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
+ _taskService.UpdateTaskStatusToNext(task);
+ }
+ }
}
}
@@ -366,7 +405,14 @@
/// <param name="childDeviceCode">瀛愯澶囩紪鍙�</param>
public void ConveyorLineOutFinish(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode)
{
- var task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode);
+ var log = $"銆恵conveyorLine.DeviceName}銆戞墭鐩樺彿锛氥�恵command.ConveyorLineBarcode}銆戜换鍔″彿锛氥�恵command.ConveyorLineTaskNum}銆戣澶囩紪鐮侊細銆恵childDeviceCode}銆�";
+ ConsoleHelper.WriteSuccessLine(log);
+
+ _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = log, time = DateTime.Now.ToString("G"), color = "red" });
+ WriteInfo(conveyorLine.DeviceName, log);
+
+
+ var task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode, command.ConveyorLineBarcode);
if (task != null)
{
WebResponseContent content = new WebResponseContent();
@@ -375,13 +421,10 @@
Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode);
if (task.PalletCode != command.ConveyorLineBarcode)
{
- //var NGAddress = _platFormRepository.QueryFirst(x => x.PlatCode == task.TargetAddress).Capacity;
- //taskCommand.ConveyorLineTargetAddress = (short)NGAddress;
taskCommand.ConveyorLineTargetAddress = Convert.ToInt16(stationManager.stationNGChildCode);
}
else
{
- //Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode);
taskCommand.ConveyorLineTargetAddress = Convert.ToInt16(stationManager.stationLocation);
}
@@ -396,46 +439,56 @@
}
}
- conveyorLine.SendCommand(taskCommand, childDeviceCode);
- conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode);
- //ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true);
- content = _taskService.UpdateTaskStatusToNext(task);
+ //conveyorLine.SendCommand(taskCommand, childDeviceCode);
+ bool sendFlag = SendCommand(taskCommand, conveyorLine, childDeviceCode);
+ if (sendFlag)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
+ content = _taskService.UpdateTaskStatusToNext(task);
+ }
}
- //else
- //{
- // Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode && x.stationArea == "Cache");
- // ////鏌ヨ瀵瑰簲浜х嚎鐨勫湪閫旀暟鎹�
- // //dt_needBarcode needBarcode = _needBarcodeRepository.QueryFirst(x => x.productLine == station.productLine);
+ else
+ {
+ var taskNext = _taskService.QueryExecutingConveyorLineTask(childDeviceCode, command.ConveyorLineBarcode);
+ if (taskNext != null)
+ {
+ WebResponseContent content = new WebResponseContent();
+ ConveyorLineTaskCommand_After taskCommand = _mapper.Map<ConveyorLineTaskCommand_After>(taskNext);
+ taskCommand.InteractiveSignal = command.InteractiveSignal;
+ Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode);
+ if (taskNext.PalletCode != command.ConveyorLineBarcode)
+ {
+ taskCommand.ConveyorLineTargetAddress = Convert.ToInt16(stationManager.stationNGChildCode);
+ }
+ else
+ {
+ taskCommand.ConveyorLineTargetAddress = Convert.ToInt16(stationManager.stationLocation);
+ }
- // //needBarcode.inLineNum = _taskRepository.QueryData(x => x.TargetAddress == station.stationChildCode).Count();
+ if (stationManager.stationPLC == "1018" && stationManager.stationArea == "Cache") //鏇存柊鍦ㄩ�旀暟鎹�
+ {
+ dt_needBarcode needBarcode = _needBarcodeRepository.QueryFirst(x => x.productLine == stationManager.productLine && x.toArea == stationManager.stationChildCode);
- // //鑻ュ湪閫旀暟閲忓皬浜庣洰鏍囦綅缃殑缂撳瓨鏁伴噺 鍒欏鎵惧搴斿父娓╁簱瀛樹腑甯告俯3宸ュ簭鐨勫彲鍑哄簱鏁版嵁 骞跺缓绔嬪嚭搴撲换鍔�
- // //if (needBarcode.inLineNum <= needBarcode.cacheNum)
- // //{
- // //}
- // //濡傛灉鍖呰缂撳瓨绔欏彴瀛樺湪 涓旀湁璇锋眰 鍒�
- // if (stationManager != null)
- // {
- // _taskService.RequestOutTaskToBZAsync(stationManager);
- // }
- //}
+ if (needBarcode != null)
+ {
+ needBarcode.inLineNum--;
+ _needBarcodeRepository.UpdateData(needBarcode);
+ }
+ }
+
+ //conveyorLine.SendCommand(taskCommand, childDeviceCode);
+
+ bool sendFlag = SendCommand(taskCommand, conveyorLine, childDeviceCode);
+ if (sendFlag)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, Convert.ToInt16(1), childDeviceCode);
+
+ taskNext.ExceptionMessage = log;
+ content = _taskService.UpdateTaskStatusToNext(taskNext);
+ }
+ }
+ }
}
-
- /// <summary>
- /// 杈撻�佺嚎浜や簰瀹屾垚
- /// </summary>
- /// <param name="conveyorLine">杈撻�佺嚎瀹炰緥瀵硅薄</param>
- /// <param name="childDeviceCode">瀛愯澶囩紪鍙�</param>
- /// <param name="ProtocalDetailValue">绾夸綋褰撳墠bool璇诲彇鍋忕Щ鍦板潃</param>
- /// <param name="value">鍊�</param>
- //public void ConveyorLineSendFinish(CommonConveyorLine conveyorLine, string childDeviceCode, int ProtocalDeValue, bool value)
- //{
- // DeviceProDTO? devicePro = conveyorLine.DeviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand) && x.DeviceChildCode == childDeviceCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault();
- // string[] x = devicePro.DeviceProAddress.Split('.');
- // x[x.Length - 1] = (ProtocalDetailValue + 1).ToString();
- // string DeviceProAddress = string.Join(".", x);
- // conveyorLine.Communicator.Write(DeviceProAddress, value);
- //}
/// <summary>
/// 鐩戞祴绌烘墭鐩樺疄鐩樺嚭搴�
@@ -466,7 +519,7 @@
private async Task CheckAndCreateTask(TaskOutboundTypeEnum taskType, string childDeviceCode, int index, Platform platform)
{
var tasks = _taskRepository.QueryData(x => x.TaskType == (int)taskType && x.TargetAddress == childDeviceCode);
- if (tasks.Count < index)
+ if (tasks.Count < platform.Capacity)
{
#region 璋冪敤WMS鑾峰彇鍑哄簱浠诲姟
@@ -482,8 +535,8 @@
}
var wmsIpAddress = wmsBase + requestTrayOutTask;
- var device = _deviceInfoRepository.QueryData(x => x.DeviceStatus == "1" && x.DeviceRemark == platform.Id.ToString());
- var deviceCode = device.Select(x => x.DeviceCode).ToList();
+ //var device = _deviceInfoRepository.QueryData(x => x.DeviceStatus == "1" && x.DeviceRemark == platform.Id.ToString());
+ //var deviceCode = device.Select(x => x.DeviceCode).ToList();
List<string> strings = platform.Location.Split(',').ToList();
var result = await HttpHelper.PostAsync(wmsIpAddress, new { Position = childDeviceCode, Tag = (int)taskType, AreaCdoe = platform.Stacker, AreaCdoes = strings, platform.ProductionLine }.ToJsonString());
@@ -515,7 +568,44 @@
}
return content;
}
+
+ public bool SendCommand(ConveyorLineTaskCommand_After taskCommand, CommonConveyorLine_GW conveyorLine, string childDeviceCode)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTargetAddress, Convert.ToInt16(taskCommand.ConveyorLineTargetAddress), childDeviceCode);
+ Thread.Sleep(100);
+ conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineBarcode, taskCommand.ConveyorLineBarcode, childDeviceCode);
+ Thread.Sleep(100);
+ conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTaskNum, taskCommand.ConveyorLineTaskNum, childDeviceCode);
+ for (int i = 0; i < 6; i++)
+ {
+ ConveyorLineTaskCommand_After command = conveyorLine.ReadCustomer<ConveyorLineTaskCommand_After>(childDeviceCode);
+ if (command != null)
+ {
+ if (command.ConveyorLineBarcode == taskCommand.ConveyorLineBarcode && command.ConveyorLineTaskNum == taskCommand.ConveyorLineTaskNum && command.ConveyorLineTargetAddress == taskCommand.ConveyorLineTargetAddress)
+ {
+ WriteInfo(conveyorLine.DeviceName, $"鍐欏叆浠诲姟鎴愬姛鍐欏叆娆℃暟{i}鍐欏叆浠诲姟銆恵JsonConvert.SerializeObject(taskCommand)}銆�");
+ return true;
+ }
+ if (command.ConveyorLineTargetAddress != taskCommand.ConveyorLineTargetAddress)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTargetAddress, Convert.ToInt16(taskCommand.ConveyorLineTargetAddress), childDeviceCode);
+ Thread.Sleep(100);
+ }
+ if (command.ConveyorLineBarcode != taskCommand.ConveyorLineBarcode)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineBarcode, taskCommand.ConveyorLineBarcode, childDeviceCode);
+ Thread.Sleep(100);
+ }
+ if (command.ConveyorLineTaskNum != taskCommand.ConveyorLineTaskNum)
+ {
+ conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTaskNum, taskCommand.ConveyorLineTaskNum, childDeviceCode); Thread.Sleep(100);
+ }
+
+ }
+ }
+ WriteInfo(conveyorLine.DeviceName, $"鍐欏叆浠诲姟澶辫触浠诲姟鍙枫�恵taskCommand.ConveyorLineTaskNum}銆戞墭鐩樺彿銆恵taskCommand.ConveyorLineBarcode}銆戠洰鏍囧湴鍧�銆恵taskCommand.ConveyorLineTargetAddress}銆戝綋鍓嶈妭鐐广�恵childDeviceCode}銆�");
+ return false;
+ }
}
}
-
#endregion
\ No newline at end of file
--
Gitblit v1.9.3