mirror of
				https://github.com/ivanch/tcc.git
				synced 2025-11-04 03:07:36 +00:00 
			
		
		
		
	Compare commits
	
		
			9 Commits
		
	
	
		
			main
			...
			aa4b1e9709
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| aa4b1e9709 | |||
| b372e1c310 | |||
| 4ef0ab508f | |||
| 9082b34aab | |||
| a9b48be817 | |||
| f2a9faed92 | |||
| 095f04e113 | |||
| 94c2296738 | |||
| 2dbdbea018 | 
							
								
								
									
										6
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +0,0 @@
 | 
				
			|||||||
[submodule "Spring"]
 | 
					 | 
				
			||||||
	path = Spring
 | 
					 | 
				
			||||||
	url = git@github.com:horakhy/springtcc.git
 | 
					 | 
				
			||||||
[submodule "Express"]
 | 
					 | 
				
			||||||
	path = Express
 | 
					 | 
				
			||||||
	url = git@github.com:horakhy/tcc-express.git
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					# Default ignored files
 | 
				
			||||||
 | 
					/shelf/
 | 
				
			||||||
 | 
					/workspace.xml
 | 
				
			||||||
 | 
					# Editor-based HTTP Client requests
 | 
				
			||||||
 | 
					/httpRequests/
 | 
				
			||||||
 | 
					# Datasource local storage ignored files
 | 
				
			||||||
 | 
					/dataSources/
 | 
				
			||||||
 | 
					/dataSources.local.xml
 | 
				
			||||||
							
								
								
									
										6
									
								
								.idea/inspectionProfiles/profiles_settings.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.idea/inspectionProfiles/profiles_settings.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					<component name="InspectionProjectProfileManager">
 | 
				
			||||||
 | 
					  <settings>
 | 
				
			||||||
 | 
					    <option name="USE_PROJECT_PROFILE" value="false" />
 | 
				
			||||||
 | 
					    <version value="1.0" />
 | 
				
			||||||
 | 
					  </settings>
 | 
				
			||||||
 | 
					</component>
 | 
				
			||||||
							
								
								
									
										4
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										8
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="ProjectModuleManager">
 | 
				
			||||||
 | 
					    <modules>
 | 
				
			||||||
 | 
					      <module fileurl="file://$PROJECT_DIR$/.idea/tcc.iml" filepath="$PROJECT_DIR$/.idea/tcc.iml" />
 | 
				
			||||||
 | 
					    </modules>
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
							
								
								
									
										8
									
								
								.idea/tcc.iml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.idea/tcc.iml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<module type="PYTHON_MODULE" version="4">
 | 
				
			||||||
 | 
					  <component name="NewModuleRootManager">
 | 
				
			||||||
 | 
					    <content url="file://$MODULE_DIR$" />
 | 
				
			||||||
 | 
					    <orderEntry type="inheritedJdk" />
 | 
				
			||||||
 | 
					    <orderEntry type="sourceFolder" forTests="false" />
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</module>
 | 
				
			||||||
							
								
								
									
										6
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project version="4">
 | 
				
			||||||
 | 
					  <component name="VcsDirectoryMappings">
 | 
				
			||||||
 | 
					    <mapping directory="" vcs="Git" />
 | 
				
			||||||
 | 
					  </component>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
@@ -15,6 +15,35 @@ namespace TCC.Controllers
 | 
				
			|||||||
            this.ImageService = imageService;
 | 
					            this.ImageService = imageService;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [HttpPost("blur")]
 | 
				
			||||||
 | 
					        public async Task<IActionResult> BlurImage([FromQuery] int radius)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            MemoryStream mstream = new MemoryStream();
 | 
				
			||||||
 | 
					            await HttpContext.Request.Body.CopyToAsync(mstream);
 | 
				
			||||||
 | 
					            mstream.Position = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var result = ImageService.BoxBlurImage(mstream, radius);
 | 
				
			||||||
 | 
					            mstream.Close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var blurredImageStream = new MemoryStream();
 | 
				
			||||||
 | 
					            result.Write(blurredImageStream);
 | 
				
			||||||
 | 
					            blurredImageStream.Position = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return File(blurredImageStream, "image/png");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [HttpGet("load-small-image")]
 | 
				
			||||||
 | 
					        public async Task<IActionResult> GetSimpleImage()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return File(ImageService.GetSimpleImage(), "image/png");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [HttpGet("load-big-image")]
 | 
				
			||||||
 | 
					        public async Task<IActionResult> GetBigImage()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return File(ImageService.GetBigImage(), "image/png");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [HttpPost("save-big-image")]
 | 
					        [HttpPost("save-big-image")]
 | 
				
			||||||
        public async Task<IActionResult> SaveBigImage()
 | 
					        public async Task<IActionResult> SaveBigImage()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,53 +0,0 @@
 | 
				
			|||||||
using Microsoft.AspNetCore.Mvc;
 | 
					 | 
				
			||||||
using tcc_app.Models;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace TCC.Controllers
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    [ApiController]
 | 
					 | 
				
			||||||
    [Route("simulation")]
 | 
					 | 
				
			||||||
    public class SimulationController : ControllerBase
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public SimulationController()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [HttpGet("harmonic-progression")]
 | 
					 | 
				
			||||||
        public async Task<IActionResult> GetHarmonicProgression([FromQuery] int n)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            double sum = 0;
 | 
					 | 
				
			||||||
            for (int i = 1; i <= n; i++)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                sum += 1.0f / i;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return Ok(sum);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [HttpPost("json")]
 | 
					 | 
				
			||||||
        public async Task<IActionResult> PostJson([FromBody] PersonJson person)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return Ok(person);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [HttpPost("protobuf")]
 | 
					 | 
				
			||||||
        public async Task<IActionResult> PostProtobuf()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            PersonProto person;
 | 
					 | 
				
			||||||
            byte[] response;
 | 
					 | 
				
			||||||
            using (var stream = Request.BodyReader.AsStream())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                person = ProtoBuf.Serializer.Deserialize<PersonProto>(stream);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            using (var stream = new MemoryStream())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                ProtoBuf.Serializer.Serialize(stream, person);
 | 
					 | 
				
			||||||
                response = stream.ToArray();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            await Response.Body.WriteAsync(response, 0, response.Length);
 | 
					 | 
				
			||||||
            return new EmptyResult();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -11,7 +11,7 @@ namespace TCC.Controllers
 | 
				
			|||||||
        [HttpGet("ok")]
 | 
					        [HttpGet("ok")]
 | 
				
			||||||
        public async Task<IActionResult> ReturnOk()
 | 
					        public async Task<IActionResult> ReturnOk()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return Ok();
 | 
					            return Ok(new { status = 200 });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,16 +12,14 @@ RUN dotnet restore
 | 
				
			|||||||
