Rename Parser projects
This commit is contained in:
parent
a9ce0c1785
commit
69db707d68
@ -1,2 +0,0 @@
|
|||||||
global using NUnit.Framework;
|
|
||||||
global using RhSolutions.MLModifiers;
|
|
@ -5,9 +5,9 @@ VisualStudioVersion = 17.0.31903.59
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.Api", "RhSolutions.Api\RhSolutions.Api.csproj", "{6AACEC90-0811-418D-8505-EB142A2B2AFA}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.Api", "RhSolutions.Api\RhSolutions.Api.csproj", "{6AACEC90-0811-418D-8505-EB142A2B2AFA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.Api.Tests", "RhSolutions.Api.Tests\RhSolutions.Api.Tests.csproj", "{E49F46C4-5F07-4055-AE8B-700AA6FC35FD}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.Parsers", "RhSolutions.Parsers\RhSolutions.Parsers.csproj", "{C00C3DAB-275B-416D-BB66-4CB144441B18}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.MLModifiers", "RhSolutions.MLModifiers\RhSolutions.MLModifiers.csproj", "{50A53BB3-1F9D-4F19-90DB-BCB4D49FF9FE}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhSolutions.Parsers.Tests", "RhSolutions.Parsers.Tests\RhSolutions.Parsers.Tests.csproj", "{5AD110C3-A08C-459F-9CB1-198E75A955EE}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -22,13 +22,13 @@ Global
|
|||||||
{6AACEC90-0811-418D-8505-EB142A2B2AFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6AACEC90-0811-418D-8505-EB142A2B2AFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6AACEC90-0811-418D-8505-EB142A2B2AFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6AACEC90-0811-418D-8505-EB142A2B2AFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6AACEC90-0811-418D-8505-EB142A2B2AFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6AACEC90-0811-418D-8505-EB142A2B2AFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{E49F46C4-5F07-4055-AE8B-700AA6FC35FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C00C3DAB-275B-416D-BB66-4CB144441B18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{E49F46C4-5F07-4055-AE8B-700AA6FC35FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C00C3DAB-275B-416D-BB66-4CB144441B18}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{E49F46C4-5F07-4055-AE8B-700AA6FC35FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C00C3DAB-275B-416D-BB66-4CB144441B18}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E49F46C4-5F07-4055-AE8B-700AA6FC35FD}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C00C3DAB-275B-416D-BB66-4CB144441B18}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{50A53BB3-1F9D-4F19-90DB-BCB4D49FF9FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{5AD110C3-A08C-459F-9CB1-198E75A955EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{50A53BB3-1F9D-4F19-90DB-BCB4D49FF9FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{5AD110C3-A08C-459F-9CB1-198E75A955EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{50A53BB3-1F9D-4F19-90DB-BCB4D49FF9FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{5AD110C3-A08C-459F-9CB1-198E75A955EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{50A53BB3-1F9D-4F19-90DB-BCB4D49FF9FE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{5AD110C3-A08C-459F-9CB1-198E75A955EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Http.Extensions;
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
using RhSolutions.Api.Services;
|
using RhSolutions.Api.Services;
|
||||||
using RhSolutions.MLModifiers;
|
using RhSolutions.Parsers;
|
||||||
|
|
||||||
namespace RhSolutions.Api.Middleware;
|
namespace RhSolutions.Api.Middleware;
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ public class QueryModifier
|
|||||||
{
|
{
|
||||||
private RequestDelegate _next;
|
private RequestDelegate _next;
|
||||||
private IServiceProvider _provider;
|
private IServiceProvider _provider;
|
||||||
private IProductMLModifier? _modifier;
|
private IProductParser? _modifier;
|
||||||
|
|
||||||
public QueryModifier(RequestDelegate nextDelegate, IServiceProvider provider)
|
public QueryModifier(RequestDelegate nextDelegate, IServiceProvider provider)
|
||||||
{
|
{
|
||||||
@ -21,15 +21,15 @@ public class QueryModifier
|
|||||||
if (context.Request.Method == HttpMethods.Get
|
if (context.Request.Method == HttpMethods.Get
|
||||||
&& context.Request.Path == "/api/search")
|
&& context.Request.Path == "/api/search")
|
||||||
{
|
{
|
||||||
string query = context.Request.Query["query"].ToString();
|
string input = context.Request.Query["query"].ToString();
|
||||||
var productType = typePredicter.GetPredictedProductType(query);
|
var productType = typePredicter.GetPredictedProductType(input);
|
||||||
_modifier = _provider.GetRequiredKeyedService<IProductMLModifier>(productType);
|
_modifier = _provider.GetRequiredKeyedService<IProductParser>(productType);
|
||||||
if (_modifier == null) return;
|
if (_modifier == null) return;
|
||||||
if (_modifier.TryQueryModify(query, out var modified))
|
if (_modifier.TryParse(input, out var output))
|
||||||
{
|
{
|
||||||
QueryBuilder qb = new()
|
QueryBuilder qb = new()
|
||||||
{
|
{
|
||||||
{"query", modified}
|
{"query", output}
|
||||||
};
|
};
|
||||||
context.Request.QueryString = qb.ToQueryString();
|
context.Request.QueryString = qb.ToQueryString();
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using RhSolutions.Models;
|
using RhSolutions.Models;
|
||||||
using RhSolutions.Api.Services;
|
using RhSolutions.Api.Services;
|
||||||
using RhSolutions.Api.Middleware;
|
using RhSolutions.Api.Middleware;
|
||||||
using RhSolutions.MLModifiers;
|
using RhSolutions.Parsers;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\RhSolutions.MLModifiers\RhSolutions.MLModifiers.csproj" />
|
<ProjectReference Include="..\RhSolutions.Parsers\RhSolutions.Parsers.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
namespace RhSolutions.MLModifiers;
|
|
||||||
|
|
||||||
public interface IProductMLModifier
|
|
||||||
{
|
|
||||||
public bool TryQueryModify(string query, out string queryModified);
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
namespace RhSolutions.MLModifiers;
|
|
||||||
|
|
||||||
public class MLModifierKey : Attribute
|
|
||||||
{
|
|
||||||
public string Value { get; private set; }
|
|
||||||
public MLModifierKey(string value)
|
|
||||||
{
|
|
||||||
Value = value;
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,13 +2,13 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
|
|
||||||
namespace RhSolutions.Api.Tests;
|
namespace RhSolutions.Api.Tests;
|
||||||
|
|
||||||
public abstract class ProductQueryModifierTests
|
public abstract class ProductParsersTests
|
||||||
{
|
{
|
||||||
public void Invoke(string productType, string query, string expected)
|
public void Invoke(string productType, string query, string expected)
|
||||||
{
|
{
|
||||||
var modifier = TestServiceCollection.ServiceProvider?.GetRequiredKeyedService<IProductMLModifier>(productType);
|
var modifier = TestServiceCollection.ServiceProvider?.GetRequiredKeyedService<IProductParser>(productType);
|
||||||
string actual = string.Empty;
|
string actual = string.Empty;
|
||||||
Assert.That(modifier?.TryQueryModify(query, out actual), Is.True);
|
Assert.That(modifier?.TryParse(query, out actual), Is.True);
|
||||||
Assert.That(actual, Is.EqualTo(expected));
|
Assert.That(actual, Is.EqualTo(expected));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
namespace RhSolutions.Api.Tests;
|
namespace RhSolutions.Api.Tests;
|
||||||
|
|
||||||
public class RautitanFittingsTests : ProductQueryModifierTests
|
public class RautitanFittingsTests : ProductParsersTests
|
||||||
{
|
{
|
||||||
[TestCase("Гильза 16", "Монтажная гильза 16")]
|
[TestCase("Гильза 16", "Монтажная гильза 16")]
|
||||||
[TestCase("Пресс-втулка 20", "Монтажная гильза 20")]
|
[TestCase("Пресс-втулка 20", "Монтажная гильза 20")]
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
namespace RhSolutions.Api.Tests;
|
namespace RhSolutions.Api.Tests;
|
||||||
|
|
||||||
public class RautitanPipesTests : ProductQueryModifierTests
|
public class RautitanPipesTests : ProductParsersTests
|
||||||
{
|
{
|
||||||
[TestCase("Унив.труба RAUTITAN flex 16x2,2, бухта 100м", "Труба Flex 16x2,2 бухта")]
|
[TestCase("Унив.труба RAUTITAN flex 16x2,2, бухта 100м", "Труба Flex 16x2,2 бухта")]
|
||||||
[TestCase("Труба flex 16", "Труба Flex 16x2,2 бухта")]
|
[TestCase("Труба flex 16", "Труба Flex 16x2,2 бухта")]
|
@ -23,7 +23,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\RhSolutions.MLModifiers\RhSolutions.MLModifiers.csproj" />
|
<ProjectReference Include="..\RhSolutions.Parsers\RhSolutions.Parsers.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
2
RhSolutions.Parsers.Tests/Usings.cs
Normal file
2
RhSolutions.Parsers.Tests/Usings.cs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
global using NUnit.Framework;
|
||||||
|
global using RhSolutions.Parsers;
|
@ -1,10 +1,10 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
public abstract class Adapter : DrinkingWaterHeatingFitting
|
public abstract class Adapter : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
Match diameter = _diameter.Match(input);
|
Match diameter = _diameter.Match(input);
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Переходник на наружную резьбу")]
|
[ParserKey("Переходник на наружную резьбу")]
|
||||||
public class AdapterExternal : Adapter
|
public class AdapterExternal : Adapter
|
||||||
{
|
{
|
||||||
protected override string _title => "Переходник с наружной резьбой";
|
protected override string _title => "Переходник с наружной резьбой";
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Переходник на внутреннюю резьбу")]
|
[ParserKey("Переходник на внутреннюю резьбу")]
|
||||||
public class AdapterInternal : Adapter
|
public class AdapterInternal : Adapter
|
||||||
{
|
{
|
||||||
protected override string _title => "Переходник с внутренней резьбой -угольник-переходник";
|
protected override string _title => "Переходник с внутренней резьбой -угольник-переходник";
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Переходник с накидной гайкой")]
|
[ParserKey("Переходник с накидной гайкой")]
|
||||||
public class AdapterScrewcap : Adapter
|
public class AdapterScrewcap : Adapter
|
||||||
{
|
{
|
||||||
protected override string _title => "Переходник с накидной гайкой";
|
protected override string _title => "Переходник с накидной гайкой";
|
@ -1,10 +1,10 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Фиксатор поворота отопление")]
|
[ParserKey("Фиксатор поворота отопление")]
|
||||||
public class BendFormerHeating : DrinkingWaterHeatingFitting
|
public class BendFormerHeating : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Фиксатор поворота";
|
protected override string _title => "Фиксатор поворота";
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,11 +1,11 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Фиксатор поворота водоснабжение")]
|
[ParserKey("Фиксатор поворота водоснабжение")]
|
||||||
public class BendFormerSanitary : DrinkingWaterHeatingFitting
|
public class BendFormerSanitary : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Фиксатор поворота с кольцами";
|
protected override string _title => "Фиксатор поворота с кольцами";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,8 +1,8 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Трубка Г-образная")]
|
[ParserKey("Трубка Г-образная")]
|
||||||
public class ConnectionBend : DrinkingWaterHeatingFitting
|
public class ConnectionBend : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
private static readonly int[] lengths = [250, 500, 1000];
|
private static readonly int[] lengths = [250, 500, 1000];
|
||||||
@ -10,7 +10,7 @@ public class ConnectionBend : DrinkingWaterHeatingFitting
|
|||||||
new(@"([\b\D]|^)?(?<Diameter>16|20|25)(\D+|.*15.*)(?<Length>\b\d{3,4})([\b\D]|$)");
|
new(@"([\b\D]|^)?(?<Diameter>16|20|25)(\D+|.*15.*)(?<Length>\b\d{3,4})([\b\D]|$)");
|
||||||
protected override string _title => "Трубка Г-образная";
|
protected override string _title => "Трубка Г-образная";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var match = _pattern.Match(input);
|
var match = _pattern.Match(input);
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Трубка Т-образная")]
|
[ParserKey("Трубка Т-образная")]
|
||||||
public class ConnectionTee : ConnectionBend
|
public class ConnectionTee : ConnectionBend
|
||||||
{
|
{
|
||||||
protected override string _title => "Трубка Т-образная";
|
protected override string _title => "Трубка Т-образная";
|
@ -1,11 +1,11 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Муфта соединительная")]
|
[ParserKey("Муфта соединительная")]
|
||||||
public class Coupling : DrinkingWaterHeatingFitting
|
public class Coupling : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Муфта соединительная";
|
protected override string _title => "Муфта соединительная";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diametersMatches = _diameter.Matches(input);
|
var diametersMatches = _diameter.Matches(input);
|
@ -1,8 +1,8 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
public abstract class DrinkingWaterHeatingFitting : IProductMLModifier
|
public abstract class DrinkingWaterHeatingFitting : IProductParser
|
||||||
{
|
{
|
||||||
protected static readonly Regex _diameter =
|
protected static readonly Regex _diameter =
|
||||||
new(@"([\b\D]|^)?(?<Diameter>16|20|25|32|40|50|63)([\b\D]|$)");
|
new(@"([\b\D]|^)?(?<Diameter>16|20|25|32|40|50|63)([\b\D]|$)");
|
||||||
@ -13,7 +13,7 @@ public abstract class DrinkingWaterHeatingFitting : IProductMLModifier
|
|||||||
|
|
||||||
protected virtual string _title { get; } = string.Empty;
|
protected virtual string _title { get; } = string.Empty;
|
||||||
|
|
||||||
public virtual bool TryQueryModify(string input, out string output)
|
public virtual bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
var match = _diameter.Match(input);
|
var match = _diameter.Match(input);
|
||||||
if (match.Success)
|
if (match.Success)
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Заглушка труб RAUTITAN")]
|
[ParserKey("Заглушка труб RAUTITAN")]
|
||||||
public class DummyPlug : DrinkingWaterHeatingFitting
|
public class DummyPlug : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Заглушка для полимерн. трубы";
|
protected override string _title => "Заглушка для полимерн. трубы";
|
@ -1,11 +1,11 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Угольник RAUTITAN")]
|
[ParserKey("Угольник RAUTITAN")]
|
||||||
public class Elbow : DrinkingWaterHeatingFitting
|
public class Elbow : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title { get; } = "Угольник -PLATINUM";
|
protected override string _title { get; } = "Угольник -PLATINUM";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,10 +1,10 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
public abstract class Eurocone : DrinkingWaterHeatingFitting
|
public abstract class Eurocone : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected virtual Dictionary<string, string> _titles { get; } = new();
|
protected virtual Dictionary<string, string> _titles { get; } = new();
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,11 +1,11 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Переходник на евроконус")]
|
[ParserKey("Переходник на евроконус")]
|
||||||
public class EuroconeAdapter : DrinkingWaterHeatingFitting
|
public class EuroconeAdapter : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Переходник на евроконус";
|
protected override string _title => "Переходник на евроконус";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,9 +1,9 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Резьбозажимное для трубки")]
|
[ParserKey("Резьбозажимное для трубки")]
|
||||||
public class EuroconeConnectionBend : DrinkingWaterHeatingFitting
|
public class EuroconeConnectionBend : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = "Резьбозажимное соединение для металлической трубки G 3/4 -15";
|
output = "Резьбозажимное соединение для металлической трубки G 3/4 -15";
|
||||||
return true;
|
return true;
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Резьбозажимное flex")]
|
[ParserKey("Резьбозажимное flex")]
|
||||||
public class EuroconeFlex : Eurocone
|
public class EuroconeFlex : Eurocone
|
||||||
{
|
{
|
||||||
protected override Dictionary<string, string> _titles => new()
|
protected override Dictionary<string, string> _titles => new()
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Резьбозажимное stabil")]
|
[ParserKey("Резьбозажимное stabil")]
|
||||||
public class EuroconeStabil : Eurocone
|
public class EuroconeStabil : Eurocone
|
||||||
{
|
{
|
||||||
protected override Dictionary<string, string> _titles => new()
|
protected override Dictionary<string, string> _titles => new()
|
@ -1,8 +1,8 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Коллектор G1")]
|
[ParserKey("Коллектор G1")]
|
||||||
public class ManifoldG1 : DrinkingWaterHeatingFitting
|
public class ManifoldG1 : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
private static readonly Regex _portsCount =
|
private static readonly Regex _portsCount =
|
||||||
@ -10,7 +10,7 @@ public class ManifoldG1 : DrinkingWaterHeatingFitting
|
|||||||
|
|
||||||
protected override string _title => "Распределительный коллектор G1";
|
protected override string _title => "Распределительный коллектор G1";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
var match = _portsCount.Match(input);
|
var match = _portsCount.Match(input);
|
||||||
if (match.Success)
|
if (match.Success)
|
@ -1,15 +1,15 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Коллектор HLV")]
|
[ParserKey("Коллектор HLV")]
|
||||||
public class ManifoldHLV : DrinkingWaterHeatingFitting
|
public class ManifoldHLV : DrinkingWaterHeatingFitting
|
||||||
{ private static readonly Regex _portsCount =
|
{ private static readonly Regex _portsCount =
|
||||||
new(@"\s(?<Ports>\d{1,2})\s");
|
new(@"\s(?<Ports>\d{1,2})\s");
|
||||||
|
|
||||||
protected override string _title => "Распределительный коллектор HLV";
|
protected override string _title => "Распределительный коллектор HLV";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
var match = _portsCount.Match(input);
|
var match = _portsCount.Match(input);
|
||||||
if (match.Success)
|
if (match.Success)
|
@ -1,9 +1,9 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Ниппель")]
|
[ParserKey("Ниппель")]
|
||||||
public class Nippel : DrinkingWaterHeatingFitting
|
public class Nippel : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = "К-т двух резьбозажим. нипелей с нар.резьбой 1/2х3/4";
|
output = "К-т двух резьбозажим. нипелей с нар.резьбой 1/2х3/4";
|
||||||
return true;
|
return true;
|
@ -1,11 +1,11 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Гофротруба RAUTITAN")]
|
[ParserKey("Гофротруба RAUTITAN")]
|
||||||
public class ProtectivePipe : DrinkingWaterHeatingFitting
|
public class ProtectivePipe : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Гофротруба защитн.для ПЭ-трубы";
|
protected override string _title => "Гофротруба защитн.для ПЭ-трубы";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Угольник с накидной гайкой")]
|
[ParserKey("Угольник с накидной гайкой")]
|
||||||
public class ScrewcapElbow : Adapter
|
public class ScrewcapElbow : Adapter
|
||||||
{
|
{
|
||||||
protected override string _title => "Угольник-переходник с накидной гайкой";
|
protected override string _title => "Угольник-переходник с накидной гайкой";
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Монтажная гильза")]
|
[ParserKey("Монтажная гильза")]
|
||||||
public class Sleeve : DrinkingWaterHeatingFitting
|
public class Sleeve : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Монтажная гильза";
|
protected override string _title => "Монтажная гильза";
|
@ -1,11 +1,11 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Желоб")]
|
[ParserKey("Желоб")]
|
||||||
public class SupportingClip : DrinkingWaterHeatingFitting
|
public class SupportingClip : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Фиксирующий желоб для ПЭ-трубы";
|
protected override string _title => "Фиксирующий желоб для ПЭ-трубы";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,11 +1,11 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Тройник RAUTITAN")]
|
[ParserKey("Тройник RAUTITAN")]
|
||||||
public class TPiece : DrinkingWaterHeatingFitting
|
public class TPiece : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Тройник -PLATINUM";
|
protected override string _title => "Тройник -PLATINUM";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameters = _diameter.Matches(input)
|
var diameters = _diameter.Matches(input)
|
@ -1,14 +1,14 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Проточный настенный угольник")]
|
[ParserKey("Проточный настенный угольник")]
|
||||||
public class ThreadElbowDoubleWallInternal : DrinkingWaterHeatingFitting
|
public class ThreadElbowDoubleWallInternal : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Проточный настенный угольник";
|
protected override string _title => "Проточный настенный угольник";
|
||||||
private Regex _type = new(@"([\b\Wу])(?<Type>длин)([\b\w\.\s])");
|
private Regex _type = new(@"([\b\Wу])(?<Type>длин)([\b\w\.\s])");
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatches = _diameter.Matches(input);
|
var diameterMatches = _diameter.Matches(input);
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Угольник с наружной резьбой")]
|
[ParserKey("Угольник с наружной резьбой")]
|
||||||
public class ThreadElbowExternal : Adapter
|
public class ThreadElbowExternal : Adapter
|
||||||
{
|
{
|
||||||
protected override string _title => "Угольник-переходник с наружной резьбой";
|
protected override string _title => "Угольник-переходник с наружной резьбой";
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Угольник с внутренней резьбой")]
|
[ParserKey("Угольник с внутренней резьбой")]
|
||||||
public class ThreadElbowInternal : Adapter
|
public class ThreadElbowInternal : Adapter
|
||||||
{
|
{
|
||||||
protected override string _title => "Угольник-переходник с внутренней резьбой";
|
protected override string _title => "Угольник-переходник с внутренней резьбой";
|
@ -1,11 +1,11 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Угольник настенный наружный")]
|
[ParserKey("Угольник настенный наружный")]
|
||||||
public class ThreadElbowWallExternal : DrinkingWaterHeatingFitting
|
public class ThreadElbowWallExternal : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Угольник настенный с наружной резьбой";
|
protected override string _title => "Угольник настенный с наружной резьбой";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,14 +1,14 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Угольник настенный внутренний")]
|
[ParserKey("Угольник настенный внутренний")]
|
||||||
public class ThreadElbowWallInternal : DrinkingWaterHeatingFitting
|
public class ThreadElbowWallInternal : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Угольник настенный внутр. резьба";
|
protected override string _title => "Угольник настенный внутр. резьба";
|
||||||
private Regex _type = new(@"([\b\Wу])(?<Type>длин)([\b\w\.\s])");
|
private Regex _type = new(@"([\b\Wу])(?<Type>длин)([\b\w\.\s])");
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,13 +1,13 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Тройник RAUTITAN резьбовой наружный")]
|
[ParserKey("Тройник RAUTITAN резьбовой наружный")]
|
||||||
public class ThreadTPieceExternal : DrinkingWaterHeatingFitting
|
public class ThreadTPieceExternal : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
protected override string _title => "Тройник с наружной резьбой";
|
protected override string _title => "Тройник с наружной резьбой";
|
||||||
|
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
MatchCollection diametersMatches = _diameter.Matches(input);
|
MatchCollection diametersMatches = _diameter.Matches(input);
|
@ -1,11 +1,11 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingFittings;
|
namespace RhSolutions.Parsers.Fittings;
|
||||||
|
|
||||||
[MLModifierKey("Тройник RAUTITAN резьбовой внутренний")]
|
[ParserKey("Тройник RAUTITAN резьбовой внутренний")]
|
||||||
public class ThreadTPieceInternal : DrinkingWaterHeatingFitting
|
public class ThreadTPieceInternal : DrinkingWaterHeatingFitting
|
||||||
{
|
{
|
||||||
public override bool TryQueryModify(string input, out string output)
|
public override bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
MatchCollection diametersMatches = _diameter.Matches(input);
|
MatchCollection diametersMatches = _diameter.Matches(input);
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingPipes;
|
namespace RhSolutions.Parsers.Pipes;
|
||||||
|
|
||||||
[MLModifierKey("Black")]
|
[ParserKey("Black")]
|
||||||
public class BlackPipe : DrinkingWaterHeatingPipe
|
public class BlackPipe : DrinkingWaterHeatingPipe
|
||||||
{
|
{
|
||||||
protected override string _title => "Black";
|
protected override string _title => "Black";
|
@ -1,8 +1,8 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingPipes;
|
namespace RhSolutions.Parsers.Pipes;
|
||||||
|
|
||||||
public abstract class DrinkingWaterHeatingPipe : IProductMLModifier
|
public abstract class DrinkingWaterHeatingPipe : IProductParser
|
||||||
{
|
{
|
||||||
protected static readonly Regex _diameter =
|
protected static readonly Regex _diameter =
|
||||||
new(@"([\b\D]|^)?(?<Diameter>16|20|25|32|40|50|63)([\b\D]|$)");
|
new(@"([\b\D]|^)?(?<Diameter>16|20|25|32|40|50|63)([\b\D]|$)");
|
||||||
@ -28,7 +28,7 @@ public abstract class DrinkingWaterHeatingPipe : IProductMLModifier
|
|||||||
["отр"] = "прям.отрезки"
|
["отр"] = "прям.отрезки"
|
||||||
};
|
};
|
||||||
|
|
||||||
public bool TryQueryModify(string input, out string output)
|
public bool TryParse(string input, out string output)
|
||||||
{
|
{
|
||||||
output = string.Empty;
|
output = string.Empty;
|
||||||
var diameterMatch = _diameter.Match(input);
|
var diameterMatch = _diameter.Match(input);
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingPipes;
|
namespace RhSolutions.Parsers.Pipes;
|
||||||
|
|
||||||
[MLModifierKey("Flex")]
|
[ParserKey("Flex")]
|
||||||
public class FlexPipe : DrinkingWaterHeatingPipe
|
public class FlexPipe : DrinkingWaterHeatingPipe
|
||||||
{
|
{
|
||||||
protected override string _title => "Flex";
|
protected override string _title => "Flex";
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingPipes;
|
namespace RhSolutions.Parsers.Pipes;
|
||||||
|
|
||||||
[MLModifierKey("Pink")]
|
[ParserKey("Pink")]
|
||||||
public class PinkPipe : DrinkingWaterHeatingPipe
|
public class PinkPipe : DrinkingWaterHeatingPipe
|
||||||
{
|
{
|
||||||
protected override string _title => "Pink+";
|
protected override string _title => "Pink+";
|
@ -1,6 +1,6 @@
|
|||||||
namespace RhSolutions.MLModifiers.DrinkingWaterHeatingPipes;
|
namespace RhSolutions.Parsers.Pipes;
|
||||||
|
|
||||||
[MLModifierKey("Stabil")]
|
[ParserKey("Stabil")]
|
||||||
public class StabilPipe : DrinkingWaterHeatingPipe
|
public class StabilPipe : DrinkingWaterHeatingPipe
|
||||||
{
|
{
|
||||||
protected override string _title => "Stabil -PLATINUM";
|
protected override string _title => "Stabil -PLATINUM";
|
6
RhSolutions.Parsers/IProductParser.cs
Normal file
6
RhSolutions.Parsers/IProductParser.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace RhSolutions.Parsers;
|
||||||
|
|
||||||
|
public interface IProductParser
|
||||||
|
{
|
||||||
|
public bool TryParse(string input, out string output);
|
||||||
|
}
|
10
RhSolutions.Parsers/ParserKey.cs
Normal file
10
RhSolutions.Parsers/ParserKey.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace RhSolutions.Parsers;
|
||||||
|
|
||||||
|
public class ParserKey : Attribute
|
||||||
|
{
|
||||||
|
public string Value { get; private set; }
|
||||||
|
public ParserKey(string value)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +1,25 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace RhSolutions.MLModifiers;
|
namespace RhSolutions.Parsers;
|
||||||
|
|
||||||
public static class MLModifiersRegistration
|
public static class ParsersRegistration
|
||||||
{
|
{
|
||||||
public static void AddModifiers(this IServiceCollection services)
|
public static void AddModifiers(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
var types = AppDomain.CurrentDomain.GetAssemblies()
|
var types = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
.SelectMany(s => s.GetTypes())
|
.SelectMany(s => s.GetTypes())
|
||||||
.Where(p => p.IsDefined(typeof(MLModifierKey), true));
|
.Where(p => p.IsDefined(typeof(ParserKey), true));
|
||||||
|
|
||||||
foreach (Type t in types)
|
foreach (Type t in types)
|
||||||
{
|
{
|
||||||
string key = GetModifierKey(t);
|
string key = GetModifierKey(t);
|
||||||
services.AddKeyedTransient(typeof(IProductMLModifier), key, t);
|
services.AddKeyedTransient(typeof(IProductParser), key, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetModifierKey(Type t)
|
private static string GetModifierKey(Type t)
|
||||||
{
|
{
|
||||||
return t.GetCustomAttribute<MLModifierKey>()?.Value ?? string.Empty;
|
return t.GetCustomAttribute<ParserKey>()?.Value ?? string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user