| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@@ -1,5 +1,4 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				using System.Net;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				using Common;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				using DotNext;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				using WebProtocol;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -261,10 +260,10 @@ class Jtag
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (retPackLen != 4)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return Convert.ToUInt32(Number.BytesToNumber(retPackOpts.Data).Value);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return Convert.ToUInt32(Common.Number.BytesToNumber(retPackOpts.Data).Value);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public async ValueTask<Result<RecvDataPackage>> RunCommand(uint devAddr, uint command)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, UInt32 data)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var ret = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var opts = new SendAddrPackOptions();
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -281,7 +280,7 @@ class Jtag
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (!ret) throw new Exception("Send 1st address package failed!");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Send Data Package
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ret = await UDPClientPool.SendDataPackAsync(ep,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                new SendDataPackage(Number.NumberToBytes(command, 4).Value));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                new SendDataPackage(Common.Number.NumberToBytes(data, 4).Value));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (!ret) throw new Exception("Send data package failed!");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Check Msg Bus
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -309,11 +308,68 @@ class Jtag
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public async ValueTask<Result<bool>> RunCommand
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        (uint devAddr, uint command, uint result, uint resultMask = 0xFF_FF_FF_FF)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public async ValueTask<Result<RecvDataPackage>> WriteFIFO(UInt32 devAddr, byte[] dataArray)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var ret = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var retPack = await RunCommand(devAddr, command);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var opts = new SendAddrPackOptions();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        opts.BurstType = BurstType.FixedBurst;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        opts.CommandID = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        opts.Address = devAddr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Check Msg Bus
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (!MsgBus.IsRunning)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            throw new Exception("Message bus not working!");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var writeTimes = dataArray.Length / (256 * (32 / 8)) + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for (var i = 0; i < writeTimes; i++)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var isLastData = i == writeTimes - 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            // Write Jtag State Register
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            opts.IsWrite = true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            opts.BurstLength = isLastData ? (byte)(dataArray.Length - i * (256 * (32 / 8)) - 1) : (byte)255;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret) throw new Exception("Send 1st address package failed!");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            // Send Data Package
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ret = await UDPClientPool.SendDataPackAsync(ep,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    new SendDataPackage(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        isLastData ?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        dataArray[(i * (256 * (32 / 8)))..] :
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                        dataArray[(i * (256 * (32 / 8)))..((i + 1) * (256 * (32 / 8)) - 1)]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                );
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret) throw new Exception("Send data package failed!");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            // Wait for Write Ack
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                var udpResp = await MsgBus.UDPServer.WaitForAckAsync(address, port);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    throw new Exception("Send address package failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Read Jtag State Register
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        opts.IsWrite = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        opts.BurstLength = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        opts.Address = JtagAddr.STATE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (!ret) throw new Exception("Send 2rd Address Package Failed!");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Wait for Read Data
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var udpResp = await MsgBus.UDPServer.WaitForDataAsync(address, port);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!udpResp.IsSuccessful || !udpResp.Value.IsSuccessful)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                throw new Exception("Send address package failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return udpResp.Value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public async ValueTask<Result<bool>> WriteFIFO
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        (UInt32 devAddr, UInt32 data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var ret = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var retPack = await WriteFIFO(devAddr, data);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (retPack.Value.Options.Data is null)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}");
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -322,8 +378,28 @@ class Jtag
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (retPackLen != 4)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (Number.BitsCheck(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (Common.Number.BitsCheck(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ret = true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public async ValueTask<Result<bool>> WriteFIFO
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        (UInt32 devAddr, byte[] data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var ret = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var retPack = await WriteFIFO(devAddr, data);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (retPack.Value.Options.Data is null)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var retPackLen = retPack.Value.Options.Data.Length;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (retPackLen != 4)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (Common.Number.BitsCheck(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ret = true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return ret;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -332,42 +408,92 @@ class Jtag
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> ClearAllRegisters()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await RunCommand(JtagAddr.STATE, 0xFF_FF_FF_FF, 0x01_02_02_02, JtagState.ALL_REG);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await WriteFIFO(JtagAddr.STATE, 0xFF_FF_FF_FF, 0x01_02_02_02, JtagState.ALL_REG);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> ClearWriteDataReg()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await RunCommand(JtagAddr.STATE, 0x00_00_11_00, 0x01_00_02_00, JtagState.WRITE_DATA_FIFO | JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await WriteFIFO(JtagAddr.STATE, 0x00_00_11_00, 0x01_00_02_00, JtagState.WRITE_DATA_FIFO | JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> CloseTest()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await WriteFIFO(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                JtagAddr.WRITE_CMD,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_CLOSE_TEST, JtagCmd.LEN_CMD_JTAG, 0, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> RunTest()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await RunCommand(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await WriteFIFO(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                JtagAddr.WRITE_CMD,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_RUN_TEST, JtagCmd.LEN_CMD_JTAG, 0, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_RUN_TEST, JtagCmd.LEN_CMD_JTAG, 0, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> DRIDcode()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> IdleDelay(UInt32 milliseconds)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await RunCommand(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (milliseconds > Math.Pow(2, 28)) throw new Exception("Timespan is over 2^28 milliseconds");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await WriteFIFO(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                JtagAddr.WRITE_CMD,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_IDLE_DELAY, JtagCmd.LEN_CMD_JTAG, milliseconds, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> ExecRDCmd(uint command)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await WriteFIFO(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                JtagAddr.WRITE_DATA,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Number.MultiBitsToNumber(0, 22, JtagCmd.JTAG_DR_IDCODE, JtagCmd.LEN_JTAG_DR).Value, 0, 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Common.Number.MultiBitsToNumber(0, 22, command, JtagCmd.LEN_JTAG_DR).Value, 0, 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Write JTAG_DR_IDCODE Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await WriteFIFO(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                JtagAddr.WRITE_CMD,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Write CMD_JTAG_LOAD_IR Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await ClearWriteDataReg();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> LoadIR()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<bool>> LoadDRCareInput(byte[] bytesArray)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return await RunCommand(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                JtagAddr.WRITE_CMD,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                0x01_00_00_00);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var bytesLen = ((uint)(bytesArray.Length * 8));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (bytesLen > Math.Pow(2, 28)) throw new Exception("Length is over 2^(28 - 3)");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await WriteFIFO(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    JtagAddr.WRITE_CMD,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREI, JtagCmd.LEN_CMD_JTAG, bytesLen, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Write CMD_JTAG_LOAD_DR_CAREI Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await WriteFIFO(JtagAddr.WRITE_DATA, bytesArray, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Write Data Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<uint>> LoadDRCareo()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    async ValueTask<Result<UInt32>> LoadDRCareOutput(UInt32 bytesLen)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var ret = await RunCommand(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (bytesLen > Math.Pow(2, 28)) throw new Exception("Length is over 2^(28 - 3)");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var ret = await WriteFIFO(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                JtagAddr.WRITE_CMD,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREO, JtagCmd.LEN_CMD_JTAG, 32, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREO, JtagCmd.LEN_CMD_JTAG, 8 * bytesLen, 28).Value,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                0x01_00_00_00, JtagState.CMD_EXEC_FINISH);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if (ret.Value)
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -378,17 +504,96 @@ class Jtag
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public async ValueTask<Result<uint>> ReadIDCode()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        var ret = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        // Clear Data
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        await MsgBus.UDPServer.ClearUDPData(this.address);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ret = (await ClearAllRegisters()).Value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ret = (await RunTest()).Value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ret = (await DRIDcode()).Value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ret = (await LoadIR()).Value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ret = (await ClearWriteDataReg()).Value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return (await LoadDRCareo()).Value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await ClearAllRegisters();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Clear All Registers Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await RunTest();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await ClearWriteDataReg();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Clear Write Registers Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return (await LoadDRCareOutput(1)).Value;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    public async ValueTask<Result<bool>> DownloadBitstream(byte[] bitstream)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await CloseTest();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await RunTest();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JRST Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await RunTest();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_CFGI Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await IdleDelay(75000);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await LoadDRCareInput(bitstream);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Load Data Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await CloseTest();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await RunTest();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Run Test Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await IdleDelay(1000);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            var ret = await CloseTest();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (!ret.IsSuccessful) throw ret.Error;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else if (!ret.Value) throw new Exception("Jtag Close Test Failed");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					
					| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				 
 |