RUN dotnet build -c Release -o out
 | 
					RUN dotnet build -c Release -o out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN cd out && \
 | 
					RUN cd out && \
 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
 | 
					    wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \
 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
 | 
					    wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \
 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
 | 
					    wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \
 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/YD4vmSsO/nginx.html && \
 | 
					 | 
				
			||||||
    rm -rf runtimes && \
 | 
					    rm -rf runtimes && \
 | 
				
			||||||
    mkdir -p ./static && \
 | 
					    mkdir -p ./static && \
 | 
				
			||||||
    mv small-image.png ./static && \
 | 
					    mv small-image.png ./static && \
 | 
				
			||||||
    mv big-image.png ./static && \
 | 
					    mv big-image.png ./static && \
 | 
				
			||||||
    mv video.mp4 ./static && \
 | 
					    mv video.mp4 ./static
 | 
				
			||||||
    mv nginx.html ./static
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Build runtime image
 | 
					# Build runtime image
 | 
				
			||||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0-bullseye-slim
 | 
					FROM mcr.microsoft.com/dotnet/aspnet:6.0-bullseye-slim
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
namespace tcc_app.Models
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public class PersonJson
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public string Name { get; set; }
 | 
					 | 
				
			||||||
        public int Age { get; set; }
 | 
					 | 
				
			||||||
        public List<string> Friends { get; set; }
 | 
					 | 
				
			||||||
        public string Email { get; set; }
 | 
					 | 
				
			||||||
        public string Phone { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,24 +0,0 @@
 | 
				
			|||||||
using ProtoBuf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace tcc_app.Models
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    [ProtoContract()]
 | 
					 | 
				
			||||||
    public class PersonProto
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        [ProtoMember(1)]
 | 
					 | 
				
			||||||
        public string Name { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ProtoMember(2)]
 | 
					 | 
				
			||||||
        public int Age { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ProtoMember(3)]
 | 
					 | 
				
			||||||
        public List<string> Friends { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ProtoMember(4)]
 | 
					 | 
				
			||||||
        public string Email { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [ProtoMember(5)]
 | 
					 | 
				
			||||||
        public string Phone { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,14 +1,76 @@
 | 
				
			|||||||
namespace TCC.Services
 | 
					using ImageMagick;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace TCC.Services
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class ImageService
 | 
					    public class ImageService
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public ImageService() { }
 | 
					        public ImageService() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public MagickImage BoxBlurImage(Stream imageStream, int radius)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var image = new MagickImage(imageStream);
 | 
				
			||||||
 | 
					            image.GaussianBlur(radius, radius);
 | 
				
			||||||
 | 
					            return image;
 | 
				
			||||||
 | 
					            //var blurredImage = new MagickImage(image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //blurredImage = BoxBlurImageSeparable(image, blurredImage, radius, 0);
 | 
				
			||||||
 | 
					            //blurredImage = BoxBlurImageSeparable(blurredImage, blurredImage, 0, radius);
 | 
				
			||||||
 | 
					            //return blurredImage;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private MagickImage BoxBlurImageSeparable(MagickImage image, MagickImage blurredImage, int radiusX, int radiusY)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var pixels = image.GetPixels();
 | 
				
			||||||
 | 
					            var blurredPixels = blurredImage.GetPixelsUnsafe();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var pixel in pixels)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int x = pixel.X,
 | 
				
			||||||
 | 
					                    y = pixel.Y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                long rTotal = 0, gTotal = 0, bTotal = 0;
 | 
				
			||||||
 | 
					                int pixelCount = 0;
 | 
				
			||||||
 | 
					                for (int offsetY = -radiusY; offsetY <= radiusY; offsetY++)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    for (int offsetX = -radiusX; offsetX <= radiusX; offsetX++)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        int newX = x + offsetX;
 | 
				
			||||||
 | 
					                        int newY = y + offsetY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (newX >= 0 && newX < image.Width && newY >= 0 && newY < image.Height)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var pixelColor = pixels[newX, newY];
 | 
				
			||||||
 | 
					                            rTotal += pixelColor.GetChannel(0);
 | 
				
			||||||
 | 
					                            gTotal += pixelColor.GetChannel(1);
 | 
				
			||||||
 | 
					                            bTotal += pixelColor.GetChannel(2);
 | 
				
			||||||
 | 
					                            pixelCount++;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                blurredPixels[x, y].SetChannel(0, Convert.ToUInt16(rTotal / pixelCount));
 | 
				
			||||||
 | 
					                blurredPixels[x, y].SetChannel(1, Convert.ToUInt16(gTotal / pixelCount));
 | 
				
			||||||
 | 
					                blurredPixels[x, y].SetChannel(2, Convert.ToUInt16(bTotal / pixelCount));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return blurredImage;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void SaveImage(Stream fileStream)
 | 
					        public void SaveImage(Stream fileStream)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var file = File.Create("image.png");
 | 
					            var file = File.Create("image.png");
 | 
				
			||||||
            fileStream.CopyToAsync(file);
 | 
					            fileStream.CopyToAsync(file);
 | 
				
			||||||
            file.Close();
 | 
					            file.Close();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public byte[] GetSimpleImage()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return File.ReadAllBytes("static/small-image.png");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public byte[] GetBigImage()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return File.ReadAllBytes("static/big-image.png");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,8 @@
 | 
				
			|||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <PackageReference Include="protobuf-net" Version="3.2.26" />
 | 
					    <PackageReference Include="Magick.NET-Q16-AnyCPU" Version="13.2.0" />
 | 
				
			||||||
 | 
					    <PackageReference Include="Magick.NET.Core" Version="13.2.0" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
Dockerfile
 | 
					 | 
				
			||||||
target/
 | 
					 | 
				
			||||||
							
								
								
									
										564
									
								
								ActixAPI/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										564
									
								
								ActixAPI/Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -7,13 +7,8 @@ name = "ActixAPI"
 | 
				
			|||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "actix-files",
 | 
					 "actix-files",
 | 
				
			||||||
 "actix-protobuf",
 | 
					 | 
				
			||||||
 "actix-web",
 | 
					 "actix-web",
 | 
				
			||||||
 "futures",
 | 
					 "magick_rust",
 | 
				
			||||||
 "prost",
 | 
					 | 
				
			||||||
 "qstring",
 | 
					 | 
				
			||||||
 "serde",
 | 
					 | 
				
			||||||
 "serde_json",
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -68,7 +63,7 @@ dependencies = [
 | 
				
			|||||||
 "actix-utils",
 | 
					 "actix-utils",
 | 
				
			||||||
 "ahash",
 | 
					 "ahash",
 | 
				
			||||||
 "base64",
 | 
					 "base64",
 | 
				
			||||||
 "bitflags 2.4.1",
 | 
					 "bitflags 2.4.0",
 | 
				
			||||||
 "brotli",
 | 
					 "brotli",
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 "bytestring",
 | 
					 "bytestring",
 | 
				
			||||||
@@ -102,19 +97,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			|||||||
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
 | 
					checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
 "syn 2.0.38",
 | 
					 "syn 2.0.32",
 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "actix-protobuf"
 | 
					 | 
				
			||||||
version = "0.10.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a14dd296f850b814ca6f21d9a8ab92232887c07be2082562b5f3e33286f5b24d"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "actix-web",
 | 
					 | 
				
			||||||
 "derive_more",
 | 
					 | 
				
			||||||
 "futures-util",
 | 
					 | 
				
			||||||
 "prost",
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -227,7 +210,7 @@ dependencies = [
 | 
				
			|||||||
 "actix-router",
 | 
					 "actix-router",
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
 "syn 2.0.38",
 | 
					 "syn 2.0.32",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -247,22 +230,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ahash"
 | 
					name = "ahash"
 | 
				
			||||||
version = "0.8.6"
 | 
					version = "0.8.3"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
 | 
					checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "getrandom",
 | 
					 "getrandom",
 | 
				
			||||||
 "once_cell",
 | 
					 "once_cell",
 | 
				
			||||||
 "version_check",
 | 
					 "version_check",
 | 
				
			||||||
 "zerocopy",
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "aho-corasick"
 | 
					name = "aho-corasick"
 | 
				
			||||||
version = "1.1.2"
 | 
					version = "1.0.5"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
 | 
					checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -282,12 +264,6 @@ dependencies = [
 | 
				
			|||||||
 "alloc-no-stdlib",
 | 
					 "alloc-no-stdlib",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "anyhow"
 | 
					 | 
				
			||||||
version = "1.0.75"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "askama_escape"
 | 
					name = "askama_escape"
 | 
				
			||||||
version = "0.10.3"
 | 
					version = "0.10.3"
 | 
				
			||||||
@@ -317,9 +293,32 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "base64"
 | 
					name = "base64"
 | 
				
			||||||
version = "0.21.5"
 | 
					version = "0.21.4"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
 | 
					checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "bindgen"
 | 
				
			||||||
 | 
					version = "0.66.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bitflags 2.4.0",
 | 
				
			||||||
 | 
					 "cexpr",
 | 
				
			||||||
 | 
					 "clang-sys",
 | 
				
			||||||
 | 
					 "lazy_static",
 | 
				
			||||||
 | 
					 "lazycell",
 | 
				
			||||||
 | 
					 "log",
 | 
				
			||||||
 | 
					 "peeking_take_while",
 | 
				
			||||||
 | 
					 "prettyplease",
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "regex",
 | 
				
			||||||
 | 
					 "rustc-hash",
 | 
				
			||||||
 | 
					 "shlex",
 | 
				
			||||||
 | 
					 "syn 2.0.32",
 | 
				
			||||||
 | 
					 "which",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "bitflags"
 | 
					name = "bitflags"
 | 
				
			||||||
@@ -329,9 +328,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "bitflags"
 | 
					name = "bitflags"
 | 
				
			||||||
version = "2.4.1"
 | 
					version = "2.4.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
 | 
					checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "block-buffer"
 | 
					name = "block-buffer"
 | 
				
			||||||
@@ -344,9 +343,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "brotli"
 | 
					name = "brotli"
 | 
				
			||||||
version = "3.4.0"
 | 
					version = "3.3.4"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f"
 | 
					checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "alloc-no-stdlib",
 | 
					 "alloc-no-stdlib",
 | 
				
			||||||
 "alloc-stdlib",
 | 
					 "alloc-stdlib",
 | 
				
			||||||
@@ -355,9 +354,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "brotli-decompressor"
 | 
					name = "brotli-decompressor"
 | 
				
			||||||
version = "2.5.1"
 | 
					version = "2.3.4"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
 | 
					checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "alloc-no-stdlib",
 | 
					 "alloc-no-stdlib",
 | 
				
			||||||
 "alloc-stdlib",
 | 
					 "alloc-stdlib",
 | 
				
			||||||
@@ -371,9 +370,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "bytestring"
 | 
					name = "bytestring"
 | 
				
			||||||
version = "1.3.1"
 | 
					version = "1.3.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72"
 | 
					checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -388,12 +387,32 @@ dependencies = [
 | 
				
			|||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "cexpr"
 | 
				
			||||||
 | 
					version = "0.6.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "nom",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "cfg-if"
 | 
					name = "cfg-if"
 | 
				
			||||||
version = "1.0.0"
 | 
					version = "1.0.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
					checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "clang-sys"
 | 
				
			||||||
 | 
					version = "1.6.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "glob",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "libloading",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "convert_case"
 | 
					name = "convert_case"
 | 
				
			||||||
version = "0.4.0"
 | 
					version = "0.4.0"
 | 
				
			||||||
@@ -413,9 +432,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "cpufeatures"
 | 
					name = "cpufeatures"
 | 
				
			||||||
version = "0.2.11"
 | 
					version = "0.2.9"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
 | 
					checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -441,12 +460,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "deranged"
 | 
					name = "deranged"
 | 
				
			||||||
version = "0.3.9"
 | 
					version = "0.3.8"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"
 | 
					checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "powerfmt",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "derive_more"
 | 
					name = "derive_more"
 | 
				
			||||||
@@ -487,10 +503,31 @@ dependencies = [
 | 
				
			|||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "flate2"
 | 
					name = "errno"
 | 
				
			||||||
version = "1.0.28"
 | 
					version = "0.3.3"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
 | 
					checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "errno-dragonfly",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "windows-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "errno-dragonfly"
 | 
				
			||||||
 | 
					version = "0.1.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cc",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "flate2"
 | 
				
			||||||
 | 
					version = "1.0.27"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "crc32fast",
 | 
					 "crc32fast",
 | 
				
			||||||
 "miniz_oxide",
 | 
					 "miniz_oxide",
 | 
				
			||||||
@@ -511,93 +548,34 @@ dependencies = [
 | 
				
			|||||||
 "percent-encoding",
 | 
					 "percent-encoding",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "futures"
 | 
					 | 
				
			||||||
version = "0.3.29"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "futures-channel",
 | 
					 | 
				
			||||||
 "futures-core",
 | 
					 | 
				
			||||||
 "futures-executor",
 | 
					 | 
				
			||||||
 "futures-io",
 | 
					 | 
				
			||||||
 "futures-sink",
 | 
					 | 
				
			||||||
 "futures-task",
 | 
					 | 
				
			||||||
 "futures-util",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "futures-channel"
 | 
					 | 
				
			||||||
version = "0.3.29"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "futures-core",
 | 
					 | 
				
			||||||
 "futures-sink",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "futures-core"
 | 
					name = "futures-core"
 | 
				
			||||||
version = "0.3.29"
 | 
					version = "0.3.28"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
 | 
					checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "futures-executor"
 | 
					 | 
				
			||||||
version = "0.3.29"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "futures-core",
 | 
					 | 
				
			||||||
 "futures-task",
 | 
					 | 
				
			||||||
 "futures-util",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "futures-io"
 | 
					 | 
				
			||||||
version = "0.3.29"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "futures-macro"
 | 
					 | 
				
			||||||
version = "0.3.29"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
 "quote",
 | 
					 | 
				
			||||||
 "syn 2.0.38",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "futures-sink"
 | 
					name = "futures-sink"
 | 
				
			||||||
version = "0.3.29"
 | 
					version = "0.3.28"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
 | 
					checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "futures-task"
 | 
					name = "futures-task"
 | 
				
			||||||
version = "0.3.29"
 | 
					version = "0.3.28"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
 | 
					checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "futures-util"
 | 
					name = "futures-util"
 | 
				
			||||||
version = "0.3.29"
 | 
					version = "0.3.28"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
 | 
					checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "futures-channel",
 | 
					 | 
				
			||||||
 "futures-core",
 | 
					 "futures-core",
 | 
				
			||||||
 "futures-io",
 | 
					 | 
				
			||||||
 "futures-macro",
 | 
					 | 
				
			||||||
 "futures-sink",
 | 
					 | 
				
			||||||
 "futures-task",
 | 
					 "futures-task",
 | 
				
			||||||
 "memchr",
 | 
					 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "pin-utils",
 | 
					 "pin-utils",
 | 
				
			||||||
 "slab",
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -627,6 +605,12 @@ version = "0.28.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
 | 
					checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "glob"
 | 
				
			||||||
 | 
					version = "0.3.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "h2"
 | 
					name = "h2"
 | 
				
			||||||
version = "0.3.21"
 | 
					version = "0.3.21"
 | 
				
			||||||
@@ -652,6 +636,15 @@ version = "0.12.3"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
 | 
					checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "home"
 | 
				
			||||||
 | 
					version = "0.5.5"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "windows-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "http"
 | 
					name = "http"
 | 
				
			||||||
version = "0.2.9"
 | 
					version = "0.2.9"
 | 
				
			||||||
@@ -701,15 +694,6 @@ dependencies = [
 | 
				
			|||||||
 "hashbrown",
 | 
					 "hashbrown",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "itertools"
 | 
					 | 
				
			||||||
version = "0.11.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "either",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "itoa"
 | 
					name = "itoa"
 | 
				
			||||||
version = "1.0.9"
 | 
					version = "1.0.9"
 | 
				
			||||||
@@ -718,9 +702,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "jobserver"
 | 
					name = "jobserver"
 | 
				
			||||||
version = "0.1.27"
 | 
					version = "0.1.26"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
 | 
					checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -732,33 +716,62 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			|||||||
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
 | 
					checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "libc"
 | 
					name = "lazy_static"
 | 
				
			||||||
version = "0.2.149"
 | 
					version = "1.4.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
 | 
					checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "lazycell"
 | 
				
			||||||
 | 
					version = "1.3.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "libc"
 | 
				
			||||||
 | 
					version = "0.2.147"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "libloading"
 | 
				
			||||||
 | 
					version = "0.7.4"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "linux-raw-sys"
 | 
				
			||||||
 | 
					version = "0.4.7"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "local-channel"
 | 
					name = "local-channel"
 | 
				
			||||||
version = "0.1.5"
 | 
					version = "0.1.3"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8"
 | 
					checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "futures-core",
 | 
					 "futures-core",
 | 
				
			||||||
 "futures-sink",
 | 
					 "futures-sink",
 | 
				
			||||||
 | 
					 "futures-util",
 | 
				
			||||||
 "local-waker",
 | 
					 "local-waker",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "local-waker"
 | 
					name = "local-waker"
 | 
				
			||||||
version = "0.1.4"
 | 
					version = "0.1.3"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487"
 | 
					checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "lock_api"
 | 
					name = "lock_api"
 | 
				
			||||||
version = "0.4.11"
 | 
					version = "0.4.10"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
 | 
					checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "autocfg",
 | 
					 "autocfg",
 | 
				
			||||||
 "scopeguard",
 | 
					 "scopeguard",
 | 
				
			||||||
@@ -771,10 +784,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			|||||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
 | 
					checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "memchr"
 | 
					name = "magick_rust"
 | 
				
			||||||
version = "2.6.4"
 | 
					version = "0.19.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
 | 
					checksum = "ce666df6ace809001c625ad383f4727657c7c7881df43b3b71486e8e9f07d017"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bindgen",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "pkg-config",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "memchr"
 | 
				
			||||||
 | 
					version = "2.6.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "mime"
 | 
					name = "mime"
 | 
				
			||||||
@@ -792,6 +816,12 @@ dependencies = [
 | 
				
			|||||||
 "unicase",
 | 
					 "unicase",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "minimal-lexical"
 | 
				
			||||||
 | 
					version = "0.2.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "miniz_oxide"
 | 
					name = "miniz_oxide"
 | 
				
			||||||
version = "0.7.1"
 | 
					version = "0.7.1"
 | 
				
			||||||
@@ -803,9 +833,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "mio"
 | 
					name = "mio"
 | 
				
			||||||
version = "0.8.9"
 | 
					version = "0.8.8"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
 | 
					checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
@@ -813,6 +843,16 @@ dependencies = [
 | 
				
			|||||||
 "windows-sys",
 | 
					 "windows-sys",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "nom"
 | 
				
			||||||
 | 
					version = "7.1.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "memchr",
 | 
				
			||||||
 | 
					 "minimal-lexical",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "object"
 | 
					name = "object"
 | 
				
			||||||
version = "0.32.1"
 | 
					version = "0.32.1"
 | 
				
			||||||
@@ -840,9 +880,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "parking_lot_core"
 | 
					name = "parking_lot_core"
 | 
				
			||||||
version = "0.9.9"
 | 
					version = "0.9.8"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
 | 
					checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
@@ -857,6 +897,12 @@ version = "1.0.14"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
 | 
					checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "peeking_take_while"
 | 
				
			||||||
 | 
					version = "0.1.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "percent-encoding"
 | 
					name = "percent-encoding"
 | 
				
			||||||
version = "2.3.0"
 | 
					version = "2.3.0"
 | 
				
			||||||
@@ -881,12 +927,6 @@ version = "0.3.27"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
 | 
					checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "powerfmt"
 | 
					 | 
				
			||||||
version = "0.2.0"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ppv-lite86"
 | 
					name = "ppv-lite86"
 | 
				
			||||||
version = "0.2.17"
 | 
					version = "0.2.17"
 | 
				
			||||||
@@ -894,46 +934,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			|||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 | 
					checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "proc-macro2"
 | 
					name = "prettyplease"
 | 
				
			||||||
version = "1.0.69"
 | 
					version = "0.2.15"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
 | 
					checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "syn 2.0.32",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "proc-macro2"
 | 
				
			||||||
 | 
					version = "1.0.66"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "unicode-ident",
 | 
					 "unicode-ident",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "prost"
 | 
					 | 
				
			||||||
version = "0.12.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "bytes",
 | 
					 | 
				
			||||||
 "prost-derive",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "prost-derive"
 | 
					 | 
				
			||||||
version = "0.12.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "anyhow",
 | 
					 | 
				
			||||||
 "itertools",
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
 "quote",
 | 
					 | 
				
			||||||
 "syn 2.0.38",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "qstring"
 | 
					 | 
				
			||||||
version = "0.7.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "percent-encoding",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "quote"
 | 
					name = "quote"
 | 
				
			||||||
version = "1.0.33"
 | 
					version = "1.0.33"
 | 
				
			||||||
@@ -975,18 +993,18 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "redox_syscall"
 | 
					name = "redox_syscall"
 | 
				
			||||||
version = "0.4.1"
 | 
					version = "0.3.5"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
 | 
					checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bitflags 1.3.2",
 | 
					 "bitflags 1.3.2",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "regex"
 | 
					name = "regex"
 | 
				
			||||||
version = "1.10.2"
 | 
					version = "1.9.5"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
 | 
					checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "aho-corasick",
 | 
					 "aho-corasick",
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
@@ -996,9 +1014,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "regex-automata"
 | 
					name = "regex-automata"
 | 
				
			||||||
version = "0.4.3"
 | 
					version = "0.3.8"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
 | 
					checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "aho-corasick",
 | 
					 "aho-corasick",
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
@@ -1007,9 +1025,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "regex-syntax"
 | 
					name = "regex-syntax"
 | 
				
			||||||
version = "0.8.2"
 | 
					version = "0.7.5"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
 | 
					checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "rustc-demangle"
 | 
					name = "rustc-demangle"
 | 
				
			||||||
@@ -1017,6 +1035,12 @@ version = "0.1.23"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
 | 
					checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rustc-hash"
 | 
				
			||||||
 | 
					version = "1.1.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "rustc_version"
 | 
					name = "rustc_version"
 | 
				
			||||||
version = "0.4.0"
 | 
					version = "0.4.0"
 | 
				
			||||||
@@ -1026,6 +1050,19 @@ dependencies = [
 | 
				
			|||||||
 "semver",
 | 
					 "semver",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rustix"
 | 
				
			||||||
 | 
					version = "0.38.13"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bitflags 2.4.0",
 | 
				
			||||||
 | 
					 "errno",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "linux-raw-sys",
 | 
				
			||||||
 | 
					 "windows-sys",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ryu"
 | 
					name = "ryu"
 | 
				
			||||||
version = "1.0.15"
 | 
					version = "1.0.15"
 | 
				
			||||||
@@ -1040,35 +1077,35 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "semver"
 | 
					name = "semver"
 | 
				
			||||||
version = "1.0.20"
 | 
					version = "1.0.18"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
 | 
					checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde"
 | 
					name = "serde"
 | 
				
			||||||
version = "1.0.190"
 | 
					version = "1.0.188"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7"
 | 
					checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "serde_derive",
 | 
					 "serde_derive",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde_derive"
 | 
					name = "serde_derive"
 | 
				
			||||||
version = "1.0.190"
 | 
					version = "1.0.188"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
 | 
					checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
 "syn 2.0.38",
 | 
					 "syn 2.0.32",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde_json"
 | 
					name = "serde_json"
 | 
				
			||||||
version = "1.0.108"
 | 
					version = "1.0.106"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
 | 
					checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "itoa",
 | 
					 "itoa",
 | 
				
			||||||
 "ryu",
 | 
					 "ryu",
 | 
				
			||||||
@@ -1089,15 +1126,21 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "sha1"
 | 
					name = "sha1"
 | 
				
			||||||
version = "0.10.6"
 | 
					version = "0.10.5"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
 | 
					checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "cpufeatures",
 | 
					 "cpufeatures",
 | 
				
			||||||
 "digest",
 | 
					 "digest",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "shlex"
 | 
				
			||||||
 | 
					version = "1.2.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "signal-hook-registry"
 | 
					name = "signal-hook-registry"
 | 
				
			||||||
version = "1.4.1"
 | 
					version = "1.4.1"
 | 
				
			||||||
@@ -1118,15 +1161,15 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "smallvec"
 | 
					name = "smallvec"
 | 
				
			||||||
version = "1.11.1"
 | 
					version = "1.11.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
 | 
					checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "socket2"
 | 
					name = "socket2"
 | 
				
			||||||
version = "0.5.5"
 | 
					version = "0.5.4"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
 | 
					checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "windows-sys",
 | 
					 "windows-sys",
 | 
				
			||||||
@@ -1145,9 +1188,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "syn"
 | 
					name = "syn"
 | 
				
			||||||
version = "2.0.38"
 | 
					version = "2.0.32"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
 | 
					checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
@@ -1156,13 +1199,12 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "time"
 | 
					name = "time"
 | 
				
			||||||
version = "0.3.30"
 | 
					version = "0.3.28"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5"
 | 
					checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "deranged",
 | 
					 "deranged",
 | 
				
			||||||
 "itoa",
 | 
					 "itoa",
 | 
				
			||||||
 "powerfmt",
 | 
					 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "time-core",
 | 
					 "time-core",
 | 
				
			||||||
 "time-macros",
 | 
					 "time-macros",
 | 
				
			||||||
@@ -1170,15 +1212,15 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "time-core"
 | 
					name = "time-core"
 | 
				
			||||||
version = "0.1.2"
 | 
					version = "0.1.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
 | 
					checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "time-macros"
 | 
					name = "time-macros"
 | 
				
			||||||
version = "0.2.15"
 | 
					version = "0.2.14"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
 | 
					checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "time-core",
 | 
					 "time-core",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -1200,9 +1242,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tokio"
 | 
					name = "tokio"
 | 
				
			||||||
version = "1.33.0"
 | 
					version = "1.32.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
 | 
					checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "backtrace",
 | 
					 "backtrace",
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
@@ -1217,9 +1259,9 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tokio-util"
 | 
					name = "tokio-util"
 | 
				
			||||||
version = "0.7.10"
 | 
					version = "0.7.8"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
 | 
					checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 "futures-core",
 | 
					 "futures-core",
 | 
				
			||||||
@@ -1231,10 +1273,11 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tracing"
 | 
					name = "tracing"
 | 
				
			||||||
version = "0.1.40"
 | 
					version = "0.1.37"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
 | 
					checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "tracing-core",
 | 
					 "tracing-core",
 | 
				
			||||||
@@ -1242,18 +1285,18 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tracing-core"
 | 
					name = "tracing-core"
 | 
				
			||||||
version = "0.1.32"
 | 
					version = "0.1.31"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
 | 
					checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "once_cell",
 | 
					 "once_cell",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "typenum"
 | 
					name = "typenum"
 | 
				
			||||||
version = "1.17.0"
 | 
					version = "1.16.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
 | 
					checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "unicase"
 | 
					name = "unicase"
 | 
				
			||||||
@@ -1272,9 +1315,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "unicode-ident"
 | 
					name = "unicode-ident"
 | 
				
			||||||
version = "1.0.12"
 | 
					version = "1.0.11"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
 | 
					checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "unicode-normalization"
 | 
					name = "unicode-normalization"
 | 
				
			||||||
@@ -1308,6 +1351,40 @@ version = "0.11.0+wasi-snapshot-preview1"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 | 
					checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "which"
 | 
				
			||||||
 | 
					version = "4.4.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "either",
 | 
				
			||||||
 | 
					 "home",
 | 
				
			||||||
 | 
					 "once_cell",
 | 
				
			||||||
 | 
					 "rustix",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "winapi"
 | 
				
			||||||
 | 
					version = "0.3.9"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "winapi-i686-pc-windows-gnu",
 | 
				
			||||||
 | 
					 "winapi-x86_64-pc-windows-gnu",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "winapi-i686-pc-windows-gnu"
 | 
				
			||||||
 | 
					version = "0.4.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "winapi-x86_64-pc-windows-gnu"
 | 
				
			||||||
 | 
					version = "0.4.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows-sys"
 | 
					name = "windows-sys"
 | 
				
			||||||
version = "0.48.0"
 | 
					version = "0.48.0"
 | 
				
			||||||
@@ -1374,26 +1451,6 @@ version = "0.48.5"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 | 
					checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "zerocopy"
 | 
					 | 
				
			||||||
version = "0.7.23"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "e50cbb27c30666a6108abd6bc7577556265b44f243e2be89a8bc4e07a528c107"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "zerocopy-derive",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "zerocopy-derive"
 | 
					 | 
				
			||||||
version = "0.7.23"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "a25f293fe55f0a48e7010d65552bb63704f6ceb55a1a385da10d41d8f78e4a3d"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
 "quote",
 | 
					 | 
				
			||||||
 "syn 2.0.38",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "zstd"
 | 
					name = "zstd"
 | 
				
			||||||
version = "0.12.4"
 | 
					version = "0.12.4"
 | 
				
			||||||
@@ -1415,10 +1472,11 @@ dependencies = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "zstd-sys"
 | 
					name = "zstd-sys"
 | 
				
			||||||
version = "2.0.9+zstd.1.5.5"
 | 
					version = "2.0.8+zstd.1.5.5"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656"
 | 
					checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cc",
 | 
					 "cc",
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 "pkg-config",
 | 
					 "pkg-config",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,9 +8,4 @@ edition = "2021"
 | 
				
			|||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
actix-web = "4"
 | 
					actix-web = "4"
 | 
				
			||||||
actix-files = "0.6.2"
 | 
					actix-files = "0.6.2"
 | 
				
			||||||
qstring = "0.7.2"
 | 
					magick_rust = "0.19.0"
 | 
				
			||||||
serde = { version = "1.0", features = ["derive"] }
 | 
					 | 
				
			||||||
serde_json = "1"
 | 
					 | 
				
			||||||
futures = "0.3"
 | 
					 | 
				
			||||||
actix-protobuf = "0.10.0"
 | 
					 | 
				
			||||||
prost = { version = "0.12", features = ["prost-derive"] }
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,22 +1,25 @@
 | 
				
			|||||||
FROM rust:1.77-buster as builder
 | 
					FROM rust:slim-bullseye AS build-env
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /app
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY . .
 | 
					COPY . .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt update && apt install wget -y && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \
 | 
				
			||||||
 | 
					    wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \
 | 
				
			||||||
 | 
					    mv small-image.png ./static && \
 | 
				
			||||||
 | 
					    mv big-image.png ./static && \
 | 
				
			||||||
 | 
					    mv video.mp4 ./static
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN cargo build --release
 | 
					RUN cargo build --release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FROM debian:bullseye-slim
 | 
					FROM debian:bullseye-slim
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /app
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN apt-get update && apt-get -y install wget && \
 | 
					COPY --from=build-env /app/target/release .
 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
 | 
					 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
 | 
					 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
 | 
					 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/YD4vmSsO/nginx.html && \
 | 
					 | 
				
			||||||
    mkdir -p ./static && \
 | 
					 | 
				
			||||||
    mv small-image.png ./static && \
 | 
					 | 
				
			||||||
    mv big-image.png ./static && \
 | 
					 | 
				
			||||||
    mv video.mp4 ./static && \
 | 
					 | 
				
			||||||
    mv nginx.html ./static
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY --from=builder /app/target/release/ActixAPI .
 | 
					COPY --from=build-env /app/static ./static
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CMD ["./ActixAPI"]
 | 
					ENTRYPOINT ["./ActixAPI"]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,36 +1,20 @@
 | 
				
			|||||||
use qstring::QString;
 | 
					 | 
				
			||||||
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, HttpRequest, Result};
 | 
					use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, HttpRequest, Result};
 | 
				
			||||||
use actix_files::NamedFile;
 | 
					use actix_files::NamedFile;
 | 
				
			||||||
use actix_protobuf::*;
 | 
					use magick_rust::{MagickWand, ToMagick};
 | 
				
			||||||
use prost::Message;
 | 
					use magick_rust::{self, FilterType};
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Clone, PartialEq, Eq, Message)]
 | 
					 | 
				
			||||||
pub struct PersonProtobuf {
 | 
					 | 
				
			||||||
    #[prost(string, tag = "1")]
 | 
					 | 
				
			||||||
    pub name: String,
 | 
					 | 
				
			||||||
    #[prost(int32, tag = "2")]
 | 
					 | 
				
			||||||
    pub age: i32,
 | 
					 | 
				
			||||||
    #[prost(string, repeated, tag = "3")]
 | 
					 | 
				
			||||||
    pub friends: Vec<String>,
 | 
					 | 
				
			||||||
    #[prost(string, tag = "4")]
 | 
					 | 
				
			||||||
    pub email: String,
 | 
					 | 
				
			||||||
    #[prost(string, tag = "5")]
 | 
					 | 
				
			||||||
    pub phone: String,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Deserialize, Serialize)]
 | 
					 | 
				
			||||||
pub struct PersonJson {
 | 
					 | 
				
			||||||
    pub name: String,
 | 
					 | 
				
			||||||
    pub age: i32,
 | 
					 | 
				
			||||||
    pub friends: Vec<String>,
 | 
					 | 
				
			||||||
    pub email: String,
 | 
					 | 
				
			||||||
    pub phone: String,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[get("/status/ok")]
 | 
					#[get("/status/ok")]
 | 
				
			||||||
async fn hello() -> impl Responder {
 | 
					async fn hello() -> impl Responder {
 | 
				
			||||||
    HttpResponse::Ok()
 | 
					    HttpResponse::Ok().body("{\"status\": 200}")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[post("/echo")]
 | 
				
			||||||
 | 
					async fn echo(req_body: String) -> impl Responder {
 | 
				
			||||||
 | 
					    HttpResponse::Ok().body(req_body)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn manual_hello() -> impl Responder {
 | 
				
			||||||
 | 
					    HttpResponse::Ok().body("Hey there!")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async fn static_serve(req: HttpRequest) -> Result<NamedFile> {
 | 
					async fn static_serve(req: HttpRequest) -> Result<NamedFile> {
 | 
				
			||||||
@@ -40,37 +24,20 @@ async fn static_serve(req: HttpRequest) -> Result<NamedFile> {
 | 
				
			|||||||
    Ok(NamedFile::open(real_path)?)
 | 
					    Ok(NamedFile::open(real_path)?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[get("/simulation/harmonic-progression")]
 | 
					#[post("/image/blur")]
 | 
				
			||||||
async fn simulation_harmonic_progression(req: HttpRequest) -> impl Responder {
 | 
					async fn blur_image(image_data: web::Bytes) -> Result<HttpResponse> {
 | 
				
			||||||
    let query_str = req.query_string();
 | 
					    // Load the image from the incoming bytes
 | 
				
			||||||
    let qs = QString::from(query_str);
 | 
					    let image = ToMagick::<magick_rust::MagickWand>::to_magick(image_data).unwrap();
 | 
				
			||||||
    let radius = qs.get("n").unwrap_or("1").parse::<f64>().unwrap_or(1.0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut sum = 0.0;
 | 
					    // Apply a blur filter to the image
 | 
				
			||||||
    for i in 1..=radius as i32 {
 | 
					    let blurred_image = image.blur(FilterType::Gaussian, 0.0).unwrap();
 | 
				
			||||||
        sum += 1.0 / i as f64;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HttpResponse::Ok().body(format!("{}", sum))
 | 
					    // Convert the blurred image back to bytes
 | 
				
			||||||
}
 | 
					    let blurred_image_bytes = blurred_image.to_bytes().unwrap();
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[post("/simulation/json")]
 | 
					 | 
				
			||||||
async fn simulation_json(msg: web::Json<PersonJson>) -> impl Responder {
 | 
					 | 
				
			||||||
    HttpResponse::Ok().json(web::Json(msg))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[post("/simulation/protobuf")]
 | 
					 | 
				
			||||||
async fn simulation_protobuf(msg: ProtoBuf<PersonProtobuf>) -> impl Responder {
 | 
					 | 
				
			||||||
    HttpResponse::Ok().protobuf(msg.0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[post("/image/save-big-image")]
 | 
					 | 
				
			||||||
async fn save_big_image(image_data: web::Bytes) -> Result<HttpResponse> {
 | 
					 | 
				
			||||||
    std::fs::write("image.png", &image_data).unwrap();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(HttpResponse::Ok()
 | 
					    Ok(HttpResponse::Ok()
 | 
				
			||||||
        .content_type("application/json")
 | 
					        .content_type("image/jpeg")
 | 
				
			||||||
        .body("{\"status\": 200}"))
 | 
					        .body(blurred_image_bytes))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[actix_web::main]
 | 
					#[actix_web::main]
 | 
				
			||||||
@@ -81,13 +48,11 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
        App::new()
 | 
					        App::new()
 | 
				
			||||||
            .route("/static/{filename:.*}", web::get().to(static_serve))
 | 
					            .route("/static/{filename:.*}", web::get().to(static_serve))
 | 
				
			||||||
            .service(hello)
 | 
					            .service(hello)
 | 
				
			||||||
            .service(save_big_image)
 | 
					            .service(echo)
 | 
				
			||||||
            .service(simulation_harmonic_progression)
 | 
					            .service(blur_image)
 | 
				
			||||||
            .service(simulation_json)
 | 
					            .route("/hey", web::get().to(manual_hello))
 | 
				
			||||||
            .service(simulation_protobuf)
 | 
					 | 
				
			||||||
            .app_data(web::PayloadConfig::new(1024 * 1024 * 1024))
 | 
					 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    .bind(("0.0.0.0", 5000))?
 | 
					    .bind(("0.0.0.0", 9090))?
 | 
				
			||||||
    .run()
 | 
					    .run()
 | 
				
			||||||
    .await
 | 
					    .await
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								Express
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								Express
									
									
									
									
									
								
							 Submodule Express deleted from 930a322dfa
									
								
							@@ -6,23 +6,16 @@ ENV PYTHONUNBUFFERED=1
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
WORKDIR /app
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN apt-get update && \
 | 
					RUN apt-get update && apt-get install -y imagemagick && apt-get install -y wget && ls
 | 
				
			||||||
    apt-get install -y wget unzip && \
 | 
					 | 
				
			||||||
    wget https://github.com/protocolbuffers/protobuf/releases/download/v25.0/protoc-25.0-linux-x86_64.zip && \
 | 
					 | 
				
			||||||
    unzip protoc-25.0-linux-x86_64.zip && \
 | 
					 | 
				
			||||||
    mv bin/protoc /usr/local/bin/ && \
 | 
					 | 
				
			||||||
    rm -rf protoc-25.0-linux-x86_64.zip bin include readme.txt
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN wget https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png && \
 | 
					RUN wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \
 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png && \
 | 
					    wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \
 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/QdKvaeQI/video.mp4 && \
 | 
					    wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \
 | 
				
			||||||
    wget https://files.ivanch.me/api/public/dl/YD4vmSsO/nginx.html && \
 | 
					 | 
				
			||||||
    rm -rf runtimes && \
 | 
					    rm -rf runtimes && \
 | 
				
			||||||
    mkdir -p ./static && \
 | 
					    mkdir -p ./static && \
 | 
				
			||||||
    mv small-image.png ./static && \
 | 
					    mv small-image.png ./static && \
 | 
				
			||||||
    mv big-image.png ./static && \
 | 
					    mv big-image.png ./static && \
 | 
				
			||||||
    mv video.mp4 ./static && \
 | 
					    mv video.mp4 ./static
 | 
				
			||||||
    mv nginx.html ./static
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY . .
 | 
					COPY . .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,11 @@
 | 
				
			|||||||
from flask import Flask
 | 
					from flask import Flask
 | 
				
			||||||
from controllers.status import status_blueprint
 | 
					from controllers.status import status_blueprint
 | 
				
			||||||
from controllers.simulation import simulation_blueprint
 | 
					 | 
				
			||||||
from controllers.image import image_blueprint
 | 
					from controllers.image import image_blueprint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app = Flask(__name__)
 | 
					app = Flask(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
app.register_blueprint(status_blueprint)
 | 
					app.register_blueprint(status_blueprint)
 | 
				
			||||||
app.register_blueprint(simulation_blueprint)
 | 
					 | 
				
			||||||
app.register_blueprint(image_blueprint)
 | 
					app.register_blueprint(image_blueprint)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								FlaskAPI/blurred_temp_image.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								FlaskAPI/blurred_temp_image.jpeg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 36 KiB  | 
@@ -5,6 +5,36 @@ from flask import request, Response, Blueprint, jsonify, send_file
 | 
				
			|||||||
image_blueprint = Blueprint('image_blueprint', __name__)
 | 
					image_blueprint = Blueprint('image_blueprint', __name__)
 | 
				
			||||||
image_service = ImageService()
 | 
					image_service = ImageService()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@image_blueprint.route('/image/blur', methods=['POST'])
 | 
				
			||||||
 | 
					def blur_image():
 | 
				
			||||||
 | 
					    radius = int(request.args.get('radius'))
 | 
				
			||||||
 | 
					    image = request.get_data()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if radius and image:
 | 
				
			||||||
 | 
					        return send_file(io.BytesIO(image_service.box_blur_image(image, radius)),
 | 
				
			||||||
 | 
					                         mimetype='image/png',
 | 
				
			||||||
 | 
					                         as_attachment=True,
 | 
				
			||||||
 | 
					                         download_name='blurred_image.png')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "Bad request", 400
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@image_blueprint.route('/image/load-small-image', methods=['GET'])
 | 
				
			||||||
 | 
					def get_simple_image():
 | 
				
			||||||
 | 
					    return send_file(io.BytesIO(image_service.get_simple_image()),
 | 
				
			||||||
 | 
					                     mimetype='image/png',
 | 
				
			||||||
 | 
					                     as_attachment=True,
 | 
				
			||||||
 | 
					                     download_name='small-image.png')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@image_blueprint.route('/image/load-big-image', methods=['GET'])
 | 
				
			||||||
 | 
					def get_big_image():
 | 
				
			||||||
 | 
					    return send_file(io.BytesIO(image_service.get_big_image()),
 | 
				
			||||||
 | 
					                     mimetype='image/png',
 | 
				
			||||||
 | 
					                     as_attachment=True,
 | 
				
			||||||
 | 
					                     download_name='big-image.png')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@image_blueprint.route('/image/save-big-image', methods=['POST'])
 | 
					@image_blueprint.route('/image/save-big-image', methods=['POST'])
 | 
				
			||||||
def save_image():
 | 
					def save_image():
 | 
				
			||||||
    image_service.save_image(request.get_data())
 | 
					    image_service.save_image(request.get_data())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,41 +0,0 @@
 | 
				
			|||||||
from flask import request, Blueprint, jsonify
 | 
					 | 
				
			||||||
import person_pb2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
simulation_blueprint = Blueprint('simulation_blueprint', __name__)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SimulationController:
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def harmonic_progression(self, n):
 | 
					 | 
				
			||||||
        sum = 0
 | 
					 | 
				
			||||||
        for i in range(1, n):
 | 
					 | 
				
			||||||
            sum += 1/i
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return sum
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def return_helloworld(self):
 | 
					 | 
				
			||||||
        return jsonify(message="Hello World!")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
simulation_controller = SimulationController()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@simulation_blueprint.route('/simulation/harmonic-progression', methods=['GET'])
 | 
					 | 
				
			||||||
def return_ok():
 | 
					 | 
				
			||||||
    n = int(request.args.get('n'))
 | 
					 | 
				
			||||||
    sum = simulation_controller.harmonic_progression(n)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return str(sum), 200
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@simulation_blueprint.route('/simulation/json', methods=['POST'])
 | 
					 | 
				
			||||||
def return_helloworld():
 | 
					 | 
				
			||||||
    data = request.json
 | 
					 | 
				
			||||||
    return data, 200
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@simulation_blueprint.route('/simulation/protobuf', methods=['POST'])
 | 
					 | 
				
			||||||
def return_protobuf():
 | 
					 | 
				
			||||||
    bytes_data = request.data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    helloworld = person_pb2.Person()
 | 
					 | 
				
			||||||
    helloworld.ParseFromString(bytes_data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return helloworld.SerializeToString(), 200
 | 
					 | 
				
			||||||
@@ -2,6 +2,18 @@ from flask import jsonify, Blueprint
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
status_blueprint = Blueprint('status_blueprint', __name__)
 | 
					status_blueprint = Blueprint('status_blueprint', __name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StatusController:
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def return_ok(self):
 | 
				
			||||||
 | 
					        return jsonify(status=200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					status_controller = StatusController()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@status_blueprint.route('/status/ok', methods=['GET'])
 | 
					@status_blueprint.route('/status/ok', methods=['GET'])
 | 
				
			||||||
def return_ok():
 | 
					def return_ok():
 | 
				
			||||||
    return '', 200
 | 
					    return jsonify(status=200)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +0,0 @@
 | 
				
			|||||||
syntax = "proto3";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
message Person {
 | 
					 | 
				
			||||||
    string name = 1;
 | 
					 | 
				
			||||||
    int32 age = 2;
 | 
					 | 
				
			||||||
    repeated string friends = 3;
 | 
					 | 
				
			||||||
    string email = 4;
 | 
					 | 
				
			||||||
    string phone = 5;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
# -*- coding: utf-8 -*-
 | 
					 | 
				
			||||||
# Generated by the protocol buffer compiler.  DO NOT EDIT!
 | 
					 | 
				
			||||||
# source: person.proto
 | 
					 | 
				
			||||||
# Protobuf Python Version: 4.25.0
 | 
					 | 
				
			||||||
"""Generated protocol buffer code."""
 | 
					 | 
				
			||||||
from google.protobuf import descriptor as _descriptor
 | 
					 | 
				
			||||||
from google.protobuf import descriptor_pool as _descriptor_pool
 | 
					 | 
				
			||||||
from google.protobuf import symbol_database as _symbol_database
 | 
					 | 
				
			||||||
from google.protobuf.internal import builder as _builder
 | 
					 | 
				
			||||||
# @@protoc_insertion_point(imports)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_sym_db = _symbol_database.Default()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cperson.proto\"R\n\x06Person\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03\x61ge\x18\x02 \x01(\x05\x12\x0f\n\x07\x66riends\x18\x03 \x03(\t\x12\r\n\x05\x65mail\x18\x04 \x01(\t\x12\r\n\x05phone\x18\x05 \x01(\tb\x06proto3')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_globals = globals()
 | 
					 | 
				
			||||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
 | 
					 | 
				
			||||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'person_pb2', _globals)
 | 
					 | 
				
			||||||
if _descriptor._USE_C_DESCRIPTORS == False:
 | 
					 | 
				
			||||||
  DESCRIPTOR._options = None
 | 
					 | 
				
			||||||
  _globals['_PERSON']._serialized_start=16
 | 
					 | 
				
			||||||
  _globals['_PERSON']._serialized_end=98
 | 
					 | 
				
			||||||
# @@protoc_insertion_point(module_scope)
 | 
					 | 
				
			||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
Flask==3.0
 | 
					Flask>=1.0
 | 
				
			||||||
gunicorn==19.9.0
 | 
					gunicorn>=19.9.0
 | 
				
			||||||
protobuf==4.25.0
 | 
					Wand
 | 
				
			||||||
@@ -1,7 +1,49 @@
 | 
				
			|||||||
 | 
					from wand.image import Image, Color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def box_blur_image_separable(image, radius_x, radius_y):
 | 
				
			||||||
 | 
					    width, height = image.width, image.height
 | 
				
			||||||
 | 
					    kernel_x_size = 2 * radius_x + 1
 | 
				
			||||||
 | 
					    kernel_y_size = 2 * radius_y + 1
 | 
				
			||||||
 | 
					    kernel_area = kernel_x_size * kernel_y_size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    blurred_image = image.clone()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for y in range(height):
 | 
				
			||||||
 | 
					        for x in range(width):
 | 
				
			||||||
 | 
					            r_total, g_total, b_total = 0, 0, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for offset_y in range(-radius_y, radius_y + 1):
 | 
				
			||||||
 | 
					                for offset_x in range(-radius_x, radius_x + 1):
 | 
				
			||||||
 | 
					                    new_x = x + offset_x
 | 
				
			||||||
 | 
					                    new_y = y + offset_y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if 0 <= new_x < width and 0 <= new_y < height:
 | 
				
			||||||
 | 
					                        pixel = image[new_x, new_y]
 | 
				
			||||||
 | 
					                        r_total += pixel.red_int8
 | 
				
			||||||
 | 
					                        g_total += pixel.green_int8
 | 
				
			||||||
 | 
					                        b_total += pixel.blue_int8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            r_avg = int(r_total / kernel_area)
 | 
				
			||||||
 | 
					            g_avg = int(g_total / kernel_area)
 | 
				
			||||||
 | 
					            b_avg = int(b_total / kernel_area)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            blurred_image[x, y] = Color(f'rgb({r_avg},{g_avg},{b_avg})')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return blurred_image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ImageService:
 | 
					class ImageService:
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def box_blur_image(self, img, radius):
 | 
				
			||||||
 | 
					        with Image(blob=img) as image:
 | 
				
			||||||
 | 
					            image.gaussian_blur(radius, radius)
 | 
				
			||||||
 | 
					            return image.make_blob()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # blurred_image = box_blur_image_separable(image, radius, 0)
 | 
				
			||||||
 | 
					            # blurred_image = box_blur_image_separable(blurred_image, 0, radius)
 | 
				
			||||||
 | 
					            # return blurred_image.make_blob()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_simple_image(self):
 | 
					    def get_simple_image(self):
 | 
				
			||||||
        with open("./static/small-image.png", "rb") as file:
 | 
					        with open("./static/small-image.png", "rb") as file:
 | 
				
			||||||
            return file.read()
 | 
					            return file.read()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								Spring
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								Spring
									
									
									
									
									
								
							 Submodule Spring deleted from 1c28f5c8e3
									
								
							@@ -31,7 +31,7 @@ services:
 | 
				
			|||||||
    build: ./ActixAPI
 | 
					    build: ./ActixAPI
 | 
				
			||||||
    restart: always
 | 
					    restart: always
 | 
				
			||||||
    ports:
 | 
					    ports:
 | 
				
			||||||
      - "9083:5000"
 | 
					      - "9083:9090"
 | 
				
			||||||
    deploy:
 | 
					    deploy:
 | 
				
			||||||
      resources:
 | 
					      resources:
 | 
				
			||||||
        limits:
 | 
					        limits:
 | 
				
			||||||
@@ -40,7 +40,7 @@ services:
 | 
				
			|||||||
  tcc-express:
 | 
					  tcc-express:
 | 
				
			||||||
    image: tcc:express
 | 
					    image: tcc:express
 | 
				
			||||||
    container_name: tcc-express
 | 
					    container_name: tcc-express
 | 
				
			||||||
    build: ./Express
 | 
					    build: ./tcc-express
 | 
				
			||||||
    restart: always
 | 
					    restart: always
 | 
				
			||||||
    ports:
 | 
					    ports:
 | 
				
			||||||
      - "9084:5000"
 | 
					      - "9084:5000"
 | 
				
			||||||
@@ -49,15 +49,3 @@ services:
 | 
				
			|||||||
        limits:
 | 
					        limits:
 | 
				
			||||||
          cpus: '1'
 | 
					          cpus: '1'
 | 
				
			||||||
          memory: 1GB
 | 
					          memory: 1GB
 | 
				
			||||||
  tcc-spring:
 | 
					 | 
				
			||||||
    image: tcc:spring
 | 
					 | 
				
			||||||
    container_name: tcc-spring
 | 
					 | 
				
			||||||
    build: ./Spring
 | 
					 | 
				
			||||||
    restart: always
 | 
					 | 
				
			||||||
    ports:
 | 
					 | 
				
			||||||
      - "9085:8080"
 | 
					 | 
				
			||||||
    deploy:
 | 
					 | 
				
			||||||
      resources:
 | 
					 | 
				
			||||||
        limits:
 | 
					 | 
				
			||||||
          cpus: '1'
 | 
					 | 
				
			||||||
          memory: 1GB
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,29 +1,8 @@
 | 
				
			|||||||
import json
 | 
					 | 
				
			||||||
import person_pb2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
person_proto = person_pb2.Person()
 | 
					 | 
				
			||||||
person_proto.name = "John Doe"
 | 
					 | 
				
			||||||
person_proto.age = 30
 | 
					 | 
				
			||||||
person_proto.friends.extend(["Jane Doe", "John Smith"])
 | 
					 | 
				
			||||||
person_proto.email = "john.doe@email.com"
 | 
					 | 
				
			||||||
person_proto.phone = "123-456-7890"
 | 
					 | 
				
			||||||
person_proto = person_proto.SerializeToString()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
person_json = {
 | 
					 | 
				
			||||||
    "name": "John Doe",
 | 
					 | 
				
			||||||
    "age": 30,
 | 
					 | 
				
			||||||
    "friends": ["Jane Doe", "John Smith"],
 | 
					 | 
				
			||||||
    "email": "john.doe@email.com",
 | 
					 | 
				
			||||||
    "phone": "123-456-7890"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
person_json = json.dumps(person_json)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FRAMEWORKS = [
 | 
					FRAMEWORKS = [
 | 
				
			||||||
    ('Actix', 'tcc-actix', 'orange'),
 | 
					    ('Actix', 'tcc-actix'),
 | 
				
			||||||
    ('ASP.NET', 'tcc-aspnet', 'blue'),
 | 
					    ('ASP.NET', 'tcc-aspnet'),
 | 
				
			||||||
    ('Flask', 'tcc-flask', 'grey'),
 | 
					    ('Flask', 'tcc-flask'),
 | 
				
			||||||
    ('Express', 'tcc-express', 'red'),
 | 
					    ('Express', 'tcc-express'),
 | 
				
			||||||
    ('Spring', 'tcc-spring', 'green'),
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENDPOINTS = {
 | 
					ENDPOINTS = {
 | 
				
			||||||
@@ -31,17 +10,16 @@ ENDPOINTS = {
 | 
				
			|||||||
    'ASP.NET': 'http://localhost:9081',
 | 
					    'ASP.NET': 'http://localhost:9081',
 | 
				
			||||||
    'Flask': 'http://localhost:9082',
 | 
					    'Flask': 'http://localhost:9082',
 | 
				
			||||||
    'Express': 'http://localhost:9084',
 | 
					    'Express': 'http://localhost:9084',
 | 
				
			||||||
    'Spring': 'http://localhost:9085',
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AVG_RUNS = 30
 | 
					BLUR_RADIUS = 5
 | 
				
			||||||
 | 
					 | 
				
			||||||
API_REQUESTS = [
 | 
					API_REQUESTS = [
 | 
				
			||||||
    ('/status/ok', 'GET', range(0, 30_000, 5000), None),
 | 
					    ('/status/ok', 'GET', range(0, 30_000, 5000), None),
 | 
				
			||||||
    ('/simulation/harmonic-progression?n=100000', 'GET', range(0, 30_000, 5000), None),
 | 
					    ('/image/save-big-image', 'POST', range(0, 10_000, 1_000), open('big-image.png', 'rb').read()),
 | 
				
			||||||
    ('/simulation/json', 'POST', range(0, 30_000, 5000), (person_json, "application/json")),
 | 
					    (f'/image/blur?radius={BLUR_RADIUS}', 'POST', range(0, 1_000, 50), open('small-image.png', 'rb').read()),
 | 
				
			||||||
    ('/simulation/protobuf', 'POST', range(0, 30_000, 5000), (person_proto, "application/protobuf")),
 | 
					    ('/image/load-small-image', 'GET', range(0, 30_000, 5000), None),
 | 
				
			||||||
    ('/image/save-big-image', 'POST', range(0, 500, 50), (open('big-image.png', 'rb').read(), "image/png")),
 | 
					 | 
				
			||||||
    ('/static/small-image.png', 'GET', range(0, 30_000, 5000), None),
 | 
					    ('/static/small-image.png', 'GET', range(0, 30_000, 5000), None),
 | 
				
			||||||
 | 
					    ('/image/load-big-image', 'GET', range(0, 500, 50), None),
 | 
				
			||||||
    ('/static/big-image.png', 'GET', range(0, 500, 50), None),
 | 
					    ('/static/big-image.png', 'GET', range(0, 500, 50), None),
 | 
				
			||||||
]
 | 
					    ('/static/video.mp4', 'GET', range(0, 10_000, 1_000), None),
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
							
								
								
									
										106
									
								
								scripts/graph.py
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								scripts/graph.py
									
									
									
									
									
								
							@@ -1,72 +1,55 @@
 | 
				
			|||||||
import numpy as np
 | 
					import numpy as np
 | 
				
			||||||
import matplotlib.pyplot as plt
 | 
					import matplotlib.pyplot as plt
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
from common import API_REQUESTS, FRAMEWORKS
 | 
					from common import API_REQUESTS, FRAMEWORKS
 | 
				
			||||||
from pylab import plot, show, savefig, xlim, figure, \
 | 
					 | 
				
			||||||
                ylim, legend, boxplot, setp, axes
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
FRAMEWORKS_COLORS = [c for _, _, c in FRAMEWORKS]
 | 
					FRAMEWORKS = [f for f, _ in FRAMEWORKS]
 | 
				
			||||||
FRAMEWORKS = [f for f, _, _ in FRAMEWORKS]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setBoxColors(bp):
 | 
					def plot_graph(x_data, y_data, title, x_label, y_label, filename):
 | 
				
			||||||
    for i, box in enumerate(bp['boxes']):
 | 
					    for i, framework in enumerate(FRAMEWORKS):
 | 
				
			||||||
        box.set(color=FRAMEWORKS_COLORS[i])
 | 
					        plt.plot(x_data, y_data[i], markersize=1, linewidth=1, linestyle='solid', label=framework)
 | 
				
			||||||
        box.set(facecolor=FRAMEWORKS_COLORS[i])
 | 
					 | 
				
			||||||
    for i in range(len(FRAMEWORKS)):
 | 
					 | 
				
			||||||
        bp['whiskers'][i*2].set(color=FRAMEWORKS_COLORS[i])
 | 
					 | 
				
			||||||
        bp['whiskers'][i*2 + 1].set(color=FRAMEWORKS_COLORS[i])
 | 
					 | 
				
			||||||
    for i in range(len(FRAMEWORKS)):
 | 
					 | 
				
			||||||
        bp['caps'][i*2].set(color=FRAMEWORKS_COLORS[i])
 | 
					 | 
				
			||||||
        bp['caps'][i*2 + 1].set(color=FRAMEWORKS_COLORS[i])
 | 
					 | 
				
			||||||
    for i, median in enumerate(bp['medians']):
 | 
					 | 
				
			||||||
        median.set(color='white')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    plt.title(title)
 | 
				
			||||||
 | 
					    plt.xlabel(x_label)
 | 
				
			||||||
 | 
					    plt.ylabel(y_label)
 | 
				
			||||||
 | 
					    plt.legend()
 | 
				
			||||||
 | 
					    plt.savefig(f'{filename}.png')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def plot_graph(x_data, y_data, title, x_label, y_label, filename, y_lim = None):
 | 
					    plt.clf()
 | 
				
			||||||
    print(filename)
 | 
					    plt.close('all')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    old_x_data = x_data
 | 
					def plot_resource_graph(x_data, y_data, title, x_label, y_label, filename):
 | 
				
			||||||
    old_y_data = y_data
 | 
					    requests = x_data
 | 
				
			||||||
 | 
					    frameworks = {}
 | 
				
			||||||
 | 
					    print(y_data)
 | 
				
			||||||
 | 
					    for i, framework in enumerate(FRAMEWORKS):
 | 
				
			||||||
 | 
					        frameworks[framework] = y_data[i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    x_data = []
 | 
					    x = np.arange(len(requests))
 | 
				
			||||||
    y_data = []
 | 
					    width = 0.10
 | 
				
			||||||
 | 
					    multiplier = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for i in range(len(old_x_data)):
 | 
					    fig, ax = plt.subplots(layout='constrained')
 | 
				
			||||||
        if old_x_data[i] not in x_data:
 | 
					 | 
				
			||||||
            x_data.append(old_x_data[i])
 | 
					 | 
				
			||||||
            y_data.append([])
 | 
					 | 
				
			||||||
            for f in range(len(FRAMEWORKS)):
 | 
					 | 
				
			||||||
                y_data[-1].append([])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for f in range(len(FRAMEWORKS)):
 | 
					    print(x)
 | 
				
			||||||
            y_data[-1][f].append(old_y_data[f][i])
 | 
					    for framework, measurements in frameworks.items():
 | 
				
			||||||
 | 
					        print(framework, measurements)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fig, axes = plt.subplots(ncols=len(x_data), sharey=True)
 | 
					    for attribute, measurement in frameworks.items():
 | 
				
			||||||
 | 
					        offset = width * multiplier
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for ax, j in zip(axes, [i for i in range(len(x_data))]):
 | 
					        rects = ax.bar(x + offset, measurement, width, label=attribute)
 | 
				
			||||||
        bp = ax.boxplot(y_data[j], showfliers=False, patch_artist=True, positions=[i for i in range(len(FRAMEWORKS))])
 | 
					        ax.bar_label(rects, padding=3)
 | 
				
			||||||
        ax.set(xlabel=x_data[j], xticklabels=['' for _ in range(len(FRAMEWORKS))])
 | 
					        multiplier += 1
 | 
				
			||||||
        ax.margins(0.05)
 | 
					 | 
				
			||||||
        setBoxColors(bp)
 | 
					 | 
				
			||||||
        if j % 2 == 1:
 | 
					 | 
				
			||||||
            ax.set_facecolor('#f2f2f2')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # set title
 | 
					    # Add some text for labels, title and custom x-axis tick labels, etc.
 | 
				
			||||||
    fig.suptitle(title)
 | 
					    ax.set_xlabel(x_label)
 | 
				
			||||||
    fig.supxlabel(x_label)
 | 
					    ax.set_ylabel(y_label)
 | 
				
			||||||
    fig.supylabel(y_label)
 | 
					    ax.set_title(title)
 | 
				
			||||||
 | 
					    ax.set_xticks(x + (width/2), requests)
 | 
				
			||||||
 | 
					    ax.legend(loc='upper left', ncols=len(frameworks.items()))
 | 
				
			||||||
 | 
					    ax.set_ylim(0, 120)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if y_lim:
 | 
					 | 
				
			||||||
        plt.ylim(y_lim)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if filename.startswith('req'):
 | 
					 | 
				
			||||||
        for i, framework in enumerate(FRAMEWORKS):
 | 
					 | 
				
			||||||
            h, = plt.plot([], c=FRAMEWORKS_COLORS[i], label=framework, marker='.', linestyle='--')
 | 
					 | 
				
			||||||
            # h.set_visible(False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        plt.legend()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plt.tight_layout()
 | 
					 | 
				
			||||||
    fig.subplots_adjust(hspace=0, wspace=0)
 | 
					 | 
				
			||||||
    plt.savefig(f'{filename}.png')
 | 
					    plt.savefig(f'{filename}.png')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    plt.clf()
 | 
					    plt.clf()
 | 
				
			||||||
@@ -97,15 +80,8 @@ def get_resource_data(filename):
 | 
				
			|||||||
    for line in lines:
 | 
					    for line in lines:
 | 
				
			||||||
        line = line.strip().split(',')
 | 
					        line = line.strip().split(',')
 | 
				
			||||||
        if line:
 | 
					        if line:
 | 
				
			||||||
            r = [round(float(line[1])*100), round(float(line[2])*100)]
 | 
					 | 
				
			||||||
            if r[0] > 100:
 | 
					 | 
				
			||||||
                r[0] = 100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if r[1] > 100:
 | 
					 | 
				
			||||||
                r[1] = 100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            x.append(int(line[0])) # requests
 | 
					            x.append(int(line[0])) # requests
 | 
				
			||||||
            y.append(r) # cpu, ram
 | 
					            y.append([float(v)*100 for v in line[1:]]) # cpu, ram
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return x, y
 | 
					    return x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -134,7 +110,7 @@ def generate_resource_graph(filename, framework_name, endpoint_name):
 | 
				
			|||||||
            y.append([data[resource_index] for data in y_data])
 | 
					            y.append([data[resource_index] for data in y_data])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        graph_file = f'{resource}_{endpoint_name.replace("/", "").replace("?", "")}'
 | 
					        graph_file = f'{resource}_{endpoint_name.replace("/", "").replace("?", "")}'
 | 
				
			||||||
        plot_graph(x, y, f'Uso de {resource.upper()} - {endpoint_name}', 'Número de requisições', f'Uso de {resource.upper()} (%)', graph_file)
 | 
					        plot_resource_graph(x, y, f'Uso de {resource.upper()} - {endpoint_name}', 'Número de requisições', 'Uso (%)', graph_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    endpoints = [config[0] for config in API_REQUESTS]
 | 
					    endpoints = [config[0] for config in API_REQUESTS]
 | 
				
			||||||
@@ -143,12 +119,8 @@ if __name__ == '__main__':
 | 
				
			|||||||
        framework_name = 'ASP.NET'
 | 
					        framework_name = 'ASP.NET'
 | 
				
			||||||
        endpoint_file = endpoint_name.replace('/', '')
 | 
					        endpoint_file = endpoint_name.replace('/', '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        endpoint_name = '/' + endpoint_name.split('/')[-1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        filename = f'data/resource_ASP.NET_{endpoint_file}.csv'
 | 
					        filename = f'data/resource_ASP.NET_{endpoint_file}.csv'
 | 
				
			||||||
        filename = filename.replace("?", "_")
 | 
					 | 
				
			||||||
        generate_resource_graph(filename, framework_name, endpoint_name)
 | 
					        generate_resource_graph(filename, framework_name, endpoint_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        filename = f'data/req_ASP.NET_{endpoint_file}.csv'
 | 
					        filename = f'data/req_ASP.NET_{endpoint_file}.csv'
 | 
				
			||||||
        filename = filename.replace("?", "_")
 | 
					 | 
				
			||||||
        generate_req_graph(filename, framework_name, endpoint_name)
 | 
					        generate_req_graph(filename, framework_name, endpoint_name)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
import requests
 | 
					import requests
 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def download_file(url):
 | 
					def download_file(url):
 | 
				
			||||||
    local_filename = url.split('/')[-1]
 | 
					    local_filename = url.split('/')[-1]
 | 
				
			||||||
@@ -14,9 +13,5 @@ def download_file(url):
 | 
				
			|||||||
    return local_filename
 | 
					    return local_filename
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def init():
 | 
					def init():
 | 
				
			||||||
    if not os.path.exists('small-image.png'):
 | 
					    download_file('https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png')
 | 
				
			||||||
        download_file('https://files.ivanch.me/api/public/dl/ch3NV0P8/small-image.png')
 | 
					    download_file('https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png')
 | 
				
			||||||
    if not os.path.exists('big-image.png'):
 | 
					 | 
				
			||||||
        download_file('https://files.ivanch.me/api/public/dl/jNlXYMLR/big-image.png')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
init()
 | 
					 | 
				
			||||||
@@ -1,9 +0,0 @@
 | 
				
			|||||||
syntax = "proto3";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
message Person {
 | 
					 | 
				
			||||||
    string name = 1;
 | 
					 | 
				
			||||||
    int32 age = 2;
 | 
					 | 
				
			||||||
    repeated string friends = 3;
 | 
					 | 
				
			||||||
    string email = 4;
 | 
					 | 
				
			||||||
    string phone = 5;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
# -*- coding: utf-8 -*-
 | 
					 | 
				
			||||||
# Generated by the protocol buffer compiler.  DO NOT EDIT!
 | 
					 | 
				
			||||||
# source: person.proto
 | 
					 | 
				
			||||||
# Protobuf Python Version: 4.25.0
 | 
					 | 
				
			||||||
"""Generated protocol buffer code."""
 | 
					 | 
				
			||||||
from google.protobuf import descriptor as _descriptor
 | 
					 | 
				
			||||||
from google.protobuf import descriptor_pool as _descriptor_pool
 | 
					 | 
				
			||||||
from google.protobuf import symbol_database as _symbol_database
 | 
					 | 
				
			||||||
from google.protobuf.internal import builder as _builder
 | 
					 | 
				
			||||||
# @@protoc_insertion_point(imports)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_sym_db = _symbol_database.Default()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cperson.proto\"R\n\x06Person\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03\x61ge\x18\x02 \x01(\x05\x12\x0f\n\x07\x66riends\x18\x03 \x03(\t\x12\r\n\x05\x65mail\x18\x04 \x01(\t\x12\r\n\x05phone\x18\x05 \x01(\tb\x06proto3')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_globals = globals()
 | 
					 | 
				
			||||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
 | 
					 | 
				
			||||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'person_pb2', _globals)
 | 
					 | 
				
			||||||
if _descriptor._USE_C_DESCRIPTORS == False:
 | 
					 | 
				
			||||||
  DESCRIPTOR._options = None
 | 
					 | 
				
			||||||
  _globals['_PERSON']._serialized_start=16
 | 
					 | 
				
			||||||
  _globals['_PERSON']._serialized_end=98
 | 
					 | 
				
			||||||
# @@protoc_insertion_point(module_scope)
 | 
					 | 
				
			||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
import person_pb2
 | 
					 | 
				
			||||||
import asyncio
 | 
					 | 
				
			||||||
import aiohttp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async def fetch(session):
 | 
					 | 
				
			||||||
    obj = get_object()
 | 
					 | 
				
			||||||
    # async with session.post('http://172.25.96.1:9090/simulation/protobuf', data=obj.SerializeToString(),
 | 
					 | 
				
			||||||
    async with session.post('http://127.0.0.1:5000/simulation/protobuf', data=obj.SerializeToString(),
 | 
					 | 
				
			||||||
        headers={"content-type": "application/protobuf"}) as resp:
 | 
					 | 
				
			||||||
        print(resp.status)
 | 
					 | 
				
			||||||
        data = await resp.read()
 | 
					 | 
				
			||||||
        receiveObj = person_pb2.Person()
 | 
					 | 
				
			||||||
        receiveObj.ParseFromString(data)
 | 
					 | 
				
			||||||
        print(receiveObj)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async def go(loop):
 | 
					 | 
				
			||||||
    async with aiohttp.ClientSession(loop=loop) as session:
 | 
					 | 
				
			||||||
        await fetch(session)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_object():
 | 
					 | 
				
			||||||
    obj = person_pb2.Person()
 | 
					 | 
				
			||||||
    obj.name = "John Doe"
 | 
					 | 
				
			||||||
    obj.age = 30
 | 
					 | 
				
			||||||
    obj.friends.extend(["Jane Doe", "John Smith"])
 | 
					 | 
				
			||||||
    obj.email = "john.doe@email.com"
 | 
					 | 
				
			||||||
    obj.phone = "123-456-7890"
 | 
					 | 
				
			||||||
    return obj
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
loop = asyncio.get_event_loop()
 | 
					 | 
				
			||||||
loop.run_until_complete(go(loop))
 | 
					 | 
				
			||||||
loop.close()
 | 
					 | 
				
			||||||
@@ -1,4 +0,0 @@
 | 
				
			|||||||
protobuf>=4.25.0
 | 
					 | 
				
			||||||
matplotlib
 | 
					 | 
				
			||||||
numpy
 | 
					 | 
				
			||||||
docker
 | 
					 | 
				
			||||||
@@ -2,10 +2,11 @@ import requests
 | 
				
			|||||||
import docker
 | 
					import docker
 | 
				
			||||||
import concurrent.futures
 | 
					import concurrent.futures
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
from math import floor
 | 
					from math import floor
 | 
				
			||||||
from init import init
 | 
					from init import init
 | 
				
			||||||
from common import FRAMEWORKS, ENDPOINTS, API_REQUESTS, AVG_RUNS
 | 
					from common import FRAMEWORKS, ENDPOINTS, API_REQUESTS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
init()
 | 
					init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,7 +15,7 @@ FRAMEWORK_NAME = ""
 | 
				
			|||||||
CONTAINER_NAME = ""
 | 
					CONTAINER_NAME = ""
 | 
				
			||||||
URL_BASE = 'http://localhost:9090'
 | 
					URL_BASE = 'http://localhost:9090'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def send_request(url, method = 'GET', data = None):
 | 
					def send_request(url, method = 'GET', payload = None):
 | 
				
			||||||
    success = False
 | 
					    success = False
 | 
				
			||||||
    responses = {
 | 
					    responses = {
 | 
				
			||||||
        2: 0, # OK
 | 
					        2: 0, # OK
 | 
				
			||||||
@@ -27,9 +28,7 @@ def send_request(url, method = 'GET', data = None):
 | 
				
			|||||||
            if method == 'GET':
 | 
					            if method == 'GET':
 | 
				
			||||||
                response = requests.get(url)
 | 
					                response = requests.get(url)
 | 
				
			||||||
            elif method == 'POST':
 | 
					            elif method == 'POST':
 | 
				
			||||||
                payload = data[0]
 | 
					                response = requests.post(url, data=payload, headers={'Content-Type': 'image/png'})
 | 
				
			||||||
                content_type = data[1]
 | 
					 | 
				
			||||||
                response = requests.post(url, data=payload, headers={'Content-Type': content_type})
 | 
					 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
        success = response.status_code == 200
 | 
					        success = response.status_code == 200
 | 
				
			||||||
@@ -63,46 +62,42 @@ def run_tests(endpoint, method, num_requests, metadata):
 | 
				
			|||||||
    for num_request in num_requests:
 | 
					    for num_request in num_requests:
 | 
				
			||||||
        if num_request <= 0: continue
 | 
					        if num_request <= 0: continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for run in range(AVG_RUNS):
 | 
					        ok_responses = 0
 | 
				
			||||||
            ok_responses = 0
 | 
					        bad_responses = 0
 | 
				
			||||||
            bad_responses = 0
 | 
					        server_errors = 0
 | 
				
			||||||
            server_errors = 0
 | 
					        cpu, ram = 0, 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            cpu, ram = 0, 0
 | 
					        with concurrent.futures.ThreadPoolExecutor(max_workers=THREADS) as executor:
 | 
				
			||||||
 | 
					            url = f'{URL_BASE}{endpoint}'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            with concurrent.futures.ThreadPoolExecutor(max_workers=THREADS) as executor:
 | 
					            start_time = time.time()
 | 
				
			||||||
                url = f'{URL_BASE}{endpoint}'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                start_time = time.time()
 | 
					            futures = []
 | 
				
			||||||
 | 
					            #with requests.Session() as session:
 | 
				
			||||||
 | 
					            #    futures = [executor.submit(send_request, session, url) for _ in range(num_request)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                futures = []
 | 
					            half = floor(num_request/2)
 | 
				
			||||||
 | 
					            for i in range(num_request):
 | 
				
			||||||
 | 
					                futures.append(executor.submit(send_request, url, method, metadata))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                half = floor(num_request/2)
 | 
					                if i == half:
 | 
				
			||||||
                for i in range(num_request):
 | 
					                    cpu, ram = get_resource_usage()
 | 
				
			||||||
                    futures.append(executor.submit(send_request, url, method, metadata))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if i == half:
 | 
					            concurrent.futures.wait(futures)
 | 
				
			||||||
                        cpu, ram = get_resource_usage()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                concurrent.futures.wait(futures)
 | 
					            elapsed_time = time.time() - start_time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                elapsed_time = time.time() - start_time
 | 
					            for future in futures:
 | 
				
			||||||
 | 
					                responses = future.result()
 | 
				
			||||||
 | 
					                ok_responses += responses[2]
 | 
				
			||||||
 | 
					                bad_responses += responses[4]
 | 
				
			||||||
 | 
					                server_errors += responses[5]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for future in futures:
 | 
					        print(f"{num_request}: {elapsed_time:.2f} seconds. {elapsed_time/num_request:.4f} seconds per request. {num_request/elapsed_time:.2f} requests per second. [OK: {ok_responses}, Bad Request: {bad_responses}, Server Error: {server_errors}]]")
 | 
				
			||||||
                    responses = future.result()
 | 
					        record(files[0], num_request, f"{num_request/elapsed_time:.2f}")
 | 
				
			||||||
                    ok_responses += responses[2]
 | 
					        record_resource(files[1], num_request, cpu, ram)
 | 
				
			||||||
                    bad_responses += responses[4]
 | 
					 | 
				
			||||||
                    server_errors += responses[5]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            print(f"[#{run}] {num_request}: {elapsed_time:.2f} seconds. {elapsed_time/num_request:.4f} seconds per request. {num_request/elapsed_time:.2f} requests per second. [OK: {ok_responses}, Bad Request: {bad_responses}, Server Error: {server_errors}]]")
 | 
					        time.sleep(3)
 | 
				
			||||||
 | 
					 | 
				
			||||||
            client = docker.from_env()
 | 
					 | 
				
			||||||
            client.containers.get(CONTAINER_NAME).restart()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            record(files[0], num_request, f"{num_request/elapsed_time:.2f}")
 | 
					 | 
				
			||||||
            record_resource(files[1], num_request, cpu, ram)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            time.sleep(30)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_resource_usage():
 | 
					def get_resource_usage():
 | 
				
			||||||
    if CONTAINER_NAME == "": return 0, 0
 | 
					    if CONTAINER_NAME == "": return 0, 0
 | 
				
			||||||
@@ -135,8 +130,6 @@ if __name__ == "__main__":
 | 
				
			|||||||
    if not os.path.exists("data"):
 | 
					    if not os.path.exists("data"):
 | 
				
			||||||
        os.mkdir("data")
 | 
					        os.mkdir("data")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for i in range(len(FRAMEWORKS)):
 | 
					    for i in range(len(FRAMEWORKS)):
 | 
				
			||||||
        FRAMEWORK_NAME = FRAMEWORKS[i][0]
 | 
					        FRAMEWORK_NAME = FRAMEWORKS[i][0]
 | 
				
			||||||
        CONTAINER_NAME = FRAMEWORKS[i][1]
 | 
					        CONTAINER_NAME = FRAMEWORKS[i][1]
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user