mirror of
https://github.com/Intervention/image.git
synced 2025-09-03 10:53:01 +02:00
Implement HSL color model & fix bugs
This commit is contained in:
@@ -9,34 +9,61 @@ use Intervention\Image\Colors\Cmyk\Channels\Yellow;
|
||||
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
|
||||
use Intervention\Image\Colors\Rgb\Color as RgbColor;
|
||||
use Intervention\Image\Colors\Hsv\Color as HsvColor;
|
||||
use Intervention\Image\Colors\Hsl\Color as HslColor;
|
||||
use Intervention\Image\Colors\Cmyk\Colorspace;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @requires extension gd
|
||||
* @covers \Intervention\Image\Colors\Cmyk\Colorspace
|
||||
*/
|
||||
class ColorspaceTest extends TestCase
|
||||
{
|
||||
public function testConvertRgbColor(): void
|
||||
public function testImportRgbColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
$result = $colorspace->importColor(new RgbColor(0, 0, 255));
|
||||
|
||||
$result = $colorspace->importColor(new RgbColor(255, 0, 255));
|
||||
$this->assertInstanceOf(CmykColor::class, $result);
|
||||
$this->assertEquals(100, $result->channel(Cyan::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Cyan::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Magenta::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Yellow::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Key::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new RgbColor(127, 127, 127));
|
||||
$this->assertInstanceOf(CmykColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Cyan::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Magenta::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Yellow::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Key::class)->value());
|
||||
}
|
||||
|
||||
public function testConvertHsvColor(): void
|
||||
public function testImportHsvColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
$result = $colorspace->importColor(new HsvColor(240, 100, 100));
|
||||
$result = $colorspace->importColor(new HsvColor(0, 0, 50));
|
||||
$this->assertInstanceOf(CmykColor::class, $result);
|
||||
$this->assertEquals(100, $result->channel(Cyan::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Cyan::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Magenta::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Yellow::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Key::class)->value());
|
||||
}
|
||||
|
||||
public function testImportHslColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
|
||||
$result = $colorspace->importColor(new HslColor(300, 100, 50));
|
||||
$this->assertInstanceOf(CmykColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Cyan::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Magenta::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Yellow::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Key::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new HslColor(0, 0, 50));
|
||||
$this->assertInstanceOf(CmykColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Cyan::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Magenta::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Yellow::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Key::class)->value());
|
||||
}
|
||||
}
|
||||
|
74
tests/Colors/Hsl/ChannelTest.php
Normal file
74
tests/Colors/Hsl/ChannelTest.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Tests\Colors\Hsl;
|
||||
|
||||
use Intervention\Image\Colors\Hsl\Channels\Hue;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Saturation;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Luminance;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \Intervention\Image\Colors\Hsl\Channels\Hue
|
||||
* @covers \Intervention\Image\Colors\Hsl\Channels\Saturation
|
||||
* @covers \Intervention\Image\Colors\Hsl\Channels\Value
|
||||
*/
|
||||
class ChannelTest extends TestCase
|
||||
{
|
||||
public function testConstructor(): void
|
||||
{
|
||||
$channel = new Hue(0);
|
||||
$this->assertInstanceOf(Hue::class, $channel);
|
||||
|
||||
$channel = new Hue(value: 0);
|
||||
$this->assertInstanceOf(Hue::class, $channel);
|
||||
|
||||
$channel = new Hue(normalized: 0);
|
||||
$this->assertInstanceOf(Hue::class, $channel);
|
||||
|
||||
$this->expectException(ColorException::class);
|
||||
$channel = new Hue();
|
||||
|
||||
$this->expectException(ColorException::class);
|
||||
$channel = new Hue(normalized: 2);
|
||||
}
|
||||
|
||||
public function testValue(): void
|
||||
{
|
||||
$channel = new Hue(10);
|
||||
$this->assertEquals(10, $channel->value());
|
||||
}
|
||||
|
||||
public function testNormalize(): void
|
||||
{
|
||||
$channel = new Hue(360);
|
||||
$this->assertEquals(1, $channel->normalize());
|
||||
$channel = new Hue(180);
|
||||
$this->assertEquals(0.5, $channel->normalize());
|
||||
$channel = new Hue(0);
|
||||
$this->assertEquals(0, $channel->normalize());
|
||||
$channel = new Luminance(90);
|
||||
$this->assertEquals(.9, $channel->normalize());
|
||||
}
|
||||
|
||||
public function testValidate(): void
|
||||
{
|
||||
$this->expectException(ColorException::class);
|
||||
new Hue(361);
|
||||
|
||||
$this->expectException(ColorException::class);
|
||||
new Hue(-1);
|
||||
|
||||
$this->expectException(ColorException::class);
|
||||
new Saturation(101);
|
||||
|
||||
$this->expectException(ColorException::class);
|
||||
new Saturation(-1);
|
||||
|
||||
$this->expectException(ColorException::class);
|
||||
new Luminance(101);
|
||||
|
||||
$this->expectException(ColorException::class);
|
||||
new Luminance(-1);
|
||||
}
|
||||
}
|
84
tests/Colors/Hsl/ColorTest.php
Normal file
84
tests/Colors/Hsl/ColorTest.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Tests\Colors\Hsl;
|
||||
|
||||
use Intervention\Image\Colors\Hsl\Channels\Hue;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Luminance;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Saturation;
|
||||
use Intervention\Image\Colors\Hsl\Color;
|
||||
use Intervention\Image\Colors\Hsl\Colorspace;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \Intervention\Image\Colors\Hsl\Color
|
||||
*/
|
||||
class ColorTest extends TestCase
|
||||
{
|
||||
public function testConstructor(): void
|
||||
{
|
||||
$color = new Color(0, 0, 0);
|
||||
$this->assertInstanceOf(Color::class, $color);
|
||||
}
|
||||
|
||||
public function testColorspace(): void
|
||||
{
|
||||
$color = new Color(0, 0, 0);
|
||||
$this->assertInstanceOf(Colorspace::class, $color->colorspace());
|
||||
}
|
||||
|
||||
public function testChannels(): void
|
||||
{
|
||||
$color = new Color(10, 20, 30);
|
||||
$this->assertIsArray($color->channels());
|
||||
$this->assertCount(3, $color->channels());
|
||||
}
|
||||
|
||||
public function testChannel(): void
|
||||
{
|
||||
$color = new Color(10, 20, 30);
|
||||
$channel = $color->channel(Hue::class);
|
||||
$this->assertInstanceOf(Hue::class, $channel);
|
||||
$this->assertEquals(10, $channel->value());
|
||||
}
|
||||
|
||||
public function testHueSaturationLuminanceKey(): void
|
||||
{
|
||||
$color = new Color(10, 20, 30);
|
||||
$this->assertInstanceOf(Hue::class, $color->hue());
|
||||
$this->assertInstanceOf(Saturation::class, $color->saturation());
|
||||
$this->assertInstanceOf(Luminance::class, $color->luminance());
|
||||
$this->assertEquals(10, $color->hue()->value());
|
||||
$this->assertEquals(20, $color->saturation()->value());
|
||||
$this->assertEquals(30, $color->luminance()->value());
|
||||
}
|
||||
|
||||
public function testToArray(): void
|
||||
{
|
||||
$color = new Color(10, 20, 30);
|
||||
$this->assertEquals([10, 20, 30], $color->toArray());
|
||||
}
|
||||
|
||||
public function testNormalize(): void
|
||||
{
|
||||
$color = new Color(180, 50, 25);
|
||||
$this->assertEquals([.5, 0.5, 0.25], $color->normalize());
|
||||
}
|
||||
|
||||
public function testToString(): void
|
||||
{
|
||||
$color = new Color(100, 50, 20, 0);
|
||||
$this->assertEquals('hsl(100, 50%, 20%)', (string) $color);
|
||||
}
|
||||
|
||||
public function testIsGreyscale(): void
|
||||
{
|
||||
$color = new Color(0, 1, 0);
|
||||
$this->assertFalse($color->isGreyscale());
|
||||
|
||||
$color = new Color(1, 0, 0);
|
||||
$this->assertTrue($color->isGreyscale());
|
||||
|
||||
$color = new Color(0, 0, 1);
|
||||
$this->assertTrue($color->isGreyscale());
|
||||
}
|
||||
}
|
70
tests/Colors/Hsl/ColorspaceTest.php
Normal file
70
tests/Colors/Hsl/ColorspaceTest.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Tests\Colors\Hsl;
|
||||
|
||||
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Hue;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Luminance;
|
||||
use Intervention\Image\Colors\Hsl\Channels\Saturation;
|
||||
use Intervention\Image\Colors\Hsl\Color as HslColor;
|
||||
use Intervention\Image\Colors\Rgb\Color as RgbColor;
|
||||
use Intervention\Image\Colors\Hsv\Color as HsvColor;
|
||||
use Intervention\Image\Colors\Hsl\Colorspace;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @covers \Intervention\Image\Colors\Hsl\Colorspace
|
||||
*/
|
||||
class ColorspaceTest extends TestCase
|
||||
{
|
||||
public function testImportRgbColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
|
||||
$result = $colorspace->importColor(new RgbColor(255, 0, 255));
|
||||
$this->assertInstanceOf(HslColor::class, $result);
|
||||
$this->assertEquals(300, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Luminance::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new RgbColor(127, 127, 127));
|
||||
$this->assertInstanceOf(HslColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Luminance::class)->value());
|
||||
}
|
||||
|
||||
public function testImportCmykColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
|
||||
$result = $colorspace->importColor(new CmykColor(0, 100, 0, 0));
|
||||
$this->assertInstanceOf(HslColor::class, $result);
|
||||
$this->assertEquals(300, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Luminance::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new CmykColor(0, 0, 0, 50));
|
||||
$this->assertInstanceOf(HslColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Luminance::class)->value());
|
||||
}
|
||||
|
||||
public function testImportHsvColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
|
||||
$result = $colorspace->importColor(new HsvColor(300, 100, 100));
|
||||
$this->assertInstanceOf(HslColor::class, $result);
|
||||
$this->assertEquals(300, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Luminance::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new HsvColor(0, 0, 50));
|
||||
$this->assertInstanceOf(HslColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Luminance::class)->value());
|
||||
}
|
||||
}
|
35
tests/Colors/Hsl/Decoders/StringColorDecoderTest.php
Normal file
35
tests/Colors/Hsl/Decoders/StringColorDecoderTest.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Tests\Colors\Hsl\Decoders;
|
||||
|
||||
use Intervention\Image\Colors\Hsl\Color;
|
||||
use Intervention\Image\Colors\Hsl\Decoders\StringColorDecoder;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @requires extension gd
|
||||
* @covers \Intervention\Image\Colors\Hsl\Decoders\StringColorDecoder
|
||||
*/
|
||||
class StringColorDecoderTest extends TestCase
|
||||
{
|
||||
public function testDecode(): void
|
||||
{
|
||||
$decoder = new StringColorDecoder();
|
||||
|
||||
$result = $decoder->decode('hsl(0,0,0)');
|
||||
$this->assertInstanceOf(Color::class, $result);
|
||||
$this->assertEquals([0, 0, 0], $result->toArray());
|
||||
|
||||
$result = $decoder->decode('hsl(0, 100, 50)');
|
||||
$this->assertInstanceOf(Color::class, $result);
|
||||
$this->assertEquals([0, 100, 50], $result->toArray());
|
||||
|
||||
$result = $decoder->decode('hsl(360, 100, 50)');
|
||||
$this->assertInstanceOf(Color::class, $result);
|
||||
$this->assertEquals([360, 100, 50], $result->toArray());
|
||||
|
||||
$result = $decoder->decode('hsl(180, 100%, 50%)');
|
||||
$this->assertInstanceOf(Color::class, $result);
|
||||
$this->assertEquals([180, 100, 50], $result->toArray());
|
||||
}
|
||||
}
|
@@ -8,32 +8,63 @@ use Intervention\Image\Colors\Hsv\Channels\Saturation;
|
||||
use Intervention\Image\Colors\Hsv\Channels\Value;
|
||||
use Intervention\Image\Colors\Hsv\Color as HsvColor;
|
||||
use Intervention\Image\Colors\Rgb\Color as RgbColor;
|
||||
use Intervention\Image\Colors\Hsl\Color as HslColor;
|
||||
use Intervention\Image\Colors\Hsv\Colorspace;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @requires extension gd
|
||||
* @covers \Intervention\Image\Colors\Hsv\Colorspace
|
||||
*/
|
||||
class ColorspaceTest extends TestCase
|
||||
{
|
||||
public function testConvertRgbColor(): void
|
||||
public function testImportRgbColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
$result = $colorspace->importColor(new RgbColor(26, 26, 128));
|
||||
|
||||
$result = $colorspace->importColor(new RgbColor(255, 0, 255));
|
||||
$this->assertInstanceOf(HsvColor::class, $result);
|
||||
$this->assertEquals(240, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(80, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(300, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Value::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new RgbColor(127, 127, 127));
|
||||
$this->assertInstanceOf(HsvColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Value::class)->value());
|
||||
}
|
||||
|
||||
public function testConvertCmykColor(): void
|
||||
public function testImportCmykColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
$result = $colorspace->importColor(new CmykColor(100, 0, 100, 0));
|
||||
|
||||
$result = $colorspace->importColor(new CmykColor(0, 100, 0, 0));
|
||||
$this->assertInstanceOf(HsvColor::class, $result);
|
||||
$this->assertEquals(120, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(300, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Value::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new CmykColor(0, 0, 0, 50));
|
||||
$this->assertInstanceOf(HsvColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Value::class)->value());
|
||||
}
|
||||
|
||||
public function testImportHslColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
|
||||
$result = $colorspace->importColor(new HslColor(300, 100, 50));
|
||||
$this->assertInstanceOf(HsvColor::class, $result);
|
||||
$this->assertEquals(300, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(100, $result->channel(Value::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new HslColor(0, 0, 50));
|
||||
$this->assertInstanceOf(HsvColor::class, $result);
|
||||
$this->assertEquals(0, $result->channel(Hue::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Saturation::class)->value());
|
||||
$this->assertEquals(50, $result->channel(Value::class)->value());
|
||||
}
|
||||
}
|
||||
|
@@ -8,33 +8,62 @@ use Intervention\Image\Colors\Rgb\Channels\Blue;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Green;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Red;
|
||||
use Intervention\Image\Colors\Rgb\Color as RgbColor;
|
||||
use Intervention\Image\Colors\Hsl\Color as HslColor;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @requires extension gd
|
||||
* @covers \Intervention\Image\Colors\Rgb\Colorspace
|
||||
*/
|
||||
class ColorspaceTest extends TestCase
|
||||
{
|
||||
public function testConvertCmykColor(): void
|
||||
public function testImportCmykColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
$this->assertInstanceOf(
|
||||
RgbColor::class,
|
||||
$colorspace->importColor(
|
||||
new CmykColor(0, 0, 0, 0)
|
||||
)
|
||||
);
|
||||
$result = $colorspace->importColor(new CmykColor(0, 100, 0, 0));
|
||||
$this->assertInstanceOf(RgbColor::class, $result);
|
||||
$this->assertEquals(255, $result->channel(Red::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Green::class)->value());
|
||||
$this->assertEquals(255, $result->channel(Blue::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new CmykColor(0, 0, 0, 50));
|
||||
$this->assertInstanceOf(RgbColor::class, $result);
|
||||
$this->assertEquals(127, $result->channel(Red::class)->value());
|
||||
$this->assertEquals(127, $result->channel(Green::class)->value());
|
||||
$this->assertEquals(127, $result->channel(Blue::class)->value());
|
||||
}
|
||||
|
||||
public function testConvertHsvColor(): void
|
||||
public function testImportHsvColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
$result = $colorspace->importColor(new HsvColor(240, 80, 50));
|
||||
|
||||
$result = $colorspace->importColor(new HsvColor(300, 100, 100));
|
||||
$this->assertInstanceOf(RgbColor::class, $result);
|
||||
$this->assertEquals(26, $result->channel(Red::class)->value());
|
||||
$this->assertEquals(26, $result->channel(Green::class)->value());
|
||||
$this->assertEquals(255, $result->channel(Red::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Green::class)->value());
|
||||
$this->assertEquals(255, $result->channel(Blue::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new HsvColor(0, 0, 50));
|
||||
$this->assertInstanceOf(RgbColor::class, $result);
|
||||
$this->assertEquals(128, $result->channel(Red::class)->value());
|
||||
$this->assertEquals(128, $result->channel(Green::class)->value());
|
||||
$this->assertEquals(128, $result->channel(Blue::class)->value());
|
||||
}
|
||||
|
||||
public function testImportHslColor(): void
|
||||
{
|
||||
$colorspace = new Colorspace();
|
||||
|
||||
$result = $colorspace->importColor(new HslColor(300, 100, 50));
|
||||
$this->assertInstanceOf(RgbColor::class, $result);
|
||||
$this->assertEquals(255, $result->channel(Red::class)->value());
|
||||
$this->assertEquals(0, $result->channel(Green::class)->value());
|
||||
$this->assertEquals(255, $result->channel(Blue::class)->value());
|
||||
|
||||
$result = $colorspace->importColor(new HslColor(0, 0, 50));
|
||||
$this->assertInstanceOf(RgbColor::class, $result);
|
||||
$this->assertEquals(128, $result->channel(Red::class)->value());
|
||||
$this->assertEquals(128, $result->channel(Green::class)->value());
|
||||
$this->assertEquals(128, $result->channel(Blue::class)->value());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user