aboutsummaryrefslogtreecommitdiff
path: root/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-01-09 10:55:03 +0100
committerCharles <sircharlesaze@gmail.com>2020-01-09 13:09:38 +0100
commit04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa (patch)
tree5c691241355c943a3c68ddb06b8cf8c60aa11319 /srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src
parent7e0d85db834d6351ed85d01e5126ac31dc510b86 (diff)
downloadft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.gz
ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.tar.bz2
ft_server-04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa.zip
phpmyadmin working
Diffstat (limited to 'srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src')
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitArray.php372
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php313
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php41
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php180
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php49
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php74
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php63
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php203
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Mode.php76
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php468
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Version.php596
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php58
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php150
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php652
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php271
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php513
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php141
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php10
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/InvalidArgumentException.php8
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/OutOfBoundsException.php8
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/RuntimeException.php8
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/UnexpectedValueException.php8
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/WriterException.php8
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Alpha.php57
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php103
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php22
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Gray.php46
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php88
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php38
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php26
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/ModuleEye.php54
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php54
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php53
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php376
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php87
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImagickImageBackEnd.php339
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php369
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php67
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php152
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php63
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php100
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php169
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php18
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/RoundnessModule.php129
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php47
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php29
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Curve.php92
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php278
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php41
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php41
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php12
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Path.php106
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php86
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php11
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/EyeFill.php74
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php168
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php46
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php22
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/RendererStyle.php90
-rw-r--r--srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Writer.php68
60 files changed, 7891 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitArray.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitArray.php
new file mode 100644
index 0000000..158384f
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitArray.php
@@ -0,0 +1,372 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+use BaconQrCode\Exception\InvalidArgumentException;
+use SplFixedArray;
+
+/**
+ * A simple, fast array of bits.
+ */
+final class BitArray
+{
+ /**
+ * Bits represented as an array of integers.
+ *
+ * @var SplFixedArray<int>
+ */
+ private $bits;
+
+ /**
+ * Size of the bit array in bits.
+ *
+ * @var int
+ */
+ private $size;
+
+ /**
+ * Creates a new bit array with a given size.
+ */
+ public function __construct(int $size = 0)
+ {
+ $this->size = $size;
+ $this->bits = SplFixedArray::fromArray(array_fill(0, ($this->size + 31) >> 3, 0));
+ }
+
+ /**
+ * Gets the size in bits.
+ */
+ public function getSize() : int
+ {
+ return $this->size;
+ }
+
+ /**
+ * Gets the size in bytes.
+ */
+ public function getSizeInBytes() : int
+ {
+ return ($this->size + 7) >> 3;
+ }
+
+ /**
+ * Ensures that the array has a minimum capacity.
+ */
+ public function ensureCapacity(int $size) : void
+ {
+ if ($size > count($this->bits) << 5) {
+ $this->bits->setSize(($size + 31) >> 5);
+ }
+ }
+
+ /**
+ * Gets a specific bit.
+ */
+ public function get(int $i) : bool
+ {
+ return 0 !== ($this->bits[$i >> 5] & (1 << ($i & 0x1f)));
+ }
+
+ /**
+ * Sets a specific bit.
+ */
+ public function set(int $i) : void
+ {
+ $this->bits[$i >> 5] = $this->bits[$i >> 5] | 1 << ($i & 0x1f);
+ }
+
+ /**
+ * Flips a specific bit.
+ */
+ public function flip(int $i) : void
+ {
+ $this->bits[$i >> 5] ^= 1 << ($i & 0x1f);
+ }
+
+ /**
+ * Gets the next set bit position from a given position.
+ */
+ public function getNextSet(int $from) : int
+ {
+ if ($from >= $this->size) {
+ return $this->size;
+ }
+
+ $bitsOffset = $from >> 5;
+ $currentBits = $this->bits[$bitsOffset];
+ $bitsLength = count($this->bits);
+ $currentBits &= ~((1 << ($from & 0x1f)) - 1);
+
+ while (0 === $currentBits) {
+ if (++$bitsOffset === $bitsLength) {
+ return $this->size;
+ }
+
+ $currentBits = $this->bits[$bitsOffset];
+ }
+
+ $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits);
+ return $result > $this->size ? $this->size : $result;
+ }
+
+ /**
+ * Gets the next unset bit position from a given position.
+ */
+ public function getNextUnset(int $from) : int
+ {
+ if ($from >= $this->size) {
+ return $this->size;
+ }
+
+ $bitsOffset = $from >> 5;
+ $currentBits = ~$this->bits[$bitsOffset];
+ $bitsLength = count($this->bits);
+ $currentBits &= ~((1 << ($from & 0x1f)) - 1);
+
+ while (0 === $currentBits) {
+ if (++$bitsOffset === $bitsLength) {
+ return $this->size;
+ }
+
+ $currentBits = ~$this->bits[$bitsOffset];
+ }
+
+ $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits);
+ return $result > $this->size ? $this->size : $result;
+ }
+
+ /**
+ * Sets a bulk of bits.
+ */
+ public function setBulk(int $i, int $newBits) : void
+ {
+ $this->bits[$i >> 5] = $newBits;
+ }
+
+ /**
+ * Sets a range of bits.
+ *
+ * @throws InvalidArgumentException if end is smaller than start
+ */
+ public function setRange(int $start, int $end) : void
+ {
+ if ($end < $start) {
+ throw new InvalidArgumentException('End must be greater or equal to start');
+ }
+
+ if ($end === $start) {
+ return;
+ }
+
+ --$end;
+
+ $firstInt = $start >> 5;
+ $lastInt = $end >> 5;
+
+ for ($i = $firstInt; $i <= $lastInt; ++$i) {
+ $firstBit = $i > $firstInt ? 0 : $start & 0x1f;
+ $lastBit = $i < $lastInt ? 31 : $end & 0x1f;
+
+ if (0 === $firstBit && 31 === $lastBit) {
+ $mask = 0x7fffffff;
+ } else {
+ $mask = 0;
+
+ for ($j = $firstBit; $j < $lastBit; ++$j) {
+ $mask |= 1 << $j;
+ }
+ }
+
+ $this->bits[$i] = $this->bits[$i] | $mask;
+ }
+ }
+
+ /**
+ * Clears the bit array, unsetting every bit.
+ */
+ public function clear() : void
+ {
+ $bitsLength = count($this->bits);
+
+ for ($i = 0; $i < $bitsLength; ++$i) {
+ $this->bits[$i] = 0;
+ }
+ }
+
+ /**
+ * Checks if a range of bits is set or not set.
+
+ * @throws InvalidArgumentException if end is smaller than start
+ */
+ public function isRange(int $start, int $end, bool $value) : bool
+ {
+ if ($end < $start) {
+ throw new InvalidArgumentException('End must be greater or equal to start');
+ }
+
+ if ($end === $start) {
+ return true;
+ }
+
+ --$end;
+
+ $firstInt = $start >> 5;
+ $lastInt = $end >> 5;
+
+ for ($i = $firstInt; $i <= $lastInt; ++$i) {
+ $firstBit = $i > $firstInt ? 0 : $start & 0x1f;
+ $lastBit = $i < $lastInt ? 31 : $end & 0x1f;
+
+ if (0 === $firstBit && 31 === $lastBit) {
+ $mask = 0x7fffffff;
+ } else {
+ $mask = 0;
+
+ for ($j = $firstBit; $j <= $lastBit; ++$j) {
+ $mask |= 1 << $j;
+ }
+ }
+
+ if (($this->bits[$i] & $mask) !== ($value ? $mask : 0)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Appends a bit to the array.
+ */
+ public function appendBit(bool $bit) : void
+ {
+ $this->ensureCapacity($this->size + 1);
+
+ if ($bit) {
+ $this->bits[$this->size >> 5] = $this->bits[$this->size >> 5] | (1 << ($this->size & 0x1f));
+ }
+
+ ++$this->size;
+ }
+
+ /**
+ * Appends a number of bits (up to 32) to the array.
+
+ * @throws InvalidArgumentException if num bits is not between 0 and 32
+ */
+ public function appendBits(int $value, int $numBits) : void
+ {
+ if ($numBits < 0 || $numBits > 32) {
+ throw new InvalidArgumentException('Num bits must be between 0 and 32');
+ }
+
+ $this->ensureCapacity($this->size + $numBits);
+
+ for ($numBitsLeft = $numBits; $numBitsLeft > 0; $numBitsLeft--) {
+ $this->appendBit((($value >> ($numBitsLeft - 1)) & 0x01) === 1);
+ }
+ }
+
+ /**
+ * Appends another bit array to this array.
+ */
+ public function appendBitArray(self $other) : void
+ {
+ $otherSize = $other->getSize();
+ $this->ensureCapacity($this->size + $other->getSize());
+
+ for ($i = 0; $i < $otherSize; ++$i) {
+ $this->appendBit($other->get($i));
+ }
+ }
+
+ /**
+ * Makes an exclusive-or comparision on the current bit array.
+ *
+ * @throws InvalidArgumentException if sizes don't match
+ */
+ public function xorBits(self $other) : void
+ {
+ $bitsLength = count($this->bits);
+ $otherBits = $other->getBitArray();
+
+ if ($bitsLength !== count($otherBits)) {
+ throw new InvalidArgumentException('Sizes don\'t match');
+ }
+
+ for ($i = 0; $i < $bitsLength; ++$i) {
+ $this->bits[$i] = $this->bits[$i] ^ $otherBits[$i];
+ }
+ }
+
+ /**
+ * Converts the bit array to a byte array.
+ *
+ * @return SplFixedArray<int>
+ */
+ public function toBytes(int $bitOffset, int $numBytes) : SplFixedArray
+ {
+ $bytes = new SplFixedArray($numBytes);
+
+ for ($i = 0; $i < $numBytes; ++$i) {
+ $byte = 0;
+
+ for ($j = 0; $j < 8; ++$j) {
+ if ($this->get($bitOffset)) {
+ $byte |= 1 << (7 - $j);
+ }
+
+ ++$bitOffset;
+ }
+
+ $bytes[$i] = $byte;
+ }
+
+ return $bytes;
+ }
+
+ /**
+ * Gets the internal bit array.
+ *
+ * @return SplFixedArray<int>
+ */
+ public function getBitArray() : SplFixedArray
+ {
+ return $this->bits;
+ }
+
+ /**
+ * Reverses the array.
+ */
+ public function reverse() : void
+ {
+ $newBits = new SplFixedArray(count($this->bits));
+
+ for ($i = 0; $i < $this->size; ++$i) {
+ if ($this->get($this->size - $i - 1)) {
+ $newBits[$i >> 5] = $newBits[$i >> 5] | (1 << ($i & 0x1f));
+ }
+ }
+
+ $this->bits = $newBits;
+ }
+
+ /**
+ * Returns a string representation of the bit array.
+ */
+ public function __toString() : string
+ {
+ $result = '';
+
+ for ($i = 0; $i < $this->size; ++$i) {
+ if (0 === ($i & 0x07)) {
+ $result .= ' ';
+ }
+
+ $result .= $this->get($i) ? 'X' : '.';
+ }
+
+ return $result;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php
new file mode 100644
index 0000000..10bf8fe
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php
@@ -0,0 +1,313 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+use BaconQrCode\Exception\InvalidArgumentException;
+use SplFixedArray;
+
+/**
+ * Bit matrix.
+ *
+ * Represents a 2D matrix of bits. In function arguments below, and throughout
+ * the common module, x is the column position, and y is the row position. The
+ * ordering is always x, y. The origin is at the top-left.
+ */
+class BitMatrix
+{
+ /**
+ * Width of the bit matrix.
+ *
+ * @var int
+ */
+ private $width;
+
+ /**
+ * Height of the bit matrix.
+ *
+ * @var int
+ */
+ private $height;
+
+ /**
+ * Size in bits of each individual row.
+ *
+ * @var int
+ */
+ private $rowSize;
+
+ /**
+ * Bits representation.
+ *
+ * @var SplFixedArray<int>
+ */
+ private $bits;
+
+ /**
+ * @throws InvalidArgumentException if a dimension is smaller than zero
+ */
+ public function __construct(int $width, int $height = null)
+ {
+ if (null === $height) {
+ $height = $width;
+ }
+
+ if ($width < 1 || $height < 1) {
+ throw new InvalidArgumentException('Both dimensions must be greater than zero');
+ }
+
+ $this->width = $width;
+ $this->height = $height;
+ $this->rowSize = ($width + 31) >> 5;
+ $this->bits = SplFixedArray::fromArray(array_fill(0, $this->rowSize * $height, 0));
+ }
+
+ /**
+ * Gets the requested bit, where true means black.
+ */
+ public function get(int $x, int $y) : bool
+ {
+ $offset = $y * $this->rowSize + ($x >> 5);
+ return 0 !== (BitUtils::unsignedRightShift($this->bits[$offset], ($x & 0x1f)) & 1);
+ }
+
+ /**
+ * Sets the given bit to true.
+ */
+ public function set(int $x, int $y) : void
+ {
+ $offset = $y * $this->rowSize + ($x >> 5);
+ $this->bits[$offset] = $this->bits[$offset] | (1 << ($x & 0x1f));
+ }
+
+ /**
+ * Flips the given bit.
+ */
+ public function flip(int $x, int $y) : void
+ {
+ $offset = $y * $this->rowSize + ($x >> 5);
+ $this->bits[$offset] = $this->bits[$offset] ^ (1 << ($x & 0x1f));
+ }
+
+ /**
+ * Clears all bits (set to false).
+ */
+ public function clear() : void
+ {
+ $max = count($this->bits);
+
+ for ($i = 0; $i < $max; ++$i) {
+ $this->bits[$i] = 0;
+ }
+ }
+
+ /**
+ * Sets a square region of the bit matrix to true.
+ *
+ * @throws InvalidArgumentException if left or top are negative
+ * @throws InvalidArgumentException if width or height are smaller than 1
+ * @throws InvalidArgumentException if region does not fit into the matix
+ */
+ public function setRegion(int $left, int $top, int $width, int $height) : void
+ {
+ if ($top < 0 || $left < 0) {
+ throw new InvalidArgumentException('Left and top must be non-negative');
+ }
+
+ if ($height < 1 || $width < 1) {
+ throw new InvalidArgumentException('Width and height must be at least 1');
+ }
+
+ $right = $left + $width;
+ $bottom = $top + $height;
+
+ if ($bottom > $this->height || $right > $this->width) {
+ throw new InvalidArgumentException('The region must fit inside the matrix');
+ }
+
+ for ($y = $top; $y < $bottom; ++$y) {
+ $offset = $y * $this->rowSize;
+
+ for ($x = $left; $x < $right; ++$x) {
+ $index = $offset + ($x >> 5);
+ $this->bits[$index] = $this->bits[$index] | (1 << ($x & 0x1f));
+ }
+ }
+ }
+
+ /**
+ * A fast method to retrieve one row of data from the matrix as a BitArray.
+ */
+ public function getRow(int $y, BitArray $row = null) : BitArray
+ {
+ if (null === $row || $row->getSize() < $this->width) {
+ $row = new BitArray($this->width);
+ }
+
+ $offset = $y * $this->rowSize;
+
+ for ($x = 0; $x < $this->rowSize; ++$x) {
+ $row->setBulk($x << 5, $this->bits[$offset + $x]);
+ }
+
+ return $row;
+ }
+
+ /**
+ * Sets a row of data from a BitArray.
+ */
+ public function setRow(int $y, BitArray $row) : void
+ {
+ $bits = $row->getBitArray();
+
+ for ($i = 0; $i < $this->rowSize; ++$i) {
+ $this->bits[$y * $this->rowSize + $i] = $bits[$i];
+ }
+ }
+
+ /**
+ * This is useful in detecting the enclosing rectangle of a 'pure' barcode.
+ *
+ * @return int[]|null
+ */
+ public function getEnclosingRectangle() : ?array
+ {
+ $left = $this->width;
+ $top = $this->height;
+ $right = -1;
+ $bottom = -1;
+
+ for ($y = 0; $y < $this->height; ++$y) {
+ for ($x32 = 0; $x32 < $this->rowSize; ++$x32) {
+ $bits = $this->bits[$y * $this->rowSize + $x32];
+
+ if (0 !== $bits) {
+ if ($y < $top) {
+ $top = $y;
+ }
+
+ if ($y > $bottom) {
+ $bottom = $y;
+ }
+
+ if ($x32 * 32 < $left) {
+ $bit = 0;
+
+ while (($bits << (31 - $bit)) === 0) {
+ $bit++;
+ }
+
+ if (($x32 * 32 + $bit) < $left) {
+ $left = $x32 * 32 + $bit;
+ }
+ }
+ }
+
+ if ($x32 * 32 + 31 > $right) {
+ $bit = 31;
+
+ while (0 === BitUtils::unsignedRightShift($bits, $bit)) {
+ --$bit;
+ }
+
+ if (($x32 * 32 + $bit) > $right) {
+ $right = $x32 * 32 + $bit;
+ }
+ }
+ }
+ }
+
+ $width = $right - $left;
+ $height = $bottom - $top;
+
+ if ($width < 0 || $height < 0) {
+ return null;
+ }
+
+ return [$left, $top, $width, $height];
+ }
+
+ /**
+ * Gets the most top left set bit.
+ *
+ * This is useful in detecting a corner of a 'pure' barcode.
+ *
+ * @return int[]|null
+ */
+ public function getTopLeftOnBit() : ?array
+ {
+ $bitsOffset = 0;
+
+ while ($bitsOffset < count($this->bits) && 0 === $this->bits[$bitsOffset]) {
+ ++$bitsOffset;
+ }
+
+ if (count($this->bits) === $bitsOffset) {
+ return null;
+ }
+
+ $x = intdiv($bitsOffset, $this->rowSize);
+ $y = ($bitsOffset % $this->rowSize) << 5;
+
+ $bits = $this->bits[$bitsOffset];
+ $bit = 0;
+
+ while (0 === ($bits << (31 - $bit))) {
+ ++$bit;
+ }
+
+ $x += $bit;
+
+ return [$x, $y];
+ }
+
+ /**
+ * Gets the most bottom right set bit.
+ *
+ * This is useful in detecting a corner of a 'pure' barcode.
+ *
+ * @return int[]|null
+ */
+ public function getBottomRightOnBit() : ?array
+ {
+ $bitsOffset = count($this->bits) - 1;
+
+ while ($bitsOffset >= 0 && 0 === $this->bits[$bitsOffset]) {
+ --$bitsOffset;
+ }
+
+ if ($bitsOffset < 0) {
+ return null;
+ }
+
+ $x = intdiv($bitsOffset, $this->rowSize);
+ $y = ($bitsOffset % $this->rowSize) << 5;
+
+ $bits = $this->bits[$bitsOffset];
+ $bit = 0;
+
+ while (0 === BitUtils::unsignedRightShift($bits, $bit)) {
+ --$bit;
+ }
+
+ $x += $bit;
+
+ return [$x, $y];
+ }
+
+ /**
+ * Gets the width of the matrix,
+ */
+ public function getWidth() : int
+ {
+ return $this->width;
+ }
+
+ /**
+ * Gets the height of the matrix.
+ */
+ public function getHeight() : int
+ {
+ return $this->height;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php
new file mode 100644
index 0000000..0c575b4
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php
@@ -0,0 +1,41 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+/**
+ * General bit utilities.
+ *
+ * All utility methods are based on 32-bit integers and also work on 64-bit
+ * systems.
+ */
+final class BitUtils
+{
+ private function __construct()
+ {
+ }
+
+ /**
+ * Performs an unsigned right shift.
+ *
+ * This is the same as the unsigned right shift operator ">>>" in other
+ * languages.
+ */
+ public static function unsignedRightShift(int $a, int $b) : int
+ {
+ return (
+ $a >= 0
+ ? $a >> $b
+ : (($a & 0x7fffffff) >> $b) | (0x40000000 >> ($b - 1))
+ );
+ }
+
+ /**
+ * Gets the number of trailing zeros.
+ */
+ public static function numberOfTrailingZeros(int $i) : int
+ {
+ $lastPos = strrpos(str_pad(decbin($i), 32, '0', STR_PAD_LEFT), '1');
+ return $lastPos === false ? 32 : 31 - $lastPos;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php
new file mode 100644
index 0000000..6dfff17
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php
@@ -0,0 +1,180 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+use BaconQrCode\Exception\InvalidArgumentException;
+use DASPRiD\Enum\AbstractEnum;
+
+/**
+ * Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1 of ISO 18004.
+ *
+ * @method static self CP437()
+ * @method static self ISO8859_1()
+ * @method static self ISO8859_2()
+ * @method static self ISO8859_3()
+ * @method static self ISO8859_4()
+ * @method static self ISO8859_5()
+ * @method static self ISO8859_6()
+ * @method static self ISO8859_7()
+ * @method static self ISO8859_8()
+ * @method static self ISO8859_9()
+ * @method static self ISO8859_10()
+ * @method static self ISO8859_11()
+ * @method static self ISO8859_12()
+ * @method static self ISO8859_13()
+ * @method static self ISO8859_14()
+ * @method static self ISO8859_15()
+ * @method static self ISO8859_16()
+ * @method static self SJIS()
+ * @method static self CP1250()
+ * @method static self CP1251()
+ * @method static self CP1252()
+ * @method static self CP1256()
+ * @method static self UNICODE_BIG_UNMARKED()
+ * @method static self UTF8()
+ * @method static self ASCII()
+ * @method static self BIG5()
+ * @method static self GB18030()
+ * @method static self EUC_KR()
+ */
+final class CharacterSetEci extends AbstractEnum
+{
+ protected const CP437 = [[0, 2]];
+ protected const ISO8859_1 = [[1, 3], 'ISO-8859-1'];
+ protected const ISO8859_2 = [[4], 'ISO-8859-2'];
+ protected const ISO8859_3 = [[5], 'ISO-8859-3'];
+ protected const ISO8859_4 = [[6], 'ISO-8859-4'];
+ protected const ISO8859_5 = [[7], 'ISO-8859-5'];
+ protected const ISO8859_6 = [[8], 'ISO-8859-6'];
+ protected const ISO8859_7 = [[9], 'ISO-8859-7'];
+ protected const ISO8859_8 = [[10], 'ISO-8859-8'];
+ protected const ISO8859_9 = [[11], 'ISO-8859-9'];
+ protected const ISO8859_10 = [[12], 'ISO-8859-10'];
+ protected const ISO8859_11 = [[13], 'ISO-8859-11'];
+ protected const ISO8859_12 = [[14], 'ISO-8859-12'];
+ protected const ISO8859_13 = [[15], 'ISO-8859-13'];
+ protected const ISO8859_14 = [[16], 'ISO-8859-14'];
+ protected const ISO8859_15 = [[17], 'ISO-8859-15'];
+ protected const ISO8859_16 = [[18], 'ISO-8859-16'];
+ protected const SJIS = [[20], 'Shift_JIS'];
+ protected const CP1250 = [[21], 'windows-1250'];
+ protected const CP1251 = [[22], 'windows-1251'];
+ protected const CP1252 = [[23], 'windows-1252'];
+ protected const CP1256 = [[24], 'windows-1256'];
+ protected const UNICODE_BIG_UNMARKED = [[25], 'UTF-16BE', 'UnicodeBig'];
+ protected const UTF8 = [[26], 'UTF-8'];
+ protected const ASCII = [[27, 170], 'US-ASCII'];
+ protected const BIG5 = [[28]];
+ protected const GB18030 = [[29], 'GB2312', 'EUC_CN', 'GBK'];
+ protected const EUC_KR = [[30], 'EUC-KR'];
+
+ /**
+ * @var int[]
+ */
+ private $values;
+
+ /**
+ * @var string[]
+ */
+ private $otherEncodingNames;
+
+ /**
+ * @var array<int, self>|null
+ */
+ private static $valueToEci;
+
+ /**
+ * @var array<string, self>|null
+ */
+ private static $nameToEci;
+
+ public function __construct(array $values, string ...$otherEncodingNames)
+ {
+ $this->values = $values;
+ $this->otherEncodingNames = $otherEncodingNames;
+ }
+
+ /**
+ * Returns the primary value.
+ */
+ public function getValue() : int
+ {
+ return $this->values[0];
+ }
+
+ /**
+ * Gets character set ECI by value.
+ *
+ * Returns the representing ECI of a given value, or null if it is legal but unsupported.
+ *
+ * @throws InvalidArgumentException if value is not between 0 and 900
+ */
+ public static function getCharacterSetEciByValue(int $value) : ?self
+ {
+ if ($value < 0 || $value >= 900) {
+ throw new InvalidArgumentException('Value must be between 0 and 900');
+ }
+
+ $valueToEci = self::valueToEci();
+
+ if (! array_key_exists($value, $valueToEci)) {
+ return null;
+ }
+
+ return $valueToEci[$value];
+ }
+
+ /**
+ * Returns character set ECI by name.
+ *
+ * Returns the representing ECI of a given name, or null if it is legal but unsupported
+ */
+ public static function getCharacterSetEciByName(string $name) : ?self
+ {
+ $nameToEci = self::nameToEci();
+ $name = strtolower($name);
+
+ if (! array_key_exists($name, $nameToEci)) {
+ return null;
+ }
+
+ return $nameToEci[$name];
+ }
+
+ private static function valueToEci() : array
+ {
+ if (null !== self::$valueToEci) {
+ return self::$valueToEci;
+ }
+
+ self::$valueToEci = [];
+
+ foreach (self::values() as $eci) {
+ foreach ($eci->values as $value) {
+ self::$valueToEci[$value] = $eci;
+ }
+ }
+
+ return self::$valueToEci;
+ }
+
+ private static function nameToEci() : array
+ {
+ if (null !== self::$nameToEci) {
+ return self::$nameToEci;
+ }
+
+ self::$nameToEci = [];
+
+ foreach (self::values() as $eci) {
+ self::$nameToEci[strtolower($eci->name())] = $eci;
+
+ foreach ($eci->otherEncodingNames as $name) {
+ self::$nameToEci[strtolower($name)] = $eci;
+ }
+ }
+
+ return self::$nameToEci;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php
new file mode 100644
index 0000000..a9a1d07
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php
@@ -0,0 +1,49 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+/**
+ * Encapsulates the parameters for one error-correction block in one symbol version.
+ *
+ * This includes the number of data codewords, and the number of times a block with these parameters is used
+ * consecutively in the QR code version's format.
+ */
+final class EcBlock
+{
+ /**
+ * How many times the block is used.
+ *
+ * @var int
+ */
+ private $count;
+
+ /**
+ * Number of data codewords.
+ *
+ * @var int
+ */
+ private $dataCodewords;
+
+ public function __construct(int $count, int $dataCodewords)
+ {
+ $this->count = $count;
+ $this->dataCodewords = $dataCodewords;
+ }
+
+ /**
+ * Returns how many times the block is used.
+ */
+ public function getCount() : int
+ {
+ return $this->count;
+ }
+
+ /**
+ * Returns the number of data codewords.
+ */
+ public function getDataCodewords() : int
+ {
+ return $this->dataCodewords;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php
new file mode 100644
index 0000000..172b5f2
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php
@@ -0,0 +1,74 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+/**
+ * Encapsulates a set of error-correction blocks in one symbol version.
+ *
+ * Most versions will use blocks of differing sizes within one version, so, this encapsulates the parameters for each
+ * set of blocks. It also holds the number of error-correction codewords per block since it will be the same across all
+ * blocks within one version.
+ */
+final class EcBlocks
+{
+ /**
+ * Number of EC codewords per block.
+ *
+ * @var int
+ */
+ private $ecCodewordsPerBlock;
+
+ /**
+ * List of EC blocks.
+ *
+ * @var EcBlock[]
+ */
+ private $ecBlocks;
+
+ public function __construct(int $ecCodewordsPerBlock, EcBlock ...$ecBlocks)
+ {
+ $this->ecCodewordsPerBlock = $ecCodewordsPerBlock;
+ $this->ecBlocks = $ecBlocks;
+ }
+
+ /**
+ * Returns the number of EC codewords per block.
+ */
+ public function getEcCodewordsPerBlock() : int
+ {
+ return $this->ecCodewordsPerBlock;
+ }
+
+ /**
+ * Returns the total number of EC block appearances.
+ */
+ public function getNumBlocks() : int
+ {
+ $total = 0;
+
+ foreach ($this->ecBlocks as $ecBlock) {
+ $total += $ecBlock->getCount();
+ }
+
+ return $total;
+ }
+
+ /**
+ * Returns the total count of EC codewords.
+ */
+ public function getTotalEcCodewords() : int
+ {
+ return $this->ecCodewordsPerBlock * $this->getNumBlocks();
+ }
+
+ /**
+ * Returns the EC blocks included in this collection.
+ *
+ * @return EcBlock[]
+ */
+ public function getEcBlocks() : array
+ {
+ return $this->ecBlocks;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php
new file mode 100644
index 0000000..9bbf440
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php
@@ -0,0 +1,63 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+use BaconQrCode\Exception\OutOfBoundsException;
+use DASPRiD\Enum\AbstractEnum;
+
+/**
+ * Enum representing the four error correction levels.
+ *
+ * @method static self L() ~7% correction
+ * @method static self M() ~15% correction
+ * @method static self Q() ~25% correction
+ * @method static self H() ~30% correction
+ */
+final class ErrorCorrectionLevel extends AbstractEnum
+{
+ protected const L = [0x01];
+ protected const M = [0x00];
+ protected const Q = [0x03];
+ protected const H = [0x02];
+
+ /**
+ * @var int
+ */
+ private $bits;
+
+ protected function __construct(int $bits)
+ {
+ $this->bits = $bits;
+ }
+
+ /**
+ * @throws OutOfBoundsException if number of bits is invalid
+ */
+ public static function forBits(int $bits) : self
+ {
+ switch ($bits) {
+ case 0:
+ return self::M();
+
+ case 1:
+ return self::L();
+
+ case 2:
+ return self::H();
+
+ case 3:
+ return self::Q();
+ }
+
+ throw new OutOfBoundsException('Invalid number of bits');
+ }
+
+ /**
+ * Returns the two bits used to encode this error correction level.
+ */
+ public function getBits() : int
+ {
+ return $this->bits;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php
new file mode 100644
index 0000000..53e3541
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * BaconQrCode
+ *
+ * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
+ * @copyright 2013 Ben 'DASPRiD' Scholzen
+ * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
+ */
+
+namespace BaconQrCode\Common;
+
+/**
+ * Encapsulates a QR Code's format information, including the data mask used and error correction level.
+ */
+class FormatInformation
+{
+ /**
+ * Mask for format information.
+ */
+ private const FORMAT_INFO_MASK_QR = 0x5412;
+
+ /**
+ * Lookup table for decoding format information.
+ *
+ * See ISO 18004:2006, Annex C, Table C.1
+ */
+ private const FORMAT_INFO_DECODE_LOOKUP = [
+ [0x5412, 0x00],
+ [0x5125, 0x01],
+ [0x5e7c, 0x02],
+ [0x5b4b, 0x03],
+ [0x45f9, 0x04],
+ [0x40ce, 0x05],
+ [0x4f97, 0x06],
+ [0x4aa0, 0x07],
+ [0x77c4, 0x08],
+ [0x72f3, 0x09],
+ [0x7daa, 0x0a],
+ [0x789d, 0x0b],
+ [0x662f, 0x0c],
+ [0x6318, 0x0d],
+ [0x6c41, 0x0e],
+ [0x6976, 0x0f],
+ [0x1689, 0x10],
+ [0x13be, 0x11],
+ [0x1ce7, 0x12],
+ [0x19d0, 0x13],
+ [0x0762, 0x14],
+ [0x0255, 0x15],
+ [0x0d0c, 0x16],
+ [0x083b, 0x17],
+ [0x355f, 0x18],
+ [0x3068, 0x19],
+ [0x3f31, 0x1a],
+ [0x3a06, 0x1b],
+ [0x24b4, 0x1c],
+ [0x2183, 0x1d],
+ [0x2eda, 0x1e],
+ [0x2bed, 0x1f],
+ ];
+
+ /**
+ * Offset i holds the number of 1 bits in the binary representation of i.
+ *
+ * @var array
+ */
+ private const BITS_SET_IN_HALF_BYTE = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4];
+
+ /**
+ * Error correction level.
+ *
+ * @var ErrorCorrectionLevel
+ */
+ private $ecLevel;
+
+ /**
+ * Data mask.
+ *
+ * @var int
+ */
+ private $dataMask;
+
+ protected function __construct(int $formatInfo)
+ {
+ $this->ecLevel = ErrorCorrectionLevel::forBits(($formatInfo >> 3) & 0x3);
+ $this->dataMask = $formatInfo & 0x7;
+ }
+
+ /**
+ * Checks how many bits are different between two integers.
+ */
+ public static function numBitsDiffering(int $a, int $b) : int
+ {
+ $a ^= $b;
+
+ return (
+ self::BITS_SET_IN_HALF_BYTE[$a & 0xf]
+ + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 4) & 0xf)]
+ + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 8) & 0xf)]
+ + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 12) & 0xf)]
+ + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 16) & 0xf)]
+ + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 20) & 0xf)]
+ + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 24) & 0xf)]
+ + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 28) & 0xf)]
+ );
+ }
+
+ /**
+ * Decodes format information.
+ */
+ public static function decodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self
+ {
+ $formatInfo = self::doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2);
+
+ if (null !== $formatInfo) {
+ return $formatInfo;
+ }
+
+ // Should return null, but, some QR codes apparently do not mask this info. Try again by actually masking the
+ // pattern first.
+ return self::doDecodeFormatInformation(
+ $maskedFormatInfo1 ^ self::FORMAT_INFO_MASK_QR,
+ $maskedFormatInfo2 ^ self::FORMAT_INFO_MASK_QR
+ );
+ }
+
+ /**
+ * Internal method for decoding format information.
+ */
+ private static function doDecodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self
+ {
+ $bestDifference = PHP_INT_MAX;
+ $bestFormatInfo = 0;
+
+ foreach (self::FORMAT_INFO_DECODE_LOOKUP as $decodeInfo) {
+ $targetInfo = $decodeInfo[0];
+
+ if ($targetInfo === $maskedFormatInfo1 || $targetInfo === $maskedFormatInfo2) {
+ // Found an exact match
+ return new self($decodeInfo[1]);
+ }
+
+ $bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $targetInfo);
+
+ if ($bitsDifference < $bestDifference) {
+ $bestFormatInfo = $decodeInfo[1];
+ $bestDifference = $bitsDifference;
+ }
+
+ if ($maskedFormatInfo1 !== $maskedFormatInfo2) {
+ // Also try the other option
+ $bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $targetInfo);
+
+ if ($bitsDifference < $bestDifference) {
+ $bestFormatInfo = $decodeInfo[1];
+ $bestDifference = $bitsDifference;
+ }
+ }
+ }
+
+ // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match.
+ if ($bestDifference <= 3) {
+ return new self($bestFormatInfo);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the error correction level.
+ */
+ public function getErrorCorrectionLevel() : ErrorCorrectionLevel
+ {
+ return $this->ecLevel;
+ }
+
+ /**
+ * Returns the data mask.
+ */
+ public function getDataMask() : int
+ {
+ return $this->dataMask;
+ }
+
+ /**
+ * Hashes the code of the EC level.
+ */
+ public function hashCode() : int
+ {
+ return ($this->ecLevel->getBits() << 3) | $this->dataMask;
+ }
+
+ /**
+ * Verifies if this instance equals another one.
+ */
+ public function equals(self $other) : bool
+ {
+ return (
+ $this->ecLevel === $other->ecLevel
+ && $this->dataMask === $other->dataMask
+ );
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Mode.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Mode.php
new file mode 100644
index 0000000..51e6c9a
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Mode.php
@@ -0,0 +1,76 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+use DASPRiD\Enum\AbstractEnum;
+
+/**
+ * Enum representing various modes in which data can be encoded to bits.
+ *
+ * @method static self TERMINATOR()
+ * @method static self NUMERIC()
+ * @method static self ALPHANUMERIC()
+ * @method static self STRUCTURED_APPEND()
+ * @method static self BYTE()
+ * @method static self ECI()
+ * @method static self KANJI()
+ * @method static self FNC1_FIRST_POSITION()
+ * @method static self FNC1_SECOND_POSITION()
+ * @method static self HANZI()
+ */
+final class Mode extends AbstractEnum
+{
+ protected const TERMINATOR = [[0, 0, 0], 0x00];
+ protected const NUMERIC = [[10, 12, 14], 0x01];
+ protected const ALPHANUMERIC = [[9, 11, 13], 0x02];
+ protected const STRUCTURED_APPEND = [[0, 0, 0], 0x03];
+ protected const BYTE = [[8, 16, 16], 0x04];
+ protected const ECI = [[0, 0, 0], 0x07];
+ protected const KANJI = [[8, 10, 12], 0x08];
+ protected const FNC1_FIRST_POSITION = [[0, 0, 0], 0x05];
+ protected const FNC1_SECOND_POSITION = [[0, 0, 0], 0x09];
+ protected const HANZI = [[8, 10, 12], 0x0d];
+
+ /**
+ * @var int[]
+ */
+ private $characterCountBitsForVersions;
+
+ /**
+ * @var int
+ */
+ private $bits;
+
+ protected function __construct(array $characterCountBitsForVersions, int $bits)
+ {
+ $this->characterCountBitsForVersions = $characterCountBitsForVersions;
+ $this->bits = $bits;
+ }
+
+ /**
+ * Returns the number of bits used in a specific QR code version.
+ */
+ public function getCharacterCountBits(Version $version) : int
+ {
+ $number = $version->getVersionNumber();
+
+ if ($number <= 9) {
+ $offset = 0;
+ } elseif ($number <= 26) {
+ $offset = 1;
+ } else {
+ $offset = 2;
+ }
+
+ return $this->characterCountBitsForVersions[$offset];
+ }
+
+ /**
+ * Returns the four bits used to encode this mode.
+ */
+ public function getBits() : int
+ {
+ return $this->bits;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php
new file mode 100644
index 0000000..a5aad0b
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php
@@ -0,0 +1,468 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+use BaconQrCode\Exception\InvalidArgumentException;
+use BaconQrCode\Exception\RuntimeException;
+use SplFixedArray;
+
+/**
+ * Reed-Solomon codec for 8-bit characters.
+ *
+ * Based on libfec by Phil Karn, KA9Q.
+ */
+final class ReedSolomonCodec
+{
+ /**
+ * Symbol size in bits.
+ *
+ * @var int
+ */
+ private $symbolSize;
+
+ /**
+ * Block size in symbols.
+ *
+ * @var int
+ */
+ private $blockSize;
+
+ /**
+ * First root of RS code generator polynomial, index form.
+ *
+ * @var int
+ */
+ private $firstRoot;
+
+ /**
+ * Primitive element to generate polynomial roots, index form.
+ *
+ * @var int
+ */
+ private $primitive;
+
+ /**
+ * Prim-th root of 1, index form.
+ *
+ * @var int
+ */
+ private $iPrimitive;
+
+ /**
+ * RS code generator polynomial degree (number of roots).
+ *
+ * @var int
+ */
+ private $numRoots;
+
+ /**
+ * Padding bytes at front of shortened block.
+ *
+ * @var int
+ */
+ private $padding;
+
+ /**
+ * Log lookup table.
+ *
+ * @var SplFixedArray
+ */
+ private $alphaTo;
+
+ /**
+ * Anti-Log lookup table.
+ *
+ * @var SplFixedArray
+ */
+ private $indexOf;
+
+ /**
+ * Generator polynomial.
+ *
+ * @var SplFixedArray
+ */
+ private $generatorPoly;
+
+ /**
+ * @throws InvalidArgumentException if symbol size ist not between 0 and 8
+ * @throws InvalidArgumentException if first root is invalid
+ * @throws InvalidArgumentException if num roots is invalid
+ * @throws InvalidArgumentException if padding is invalid
+ * @throws RuntimeException if field generator polynomial is not primitive
+ */
+ public function __construct(
+ int $symbolSize,
+ int $gfPoly,
+ int $firstRoot,
+ int $primitive,
+ int $numRoots,
+ int $padding
+ ) {
+ if ($symbolSize < 0 || $symbolSize > 8) {
+ throw new InvalidArgumentException('Symbol size must be between 0 and 8');
+ }
+
+ if ($firstRoot < 0 || $firstRoot >= (1 << $symbolSize)) {
+ throw new InvalidArgumentException('First root must be between 0 and ' . (1 << $symbolSize));
+ }
+
+ if ($numRoots < 0 || $numRoots >= (1 << $symbolSize)) {
+ throw new InvalidArgumentException('Num roots must be between 0 and ' . (1 << $symbolSize));
+ }
+
+ if ($padding < 0 || $padding >= ((1 << $symbolSize) - 1 - $numRoots)) {
+ throw new InvalidArgumentException(
+ 'Padding must be between 0 and ' . ((1 << $symbolSize) - 1 - $numRoots)
+ );
+ }
+
+ $this->symbolSize = $symbolSize;
+ $this->blockSize = (1 << $symbolSize) - 1;
+ $this->padding = $padding;
+ $this->alphaTo = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false);
+ $this->indexOf = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false);
+
+ // Generate galous field lookup table
+ $this->indexOf[0] = $this->blockSize;
+ $this->alphaTo[$this->blockSize] = 0;
+
+ $sr = 1;
+
+ for ($i = 0; $i < $this->blockSize; ++$i) {
+ $this->indexOf[$sr] = $i;
+ $this->alphaTo[$i] = $sr;
+
+ $sr <<= 1;
+
+ if ($sr & (1 << $symbolSize)) {
+ $sr ^= $gfPoly;
+ }
+
+ $sr &= $this->blockSize;
+ }
+
+ if (1 !== $sr) {
+ throw new RuntimeException('Field generator polynomial is not primitive');
+ }
+
+ // Form RS code generator polynomial from its roots
+ $this->generatorPoly = SplFixedArray::fromArray(array_fill(0, $numRoots + 1, 0), false);
+ $this->firstRoot = $firstRoot;
+ $this->primitive = $primitive;
+ $this->numRoots = $numRoots;
+
+ // Find prim-th root of 1, used in decoding
+ for ($iPrimitive = 1; ($iPrimitive % $primitive) !== 0; $iPrimitive += $this->blockSize) {
+ }
+
+ $this->iPrimitive = intdiv($iPrimitive, $primitive);
+
+ $this->generatorPoly[0] = 1;
+
+ for ($i = 0, $root = $firstRoot * $primitive; $i < $numRoots; ++$i, $root += $primitive) {
+ $this->generatorPoly[$i + 1] = 1;
+
+ for ($j = $i; $j > 0; $j--) {
+ if ($this->generatorPoly[$j] !== 0) {
+ $this->generatorPoly[$j] = $this->generatorPoly[$j - 1] ^ $this->alphaTo[
+ $this->modNn($this->indexOf[$this->generatorPoly[$j]] + $root)
+ ];
+ } else {
+ $this->generatorPoly[$j] = $this->generatorPoly[$j - 1];
+ }
+ }
+
+ $this->generatorPoly[$j] = $this->alphaTo[$this->modNn($this->indexOf[$this->generatorPoly[0]] + $root)];
+ }
+
+ // Convert generator poly to index form for quicker encoding
+ for ($i = 0; $i <= $numRoots; ++$i) {
+ $this->generatorPoly[$i] = $this->indexOf[$this->generatorPoly[$i]];
+ }
+ }
+
+ /**
+ * Encodes data and writes result back into parity array.
+ */
+ public function encode(SplFixedArray $data, SplFixedArray $parity) : void
+ {
+ for ($i = 0; $i < $this->numRoots; ++$i) {
+ $parity[$i] = 0;
+ }
+
+ $iterations = $this->blockSize - $this->numRoots - $this->padding;
+
+ for ($i = 0; $i < $iterations; ++$i) {
+ $feedback = $this->indexOf[$data[$i] ^ $parity[0]];
+
+ if ($feedback !== $this->blockSize) {
+ // Feedback term is non-zero
+ $feedback = $this->modNn($this->blockSize - $this->generatorPoly[$this->numRoots] + $feedback);
+
+ for ($j = 1; $j < $this->numRoots; ++$j) {
+ $parity[$j] = $parity[$j] ^ $this->alphaTo[
+ $this->modNn($feedback + $this->generatorPoly[$this->numRoots - $j])
+ ];
+ }
+ }
+
+ for ($j = 0; $j < $this->numRoots - 1; ++$j) {
+ $parity[$j] = $parity[$j + 1];
+ }
+
+ if ($feedback !== $this->blockSize) {
+ $parity[$this->numRoots - 1] = $this->alphaTo[$this->modNn($feedback + $this->generatorPoly[0])];
+ } else {
+ $parity[$this->numRoots - 1] = 0;
+ }
+ }
+ }
+
+ /**
+ * Decodes received data.
+ */
+ public function decode(SplFixedArray $data, SplFixedArray $erasures = null) : ?int
+ {
+ // This speeds up the initialization a bit.
+ $numRootsPlusOne = SplFixedArray::fromArray(array_fill(0, $this->numRoots + 1, 0), false);
+ $numRoots = SplFixedArray::fromArray(array_fill(0, $this->numRoots, 0), false);
+
+ $lambda = clone $numRootsPlusOne;
+ $b = clone $numRootsPlusOne;
+ $t = clone $numRootsPlusOne;
+ $omega = clone $numRootsPlusOne;
+ $root = clone $numRoots;
+ $loc = clone $numRoots;
+
+ $numErasures = (null !== $erasures ? count($erasures) : 0);
+
+ // Form the Syndromes; i.e., evaluate data(x) at roots of g(x)
+ $syndromes = SplFixedArray::fromArray(array_fill(0, $this->numRoots, $data[0]), false);
+
+ for ($i = 1; $i < $this->blockSize - $this->padding; ++$i) {
+ for ($j = 0; $j < $this->numRoots; ++$j) {
+ if ($syndromes[$j] === 0) {
+ $syndromes[$j] = $data[$i];
+ } else {
+ $syndromes[$j] = $data[$i] ^ $this->alphaTo[
+ $this->modNn($this->indexOf[$syndromes[$j]] + ($this->firstRoot + $j) * $this->primitive)
+ ];
+ }
+ }
+ }
+
+ // Convert syndromes to index form, checking for nonzero conditions
+ $syndromeError = 0;
+
+ for ($i = 0; $i < $this->numRoots; ++$i) {
+ $syndromeError |= $syndromes[$i];
+ $syndromes[$i] = $this->indexOf[$syndromes[$i]];
+ }
+
+ if (! $syndromeError) {
+ // If syndrome is zero, data[] is a codeword and there are no errors to correct, so return data[]
+ // unmodified.
+ return 0;
+ }
+
+ $lambda[0] = 1;
+
+ if ($numErasures > 0) {
+ // Init lambda to be the erasure locator polynomial
+ $lambda[1] = $this->alphaTo[$this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[0]))];
+
+ for ($i = 1; $i < $numErasures; ++$i) {
+ $u = $this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[$i]));
+
+ for ($j = $i + 1; $j > 0; --$j) {
+ $tmp = $this->indexOf[$lambda[$j - 1]];
+
+ if ($tmp !== $this->blockSize) {
+ $lambda[$j] = $lambda[$j] ^ $this->alphaTo[$this->modNn($u + $tmp)];
+ }
+ }
+ }
+ }
+
+ for ($i = 0; $i <= $this->numRoots; ++$i) {
+ $b[$i] = $this->indexOf[$lambda[$i]];
+ }
+
+ // Begin Berlekamp-Massey algorithm to determine error+erasure locator polynomial
+ $r = $numErasures;
+ $el = $numErasures;
+
+ while (++$r <= $this->numRoots) {
+ // Compute discrepancy at the r-th step in poly form
+ $discrepancyR = 0;
+
+ for ($i = 0; $i < $r; ++$i) {
+ if ($lambda[$i] !== 0 && $syndromes[$r - $i - 1] !== $this->blockSize) {
+ $discrepancyR ^= $this->alphaTo[
+ $this->modNn($this->indexOf[$lambda[$i]] + $syndromes[$r - $i - 1])
+ ];
+ }
+ }
+
+ $discrepancyR = $this->indexOf[$discrepancyR];
+
+ if ($discrepancyR === $this->blockSize) {
+ $tmp = $b->toArray();
+ array_unshift($tmp, $this->blockSize);
+ array_pop($tmp);
+ $b = SplFixedArray::fromArray($tmp, false);
+ continue;
+ }
+
+ $t[0] = $lambda[0];
+
+ for ($i = 0; $i < $this->numRoots; ++$i) {
+ if ($b[$i] !== $this->blockSize) {
+ $t[$i + 1] = $lambda[$i + 1] ^ $this->alphaTo[$this->modNn($discrepancyR + $b[$i])];
+ } else {
+ $t[$i + 1] = $lambda[$i + 1];
+ }
+ }
+
+ if (2 * $el <= $r + $numErasures - 1) {
+ $el = $r + $numErasures - $el;
+
+ for ($i = 0; $i <= $this->numRoots; ++$i) {
+ $b[$i] = (
+ $lambda[$i] === 0
+ ? $this->blockSize
+ : $this->modNn($this->indexOf[$lambda[$i]] - $discrepancyR + $this->blockSize)
+ );
+ }
+ } else {
+ $tmp = $b->toArray();
+ array_unshift($tmp, $this->blockSize);
+ array_pop($tmp);
+ $b = SplFixedArray::fromArray($tmp, false);
+ }
+
+ $lambda = clone $t;
+ }
+
+ // Convert lambda to index form and compute deg(lambda(x))
+ $degLambda = 0;
+
+ for ($i = 0; $i <= $this->numRoots; ++$i) {
+ $lambda[$i] = $this->indexOf[$lambda[$i]];
+
+ if ($lambda[$i] !== $this->blockSize) {
+ $degLambda = $i;
+ }
+ }
+
+ // Find roots of the error+erasure locator polynomial by Chien search.
+ $reg = clone $lambda;
+ $reg[0] = 0;
+ $count = 0;
+ $i = 1;
+
+ for ($k = $this->iPrimitive - 1; $i <= $this->blockSize; ++$i, $k = $this->modNn($k + $this->iPrimitive)) {
+ $q = 1;
+
+ for ($j = $degLambda; $j > 0; $j--) {
+ if ($reg[$j] !== $this->blockSize) {
+ $reg[$j] = $this->modNn($reg[$j] + $j);
+ $q ^= $this->alphaTo[$reg[$j]];
+ }
+ }
+
+ if ($q !== 0) {
+ // Not a root
+ continue;
+ }
+
+ // Store root (index-form) and error location number
+ $root[$count] = $i;
+ $loc[$count] = $k;
+
+ if (++$count === $degLambda) {
+ break;
+ }
+ }
+
+ if ($degLambda !== $count) {
+ // deg(lambda) unequal to number of roots: uncorrectable error detected
+ return null;
+ }
+
+ // Compute err+eras evaluate poly omega(x) = s(x)*lambda(x) (modulo x**numRoots). In index form. Also find
+ // deg(omega).
+ $degOmega = $degLambda - 1;
+
+ for ($i = 0; $i <= $degOmega; ++$i) {
+ $tmp = 0;
+
+ for ($j = $i; $j >= 0; --$j) {
+ if ($syndromes[$i - $j] !== $this->blockSize && $lambda[$j] !== $this->blockSize) {
+ $tmp ^= $this->alphaTo[$this->modNn($syndromes[$i - $j] + $lambda[$j])];
+ }
+ }
+
+ $omega[$i] = $this->indexOf[$tmp];
+ }
+
+ // Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = inv(X(l))**(firstRoot-1) and
+ // den = lambda_pr(inv(X(l))) all in poly form.
+ for ($j = $count - 1; $j >= 0; --$j) {
+ $num1 = 0;
+
+ for ($i = $degOmega; $i >= 0; $i--) {
+ if ($omega[$i] !== $this->blockSize) {
+ $num1 ^= $this->alphaTo[$this->modNn($omega[$i] + $i * $root[$j])];
+ }
+ }
+
+ $num2 = $this->alphaTo[$this->modNn($root[$j] * ($this->firstRoot - 1) + $this->blockSize)];
+ $den = 0;
+
+ // lambda[i+1] for i even is the formal derivativelambda_pr of lambda[i]
+ for ($i = min($degLambda, $this->numRoots - 1) & ~1; $i >= 0; $i -= 2) {
+ if ($lambda[$i + 1] !== $this->blockSize) {
+ $den ^= $this->alphaTo[$this->modNn($lambda[$i + 1] + $i * $root[$j])];
+ }
+ }
+
+ // Apply error to data
+ if ($num1 !== 0 && $loc[$j] >= $this->padding) {
+ $data[$loc[$j] - $this->padding] = $data[$loc[$j] - $this->padding] ^ (
+ $this->alphaTo[
+ $this->modNn(
+ $this->indexOf[$num1] + $this->indexOf[$num2] + $this->blockSize - $this->indexOf[$den]
+ )
+ ]
+ );
+ }
+ }
+
+ if (null !== $erasures) {
+ if (count($erasures) < $count) {
+ $erasures->setSize($count);
+ }
+
+ for ($i = 0; $i < $count; $i++) {
+ $erasures[$i] = $loc[$i];
+ }
+ }
+
+ return $count;
+ }
+
+ /**
+ * Computes $x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, without a slow divide.
+ */
+ private function modNn(int $x) : int
+ {
+ while ($x >= $this->blockSize) {
+ $x -= $this->blockSize;
+ $x = ($x >> $this->symbolSize) + ($x & $this->blockSize);
+ }
+
+ return $x;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Version.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Version.php
new file mode 100644
index 0000000..917d048
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Common/Version.php
@@ -0,0 +1,596 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Common;
+
+use BaconQrCode\Exception\InvalidArgumentException;
+use SplFixedArray;
+
+/**
+ * Version representation.
+ */
+final class Version
+{
+ private const VERSION_DECODE_INFO = [
+ 0x07c94,
+ 0x085bc,
+ 0x09a99,
+ 0x0a4d3,
+ 0x0bbf6,
+ 0x0c762,
+ 0x0d847,
+ 0x0e60d,
+ 0x0f928,
+ 0x10b78,
+ 0x1145d,
+ 0x12a17,
+ 0x13532,
+ 0x149a6,
+ 0x15683,
+ 0x168c9,
+ 0x177ec,
+ 0x18ec4,
+ 0x191e1,
+ 0x1afab,
+ 0x1b08e,
+ 0x1cc1a,
+ 0x1d33f,
+ 0x1ed75,
+ 0x1f250,
+ 0x209d5,
+ 0x216f0,
+ 0x228ba,
+ 0x2379f,
+ 0x24b0b,
+ 0x2542e,
+ 0x26a64,
+ 0x27541,
+ 0x28c69,
+ ];
+
+ /**
+ * Version number of this version.
+ *
+ * @var int
+ */
+ private $versionNumber;
+
+ /**
+ * Alignment pattern centers.
+ *
+ * @var SplFixedArray
+ */
+ private $alignmentPatternCenters;
+
+ /**
+ * Error correction blocks.
+ *
+ * @var EcBlocks[]
+ */
+ private $ecBlocks;
+
+ /**
+ * Total number of codewords.
+ *
+ * @var int
+ */
+ private $totalCodewords;
+
+ /**
+ * Cached version instances.
+ *
+ * @var array<int, self>|null
+ */
+ private static $versions;
+
+ /**
+ * @param int[] $alignmentPatternCenters
+ */
+ private function __construct(
+ int $versionNumber,
+ array $alignmentPatternCenters,
+ EcBlocks ...$ecBlocks
+ ) {
+ $this->versionNumber = $versionNumber;
+ $this->alignmentPatternCenters = $alignmentPatternCenters;
+ $this->ecBlocks = $ecBlocks;
+
+ $totalCodewords = 0;
+ $ecCodewords = $ecBlocks[0]->getEcCodewordsPerBlock();
+
+ foreach ($ecBlocks[0]->getEcBlocks() as $ecBlock) {
+ $totalCodewords += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords);
+ }
+
+ $this->totalCodewords = $totalCodewords;
+ }
+
+ /**
+ * Returns the version number.
+ */
+ public function getVersionNumber() : int
+ {
+ return $this->versionNumber;
+ }
+
+ /**
+ * Returns the alignment pattern centers.
+ *
+ * @return int[]
+ */
+ public function getAlignmentPatternCenters() : array
+ {
+ return $this->alignmentPatternCenters;
+ }
+
+ /**
+ * Returns the total number of codewords.
+ */
+ public function getTotalCodewords() : int
+ {
+ return $this->totalCodewords;
+ }
+
+ /**
+ * Calculates the dimension for the current version.
+ */
+ public function getDimensionForVersion() : int
+ {
+ return 17 + 4 * $this->versionNumber;
+ }
+
+ /**
+ * Returns the number of EC blocks for a specific EC level.
+ */
+ public function getEcBlocksForLevel(ErrorCorrectionLevel $ecLevel) : EcBlocks
+ {
+ return $this->ecBlocks[$ecLevel->ordinal()];
+ }
+
+ /**
+ * Gets a provisional version number for a specific dimension.
+ *
+ * @throws InvalidArgumentException if dimension is not 1 mod 4
+ */
+ public static function getProvisionalVersionForDimension(int $dimension) : self
+ {
+ if (1 !== $dimension % 4) {
+ throw new InvalidArgumentException('Dimension is not 1 mod 4');
+ }
+
+ return self::getVersionForNumber(intdiv($dimension - 17, 4));
+ }
+
+ /**
+ * Gets a version instance for a specific version number.
+ *
+ * @throws InvalidArgumentException if version number is out of range
+ */
+ public static function getVersionForNumber(int $versionNumber) : self
+ {
+ if ($versionNumber < 1 || $versionNumber > 40) {
+ throw new InvalidArgumentException('Version number must be between 1 and 40');
+ }
+
+ return self::versions()[$versionNumber - 1];
+ }
+
+ /**
+ * Decodes version information from an integer and returns the version.
+ */
+ public static function decodeVersionInformation(int $versionBits) : ?self
+ {
+ $bestDifference = PHP_INT_MAX;
+ $bestVersion = 0;
+
+ foreach (self::VERSION_DECODE_INFO as $i => $targetVersion) {
+ if ($targetVersion === $versionBits) {
+ return self::getVersionForNumber($i + 7);
+ }
+
+ $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion);
+
+ if ($bitsDifference < $bestDifference) {
+ $bestVersion = $i + 7;
+ $bestDifference = $bitsDifference;
+ }
+ }
+
+ if ($bestDifference <= 3) {
+ return self::getVersionForNumber($bestVersion);
+ }
+
+ return null;
+ }
+
+ /**
+ * Builds the function pattern for the current version.
+ */
+ public function buildFunctionPattern() : BitMatrix
+ {
+ $dimension = $this->getDimensionForVersion();
+ $bitMatrix = new BitMatrix($dimension);
+
+ // Top left finder pattern + separator + format
+ $bitMatrix->setRegion(0, 0, 9, 9);
+ // Top right finder pattern + separator + format
+ $bitMatrix->setRegion($dimension - 8, 0, 8, 9);
+ // Bottom left finder pattern + separator + format
+ $bitMatrix->setRegion(0, $dimension - 8, 9, 8);
+
+ // Alignment patterns
+ $max = count($this->alignmentPatternCenters);
+
+ for ($x = 0; $x < $max; ++$x) {
+ $i = $this->alignmentPatternCenters[$x] - 2;
+
+ for ($y = 0; $y < $max; ++$y) {
+ if (($x === 0 && ($y === 0 || $y === $max - 1)) || ($x === $max - 1 && $y === 0)) {
+ // No alignment patterns near the three finder paterns
+ continue;
+ }
+
+ $bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5);
+ }
+ }
+
+ // Vertical timing pattern
+ $bitMatrix->setRegion(6, 9, 1, $dimension - 17);
+ // Horizontal timing pattern
+ $bitMatrix->setRegion(9, 6, $dimension - 17, 1);
+
+ if ($this->versionNumber > 6) {
+ // Version info, top right
+ $bitMatrix->setRegion($dimension - 11, 0, 3, 6);
+ // Version info, bottom left
+ $bitMatrix->setRegion(0, $dimension - 11, 6, 3);
+ }
+
+ return $bitMatrix;
+ }
+
+ /**
+ * Returns a string representation for the version.
+ */
+ public function __toString() : string
+ {
+ return (string) $this->versionNumber;
+ }
+
+ /**
+ * Build and cache a specific version.
+ *
+ * See ISO 18004:2006 6.5.1 Table 9.
+ *
+ * @return array<int, self>
+ */
+ private static function versions() : array
+ {
+ if (null !== self::$versions) {
+ return self::$versions;
+ }
+
+ return self::$versions = [
+ new self(
+ 1,
+ [],
+ new EcBlocks(7, new EcBlock(1, 19)),
+ new EcBlocks(10, new EcBlock(1, 16)),
+ new EcBlocks(13, new EcBlock(1, 13)),
+ new EcBlocks(17, new EcBlock(1, 9))
+ ),
+ new self(
+ 2,
+ [6, 18],
+ new EcBlocks(10, new EcBlock(1, 34)),
+ new EcBlocks(16, new EcBlock(1, 28)),
+ new EcBlocks(22, new EcBlock(1, 22)),
+ new EcBlocks(28, new EcBlock(1, 16))
+ ),
+ new self(
+ 3,
+ [6, 22],
+ new EcBlocks(15, new EcBlock(1, 55)),
+ new EcBlocks(26, new EcBlock(1, 44)),
+ new EcBlocks(18, new EcBlock(2, 17)),
+ new EcBlocks(22, new EcBlock(2, 13))
+ ),
+ new self(
+ 4,
+ [6, 26],
+ new EcBlocks(20, new EcBlock(1, 80)),
+ new EcBlocks(18, new EcBlock(2, 32)),
+ new EcBlocks(26, new EcBlock(3, 24)),
+ new EcBlocks(16, new EcBlock(4, 9))
+ ),
+ new self(
+ 5,
+ [6, 30],
+ new EcBlocks(26, new EcBlock(1, 108)),
+ new EcBlocks(24, new EcBlock(2, 43)),
+ new EcBlocks(18, new EcBlock(2, 15), new EcBlock(2, 16)),
+ new EcBlocks(22, new EcBlock(2, 11), new EcBlock(2, 12))
+ ),
+ new self(
+ 6,
+ [6, 34],
+ new EcBlocks(18, new EcBlock(2, 68)),
+ new EcBlocks(16, new EcBlock(4, 27)),
+ new EcBlocks(24, new EcBlock(4, 19)),
+ new EcBlocks(28, new EcBlock(4, 15))
+ ),
+ new self(
+ 7,
+ [6, 22, 38],
+ new EcBlocks(20, new EcBlock(2, 78)),
+ new EcBlocks(18, new EcBlock(4, 31)),
+ new EcBlocks(18, new EcBlock(2, 14), new EcBlock(4, 15)),
+ new EcBlocks(26, new EcBlock(4, 13), new EcBlock(1, 14))
+ ),
+ new self(
+ 8,
+ [6, 24, 42],
+ new EcBlocks(24, new EcBlock(2, 97)),
+ new EcBlocks(22, new EcBlock(2, 38), new EcBlock(2, 39)),
+ new EcBlocks(22, new EcBlock(4, 18), new EcBlock(2, 19)),
+ new EcBlocks(26, new EcBlock(4, 14), new EcBlock(2, 15))
+ ),
+ new self(
+ 9,
+ [6, 26, 46],
+ new EcBlocks(30, new EcBlock(2, 116)),
+ new EcBlocks(22, new EcBlock(3, 36), new EcBlock(2, 37)),
+ new EcBlocks(20, new EcBlock(4, 16), new EcBlock(4, 17)),
+ new EcBlocks(24, new EcBlock(4, 12), new EcBlock(4, 13))
+ ),
+ new self(
+ 10,
+ [6, 28, 50],
+ new EcBlocks(18, new EcBlock(2, 68), new EcBlock(2, 69)),
+ new EcBlocks(26, new EcBlock(4, 43), new EcBlock(1, 44)),
+ new EcBlocks(24, new EcBlock(6, 19), new EcBlock(2, 20)),
+ new EcBlocks(28, new EcBlock(6, 15), new EcBlock(2, 16))
+ ),
+ new self(
+ 11,
+ [6, 30, 54],
+ new EcBlocks(20, new EcBlock(4, 81)),
+ new EcBlocks(30, new EcBlock(1, 50), new EcBlock(4, 51)),
+ new EcBlocks(28, new EcBlock(4, 22), new EcBlock(4, 23)),
+ new EcBlocks(24, new EcBlock(3, 12), new EcBlock(8, 13))
+ ),
+ new self(
+ 12,
+ [6, 32, 58],
+ new EcBlocks(24, new EcBlock(2, 92), new EcBlock(2, 93)),
+ new EcBlocks(22, new EcBlock(6, 36), new EcBlock(2, 37)),
+ new EcBlocks(26, new EcBlock(4, 20), new EcBlock(6, 21)),
+ new EcBlocks(28, new EcBlock(7, 14), new EcBlock(4, 15))
+ ),
+ new self(
+ 13,
+ [6, 34, 62],
+ new EcBlocks(26, new EcBlock(4, 107)),
+ new EcBlocks(22, new EcBlock(8, 37), new EcBlock(1, 38)),
+ new EcBlocks(24, new EcBlock(8, 20), new EcBlock(4, 21)),
+ new EcBlocks(22, new EcBlock(12, 11), new EcBlock(4, 12))
+ ),
+ new self(
+ 14,
+ [6, 26, 46, 66],
+ new EcBlocks(30, new EcBlock(3, 115), new EcBlock(1, 116)),
+ new EcBlocks(24, new EcBlock(4, 40), new EcBlock(5, 41)),
+ new EcBlocks(20, new EcBlock(11, 16), new EcBlock(5, 17)),
+ new EcBlocks(24, new EcBlock(11, 12), new EcBlock(5, 13))
+ ),
+ new self(
+ 15,
+ [6, 26, 48, 70],
+ new EcBlocks(22, new EcBlock(5, 87), new EcBlock(1, 88)),
+ new EcBlocks(24, new EcBlock(5, 41), new EcBlock(5, 42)),
+ new EcBlocks(30, new EcBlock(5, 24), new EcBlock(7, 25)),
+ new EcBlocks(24, new EcBlock(11, 12), new EcBlock(7, 13))
+ ),
+ new self(
+ 16,
+ [6, 26, 50, 74],
+ new EcBlocks(24, new EcBlock(5, 98), new EcBlock(1, 99)),
+ new EcBlocks(28, new EcBlock(7, 45), new EcBlock(3, 46)),
+ new EcBlocks(24, new EcBlock(15, 19), new EcBlock(2, 20)),
+ new EcBlocks(30, new EcBlock(3, 15), new EcBlock(13, 16))
+ ),
+ new self(
+ 17,
+ [6, 30, 54, 78],
+ new EcBlocks(28, new EcBlock(1, 107), new EcBlock(5, 108)),
+ new EcBlocks(28, new EcBlock(10, 46), new EcBlock(1, 47)),
+ new EcBlocks(28, new EcBlock(1, 22), new EcBlock(15, 23)),
+ new EcBlocks(28, new EcBlock(2, 14), new EcBlock(17, 15))
+ ),
+ new self(
+ 18,
+ [6, 30, 56, 82],
+ new EcBlocks(30, new EcBlock(5, 120), new EcBlock(1, 121)),
+ new EcBlocks(26, new EcBlock(9, 43), new EcBlock(4, 44)),
+ new EcBlocks(28, new EcBlock(17, 22), new EcBlock(1, 23)),
+ new EcBlocks(28, new EcBlock(2, 14), new EcBlock(19, 15))
+ ),
+ new self(
+ 19,
+ [6, 30, 58, 86],
+ new EcBlocks(28, new EcBlock(3, 113), new EcBlock(4, 114)),
+ new EcBlocks(26, new EcBlock(3, 44), new EcBlock(11, 45)),
+ new EcBlocks(26, new EcBlock(17, 21), new EcBlock(4, 22)),
+ new EcBlocks(26, new EcBlock(9, 13), new EcBlock(16, 14))
+ ),
+ new self(
+ 20,
+ [6, 34, 62, 90],
+ new EcBlocks(28, new EcBlock(3, 107), new EcBlock(5, 108)),
+ new EcBlocks(26, new EcBlock(3, 41), new EcBlock(13, 42)),
+ new EcBlocks(30, new EcBlock(15, 24), new EcBlock(5, 25)),
+ new EcBlocks(28, new EcBlock(15, 15), new EcBlock(10, 16))
+ ),
+ new self(
+ 21,
+ [6, 28, 50, 72, 94],
+ new EcBlocks(28, new EcBlock(4, 116), new EcBlock(4, 117)),
+ new EcBlocks(26, new EcBlock(17, 42)),
+ new EcBlocks(28, new EcBlock(17, 22), new EcBlock(6, 23)),
+ new EcBlocks(30, new EcBlock(19, 16), new EcBlock(6, 17))
+ ),
+ new self(
+ 22,
+ [6, 26, 50, 74, 98],
+ new EcBlocks(28, new EcBlock(2, 111), new EcBlock(7, 112)),
+ new EcBlocks(28, new EcBlock(17, 46)),
+ new EcBlocks(30, new EcBlock(7, 24), new EcBlock(16, 25)),
+ new EcBlocks(24, new EcBlock(34, 13))
+ ),
+ new self(
+ 23,
+ [6, 30, 54, 78, 102],
+ new EcBlocks(30, new EcBlock(4, 121), new EcBlock(5, 122)),
+ new EcBlocks(28, new EcBlock(4, 47), new EcBlock(14, 48)),
+ new EcBlocks(30, new EcBlock(11, 24), new EcBlock(14, 25)),
+ new EcBlocks(30, new EcBlock(16, 15), new EcBlock(14, 16))
+ ),
+ new self(
+ 24,
+ [6, 28, 54, 80, 106],
+ new EcBlocks(30, new EcBlock(6, 117), new EcBlock(4, 118)),
+ new EcBlocks(28, new EcBlock(6, 45), new EcBlock(14, 46)),
+ new EcBlocks(30, new EcBlock(11, 24), new EcBlock(16, 25)),
+ new EcBlocks(30, new EcBlock(30, 16), new EcBlock(2, 17))
+ ),
+ new self(
+ 25,
+ [6, 32, 58, 84, 110],
+ new EcBlocks(26, new EcBlock(8, 106), new EcBlock(4, 107)),
+ new EcBlocks(28, new EcBlock(8, 47), new EcBlock(13, 48)),
+ new EcBlocks(30, new EcBlock(7, 24), new EcBlock(22, 25)),
+ new EcBlocks(30, new EcBlock(22, 15), new EcBlock(13, 16))
+ ),
+ new self(
+ 26,
+ [6, 30, 58, 86, 114],
+ new EcBlocks(28, new EcBlock(10, 114), new EcBlock(2, 115)),
+ new EcBlocks(28, new EcBlock(19, 46), new EcBlock(4, 47)),
+ new EcBlocks(28, new EcBlock(28, 22), new EcBlock(6, 23)),
+ new EcBlocks(30, new EcBlock(33, 16), new EcBlock(4, 17))
+ ),
+ new self(
+ 27,
+ [6, 34, 62, 90, 118],
+ new EcBlocks(30, new EcBlock(8, 122), new EcBlock(4, 123)),
+ new EcBlocks(28, new EcBlock(22, 45), new EcBlock(3, 46)),
+ new EcBlocks(30, new EcBlock(8, 23), new EcBlock(26, 24)),
+ new EcBlocks(30, new EcBlock(12, 15), new EcBlock(28, 16))
+ ),
+ new self(
+ 28,
+ [6, 26, 50, 74, 98, 122],
+ new EcBlocks(30, new EcBlock(3, 117), new EcBlock(10, 118)),
+ new EcBlocks(28, new EcBlock(3, 45), new EcBlock(23, 46)),
+ new EcBlocks(30, new EcBlock(4, 24), new EcBlock(31, 25)),
+ new EcBlocks(30, new EcBlock(11, 15), new EcBlock(31, 16))
+ ),
+ new self(
+ 29,
+ [6, 30, 54, 78, 102, 126],
+ new EcBlocks(30, new EcBlock(7, 116), new EcBlock(7, 117)),
+ new EcBlocks(28, new EcBlock(21, 45), new EcBlock(7, 46)),
+ new EcBlocks(30, new EcBlock(1, 23), new EcBlock(37, 24)),
+ new EcBlocks(30, new EcBlock(19, 15), new EcBlock(26, 16))
+ ),
+ new self(
+ 30,
+ [6, 26, 52, 78, 104, 130],
+ new EcBlocks(30, new EcBlock(5, 115), new EcBlock(10, 116)),
+ new EcBlocks(28, new EcBlock(19, 47), new EcBlock(10, 48)),
+ new EcBlocks(30, new EcBlock(15, 24), new EcBlock(25, 25)),
+ new EcBlocks(30, new EcBlock(23, 15), new EcBlock(25, 16))
+ ),
+ new self(
+ 31,
+ [6, 30, 56, 82, 108, 134],
+ new EcBlocks(30, new EcBlock(13, 115), new EcBlock(3, 116)),
+ new EcBlocks(28, new EcBlock(2, 46), new EcBlock(29, 47)),
+ new EcBlocks(30, new EcBlock(42, 24), new EcBlock(1, 25)),
+ new EcBlocks(30, new EcBlock(23, 15), new EcBlock(28, 16))
+ ),
+ new self(
+ 32,
+ [6, 34, 60, 86, 112, 138],
+ new EcBlocks(30, new EcBlock(17, 115)),
+ new EcBlocks(28, new EcBlock(10, 46), new EcBlock(23, 47)),
+ new EcBlocks(30, new EcBlock(10, 24), new EcBlock(35, 25)),
+ new EcBlocks(30, new EcBlock(19, 15), new EcBlock(35, 16))
+ ),
+ new self(
+ 33,
+ [6, 30, 58, 86, 114, 142],
+ new EcBlocks(30, new EcBlock(17, 115), new EcBlock(1, 116)),
+ new EcBlocks(28, new EcBlock(14, 46), new EcBlock(21, 47)),
+ new EcBlocks(30, new EcBlock(29, 24), new EcBlock(19, 25)),
+ new EcBlocks(30, new EcBlock(11, 15), new EcBlock(46, 16))
+ ),
+ new self(
+ 34,
+ [6, 34, 62, 90, 118, 146],
+ new EcBlocks(30, new EcBlock(13, 115), new EcBlock(6, 116)),
+ new EcBlocks(28, new EcBlock(14, 46), new EcBlock(23, 47)),
+ new EcBlocks(30, new EcBlock(44, 24), new EcBlock(7, 25)),
+ new EcBlocks(30, new EcBlock(59, 16), new EcBlock(1, 17))
+ ),
+ new self(
+ 35,
+ [6, 30, 54, 78, 102, 126, 150],
+ new EcBlocks(30, new EcBlock(12, 121), new EcBlock(7, 122)),
+ new EcBlocks(28, new EcBlock(12, 47), new EcBlock(26, 48)),
+ new EcBlocks(30, new EcBlock(39, 24), new EcBlock(14, 25)),
+ new EcBlocks(30, new EcBlock(22, 15), new EcBlock(41, 16))
+ ),
+ new self(
+ 36,
+ [6, 24, 50, 76, 102, 128, 154],
+ new EcBlocks(30, new EcBlock(6, 121), new EcBlock(14, 122)),
+ new EcBlocks(28, new EcBlock(6, 47), new EcBlock(34, 48)),
+ new EcBlocks(30, new EcBlock(46, 24), new EcBlock(10, 25)),
+ new EcBlocks(30, new EcBlock(2, 15), new EcBlock(64, 16))
+ ),
+ new self(
+ 37,
+ [6, 28, 54, 80, 106, 132, 158],
+ new EcBlocks(30, new EcBlock(17, 122), new EcBlock(4, 123)),
+ new EcBlocks(28, new EcBlock(29, 46), new EcBlock(14, 47)),
+ new EcBlocks(30, new EcBlock(49, 24), new EcBlock(10, 25)),
+ new EcBlocks(30, new EcBlock(24, 15), new EcBlock(46, 16))
+ ),
+ new self(
+ 38,
+ [6, 32, 58, 84, 110, 136, 162],
+ new EcBlocks(30, new EcBlock(4, 122), new EcBlock(18, 123)),
+ new EcBlocks(28, new EcBlock(13, 46), new EcBlock(32, 47)),
+ new EcBlocks(30, new EcBlock(48, 24), new EcBlock(14, 25)),
+ new EcBlocks(30, new EcBlock(42, 15), new EcBlock(32, 16))
+ ),
+ new self(
+ 39,
+ [6, 26, 54, 82, 110, 138, 166],
+ new EcBlocks(30, new EcBlock(20, 117), new EcBlock(4, 118)),
+ new EcBlocks(28, new EcBlock(40, 47), new EcBlock(7, 48)),
+ new EcBlocks(30, new EcBlock(43, 24), new EcBlock(22, 25)),
+ new EcBlocks(30, new EcBlock(10, 15), new EcBlock(67, 16))
+ ),
+ new self(
+ 40,
+ [6, 30, 58, 86, 114, 142, 170],
+ new EcBlocks(30, new EcBlock(19, 118), new EcBlock(6, 119)),
+ new EcBlocks(28, new EcBlock(18, 47), new EcBlock(31, 48)),
+ new EcBlocks(30, new EcBlock(34, 24), new EcBlock(34, 25)),
+ new EcBlocks(30, new EcBlock(20, 15), new EcBlock(61, 16))
+ ),
+ ];
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php
new file mode 100644
index 0000000..be54afa
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php
@@ -0,0 +1,58 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Encoder;
+
+use SplFixedArray;
+
+/**
+ * Block pair.
+ */
+final class BlockPair
+{
+ /**
+ * Data bytes in the block.
+ *
+ * @var SplFixedArray<int>
+ */
+ private $dataBytes;
+
+ /**
+ * Error correction bytes in the block.
+ *
+ * @var SplFixedArray<int>
+ */
+ private $errorCorrectionBytes;
+
+ /**
+ * Creates a new block pair.
+ *
+ * @param SplFixedArray<int> $data
+ * @param SplFixedArray<int> $errorCorrection
+ */
+ public function __construct(SplFixedArray $data, SplFixedArray $errorCorrection)
+ {
+ $this->dataBytes = $data;
+ $this->errorCorrectionBytes = $errorCorrection;
+ }
+
+ /**
+ * Gets the data bytes.
+ *
+ * @return SplFixedArray<int>
+ */
+ public function getDataBytes() : SplFixedArray
+ {
+ return $this->dataBytes;
+ }
+
+ /**
+ * Gets the error correction bytes.
+ *
+ * @return SplFixedArray<int>
+ */
+ public function getErrorCorrectionBytes() : SplFixedArray
+ {
+ return $this->errorCorrectionBytes;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php
new file mode 100644
index 0000000..b58cc0a
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php
@@ -0,0 +1,150 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Encoder;
+
+use SplFixedArray;
+use Traversable;
+
+/**
+ * Byte matrix.
+ */
+final class ByteMatrix
+{
+ /**
+ * Bytes in the matrix, represented as array.
+ *
+ * @var SplFixedArray<SplFixedArray<int>>
+ */
+ private $bytes;
+
+ /**
+ * Width of the matrix.
+ *
+ * @var int
+ */
+ private $width;
+
+ /**
+ * Height of the matrix.
+ *
+ * @var int
+ */
+ private $height;
+
+ public function __construct(int $width, int $height)
+ {
+ $this->height = $height;
+ $this->width = $width;
+ $this->bytes = new SplFixedArray($height);
+
+ for ($y = 0; $y < $height; ++$y) {
+ $this->bytes[$y] = SplFixedArray::fromArray(array_fill(0, $width, 0));
+ }
+ }
+
+ /**
+ * Gets the width of the matrix.
+ */
+ public function getWidth() : int
+ {
+ return $this->width;
+ }
+
+ /**
+ * Gets the height of the matrix.
+ */
+ public function getHeight() : int
+ {
+ return $this->height;
+ }
+
+ /**
+ * Gets the internal representation of the matrix.
+ *
+ * @return SplFixedArray<SplFixedArray<int>>
+ */
+ public function getArray() : SplFixedArray
+ {
+ return $this->bytes;
+ }
+
+ /**
+ * @return Traversable<int>
+ */
+ public function getBytes() : Traversable
+ {
+ foreach ($this->bytes as $row) {
+ foreach ($row as $byte) {
+ yield $byte;
+ }
+ }
+ }
+
+ /**
+ * Gets the byte for a specific position.
+ */
+ public function get(int $x, int $y) : int
+ {
+ return $this->bytes[$y][$x];
+ }
+
+ /**
+ * Sets the byte for a specific position.
+ */
+ public function set(int $x, int $y, int $value) : void
+ {
+ $this->bytes[$y][$x] = $value;
+ }
+
+ /**
+ * Clears the matrix with a specific value.
+ */
+ public function clear(int $value) : void
+ {
+ for ($y = 0; $y < $this->height; ++$y) {
+ for ($x = 0; $x < $this->width; ++$x) {
+ $this->bytes[$y][$x] = $value;
+ }
+ }
+ }
+
+ public function __clone()
+ {
+ $this->bytes = clone $this->bytes;
+
+ foreach ($this->bytes as $index => $row) {
+ $this->bytes[$index] = clone $row;
+ }
+ }
+
+ /**
+ * Returns a string representation of the matrix.
+ */
+ public function __toString() : string
+ {
+ $result = '';
+
+ for ($y = 0; $y < $this->height; $y++) {
+ for ($x = 0; $x < $this->width; $x++) {
+ switch ($this->bytes[$y][$x]) {
+ case 0:
+ $result .= ' 0';
+ break;
+
+ case 1:
+ $result .= ' 1';
+ break;
+
+ default:
+ $result .= ' ';
+ break;
+ }
+ }
+
+ $result .= "\n";
+ }
+
+ return $result;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php
new file mode 100644
index 0000000..4345f57
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php
@@ -0,0 +1,652 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Encoder;
+
+use BaconQrCode\Common\BitArray;
+use BaconQrCode\Common\CharacterSetEci;
+use BaconQrCode\Common\ErrorCorrectionLevel;
+use BaconQrCode\Common\Mode;
+use BaconQrCode\Common\ReedSolomonCodec;
+use BaconQrCode\Common\Version;
+use BaconQrCode\Exception\WriterException;
+use SplFixedArray;
+
+/**
+ * Encoder.
+ */
+final class Encoder
+{
+ /**
+ * Default byte encoding.
+ */
+ public const DEFAULT_BYTE_MODE_ECODING = 'ISO-8859-1';
+
+ /**
+ * The original table is defined in the table 5 of JISX0510:2004 (p.19).
+ */
+ private const ALPHANUMERIC_TABLE = [
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x00-0x0f
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x10-0x1f
+ 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, // 0x20-0x2f
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, // 0x30-0x3f
+ -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 0x40-0x4f
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 0x50-0x5f
+ ];
+
+ /**
+ * Codec cache.
+ *
+ * @var array
+ */
+ private static $codecs = [];
+
+ /**
+ * Encodes "content" with the error correction level "ecLevel".
+ */
+ public static function encode(
+ string $content,
+ ErrorCorrectionLevel $ecLevel,
+ string $encoding = self::DEFAULT_BYTE_MODE_ECODING
+ ) : QrCode {
+ // Pick an encoding mode appropriate for the content. Note that this
+ // will not attempt to use multiple modes / segments even if that were
+ // more efficient. Would be nice.
+ $mode = self::chooseMode($content, $encoding);
+
+ // This will store the header information, like mode and length, as well
+ // as "header" segments like an ECI segment.
+ $headerBits = new BitArray();
+
+ // Append ECI segment if applicable
+ if (Mode::BYTE() === $mode && self::DEFAULT_BYTE_MODE_ECODING !== $encoding) {
+ $eci = CharacterSetEci::getCharacterSetEciByName($encoding);
+
+ if (null !== $eci) {
+ self::appendEci($eci, $headerBits);
+ }
+ }
+
+ // (With ECI in place,) Write the mode marker
+ self::appendModeInfo($mode, $headerBits);
+
+ // Collect data within the main segment, separately, to count its size
+ // if needed. Don't add it to main payload yet.
+ $dataBits = new BitArray();
+ self::appendBytes($content, $mode, $dataBits, $encoding);
+
+ // Hard part: need to know version to know how many bits length takes.
+ // But need to know how many bits it takes to know version. First we
+ // take a guess at version by assuming version will be the minimum, 1:
+ $provisionalBitsNeeded = $headerBits->getSize()
+ + $mode->getCharacterCountBits(Version::getVersionForNumber(1))
+ + $dataBits->getSize();
+ $provisionalVersion = self::chooseVersion($provisionalBitsNeeded, $ecLevel);
+
+ // Use that guess to calculate the right version. I am still not sure
+ // this works in 100% of cases.
+ $bitsNeeded = $headerBits->getSize()
+ + $mode->getCharacterCountBits($provisionalVersion)
+ + $dataBits->getSize();
+ $version = self::chooseVersion($bitsNeeded, $ecLevel);
+
+ $headerAndDataBits = new BitArray();
+ $headerAndDataBits->appendBitArray($headerBits);
+
+ // Find "length" of main segment and write it.
+ $numLetters = (Mode::BYTE() === $mode ? $dataBits->getSizeInBytes() : strlen($content));
+ self::appendLengthInfo($numLetters, $version, $mode, $headerAndDataBits);
+
+ // Put data together into the overall payload.
+ $headerAndDataBits->appendBitArray($dataBits);
+ $ecBlocks = $version->getEcBlocksForLevel($ecLevel);
+ $numDataBytes = $version->getTotalCodewords() - $ecBlocks->getTotalEcCodewords();
+
+ // Terminate the bits properly.
+ self::terminateBits($numDataBytes, $headerAndDataBits);
+
+ // Interleave data bits with error correction code.
+ $finalBits = self::interleaveWithEcBytes(
+ $headerAndDataBits,
+ $version->getTotalCodewords(),
+ $numDataBytes,
+ $ecBlocks->getNumBlocks()
+ );
+
+ // Choose the mask pattern.
+ $dimension = $version->getDimensionForVersion();
+ $matrix = new ByteMatrix($dimension, $dimension);
+ $maskPattern = self::chooseMaskPattern($finalBits, $ecLevel, $version, $matrix);
+
+ // Build the matrix.
+ MatrixUtil::buildMatrix($finalBits, $ecLevel, $version, $maskPattern, $matrix);
+
+ return new QrCode($mode, $ecLevel, $version, $maskPattern, $matrix);
+ }
+
+ /**
+ * Gets the alphanumeric code for a byte.
+ */
+ private static function getAlphanumericCode(int $code) : int
+ {
+ if (isset(self::ALPHANUMERIC_TABLE[$code])) {
+ return self::ALPHANUMERIC_TABLE[$code];
+ }
+
+ return -1;
+ }
+
+ /**
+ * Chooses the best mode for a given content.
+ */
+ private static function chooseMode(string $content, string $encoding = null) : Mode
+ {
+ if (null !== $encoding && 0 === strcasecmp($encoding, 'SHIFT-JIS')) {
+ return self::isOnlyDoubleByteKanji($content) ? Mode::KANJI() : Mode::BYTE();
+ }
+
+ $hasNumeric = false;
+ $hasAlphanumeric = false;
+ $contentLength = strlen($content);
+
+ for ($i = 0; $i < $contentLength; ++$i) {
+ $char = $content[$i];
+
+ if (ctype_digit($char)) {
+ $hasNumeric = true;
+ } elseif (-1 !== self::getAlphanumericCode(ord($char))) {
+ $hasAlphanumeric = true;
+ } else {
+ return Mode::BYTE();
+ }
+ }
+
+ if ($hasAlphanumeric) {
+ return Mode::ALPHANUMERIC();
+ } elseif ($hasNumeric) {
+ return Mode::NUMERIC();
+ }
+
+ return Mode::BYTE();
+ }
+
+ /**
+ * Calculates the mask penalty for a matrix.
+ */
+ private static function calculateMaskPenalty(ByteMatrix $matrix) : int
+ {
+ return (
+ MaskUtil::applyMaskPenaltyRule1($matrix)
+ + MaskUtil::applyMaskPenaltyRule2($matrix)
+ + MaskUtil::applyMaskPenaltyRule3($matrix)
+ + MaskUtil::applyMaskPenaltyRule4($matrix)
+ );
+ }
+
+ /**
+ * Checks if content only consists of double-byte kanji characters.
+ */
+ private static function isOnlyDoubleByteKanji(string $content) : bool
+ {
+ $bytes = @iconv('utf-8', 'SHIFT-JIS', $content);
+
+ if (false === $bytes) {
+ return false;
+ }
+
+ $length = strlen($bytes);
+
+ if (0 !== $length % 2) {
+ return false;
+ }
+
+ for ($i = 0; $i < $length; $i += 2) {
+ $byte = $bytes[$i] & 0xff;
+
+ if (($byte < 0x81 || $byte > 0x9f) && $byte < 0xe0 || $byte > 0xeb) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Chooses the best mask pattern for a matrix.
+ */
+ private static function chooseMaskPattern(
+ BitArray $bits,
+ ErrorCorrectionLevel $ecLevel,
+ Version $version,
+ ByteMatrix $matrix
+ ) : int {
+ $minPenalty = PHP_INT_MAX;
+ $bestMaskPattern = -1;
+
+ for ($maskPattern = 0; $maskPattern < QrCode::NUM_MASK_PATTERNS; ++$maskPattern) {
+ MatrixUtil::buildMatrix($bits, $ecLevel, $version, $maskPattern, $matrix);
+ $penalty = self::calculateMaskPenalty($matrix);
+
+ if ($penalty < $minPenalty) {
+ $minPenalty = $penalty;
+ $bestMaskPattern = $maskPattern;
+ }
+ }
+
+ return $bestMaskPattern;
+ }
+
+ /**
+ * Chooses the best version for the input.
+ *
+ * @throws WriterException if data is too big
+ */
+ private static function chooseVersion(int $numInputBits, ErrorCorrectionLevel $ecLevel) : Version
+ {
+ for ($versionNum = 1; $versionNum <= 40; ++$versionNum) {
+ $version = Version::getVersionForNumber($versionNum);
+ $numBytes = $version->getTotalCodewords();
+
+ $ecBlocks = $version->getEcBlocksForLevel($ecLevel);
+ $numEcBytes = $ecBlocks->getTotalEcCodewords();
+
+ $numDataBytes = $numBytes - $numEcBytes;
+ $totalInputBytes = intdiv($numInputBits + 8, 8);
+
+ if ($numDataBytes >= $totalInputBytes) {
+ return $version;
+ }
+ }
+
+ throw new WriterException('Data too big');
+ }
+
+ /**
+ * Terminates the bits in a bit array.
+ *
+ * @throws WriterException if data bits cannot fit in the QR code
+ * @throws WriterException if bits size does not equal the capacity
+ */
+ private static function terminateBits(int $numDataBytes, BitArray $bits) : void
+ {
+ $capacity = $numDataBytes << 3;
+
+ if ($bits->getSize() > $capacity) {
+ throw new WriterException('Data bits cannot fit in the QR code');
+ }
+
+ for ($i = 0; $i < 4 && $bits->getSize() < $capacity; ++$i) {
+ $bits->appendBit(false);
+ }
+
+ $numBitsInLastByte = $bits->getSize() & 0x7;
+
+ if ($numBitsInLastByte > 0) {
+ for ($i = $numBitsInLastByte; $i < 8; ++$i) {
+ $bits->appendBit(false);
+ }
+ }
+
+ $numPaddingBytes = $numDataBytes - $bits->getSizeInBytes();
+
+ for ($i = 0; $i < $numPaddingBytes; ++$i) {
+ $bits->appendBits(0 === ($i & 0x1) ? 0xec : 0x11, 8);
+ }
+
+ if ($bits->getSize() !== $capacity) {
+ throw new WriterException('Bits size does not equal capacity');
+ }
+ }
+
+ /**
+ * Gets number of data- and EC bytes for a block ID.
+ *
+ * @return int[]
+ * @throws WriterException if block ID is too large
+ * @throws WriterException if EC bytes mismatch
+ * @throws WriterException if RS blocks mismatch
+ * @throws WriterException if total bytes mismatch
+ */
+ private static function getNumDataBytesAndNumEcBytesForBlockId(
+ int $numTotalBytes,
+ int $numDataBytes,
+ int $numRsBlocks,
+ int $blockId
+ ) : array {
+ if ($blockId >= $numRsBlocks) {
+ throw new WriterException('Block ID too large');
+ }
+
+ $numRsBlocksInGroup2 = $numTotalBytes % $numRsBlocks;
+ $numRsBlocksInGroup1 = $numRsBlocks - $numRsBlocksInGroup2;
+ $numTotalBytesInGroup1 = intdiv($numTotalBytes, $numRsBlocks);
+ $numTotalBytesInGroup2 = $numTotalBytesInGroup1 + 1;
+ $numDataBytesInGroup1 = intdiv($numDataBytes, $numRsBlocks);
+ $numDataBytesInGroup2 = $numDataBytesInGroup1 + 1;
+ $numEcBytesInGroup1 = $numTotalBytesInGroup1 - $numDataBytesInGroup1;
+ $numEcBytesInGroup2 = $numTotalBytesInGroup2 - $numDataBytesInGroup2;
+
+ if ($numEcBytesInGroup1 !== $numEcBytesInGroup2) {
+ throw new WriterException('EC bytes mismatch');
+ }
+
+ if ($numRsBlocks !== $numRsBlocksInGroup1 + $numRsBlocksInGroup2) {
+ throw new WriterException('RS blocks mismatch');
+ }
+
+ if ($numTotalBytes !==
+ (($numDataBytesInGroup1 + $numEcBytesInGroup1) * $numRsBlocksInGroup1)
+ + (($numDataBytesInGroup2 + $numEcBytesInGroup2) * $numRsBlocksInGroup2)
+ ) {
+ throw new WriterException('Total bytes mismatch');
+ }
+
+ if ($blockId < $numRsBlocksInGroup1) {
+ return [$numDataBytesInGroup1, $numEcBytesInGroup1];
+ } else {
+ return [$numDataBytesInGroup2, $numEcBytesInGroup2];
+ }
+ }
+
+ /**
+ * Interleaves data with EC bytes.
+ *
+ * @throws WriterException if number of bits and data bytes does not match
+ * @throws WriterException if data bytes does not match offset
+ * @throws WriterException if an interleaving error occurs
+ */
+ private static function interleaveWithEcBytes(
+ BitArray $bits,
+ int $numTotalBytes,
+ int $numDataBytes,
+ int $numRsBlocks
+ ) : BitArray {
+ if ($bits->getSizeInBytes() !== $numDataBytes) {
+ throw new WriterException('Number of bits and data bytes does not match');
+ }
+
+ $dataBytesOffset = 0;
+ $maxNumDataBytes = 0;
+ $maxNumEcBytes = 0;
+
+ $blocks = new SplFixedArray($numRsBlocks);
+
+ for ($i = 0; $i < $numRsBlocks; ++$i) {
+ list($numDataBytesInBlock, $numEcBytesInBlock) = self::getNumDataBytesAndNumEcBytesForBlockId(
+ $numTotalBytes,
+ $numDataBytes,
+ $numRsBlocks,
+ $i
+ );
+
+ $size = $numDataBytesInBlock;
+ $dataBytes = $bits->toBytes(8 * $dataBytesOffset, $size);
+ $ecBytes = self::generateEcBytes($dataBytes, $numEcBytesInBlock);
+ $blocks[$i] = new BlockPair($dataBytes, $ecBytes);
+
+ $maxNumDataBytes = max($maxNumDataBytes, $size);
+ $maxNumEcBytes = max($maxNumEcBytes, count($ecBytes));
+ $dataBytesOffset += $numDataBytesInBlock;
+ }
+
+ if ($numDataBytes !== $dataBytesOffset) {
+ throw new WriterException('Data bytes does not match offset');
+ }
+
+ $result = new BitArray();
+
+ for ($i = 0; $i < $maxNumDataBytes; ++$i) {
+ foreach ($blocks as $block) {
+ $dataBytes = $block->getDataBytes();
+
+ if ($i < count($dataBytes)) {
+ $result->appendBits($dataBytes[$i], 8);
+ }
+ }
+ }
+
+ for ($i = 0; $i < $maxNumEcBytes; ++$i) {
+ foreach ($blocks as $block) {
+ $ecBytes = $block->getErrorCorrectionBytes();
+
+ if ($i < count($ecBytes)) {
+ $result->appendBits($ecBytes[$i], 8);
+ }
+ }
+ }
+
+ if ($numTotalBytes !== $result->getSizeInBytes()) {
+ throw new WriterException(
+ 'Interleaving error: ' . $numTotalBytes . ' and ' . $result->getSizeInBytes() . ' differ'
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Generates EC bytes for given data.
+ *
+ * @param SplFixedArray<int> $dataBytes
+ * @return SplFixedArray<int>
+ */
+ private static function generateEcBytes(SplFixedArray $dataBytes, int $numEcBytesInBlock) : SplFixedArray
+ {
+ $numDataBytes = count($dataBytes);
+ $toEncode = new SplFixedArray($numDataBytes + $numEcBytesInBlock);
+
+ for ($i = 0; $i < $numDataBytes; $i++) {
+ $toEncode[$i] = $dataBytes[$i] & 0xff;
+ }
+
+ $ecBytes = new SplFixedArray($numEcBytesInBlock);
+ $codec = self::getCodec($numDataBytes, $numEcBytesInBlock);
+ $codec->encode($toEncode, $ecBytes);
+
+ return $ecBytes;
+ }
+
+ /**
+ * Gets an RS codec and caches it.
+ */
+ private static function getCodec(int $numDataBytes, int $numEcBytesInBlock) : ReedSolomonCodec
+ {
+ $cacheId = $numDataBytes . '-' . $numEcBytesInBlock;
+
+ if (isset(self::$codecs[$cacheId])) {
+ return self::$codecs[$cacheId];
+ }
+
+ return self::$codecs[$cacheId] = new ReedSolomonCodec(
+ 8,
+ 0x11d,
+ 0,
+ 1,
+ $numEcBytesInBlock,
+ 255 - $numDataBytes - $numEcBytesInBlock
+ );
+ }
+
+ /**
+ * Appends mode information to a bit array.
+ */
+ private static function appendModeInfo(Mode $mode, BitArray $bits) : void
+ {
+ $bits->appendBits($mode->getBits(), 4);
+ }
+
+ /**
+ * Appends length information to a bit array.
+ *
+ * @throws WriterException if num letters is bigger than expected
+ */
+ private static function appendLengthInfo(int $numLetters, Version $version, Mode $mode, BitArray $bits) : void
+ {
+ $numBits = $mode->getCharacterCountBits($version);
+
+ if ($numLetters >= (1 << $numBits)) {
+ throw new WriterException($numLetters . ' is bigger than ' . ((1 << $numBits) - 1));
+ }
+
+ $bits->appendBits($numLetters, $numBits);
+ }
+
+ /**
+ * Appends bytes to a bit array in a specific mode.
+ *
+ * @throws WriterException if an invalid mode was supplied
+ */
+ private static function appendBytes(string $content, Mode $mode, BitArray $bits, string $encoding) : void
+ {
+ switch ($mode) {
+ case Mode::NUMERIC():
+ self::appendNumericBytes($content, $bits);
+ break;
+
+ case Mode::ALPHANUMERIC():
+ self::appendAlphanumericBytes($content, $bits);
+ break;
+
+ case Mode::BYTE():
+ self::append8BitBytes($content, $bits, $encoding);
+ break;
+
+ case Mode::KANJI():
+ self::appendKanjiBytes($content, $bits);
+ break;
+
+ default:
+ throw new WriterException('Invalid mode: ' . $mode);
+ }
+ }
+
+ /**
+ * Appends numeric bytes to a bit array.
+ */
+ private static function appendNumericBytes(string $content, BitArray $bits) : void
+ {
+ $length = strlen($content);
+ $i = 0;
+
+ while ($i < $length) {
+ $num1 = (int) $content[$i];
+
+ if ($i + 2 < $length) {
+ // Encode three numeric letters in ten bits.
+ $num2 = (int) $content[$i + 1];
+ $num3 = (int) $content[$i + 2];
+ $bits->appendBits($num1 * 100 + $num2 * 10 + $num3, 10);
+ $i += 3;
+ } elseif ($i + 1 < $length) {
+ // Encode two numeric letters in seven bits.
+ $num2 = (int) $content[$i + 1];
+ $bits->appendBits($num1 * 10 + $num2, 7);
+ $i += 2;
+ } else {
+ // Encode one numeric letter in four bits.
+ $bits->appendBits($num1, 4);
+ ++$i;
+ }
+ }
+ }
+
+ /**
+ * Appends alpha-numeric bytes to a bit array.
+ *
+ * @throws WriterException if an invalid alphanumeric code was found
+ */
+ private static function appendAlphanumericBytes(string $content, BitArray $bits) : void
+ {
+ $length = strlen($content);
+ $i = 0;
+
+ while ($i < $length) {
+ $code1 = self::getAlphanumericCode(ord($content[$i]));
+
+ if (-1 === $code1) {
+ throw new WriterException('Invalid alphanumeric code');
+ }
+
+ if ($i + 1 < $length) {
+ $code2 = self::getAlphanumericCode(ord($content[$i + 1]));
+
+ if (-1 === $code2) {
+ throw new WriterException('Invalid alphanumeric code');
+ }
+
+ // Encode two alphanumeric letters in 11 bits.
+ $bits->appendBits($code1 * 45 + $code2, 11);
+ $i += 2;
+ } else {
+ // Encode one alphanumeric letter in six bits.
+ $bits->appendBits($code1, 6);
+ ++$i;
+ }
+ }
+ }
+
+ /**
+ * Appends regular 8-bit bytes to a bit array.
+ *
+ * @throws WriterException if content cannot be encoded to target encoding
+ */
+ private static function append8BitBytes(string $content, BitArray $bits, string $encoding) : void
+ {
+ $bytes = @iconv('utf-8', $encoding, $content);
+
+ if (false === $bytes) {
+ throw new WriterException('Could not encode content to ' . $encoding);
+ }
+
+ $length = strlen($bytes);
+
+ for ($i = 0; $i < $length; $i++) {
+ $bits->appendBits(ord($bytes[$i]), 8);
+ }
+ }
+
+ /**
+ * Appends KANJI bytes to a bit array.
+ *
+ * @throws WriterException if content does not seem to be encoded in SHIFT-JIS
+ * @throws WriterException if an invalid byte sequence occurs
+ */
+ private static function appendKanjiBytes(string $content, BitArray $bits) : void
+ {
+ if (strlen($content) % 2 > 0) {
+ // We just do a simple length check here. The for loop will check
+ // individual characters.
+ throw new WriterException('Content does not seem to be encoded in SHIFT-JIS');
+ }
+
+ $length = strlen($content);
+
+ for ($i = 0; $i < $length; $i += 2) {
+ $byte1 = ord($content[$i]) & 0xff;
+ $byte2 = ord($content[$i + 1]) & 0xff;
+ $code = ($byte1 << 8) | $byte2;
+
+ if ($code >= 0x8140 && $code <= 0x9ffc) {
+ $subtracted = $code - 0x8140;
+ } elseif ($code >= 0xe040 && $code <= 0xebbf) {
+ $subtracted = $code - 0xc140;
+ } else {
+ throw new WriterException('Invalid byte sequence');
+ }
+
+ $encoded = (($subtracted >> 8) * 0xc0) + ($subtracted & 0xff);
+
+ $bits->appendBits($encoded, 13);
+ }
+ }
+
+ /**
+ * Appends ECI information to a bit array.
+ */
+ private static function appendEci(CharacterSetEci $eci, BitArray $bits) : void
+ {
+ $mode = Mode::ECI();
+ $bits->appendBits($mode->getBits(), 4);
+ $bits->appendBits($eci->getValue(), 8);
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php
new file mode 100644
index 0000000..3baddbd
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php
@@ -0,0 +1,271 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Encoder;
+
+use BaconQrCode\Common\BitUtils;
+use BaconQrCode\Exception\InvalidArgumentException;
+
+/**
+ * Mask utility.
+ */
+final class MaskUtil
+{
+ /**#@+
+ * Penalty weights from section 6.8.2.1
+ */
+ const N1 = 3;
+ const N2 = 3;
+ const N3 = 40;
+ const N4 = 10;
+ /**#@-*/
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * Applies mask penalty rule 1 and returns the penalty.
+ *
+ * Finds repetitive cells with the same color and gives penalty to them.
+ * Example: 00000 or 11111.
+ */
+ public static function applyMaskPenaltyRule1(ByteMatrix $matrix) : int
+ {
+ return (
+ self::applyMaskPenaltyRule1Internal($matrix, true)
+ + self::applyMaskPenaltyRule1Internal($matrix, false)
+ );
+ }
+
+ /**
+ * Applies mask penalty rule 2 and returns the penalty.
+ *
+ * Finds 2x2 blocks with the same color and gives penalty to them. This is
+ * actually equivalent to the spec's rule, which is to find MxN blocks and
+ * give a penalty proportional to (M-1)x(N-1), because this is the number of
+ * 2x2 blocks inside such a block.
+ */
+ public static function applyMaskPenaltyRule2(ByteMatrix $matrix) : int
+ {
+ $penalty = 0;
+ $array = $matrix->getArray();
+ $width = $matrix->getWidth();
+ $height = $matrix->getHeight();
+
+ for ($y = 0; $y < $height - 1; ++$y) {
+ for ($x = 0; $x < $width - 1; ++$x) {
+ $value = $array[$y][$x];
+
+ if ($value === $array[$y][$x + 1]
+ && $value === $array[$y + 1][$x]
+ && $value === $array[$y + 1][$x + 1]
+ ) {
+ ++$penalty;
+ }
+ }
+ }
+
+ return self::N2 * $penalty;
+ }
+
+ /**
+ * Applies mask penalty rule 3 and returns the penalty.
+ *
+ * Finds consecutive cells of 00001011101 or 10111010000, and gives penalty
+ * to them. If we find patterns like 000010111010000, we give penalties
+ * twice (i.e. 40 * 2).
+ */
+ public static function applyMaskPenaltyRule3(ByteMatrix $matrix) : int
+ {
+ $penalty = 0;
+ $array = $matrix->getArray();
+ $width = $matrix->getWidth();
+ $height = $matrix->getHeight();
+
+ for ($y = 0; $y < $height; ++$y) {
+ for ($x = 0; $x < $width; ++$x) {
+ if ($x + 6 < $width
+ && 1 === $array[$y][$x]
+ && 0 === $array[$y][$x + 1]
+ && 1 === $array[$y][$x + 2]
+ && 1 === $array[$y][$x + 3]
+ && 1 === $array[$y][$x + 4]
+ && 0 === $array[$y][$x + 5]
+ && 1 === $array[$y][$x + 6]
+ && (
+ (
+ $x + 10 < $width
+ && 0 === $array[$y][$x + 7]
+ && 0 === $array[$y][$x + 8]
+ && 0 === $array[$y][$x + 9]
+ && 0 === $array[$y][$x + 10]
+ )
+ || (
+ $x - 4 >= 0
+ && 0 === $array[$y][$x - 1]
+ && 0 === $array[$y][$x - 2]
+ && 0 === $array[$y][$x - 3]
+ && 0 === $array[$y][$x - 4]
+ )
+ )
+ ) {
+ $penalty += self::N3;
+ }
+
+ if ($y + 6 < $height
+ && 1 === $array[$y][$x]
+ && 0 === $array[$y + 1][$x]
+ && 1 === $array[$y + 2][$x]
+ && 1 === $array[$y + 3][$x]
+ && 1 === $array[$y + 4][$x]
+ && 0 === $array[$y + 5][$x]
+ && 1 === $array[$y + 6][$x]
+ && (
+ (
+ $y + 10 < $height
+ && 0 === $array[$y + 7][$x]
+ && 0 === $array[$y + 8][$x]
+ && 0 === $array[$y + 9][$x]
+ && 0 === $array[$y + 10][$x]
+ )
+ || (
+ $y - 4 >= 0
+ && 0 === $array[$y - 1][$x]
+ && 0 === $array[$y - 2][$x]
+ && 0 === $array[$y - 3][$x]
+ && 0 === $array[$y - 4][$x]
+ )
+ )
+ ) {
+ $penalty += self::N3;
+ }
+ }
+ }
+
+ return $penalty;
+ }
+
+ /**
+ * Applies mask penalty rule 4 and returns the penalty.
+ *
+ * Calculates the ratio of dark cells and gives penalty if the ratio is far
+ * from 50%. It gives 10 penalty for 5% distance.
+ */
+ public static function applyMaskPenaltyRule4(ByteMatrix $matrix) : int
+ {
+ $numDarkCells = 0;
+
+ $array = $matrix->getArray();
+ $width = $matrix->getWidth();
+ $height = $matrix->getHeight();
+
+ for ($y = 0; $y < $height; ++$y) {
+ $arrayY = $array[$y];
+
+ for ($x = 0; $x < $width; ++$x) {
+ if (1 === $arrayY[$x]) {
+ ++$numDarkCells;
+ }
+ }
+ }
+
+ $numTotalCells = $height * $width;
+ $darkRatio = $numDarkCells / $numTotalCells;
+ $fixedPercentVariances = (int) (abs($darkRatio - 0.5) * 20);
+
+ return $fixedPercentVariances * self::N4;
+ }
+
+ /**
+ * Returns the mask bit for "getMaskPattern" at "x" and "y".
+ *
+ * See 8.8 of JISX0510:2004 for mask pattern conditions.
+ *
+ * @throws InvalidArgumentException if an invalid mask pattern was supplied
+ */
+ public static function getDataMaskBit(int $maskPattern, int $x, int $y) : bool
+ {
+ switch ($maskPattern) {
+ case 0:
+ $intermediate = ($y + $x) & 0x1;
+ break;
+
+ case 1:
+ $intermediate = $y & 0x1;
+ break;
+
+ case 2:
+ $intermediate = $x % 3;
+ break;
+
+ case 3:
+ $intermediate = ($y + $x) % 3;
+ break;
+
+ case 4:
+ $intermediate = (BitUtils::unsignedRightShift($y, 1) + ($x / 3)) & 0x1;
+ break;
+
+ case 5:
+ $temp = $y * $x;
+ $intermediate = ($temp & 0x1) + ($temp % 3);
+ break;
+
+ case 6:
+ $temp = $y * $x;
+ $intermediate = (($temp & 0x1) + ($temp % 3)) & 0x1;
+ break;
+
+ case 7:
+ $temp = $y * $x;
+ $intermediate = (($temp % 3) + (($y + $x) & 0x1)) & 0x1;
+ break;
+
+ default:
+ throw new InvalidArgumentException('Invalid mask pattern: ' . $maskPattern);
+ }
+
+ return 0 == $intermediate;
+ }
+
+ /**
+ * Helper function for applyMaskPenaltyRule1.
+ *
+ * We need this for doing this calculation in both vertical and horizontal
+ * orders respectively.
+ */
+ private static function applyMaskPenaltyRule1Internal(ByteMatrix $matrix, bool $isHorizontal) : int
+ {
+ $penalty = 0;
+ $iLimit = $isHorizontal ? $matrix->getHeight() : $matrix->getWidth();
+ $jLimit = $isHorizontal ? $matrix->getWidth() : $matrix->getHeight();
+ $array = $matrix->getArray();
+
+ for ($i = 0; $i < $iLimit; ++$i) {
+ $numSameBitCells = 0;
+ $prevBit = -1;
+
+ for ($j = 0; $j < $jLimit; $j++) {
+ $bit = $isHorizontal ? $array[$i][$j] : $array[$j][$i];
+
+ if ($bit === $prevBit) {
+ ++$numSameBitCells;
+ } else {
+ if ($numSameBitCells >= 5) {
+ $penalty += self::N1 + ($numSameBitCells - 5);
+ }
+
+ $numSameBitCells = 1;
+ $prevBit = $bit;
+ }
+ }
+
+ if ($numSameBitCells >= 5) {
+ $penalty += self::N1 + ($numSameBitCells - 5);
+ }
+ }
+
+ return $penalty;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php
new file mode 100644
index 0000000..0967e29
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php
@@ -0,0 +1,513 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Encoder;
+
+use BaconQrCode\Common\BitArray;
+use BaconQrCode\Common\ErrorCorrectionLevel;
+use BaconQrCode\Common\Version;
+use BaconQrCode\Exception\RuntimeException;
+use BaconQrCode\Exception\WriterException;
+
+/**
+ * Matrix utility.
+ */
+final class MatrixUtil
+{
+ /**
+ * Position detection pattern.
+ */
+ private const POSITION_DETECTION_PATTERN = [
+ [1, 1, 1, 1, 1, 1, 1],
+ [1, 0, 0, 0, 0, 0, 1],
+ [1, 0, 1, 1, 1, 0, 1],
+ [1, 0, 1, 1, 1, 0, 1],
+ [1, 0, 1, 1, 1, 0, 1],
+ [1, 0, 0, 0, 0, 0, 1],
+ [1, 1, 1, 1, 1, 1, 1],
+ ];
+
+ /**
+ * Position adjustment pattern.
+ */
+ private const POSITION_ADJUSTMENT_PATTERN = [
+ [1, 1, 1, 1, 1],
+ [1, 0, 0, 0, 1],
+ [1, 0, 1, 0, 1],
+ [1, 0, 0, 0, 1],
+ [1, 1, 1, 1, 1],
+ ];
+
+ /**
+ * Coordinates for position adjustment patterns for each version.
+ */
+ private const POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE = [
+ [null, null, null, null, null, null, null], // Version 1
+ [ 6, 18, null, null, null, null, null], // Version 2
+ [ 6, 22, null, null, null, null, null], // Version 3
+ [ 6, 26, null, null, null, null, null], // Version 4
+ [ 6, 30, null, null, null, null, null], // Version 5
+ [ 6, 34, null, null, null, null, null], // Version 6
+ [ 6, 22, 38, null, null, null, null], // Version 7
+ [ 6, 24, 42, null, null, null, null], // Version 8
+ [ 6, 26, 46, null, null, null, null], // Version 9
+ [ 6, 28, 50, null, null, null, null], // Version 10
+ [ 6, 30, 54, null, null, null, null], // Version 11
+ [ 6, 32, 58, null, null, null, null], // Version 12
+ [ 6, 34, 62, null, null, null, null], // Version 13
+ [ 6, 26, 46, 66, null, null, null], // Version 14
+ [ 6, 26, 48, 70, null, null, null], // Version 15
+ [ 6, 26, 50, 74, null, null, null], // Version 16
+ [ 6, 30, 54, 78, null, null, null], // Version 17
+ [ 6, 30, 56, 82, null, null, null], // Version 18
+ [ 6, 30, 58, 86, null, null, null], // Version 19
+ [ 6, 34, 62, 90, null, null, null], // Version 20
+ [ 6, 28, 50, 72, 94, null, null], // Version 21
+ [ 6, 26, 50, 74, 98, null, null], // Version 22
+ [ 6, 30, 54, 78, 102, null, null], // Version 23
+ [ 6, 28, 54, 80, 106, null, null], // Version 24
+ [ 6, 32, 58, 84, 110, null, null], // Version 25
+ [ 6, 30, 58, 86, 114, null, null], // Version 26
+ [ 6, 34, 62, 90, 118, null, null], // Version 27
+ [ 6, 26, 50, 74, 98, 122, null], // Version 28
+ [ 6, 30, 54, 78, 102, 126, null], // Version 29
+ [ 6, 26, 52, 78, 104, 130, null], // Version 30
+ [ 6, 30, 56, 82, 108, 134, null], // Version 31
+ [ 6, 34, 60, 86, 112, 138, null], // Version 32
+ [ 6, 30, 58, 86, 114, 142, null], // Version 33
+ [ 6, 34, 62, 90, 118, 146, null], // Version 34
+ [ 6, 30, 54, 78, 102, 126, 150], // Version 35
+ [ 6, 24, 50, 76, 102, 128, 154], // Version 36
+ [ 6, 28, 54, 80, 106, 132, 158], // Version 37
+ [ 6, 32, 58, 84, 110, 136, 162], // Version 38
+ [ 6, 26, 54, 82, 110, 138, 166], // Version 39
+ [ 6, 30, 58, 86, 114, 142, 170], // Version 40
+ ];
+
+ /**
+ * Type information coordinates.
+ */
+ private const TYPE_INFO_COORDINATES = [
+ [8, 0],
+ [8, 1],
+ [8, 2],
+ [8, 3],
+ [8, 4],
+ [8, 5],
+ [8, 7],
+ [8, 8],
+ [7, 8],
+ [5, 8],
+ [4, 8],
+ [3, 8],
+ [2, 8],
+ [1, 8],
+ [0, 8],
+ ];
+
+ /**
+ * Version information polynomial.
+ */
+ private const VERSION_INFO_POLY = 0x1f25;
+
+ /**
+ * Type information polynomial.
+ */
+ private const TYPE_INFO_POLY = 0x537;
+
+ /**
+ * Type information mask pattern.
+ */
+ private const TYPE_INFO_MASK_PATTERN = 0x5412;
+
+ /**
+ * Clears a given matrix.
+ */
+ public static function clearMatrix(ByteMatrix $matrix) : void
+ {
+ $matrix->clear(-1);
+ }
+
+ /**
+ * Builds a complete matrix.
+ */
+ public static function buildMatrix(
+ BitArray $dataBits,
+ ErrorCorrectionLevel $level,
+ Version $version,
+ int $maskPattern,
+ ByteMatrix $matrix
+ ) : void {
+ self::clearMatrix($matrix);
+ self::embedBasicPatterns($version, $matrix);
+ self::embedTypeInfo($level, $maskPattern, $matrix);
+ self::maybeEmbedVersionInfo($version, $matrix);
+ self::embedDataBits($dataBits, $maskPattern, $matrix);
+ }
+
+ /**
+ * Removes the position detection patterns from a matrix.
+ *
+ * This can be useful if you need to render those patterns separately.
+ */
+ public static function removePositionDetectionPatterns(ByteMatrix $matrix) : void
+ {
+ $pdpWidth = count(self::POSITION_DETECTION_PATTERN[0]);
+
+ self::removePositionDetectionPattern(0, 0, $matrix);
+ self::removePositionDetectionPattern($matrix->getWidth() - $pdpWidth, 0, $matrix);
+ self::removePositionDetectionPattern(0, $matrix->getWidth() - $pdpWidth, $matrix);
+ }
+
+ /**
+ * Embeds type information into a matrix.
+ */
+ private static function embedTypeInfo(ErrorCorrectionLevel $level, int $maskPattern, ByteMatrix $matrix) : void
+ {
+ $typeInfoBits = new BitArray();
+ self::makeTypeInfoBits($level, $maskPattern, $typeInfoBits);
+
+ $typeInfoBitsSize = $typeInfoBits->getSize();
+
+ for ($i = 0; $i < $typeInfoBitsSize; ++$i) {
+ $bit = $typeInfoBits->get($typeInfoBitsSize - 1 - $i);
+
+ $x1 = self::TYPE_INFO_COORDINATES[$i][0];
+ $y1 = self::TYPE_INFO_COORDINATES[$i][1];
+
+ $matrix->set($x1, $y1, (int) $bit);
+
+ if ($i < 8) {
+ $x2 = $matrix->getWidth() - $i - 1;
+ $y2 = 8;
+ } else {
+ $x2 = 8;
+ $y2 = $matrix->getHeight() - 7 + ($i - 8);
+ }
+
+ $matrix->set($x2, $y2, (int) $bit);
+ }
+ }
+
+ /**
+ * Generates type information bits and appends them to a bit array.
+ *
+ * @throws RuntimeException if bit array resulted in invalid size
+ */
+ private static function makeTypeInfoBits(ErrorCorrectionLevel $level, int $maskPattern, BitArray $bits) : void
+ {
+ $typeInfo = ($level->getBits() << 3) | $maskPattern;
+ $bits->appendBits($typeInfo, 5);
+
+ $bchCode = self::calculateBchCode($typeInfo, self::TYPE_INFO_POLY);
+ $bits->appendBits($bchCode, 10);
+
+ $maskBits = new BitArray();
+ $maskBits->appendBits(self::TYPE_INFO_MASK_PATTERN, 15);
+ $bits->xorBits($maskBits);
+
+ if (15 !== $bits->getSize()) {
+ throw new RuntimeException('Bit array resulted in invalid size: ' . $bits->getSize());
+ }
+ }
+
+ /**
+ * Embeds version information if required.
+ */
+ private static function maybeEmbedVersionInfo(Version $version, ByteMatrix $matrix) : void
+ {
+ if ($version->getVersionNumber() < 7) {
+ return;
+ }
+
+ $versionInfoBits = new BitArray();
+ self::makeVersionInfoBits($version, $versionInfoBits);
+
+ $bitIndex = 6 * 3 - 1;
+
+ for ($i = 0; $i < 6; ++$i) {
+ for ($j = 0; $j < 3; ++$j) {
+ $bit = $versionInfoBits->get($bitIndex);
+ --$bitIndex;
+
+ $matrix->set($i, $matrix->getHeight() - 11 + $j, (int) $bit);
+ $matrix->set($matrix->getHeight() - 11 + $j, $i, (int) $bit);
+ }
+ }
+ }
+
+ /**
+ * Generates version information bits and appends them to a bit array.
+ *
+ * @throws RuntimeException if bit array resulted in invalid size
+ */
+ private static function makeVersionInfoBits(Version $version, BitArray $bits) : void
+ {
+ $bits->appendBits($version->getVersionNumber(), 6);
+
+ $bchCode = self::calculateBchCode($version->getVersionNumber(), self::VERSION_INFO_POLY);
+ $bits->appendBits($bchCode, 12);
+
+ if (18 !== $bits->getSize()) {
+ throw new RuntimeException('Bit array resulted in invalid size: ' . $bits->getSize());
+ }
+ }
+
+ /**
+ * Calculates the BCH code for a value and a polynomial.
+ */
+ private static function calculateBchCode(int $value, int $poly) : int
+ {
+ $msbSetInPoly = self::findMsbSet($poly);
+ $value <<= $msbSetInPoly - 1;
+
+ while (self::findMsbSet($value) >= $msbSetInPoly) {
+ $value ^= $poly << (self::findMsbSet($value) - $msbSetInPoly);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Finds and MSB set.
+ */
+ private static function findMsbSet(int $value) : int
+ {
+ $numDigits = 0;
+
+ while (0 !== $value) {
+ $value >>= 1;
+ ++$numDigits;
+ }
+
+ return $numDigits;
+ }
+
+ /**
+ * Embeds basic patterns into a matrix.
+ */
+ private static function embedBasicPatterns(Version $version, ByteMatrix $matrix) : void
+ {
+ self::embedPositionDetectionPatternsAndSeparators($matrix);
+ self::embedDarkDotAtLeftBottomCorner($matrix);
+ self::maybeEmbedPositionAdjustmentPatterns($version, $matrix);
+ self::embedTimingPatterns($matrix);
+ }
+
+ /**
+ * Embeds position detection patterns and separators into a byte matrix.
+ */
+ private static function embedPositionDetectionPatternsAndSeparators(ByteMatrix $matrix) : void
+ {
+ $pdpWidth = count(self::POSITION_DETECTION_PATTERN[0]);
+
+ self::embedPositionDetectionPattern(0, 0, $matrix);
+ self::embedPositionDetectionPattern($matrix->getWidth() - $pdpWidth, 0, $matrix);
+ self::embedPositionDetectionPattern(0, $matrix->getWidth() - $pdpWidth, $matrix);
+
+ $hspWidth = 8;
+
+ self::embedHorizontalSeparationPattern(0, $hspWidth - 1, $matrix);
+ self::embedHorizontalSeparationPattern($matrix->getWidth() - $hspWidth, $hspWidth - 1, $matrix);
+ self::embedHorizontalSeparationPattern(0, $matrix->getWidth() - $hspWidth, $matrix);
+
+ $vspSize = 7;
+
+ self::embedVerticalSeparationPattern($vspSize, 0, $matrix);
+ self::embedVerticalSeparationPattern($matrix->getHeight() - $vspSize - 1, 0, $matrix);
+ self::embedVerticalSeparationPattern($vspSize, $matrix->getHeight() - $vspSize, $matrix);
+ }
+
+ /**
+ * Embeds a single position detection pattern into a byte matrix.
+ */
+ private static function embedPositionDetectionPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void
+ {
+ for ($y = 0; $y < 7; ++$y) {
+ for ($x = 0; $x < 7; ++$x) {
+ $matrix->set($xStart + $x, $yStart + $y, self::POSITION_DETECTION_PATTERN[$y][$x]);
+ }
+ }
+ }
+
+ private static function removePositionDetectionPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void
+ {
+ for ($y = 0; $y < 7; ++$y) {
+ for ($x = 0; $x < 7; ++$x) {
+ $matrix->set($xStart + $x, $yStart + $y, 0);
+ }
+ }
+ }
+
+ /**
+ * Embeds a single horizontal separation pattern.
+ *
+ * @throws RuntimeException if a byte was already set
+ */
+ private static function embedHorizontalSeparationPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void
+ {
+ for ($x = 0; $x < 8; $x++) {
+ if (-1 !== $matrix->get($xStart + $x, $yStart)) {
+ throw new RuntimeException('Byte already set');
+ }
+
+ $matrix->set($xStart + $x, $yStart, 0);
+ }
+ }
+
+ /**
+ * Embeds a single vertical separation pattern.
+ *
+ * @throws RuntimeException if a byte was already set
+ */
+ private static function embedVerticalSeparationPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void
+ {
+ for ($y = 0; $y < 7; $y++) {
+ if (-1 !== $matrix->get($xStart, $yStart + $y)) {
+ throw new RuntimeException('Byte already set');
+ }
+
+ $matrix->set($xStart, $yStart + $y, 0);
+ }
+ }
+
+ /**
+ * Embeds a dot at the left bottom corner.
+ *
+ * @throws RuntimeException if a byte was already set to 0
+ */
+ private static function embedDarkDotAtLeftBottomCorner(ByteMatrix $matrix) : void
+ {
+ if (0 === $matrix->get(8, $matrix->getHeight() - 8)) {
+ throw new RuntimeException('Byte already set to 0');
+ }
+
+ $matrix->set(8, $matrix->getHeight() - 8, 1);
+ }
+
+ /**
+ * Embeds position adjustment patterns if required.
+ */
+ private static function maybeEmbedPositionAdjustmentPatterns(Version $version, ByteMatrix $matrix) : void
+ {
+ if ($version->getVersionNumber() < 2) {
+ return;
+ }
+
+ $index = $version->getVersionNumber() - 1;
+
+ $coordinates = self::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[$index];
+ $numCoordinates = count($coordinates);
+
+ for ($i = 0; $i < $numCoordinates; ++$i) {
+ for ($j = 0; $j < $numCoordinates; ++$j) {
+ $y = $coordinates[$i];
+ $x = $coordinates[$j];
+
+ if (null === $x || null === $y) {
+ continue;
+ }
+
+ if (-1 === $matrix->get($x, $y)) {
+ self::embedPositionAdjustmentPattern($x - 2, $y - 2, $matrix);
+ }
+ }
+ }
+ }
+
+ /**
+ * Embeds a single position adjustment pattern.
+ */
+ private static function embedPositionAdjustmentPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void
+ {
+ for ($y = 0; $y < 5; $y++) {
+ for ($x = 0; $x < 5; $x++) {
+ $matrix->set($xStart + $x, $yStart + $y, self::POSITION_ADJUSTMENT_PATTERN[$y][$x]);
+ }
+ }
+ }
+
+ /**
+ * Embeds timing patterns into a matrix.
+ */
+ private static function embedTimingPatterns(ByteMatrix $matrix) : void
+ {
+ $matrixWidth = $matrix->getWidth();
+
+ for ($i = 8; $i < $matrixWidth - 8; ++$i) {
+ $bit = ($i + 1) % 2;
+
+ if (-1 === $matrix->get($i, 6)) {
+ $matrix->set($i, 6, $bit);
+ }
+
+ if (-1 === $matrix->get(6, $i)) {
+ $matrix->set(6, $i, $bit);
+ }
+ }
+ }
+
+ /**
+ * Embeds "dataBits" using "getMaskPattern".
+ *
+ * For debugging purposes, it skips masking process if "getMaskPattern" is -1. See 8.7 of JISX0510:2004 (p.38) for
+ * how to embed data bits.
+ *
+ * @throws WriterException if not all bits could be consumed
+ */
+ private static function embedDataBits(BitArray $dataBits, int $maskPattern, ByteMatrix $matrix) : void
+ {
+ $bitIndex = 0;
+ $direction = -1;
+
+ // Start from the right bottom cell.
+ $x = $matrix->getWidth() - 1;
+ $y = $matrix->getHeight() - 1;
+
+ while ($x > 0) {
+ // Skip vertical timing pattern.
+ if (6 === $x) {
+ --$x;
+ }
+
+ while ($y >= 0 && $y < $matrix->getHeight()) {
+ for ($i = 0; $i < 2; $i++) {
+ $xx = $x - $i;
+
+ // Skip the cell if it's not empty.
+ if (-1 !== $matrix->get($xx, $y)) {
+ continue;
+ }
+
+ if ($bitIndex < $dataBits->getSize()) {
+ $bit = $dataBits->get($bitIndex);
+ ++$bitIndex;
+ } else {
+ // Padding bit. If there is no bit left, we'll fill the
+ // left cells with 0, as described in 8.4.9 of
+ // JISX0510:2004 (p. 24).
+ $bit = false;
+ }
+
+ // Skip masking if maskPattern is -1.
+ if (-1 !== $maskPattern && MaskUtil::getDataMaskBit($maskPattern, $xx, $y)) {
+ $bit = ! $bit;
+ }
+
+ $matrix->set($xx, $y, (int) $bit);
+ }
+
+ $y += $direction;
+ }
+
+ $direction = -$direction;
+ $y += $direction;
+ $x -= 2;
+ }
+
+ // All bits should be consumed
+ if ($dataBits->getSize() !== $bitIndex) {
+ throw new WriterException('Not all bits consumed (' . $bitIndex . ' out of ' . $dataBits->getSize() .')');
+ }
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php
new file mode 100644
index 0000000..f568e88
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php
@@ -0,0 +1,141 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Encoder;
+
+use BaconQrCode\Common\ErrorCorrectionLevel;
+use BaconQrCode\Common\Mode;
+use BaconQrCode\Common\Version;
+
+/**
+ * QR code.
+ */
+final class QrCode
+{
+ /**
+ * Number of possible mask patterns.
+ */
+ public const NUM_MASK_PATTERNS = 8;
+
+ /**
+ * Mode of the QR code.
+ *
+ * @var Mode
+ */
+ private $mode;
+
+ /**
+ * EC level of the QR code.
+ *
+ * @var ErrorCorrectionLevel
+ */
+ private $errorCorrectionLevel;
+
+ /**
+ * Version of the QR code.
+ *
+ * @var Version
+ */
+ private $version;
+
+ /**
+ * Mask pattern of the QR code.
+ *
+ * @var int
+ */
+ private $maskPattern = -1;
+
+ /**
+ * Matrix of the QR code.
+ *
+ * @var ByteMatrix
+ */
+ private $matrix;
+
+ public function __construct(
+ Mode $mode,
+ ErrorCorrectionLevel $errorCorrectionLevel,
+ Version $version,
+ int $maskPattern,
+ ByteMatrix $matrix
+ ) {
+ $this->mode = $mode;
+ $this->errorCorrectionLevel = $errorCorrectionLevel;
+ $this->version = $version;
+ $this->maskPattern = $maskPattern;
+ $this->matrix = $matrix;
+ }
+
+ /**
+ * Gets the mode.
+ */
+ public function getMode() : Mode
+ {
+ return $this->mode;
+ }
+
+ /**
+ * Gets the EC level.
+ */
+ public function getErrorCorrectionLevel() : ErrorCorrectionLevel
+ {
+ return $this->errorCorrectionLevel;
+ }
+
+ /**
+ * Gets the version.
+ */
+ public function getVersion() : Version
+ {
+ return $this->version;
+ }
+
+ /**
+ * Gets the mask pattern.
+ */
+ public function getMaskPattern() : int
+ {
+ return $this->maskPattern;
+ }
+
+ /**
+ * Gets the matrix.
+ *
+ * @return ByteMatrix
+ */
+ public function getMatrix()
+ {
+ return $this->matrix;
+ }
+
+ /**
+ * Validates whether a mask pattern is valid.
+ */
+ public static function isValidMaskPattern(int $maskPattern) : bool
+ {
+ return $maskPattern > 0 && $maskPattern < self::NUM_MASK_PATTERNS;
+ }
+
+ /**
+ * Returns a string representation of the QR code.
+ */
+ public function __toString() : string
+ {
+ $result = "<<\n"
+ . ' mode: ' . $this->mode . "\n"
+ . ' ecLevel: ' . $this->errorCorrectionLevel . "\n"
+ . ' version: ' . $this->version . "\n"
+ . ' maskPattern: ' . $this->maskPattern . "\n";
+
+ if ($this->matrix === null) {
+ $result .= " matrix: null\n";
+ } else {
+ $result .= " matrix:\n";
+ $result .= $this->matrix;
+ }
+
+ $result .= ">>\n";
+
+ return $result;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..6f70c20
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php
@@ -0,0 +1,10 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Exception;
+
+use Throwable;
+
+interface ExceptionInterface extends Throwable
+{
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/InvalidArgumentException.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..0ec4249
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/InvalidArgumentException.php
@@ -0,0 +1,8 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Exception;
+
+final class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/OutOfBoundsException.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/OutOfBoundsException.php
new file mode 100644
index 0000000..79e53af
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/OutOfBoundsException.php
@@ -0,0 +1,8 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Exception;
+
+final class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface
+{
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/RuntimeException.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/RuntimeException.php
new file mode 100644
index 0000000..1e7fcc8
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/RuntimeException.php
@@ -0,0 +1,8 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Exception;
+
+final class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/UnexpectedValueException.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/UnexpectedValueException.php
new file mode 100644
index 0000000..24edcb8
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/UnexpectedValueException.php
@@ -0,0 +1,8 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Exception;
+
+final class UnexpectedValueException extends \UnexpectedValueException implements ExceptionInterface
+{
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/WriterException.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/WriterException.php
new file mode 100644
index 0000000..4cb2f2e
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Exception/WriterException.php
@@ -0,0 +1,8 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Exception;
+
+final class WriterException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Alpha.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Alpha.php
new file mode 100644
index 0000000..3490252
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Alpha.php
@@ -0,0 +1,57 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Color;
+
+use BaconQrCode\Exception;
+
+final class Alpha implements ColorInterface
+{
+ /**
+ * @var int
+ */
+ private $alpha;
+
+ /**
+ * @var ColorInterface
+ */
+ private $baseColor;
+
+ /**
+ * @param int $alpha the alpha value, 0 to 100
+ */
+ public function __construct(int $alpha, ColorInterface $baseColor)
+ {
+ if ($alpha < 0 || $alpha > 100) {
+ throw new Exception\InvalidArgumentException('Alpha must be between 0 and 100');
+ }
+
+ $this->alpha = $alpha;
+ $this->baseColor = $baseColor;
+ }
+
+ public function getAlpha() : int
+ {
+ return $this->alpha;
+ }
+
+ public function getBaseColor() : ColorInterface
+ {
+ return $this->baseColor;
+ }
+
+ public function toRgb() : Rgb
+ {
+ return $this->baseColor->toRgb();
+ }
+
+ public function toCmyk() : Cmyk
+ {
+ return $this->baseColor->toCmyk();
+ }
+
+ public function toGray() : Gray
+ {
+ return $this->baseColor->toGray();
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php
new file mode 100644
index 0000000..d6de390
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php
@@ -0,0 +1,103 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Color;
+
+use BaconQrCode\Exception;
+
+final class Cmyk implements ColorInterface
+{
+ /**
+ * @var int
+ */
+ private $cyan;
+
+ /**
+ * @var int
+ */
+ private $magenta;
+
+ /**
+ * @var int
+ */
+ private $yellow;
+
+ /**
+ * @var int
+ */
+ private $black;
+
+ /**
+ * @param int $cyan the cyan amount, 0 to 100
+ * @param int $magenta the magenta amount, 0 to 100
+ * @param int $yellow the yellow amount, 0 to 100
+ * @param int $black the black amount, 0 to 100
+ */
+ public function __construct(int $cyan, int $magenta, int $yellow, int $black)
+ {
+ if ($cyan < 0 || $cyan > 100) {
+ throw new Exception\InvalidArgumentException('Cyan must be between 0 and 100');
+ }
+
+ if ($magenta < 0 || $magenta > 100) {
+ throw new Exception\InvalidArgumentException('Magenta must be between 0 and 100');
+ }
+
+ if ($yellow < 0 || $yellow > 100) {
+ throw new Exception\InvalidArgumentException('Yellow must be between 0 and 100');
+ }
+
+ if ($black < 0 || $black > 100) {
+ throw new Exception\InvalidArgumentException('Black must be between 0 and 100');
+ }
+
+ $this->cyan = $cyan;
+ $this->magenta = $magenta;
+ $this->yellow = $yellow;
+ $this->black = $black;
+ }
+
+ public function getCyan() : int
+ {
+ return $this->cyan;
+ }
+
+ public function getMagenta() : int
+ {
+ return $this->magenta;
+ }
+
+ public function getYellow() : int
+ {
+ return $this->yellow;
+ }
+
+ public function getBlack() : int
+ {
+ return $this->black;
+ }
+
+ public function toRgb() : Rgb
+ {
+ $k = $this->black / 100;
+ $c = (-$k * $this->cyan + $k * 100 + $this->cyan) / 100;
+ $m = (-$k * $this->magenta + $k * 100 + $this->magenta) / 100;
+ $y = (-$k * $this->yellow + $k * 100 + $this->yellow) / 100;
+
+ return new Rgb(
+ (int) (-$c * 255 + 255),
+ (int) (-$m * 255 + 255),
+ (int) (-$y * 255 + 255)
+ );
+ }
+
+ public function toCmyk() : Cmyk
+ {
+ return $this;
+ }
+
+ public function toGray() : Gray
+ {
+ return $this->toRgb()->toGray();
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php
new file mode 100644
index 0000000..b50d1ca
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Color;
+
+interface ColorInterface
+{
+ /**
+ * Converts the color to RGB.
+ */
+ public function toRgb() : Rgb;
+
+ /**
+ * Converts the color to CMYK.
+ */
+ public function toCmyk() : Cmyk;
+
+ /**
+ * Converts the color to gray.
+ */
+ public function toGray() : Gray;
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Gray.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Gray.php
new file mode 100644
index 0000000..acb986d
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Gray.php
@@ -0,0 +1,46 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Color;
+
+use BaconQrCode\Exception;
+
+final class Gray implements ColorInterface
+{
+ /**
+ * @var int
+ */
+ private $gray;
+
+ /**
+ * @param int $gray the gray value between 0 (black) and 100 (white)
+ */
+ public function __construct(int $gray)
+ {
+ if ($gray < 0 || $gray > 100) {
+ throw new Exception\InvalidArgumentException('Gray must be between 0 and 100');
+ }
+
+ $this->gray = (int) $gray;
+ }
+
+ public function getGray() : int
+ {
+ return $this->gray;
+ }
+
+ public function toRgb() : Rgb
+ {
+ return new Rgb((int) ($this->gray * 2.55), (int) ($this->gray * 2.55), (int) ($this->gray * 2.55));
+ }
+
+ public function toCmyk() : Cmyk
+ {
+ return new Cmyk(0, 0, 0, 100 - $this->gray);
+ }
+
+ public function toGray() : Gray
+ {
+ return $this;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php
new file mode 100644
index 0000000..7935406
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php
@@ -0,0 +1,88 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Color;
+
+use BaconQrCode\Exception;
+
+final class Rgb implements ColorInterface
+{
+ /**
+ * @var int
+ */
+ private $red;
+
+ /**
+ * @var int
+ */
+ private $green;
+
+ /**
+ * @var int
+ */
+ private $blue;
+
+ /**
+ * @param int $red the red amount of the color, 0 to 255
+ * @param int $green the green amount of the color, 0 to 255
+ * @param int $blue the blue amount of the color, 0 to 255
+ */
+ public function __construct(int $red, int $green, int $blue)
+ {
+ if ($red < 0 || $red > 255) {
+ throw new Exception\InvalidArgumentException('Red must be between 0 and 255');
+ }
+
+ if ($green < 0 || $green > 255) {
+ throw new Exception\InvalidArgumentException('Green must be between 0 and 255');
+ }
+
+ if ($blue < 0 || $blue > 255) {
+ throw new Exception\InvalidArgumentException('Blue must be between 0 and 255');
+ }
+
+ $this->red = $red;
+ $this->green = $green;
+ $this->blue = $blue;
+ }
+
+ public function getRed() : int
+ {
+ return $this->red;
+ }
+
+ public function getGreen() : int
+ {
+ return $this->green;
+ }
+
+ public function getBlue() : int
+ {
+ return $this->blue;
+ }
+
+ public function toRgb() : Rgb
+ {
+ return $this;
+ }
+
+ public function toCmyk() : Cmyk
+ {
+ $c = 1 - ($this->red / 255);
+ $m = 1 - ($this->green / 255);
+ $y = 1 - ($this->blue / 255);
+ $k = min($c, $m, $y);
+
+ return new Cmyk(
+ (int) (100 * ($c - $k) / (1 - $k)),
+ (int) (100 * ($m - $k) / (1 - $k)),
+ (int) (100 * ($y - $k) / (1 - $k)),
+ (int) (100 * $k)
+ );
+ }
+
+ public function toGray() : Gray
+ {
+ return new Gray((int) (($this->red * 0.21 + $this->green * 0.71 + $this->blue * 0.07) / 2.55));
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php
new file mode 100644
index 0000000..a3e1909
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php
@@ -0,0 +1,38 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Eye;
+
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Combines the style of two different eyes.
+ */
+final class CompositeEye implements EyeInterface
+{
+ /**
+ * @var EyeInterface
+ */
+ private $externalEye;
+
+ /**
+ * @var EyeInterface
+ */
+ private $internalEye;
+
+ public function __construct(EyeInterface $externalEye, EyeInterface $internalEye)
+ {
+ $this->externalEye = $externalEye;
+ $this->internalEye = $internalEye;
+ }
+
+ public function getExternalPath() : Path
+ {
+ return $this->externalEye->getExternalPath();
+ }
+
+ public function getInternalPath() : Path
+ {
+ return $this->externalEye->getInternalPath();
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php
new file mode 100644
index 0000000..ab68f3c
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php
@@ -0,0 +1,26 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Eye;
+
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Interface for describing the look of an eye.
+ */
+interface EyeInterface
+{
+ /**
+ * Returns the path of the external eye element.
+ *
+ * The path origin point (0, 0) must be anchored at the middle of the path.
+ */
+ public function getExternalPath() : Path;
+
+ /**
+ * Returns the path of the internal eye element.
+ *
+ * The path origin point (0, 0) must be anchored at the middle of the path.
+ */
+ public function getInternalPath() : Path;
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/ModuleEye.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/ModuleEye.php
new file mode 100644
index 0000000..84f7d12
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/ModuleEye.php
@@ -0,0 +1,54 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Eye;
+
+use BaconQrCode\Encoder\ByteMatrix;
+use BaconQrCode\Renderer\Module\ModuleInterface;
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Renders an eye based on a module renderer.
+ */
+final class ModuleEye implements EyeInterface
+{
+ /**
+ * @var ModuleInterface
+ */
+ private $module;
+
+ public function __construct(ModuleInterface $module)
+ {
+ $this->module = $module;
+ }
+
+ public function getExternalPath() : Path
+ {
+ $matrix = new ByteMatrix(7, 7);
+
+ for ($x = 0; $x < 7; ++$x) {
+ $matrix->set($x, 0, 1);
+ $matrix->set($x, 6, 1);
+ }
+
+ for ($y = 1; $y < 6; ++$y) {
+ $matrix->set(0, $y, 1);
+ $matrix->set(6, $y, 1);
+ }
+
+ return $this->module->createPath($matrix)->translate(-3.5, -3.5);
+ }
+
+ public function getInternalPath() : Path
+ {
+ $matrix = new ByteMatrix(3, 3);
+
+ for ($x = 0; $x < 3; ++$x) {
+ for ($y = 0; $y < 3; ++$y) {
+ $matrix->set($x, $y, 1);
+ }
+ }
+
+ return $this->module->createPath($matrix)->translate(-1.5, -1.5);
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php
new file mode 100644
index 0000000..64d54ee
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php
@@ -0,0 +1,54 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Eye;
+
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Renders the inner eye as a circle.
+ */
+final class SimpleCircleEye implements EyeInterface
+{
+ /**
+ * @var self|null
+ */
+ private static $instance;
+
+ private function __construct()
+ {
+ }
+
+ public static function instance() : self
+ {
+ return self::$instance ?: self::$instance = new self();
+ }
+
+ public function getExternalPath() : Path
+ {
+ return (new Path())
+ ->move(-3.5, -3.5)
+ ->line(3.5, -3.5)
+ ->line(3.5, 3.5)
+ ->line(-3.5, 3.5)
+ ->close()
+ ->move(-2.5, -2.5)
+ ->line(-2.5, 2.5)
+ ->line(2.5, 2.5)
+ ->line(2.5, -2.5)
+ ->close()
+ ;
+ }
+
+ public function getInternalPath() : Path
+ {
+ return (new Path())
+ ->move(1.5, 0)
+ ->ellipticArc(1.5, 1.5, 0., false, true, 0., 1.5)
+ ->ellipticArc(1.5, 1.5, 0., false, true, -1.5, 0.)
+ ->ellipticArc(1.5, 1.5, 0., false, true, 0., -1.5)
+ ->ellipticArc(1.5, 1.5, 0., false, true, 1.5, 0.)
+ ->close()
+ ;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php
new file mode 100644
index 0000000..a3892b4
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php
@@ -0,0 +1,53 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Eye;
+
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Renders the eyes in their default square shape.
+ */
+final class SquareEye implements EyeInterface
+{
+ /**
+ * @var self|null
+ */
+ private static $instance;
+
+ private function __construct()
+ {
+ }
+
+ public static function instance() : self
+ {
+ return self::$instance ?: self::$instance = new self();
+ }
+
+ public function getExternalPath() : Path
+ {
+ return (new Path())
+ ->move(-3.5, -3.5)
+ ->line(3.5, -3.5)
+ ->line(3.5, 3.5)
+ ->line(-3.5, 3.5)
+ ->close()
+ ->move(-2.5, -2.5)
+ ->line(-2.5, 2.5)
+ ->line(2.5, 2.5)
+ ->line(2.5, -2.5)
+ ->close()
+ ;
+ }
+
+ public function getInternalPath() : Path
+ {
+ return (new Path())
+ ->move(-1.5, -1.5)
+ ->line(1.5, -1.5)
+ ->line(1.5, 1.5)
+ ->line(-1.5, 1.5)
+ ->close()
+ ;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php
new file mode 100644
index 0000000..b581b54
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php
@@ -0,0 +1,376 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Image;
+
+use BaconQrCode\Exception\RuntimeException;
+use BaconQrCode\Renderer\Color\Alpha;
+use BaconQrCode\Renderer\Color\Cmyk;
+use BaconQrCode\Renderer\Color\ColorInterface;
+use BaconQrCode\Renderer\Color\Gray;
+use BaconQrCode\Renderer\Color\Rgb;
+use BaconQrCode\Renderer\Path\Close;
+use BaconQrCode\Renderer\Path\Curve;
+use BaconQrCode\Renderer\Path\EllipticArc;
+use BaconQrCode\Renderer\Path\Line;
+use BaconQrCode\Renderer\Path\Move;
+use BaconQrCode\Renderer\Path\Path;
+use BaconQrCode\Renderer\RendererStyle\Gradient;
+use BaconQrCode\Renderer\RendererStyle\GradientType;
+
+final class EpsImageBackEnd implements ImageBackEndInterface
+{
+ private const PRECISION = 3;
+
+ /**
+ * @var string|null
+ */
+ private $eps;
+
+ public function new(int $size, ColorInterface $backgroundColor) : void
+ {
+ $this->eps = "%!PS-Adobe-3.0 EPSF-3.0\n"
+ . "%%Creator: BaconQrCode\n"
+ . sprintf("%%%%BoundingBox: 0 0 %d %d \n", $size, $size)
+ . "%%BeginProlog\n"
+ . "save\n"
+ . "50 dict begin\n"
+ . "/q { gsave } bind def\n"
+ . "/Q { grestore } bind def\n"
+ . "/s { scale } bind def\n"
+ . "/t { translate } bind def\n"
+ . "/r { rotate } bind def\n"
+ . "/n { newpath } bind def\n"
+ . "/m { moveto } bind def\n"
+ . "/l { lineto } bind def\n"
+ . "/c { curveto } bind def\n"
+ . "/z { closepath } bind def\n"
+ . "/f { eofill } bind def\n"
+ . "/rgb { setrgbcolor } bind def\n"
+ . "/cmyk { setcmykcolor } bind def\n"
+ . "/gray { setgray } bind def\n"
+ . "%%EndProlog\n"
+ . "1 -1 s\n"
+ . sprintf("0 -%d t\n", $size);
+
+ if ($backgroundColor instanceof Alpha && 0 === $backgroundColor->getAlpha()) {
+ return;
+ }
+
+ $this->eps .= wordwrap(
+ '0 0 m'
+ . sprintf(' %s 0 l', (string) $size)
+ . sprintf(' %s %s l', (string) $size, (string) $size)
+ . sprintf(' 0 %s l', (string) $size)
+ . ' z'
+ . ' ' .$this->getColorSetString($backgroundColor) . " f\n",
+ 75,
+ "\n "
+ );
+ }
+
+ public function scale(float $size) : void
+ {
+ if (null === $this->eps) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->eps .= sprintf("%1\$s %1\$s s\n", round($size, self::PRECISION));
+ }
+
+ public function translate(float $x, float $y) : void
+ {
+ if (null === $this->eps) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->eps .= sprintf("%s %s t\n", round($x, self::PRECISION), round($y, self::PRECISION));
+ }
+
+ public function rotate(int $degrees) : void
+ {
+ if (null === $this->eps) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->eps .= sprintf("%d r\n", $degrees);
+ }
+
+ public function push() : void
+ {
+ if (null === $this->eps) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->eps .= "q\n";
+ }
+
+ public function pop() : void
+ {
+ if (null === $this->eps) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->eps .= "Q\n";
+ }
+
+ public function drawPathWithColor(Path $path, ColorInterface $color) : void
+ {
+ if (null === $this->eps) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $fromX = 0;
+ $fromY = 0;
+ $this->eps .= wordwrap(
+ 'n '
+ . $this->drawPathOperations($path, $fromX, $fromY)
+ . ' ' . $this->getColorSetString($color) . " f\n",
+ 75,
+ "\n "
+ );
+ }
+
+ public function drawPathWithGradient(
+ Path $path,
+ Gradient $gradient,
+ float $x,
+ float $y,
+ float $width,
+ float $height
+ ) : void {
+ if (null === $this->eps) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $fromX = 0;
+ $fromY = 0;
+ $this->eps .= wordwrap(
+ 'q n ' . $this->drawPathOperations($path, $fromX, $fromY) . "\n",
+ 75,
+ "\n "
+ );
+
+ $this->createGradientFill($gradient, $x, $y, $width, $height);
+ }
+
+ public function done() : string
+ {
+ if (null === $this->eps) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->eps .= "%%TRAILER\nend restore\n%%EOF";
+ $blob = $this->eps;
+ $this->eps = null;
+
+ return $blob;
+ }
+
+ private function drawPathOperations(Iterable $ops, &$fromX, &$fromY) : string
+ {
+ $pathData = [];
+
+ foreach ($ops as $op) {
+ switch (true) {
+ case $op instanceof Move:
+ $fromX = $toX = round($op->getX(), self::PRECISION);
+ $fromY = $toY = round($op->getY(), self::PRECISION);
+ $pathData[] = sprintf('%s %s m', $toX, $toY);
+ break;
+
+ case $op instanceof Line:
+ $fromX = $toX = round($op->getX(), self::PRECISION);
+ $fromY = $toY = round($op->getY(), self::PRECISION);
+ $pathData[] = sprintf('%s %s l', $toX, $toY);
+ break;
+
+ case $op instanceof EllipticArc:
+ $pathData[] = $this->drawPathOperations($op->toCurves($fromX, $fromY), $fromX, $fromY);
+ break;
+
+ case $op instanceof Curve:
+ $x1 = round($op->getX1(), self::PRECISION);
+ $y1 = round($op->getY1(), self::PRECISION);
+ $x2 = round($op->getX2(), self::PRECISION);
+ $y2 = round($op->getY2(), self::PRECISION);
+ $fromX = $x3 = round($op->getX3(), self::PRECISION);
+ $fromY = $y3 = round($op->getY3(), self::PRECISION);
+ $pathData[] = sprintf('%s %s %s %s %s %s c', $x1, $y1, $x2, $y2, $x3, $y3);
+ break;
+
+ case $op instanceof Close:
+ $pathData[] = 'z';
+ break;
+
+ default:
+ throw new RuntimeException('Unexpected draw operation: ' . get_class($op));
+ }
+ }
+
+ return implode(' ', $pathData);
+ }
+
+ private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : void
+ {
+ $startColor = $gradient->getStartColor();
+ $endColor = $gradient->getEndColor();
+
+ if ($startColor instanceof Alpha) {
+ $startColor = $startColor->getBaseColor();
+ }
+
+ $startColorType = get_class($startColor);
+
+ if (! in_array($startColorType, [Rgb::class, Cmyk::class, Gray::class])) {
+ $startColorType = Cmyk::class;
+ $startColor = $startColor->toCmyk();
+ }
+
+ if (get_class($endColor) !== $startColorType) {
+ switch ($startColorType) {
+ case Cmyk::class:
+ $endColor = $endColor->toCmyk();
+ break;
+
+ case Rgb::class:
+ $endColor = $endColor->toRgb();
+ break;
+
+ case Gray::class:
+ $endColor = $endColor->toGray();
+ break;
+ }
+ }
+
+ $this->eps .= "eoclip\n<<\n";
+
+ if ($gradient->getType() === GradientType::RADIAL()) {
+ $this->eps .= " /ShadingType 3\n";
+ } else {
+ $this->eps .= " /ShadingType 2\n";
+ }
+
+ $this->eps .= " /Extend [ true true ]\n"
+ . " /AntiAlias true\n";
+
+ switch ($startColorType) {
+ case Cmyk::class:
+ $this->eps .= " /ColorSpace /DeviceCMYK\n";
+ break;
+
+ case Rgb::class:
+ $this->eps .= " /ColorSpace /DeviceRGB\n";
+ break;
+
+ case Gray::class:
+ $this->eps .= " /ColorSpace /DeviceGray\n";
+ break;
+ }
+
+ switch ($gradient->getType()) {
+ case GradientType::HORIZONTAL():
+ $this->eps .= sprintf(
+ " /Coords [ %s %s %s %s ]\n",
+ round($x, self::PRECISION),
+ round($y, self::PRECISION),
+ round($x + $width, self::PRECISION),
+ round($y, self::PRECISION)
+ );
+ break;
+
+ case GradientType::VERTICAL():
+ $this->eps .= sprintf(
+ " /Coords [ %s %s %s %s ]\n",
+ round($x, self::PRECISION),
+ round($y, self::PRECISION),
+ round($x, self::PRECISION),
+ round($y + $height, self::PRECISION)
+ );
+ break;
+
+ case GradientType::DIAGONAL():
+ $this->eps .= sprintf(
+ " /Coords [ %s %s %s %s ]\n",
+ round($x, self::PRECISION),
+ round($y, self::PRECISION),
+ round($x + $width, self::PRECISION),
+ round($y + $height, self::PRECISION)
+ );
+ break;
+
+ case GradientType::INVERSE_DIAGONAL():
+ $this->eps .= sprintf(
+ " /Coords [ %s %s %s %s ]\n",
+ round($x, self::PRECISION),
+ round($y + $height, self::PRECISION),
+ round($x + $width, self::PRECISION),
+ round($y, self::PRECISION)
+ );
+ break;
+
+ case GradientType::RADIAL():
+ $centerX = ($x + $width) / 2;
+ $centerY = ($y + $height) / 2;
+
+ $this->eps .= sprintf(
+ " /Coords [ %s %s 0 %s %s %s ]\n",
+ round($centerX, self::PRECISION),
+ round($centerY, self::PRECISION),
+ round($centerX, self::PRECISION),
+ round($centerY, self::PRECISION),
+ round(max($width, $height) / 2, self::PRECISION)
+ );
+ break;
+ }
+
+ $this->eps .= " /Function\n"
+ . " <<\n"
+ . " /FunctionType 2\n"
+ . " /Domain [ 0 1 ]\n"
+ . sprintf(" /C0 [ %s ]\n", $this->getColorString($startColor))
+ . sprintf(" /C1 [ %s ]\n", $this->getColorString($endColor))
+ . " /N 1\n"
+ . " >>\n>>\nshfill\nQ\n";
+ }
+
+ private function getColorSetString(ColorInterface $color) : string
+ {
+ if ($color instanceof Rgb) {
+ return $this->getColorString($color) . ' rgb';
+ }
+
+ if ($color instanceof Cmyk) {
+ return $this->getColorString($color) . ' cmyk';
+ }
+
+ if ($color instanceof Gray) {
+ return $this->getColorString($color) . ' gray';
+ }
+
+ return $this->getColorSetString($color->toCmyk());
+ }
+
+ private function getColorString(ColorInterface $color) : string
+ {
+ if ($color instanceof Rgb) {
+ return sprintf('%s %s %s', $color->getRed() / 255, $color->getGreen() / 255, $color->getBlue() / 255);
+ }
+
+ if ($color instanceof Cmyk) {
+ return sprintf(
+ '%s %s %s %s',
+ $color->getCyan() / 100,
+ $color->getMagenta() / 100,
+ $color->getYellow() / 100,
+ $color->getBlack() / 100
+ );
+ }
+
+ if ($color instanceof Gray) {
+ return sprintf('%s', $color->getGray() / 100);
+ }
+
+ return $this->getColorString($color->toCmyk());
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php
new file mode 100644
index 0000000..0935819
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php
@@ -0,0 +1,87 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Image;
+
+use BaconQrCode\Exception\RuntimeException;
+use BaconQrCode\Renderer\Color\ColorInterface;
+use BaconQrCode\Renderer\Path\Path;
+use BaconQrCode\Renderer\RendererStyle\Gradient;
+
+/**
+ * Interface for back ends able to to produce path based images.
+ */
+interface ImageBackEndInterface
+{
+ /**
+ * Starts a new image.
+ *
+ * If a previous image was already started, previous data get erased.
+ */
+ public function new(int $size, ColorInterface $backgroundColor) : void;
+
+ /**
+ * Transforms all following drawing operation coordinates by scaling them by a given factor.
+ *
+ * @throws RuntimeException if no image was started yet.
+ */
+ public function scale(float $size) : void;
+
+ /**
+ * Transforms all following drawing operation coordinates by translating them by a given amount.
+ *
+ * @throws RuntimeException if no image was started yet.
+ */
+ public function translate(float $x, float $y) : void;
+
+ /**
+ * Transforms all following drawing operation coordinates by rotating them by a given amount.
+ *
+ * @throws RuntimeException if no image was started yet.
+ */
+ public function rotate(int $degrees) : void;
+
+ /**
+ * Pushes the current coordinate transformation onto a stack.
+ *
+ * @throws RuntimeException if no image was started yet.
+ */
+ public function push() : void;
+
+ /**
+ * Pops the last coordinate transformation from a stack.
+ *
+ * @throws RuntimeException if no image was started yet.
+ */
+ public function pop() : void;
+
+ /**
+ * Draws a path with a given color.
+ *
+ * @throws RuntimeException if no image was started yet.
+ */
+ public function drawPathWithColor(Path $path, ColorInterface $color) : void;
+
+ /**
+ * Draws a path with a given gradient which spans the box described by the position and size.
+ *
+ * @throws RuntimeException if no image was started yet.
+ */
+ public function drawPathWithGradient(
+ Path $path,
+ Gradient $gradient,
+ float $x,
+ float $y,
+ float $width,
+ float $height
+ ) : void;
+
+ /**
+ * Ends the image drawing operation and returns the resulting blob.
+ *
+ * This should reset the state of the back end and thus this method should only be callable once per image.
+ *
+ * @throws RuntimeException if no image was started yet.
+ */
+ public function done() : string;
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImagickImageBackEnd.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImagickImageBackEnd.php
new file mode 100644
index 0000000..f1a94e5
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImagickImageBackEnd.php
@@ -0,0 +1,339 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Image;
+
+use BaconQrCode\Exception\RuntimeException;
+use BaconQrCode\Renderer\Color\Alpha;
+use BaconQrCode\Renderer\Color\Cmyk;
+use BaconQrCode\Renderer\Color\ColorInterface;
+use BaconQrCode\Renderer\Color\Gray;
+use BaconQrCode\Renderer\Color\Rgb;
+use BaconQrCode\Renderer\Path\Close;
+use BaconQrCode\Renderer\Path\Curve;
+use BaconQrCode\Renderer\Path\EllipticArc;
+use BaconQrCode\Renderer\Path\Line;
+use BaconQrCode\Renderer\Path\Move;
+use BaconQrCode\Renderer\Path\Path;
+use BaconQrCode\Renderer\RendererStyle\Gradient;
+use BaconQrCode\Renderer\RendererStyle\GradientType;
+use Imagick;
+use ImagickDraw;
+use ImagickPixel;
+
+final class ImagickImageBackEnd implements ImageBackEndInterface
+{
+ /**
+ * @var string
+ */
+ private $imageFormat;
+
+ /**
+ * @var int
+ */
+ private $compressionQuality;
+
+ /**
+ * @var Imagick|null
+ */
+ private $image;
+
+ /**
+ * @var ImagickDraw|null
+ */
+ private $draw;
+
+ /**
+ * @var int|null
+ */
+ private $gradientCount;
+
+ /**
+ * @var TransformationMatrix[]|null
+ */
+ private $matrices;
+
+ /**
+ * @var int|null
+ */
+ private $matrixIndex;
+
+ public function __construct(string $imageFormat = 'png', int $compressionQuality = 100)
+ {
+ if (! class_exists(Imagick::class)) {
+ throw new RuntimeException('You need to install the imagick extension to use this back end');
+ }
+
+ $this->imageFormat = $imageFormat;
+ $this->compressionQuality = $compressionQuality;
+ }
+
+ public function new(int $size, ColorInterface $backgroundColor) : void
+ {
+ $this->image = new Imagick();
+ $this->image->newImage($size, $size, $this->getColorPixel($backgroundColor));
+ $this->image->setImageFormat($this->imageFormat);
+ $this->image->setCompressionQuality($this->compressionQuality);
+ $this->draw = new ImagickDraw();
+ $this->gradientCount = 0;
+ $this->matrices = [new TransformationMatrix()];
+ $this->matrixIndex = 0;
+ }
+
+ public function scale(float $size) : void
+ {
+ if (null === $this->draw) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->draw->scale($size, $size);
+ $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex]
+ ->multiply(TransformationMatrix::scale($size));
+ }
+
+ public function translate(float $x, float $y) : void
+ {
+ if (null === $this->draw) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->draw->translate($x, $y);
+ $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex]
+ ->multiply(TransformationMatrix::translate($x, $y));
+ }
+
+ public function rotate(int $degrees) : void
+ {
+ if (null === $this->draw) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->draw->rotate($degrees);
+ $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex]
+ ->multiply(TransformationMatrix::rotate($degrees));
+ }
+
+ public function push() : void
+ {
+ if (null === $this->draw) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->draw->push();
+ $this->matrices[++$this->matrixIndex] = $this->matrices[$this->matrixIndex - 1];
+ }
+
+ public function pop() : void
+ {
+ if (null === $this->draw) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->draw->pop();
+ unset($this->matrices[$this->matrixIndex--]);
+ }
+
+ public function drawPathWithColor(Path $path, ColorInterface $color) : void
+ {
+ if (null === $this->draw) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->draw->setFillColor($this->getColorPixel($color));
+ $this->drawPath($path);
+ }
+
+ public function drawPathWithGradient(
+ Path $path,
+ Gradient $gradient,
+ float $x,
+ float $y,
+ float $width,
+ float $height
+ ) : void {
+ if (null === $this->draw) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->draw->setFillPatternURL('#' . $this->createGradientFill($gradient, $x, $y, $width, $height));
+ $this->drawPath($path);
+ }
+
+ public function done() : string
+ {
+ if (null === $this->draw) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->image->drawImage($this->draw);
+ $blob = $this->image->getImageBlob();
+ $this->draw->clear();
+ $this->image->clear();
+ $this->draw = null;
+ $this->image = null;
+ $this->gradientCount = null;
+
+ return $blob;
+ }
+
+ private function drawPath(Path $path) : void
+ {
+ $this->draw->pathStart();
+
+ foreach ($path as $op) {
+ switch (true) {
+ case $op instanceof Move:
+ $this->draw->pathMoveToAbsolute($op->getX(), $op->getY());
+ break;
+
+ case $op instanceof Line:
+ $this->draw->pathLineToAbsolute($op->getX(), $op->getY());
+ break;
+
+ case $op instanceof EllipticArc:
+ $this->draw->pathEllipticArcAbsolute(
+ $op->getXRadius(),
+ $op->getYRadius(),
+ $op->getXAxisAngle(),
+ $op->isLargeArc(),
+ $op->isSweep(),
+ $op->getX(),
+ $op->getY()
+ );
+ break;
+
+ case $op instanceof Curve:
+ $this->draw->pathCurveToAbsolute(
+ $op->getX1(),
+ $op->getY1(),
+ $op->getX2(),
+ $op->getY2(),
+ $op->getX3(),
+ $op->getY3()
+ );
+ break;
+
+ case $op instanceof Close:
+ $this->draw->pathClose();
+ break;
+
+ default:
+ throw new RuntimeException('Unexpected draw operation: ' . get_class($op));
+ }
+ }
+
+ $this->draw->pathFinish();
+ }
+
+ private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : string
+ {
+ list($width, $height) = $this->matrices[$this->matrixIndex]->apply($x + $width, $y + $height);
+ list($x, $y) = $this->matrices[$this->matrixIndex]->apply($x, $y);
+ $width -= $x;
+ $height -= $y;
+
+ $startColor = $this->getColorPixel($gradient->getStartColor())->getColorAsString();
+ $endColor = $this->getColorPixel($gradient->getEndColor())->getColorAsString();
+ $gradientImage = new Imagick();
+
+ switch ($gradient->getType()) {
+ case GradientType::HORIZONTAL():
+ $gradientImage->newPseudoImage((int) $height, (int) $width, sprintf(
+ 'gradient:%s-%s',
+ $startColor,
+ $endColor
+ ));
+ $gradientImage->rotateImage('transparent', -90);
+ break;
+
+ case GradientType::VERTICAL():
+ $gradientImage->newPseudoImage((int) $width, (int) $height, sprintf(
+ 'gradient:%s-%s',
+ $startColor,
+ $endColor
+ ));
+ break;
+
+ case GradientType::DIAGONAL():
+ case GradientType::INVERSE_DIAGONAL():
+ $gradientImage->newPseudoImage((int) ($width * sqrt(2)), (int) ($height * sqrt(2)), sprintf(
+ 'gradient:%s-%s',
+ $startColor,
+ $endColor
+ ));
+
+ if (GradientType::DIAGONAL() === $gradient->getType()) {
+ $gradientImage->rotateImage('transparent', -45);
+ } else {
+ $gradientImage->rotateImage('transparent', -135);
+ }
+
+ $rotatedWidth = $gradientImage->getImageWidth();
+ $rotatedHeight = $gradientImage->getImageHeight();
+
+ $gradientImage->setImagePage($rotatedWidth, $rotatedHeight, 0, 0);
+ $gradientImage->cropImage(
+ intdiv($rotatedWidth, 2) - 2,
+ intdiv($rotatedHeight, 2) - 2,
+ intdiv($rotatedWidth, 4) + 1,
+ intdiv($rotatedWidth, 4) + 1
+ );
+ break;
+
+ case GradientType::RADIAL():
+ $gradientImage->newPseudoImage((int) $width, (int) $height, sprintf(
+ 'radial-gradient:%s-%s',
+ $startColor,
+ $endColor
+ ));
+ break;
+ }
+
+ $id = sprintf('g%d', ++$this->gradientCount);
+ $this->draw->pushPattern($id, 0, 0, $x + $width, $y + $height);
+ $this->draw->composite(Imagick::COMPOSITE_COPY, $x, $y, $width, $height, $gradientImage);
+ $this->draw->popPattern();
+ return $id;
+ }
+
+ private function getColorPixel(ColorInterface $color) : ImagickPixel
+ {
+ $alpha = 100;
+
+ if ($color instanceof Alpha) {
+ $alpha = $color->getAlpha();
+ $color = $color->getBaseColor();
+ }
+
+ if ($color instanceof Rgb) {
+ return new ImagickPixel(sprintf(
+ 'rgba(%d, %d, %d, %F)',
+ $color->getRed(),
+ $color->getGreen(),
+ $color->getBlue(),
+ $alpha / 100
+ ));
+ }
+
+ if ($color instanceof Cmyk) {
+ return new ImagickPixel(sprintf(
+ 'cmyka(%d, %d, %d, %d, %F)',
+ $color->getCyan(),
+ $color->getMagenta(),
+ $color->getYellow(),
+ $color->getBlack(),
+ $alpha / 100
+ ));
+ }
+
+ if ($color instanceof Gray) {
+ return new ImagickPixel(sprintf(
+ 'graya(%d%%, %F)',
+ $color->getGray(),
+ $alpha / 100
+ ));
+ }
+
+ return $this->getColorPixel(new Alpha($alpha, $color->toRgb()));
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php
new file mode 100644
index 0000000..714da6e
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php
@@ -0,0 +1,369 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Image;
+
+use BaconQrCode\Exception\RuntimeException;
+use BaconQrCode\Renderer\Color\Alpha;
+use BaconQrCode\Renderer\Color\ColorInterface;
+use BaconQrCode\Renderer\Path\Close;
+use BaconQrCode\Renderer\Path\Curve;
+use BaconQrCode\Renderer\Path\EllipticArc;
+use BaconQrCode\Renderer\Path\Line;
+use BaconQrCode\Renderer\Path\Move;
+use BaconQrCode\Renderer\Path\Path;
+use BaconQrCode\Renderer\RendererStyle\Gradient;
+use BaconQrCode\Renderer\RendererStyle\GradientType;
+use XMLWriter;
+
+final class SvgImageBackEnd implements ImageBackEndInterface
+{
+ private const PRECISION = 3;
+
+ /**
+ * @var XMLWriter|null
+ */
+ private $xmlWriter;
+
+ /**
+ * @var int[]|null
+ */
+ private $stack;
+
+ /**
+ * @var int|null
+ */
+ private $currentStack;
+
+ /**
+ * @var int|null
+ */
+ private $gradientCount;
+
+ public function __construct()
+ {
+ if (! class_exists(XMLWriter::class)) {
+ throw new RuntimeException('You need to install the libxml extension to use this back end');
+ }
+ }
+
+ public function new(int $size, ColorInterface $backgroundColor) : void
+ {
+ $this->xmlWriter = new XMLWriter();
+ $this->xmlWriter->openMemory();
+
+ $this->xmlWriter->startDocument('1.0', 'UTF-8');
+ $this->xmlWriter->startElement('svg');
+ $this->xmlWriter->writeAttribute('xmlns', 'http://www.w3.org/2000/svg');
+ $this->xmlWriter->writeAttribute('version', '1.1');
+ $this->xmlWriter->writeAttribute('width', (string) $size);
+ $this->xmlWriter->writeAttribute('height', (string) $size);
+ $this->xmlWriter->writeAttribute('viewBox', '0 0 '. $size . ' ' . $size);
+
+ $this->gradientCount = 0;
+ $this->currentStack = 0;
+ $this->stack[0] = 0;
+
+ $alpha = 1;
+
+ if ($backgroundColor instanceof Alpha) {
+ $alpha = $backgroundColor->getAlpha() / 100;
+ }
+
+ if (0 === $alpha) {
+ return;
+ }
+
+ $this->xmlWriter->startElement('rect');
+ $this->xmlWriter->writeAttribute('x', '0');
+ $this->xmlWriter->writeAttribute('y', '0');
+ $this->xmlWriter->writeAttribute('width', (string) $size);
+ $this->xmlWriter->writeAttribute('height', (string) $size);
+ $this->xmlWriter->writeAttribute('fill', $this->getColorString($backgroundColor));
+
+ if ($alpha < 1) {
+ $this->xmlWriter->writeAttribute('fill-opacity', (string) $alpha);
+ }
+
+ $this->xmlWriter->endElement();
+ }
+
+ public function scale(float $size) : void
+ {
+ if (null === $this->xmlWriter) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->xmlWriter->startElement('g');
+ $this->xmlWriter->writeAttribute(
+ 'transform',
+ sprintf('scale(%s)', round($size, self::PRECISION))
+ );
+ ++$this->stack[$this->currentStack];
+ }
+
+ public function translate(float $x, float $y) : void
+ {
+ if (null === $this->xmlWriter) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->xmlWriter->startElement('g');
+ $this->xmlWriter->writeAttribute(
+ 'transform',
+ sprintf('translate(%s,%s)', round($x, self::PRECISION), round($y, self::PRECISION))
+ );
+ ++$this->stack[$this->currentStack];
+ }
+
+ public function rotate(int $degrees) : void
+ {
+ if (null === $this->xmlWriter) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->xmlWriter->startElement('g');
+ $this->xmlWriter->writeAttribute('transform', sprintf('rotate(%d)', $degrees));
+ ++$this->stack[$this->currentStack];
+ }
+
+ public function push() : void
+ {
+ if (null === $this->xmlWriter) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $this->xmlWriter->startElement('g');
+ $this->stack[] = 1;
+ ++$this->currentStack;
+ }
+
+ public function pop() : void
+ {
+ if (null === $this->xmlWriter) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ for ($i = 0; $i < $this->stack[$this->currentStack]; ++$i) {
+ $this->xmlWriter->endElement();
+ }
+
+ array_pop($this->stack);
+ --$this->currentStack;
+ }
+
+ public function drawPathWithColor(Path $path, ColorInterface $color) : void
+ {
+ if (null === $this->xmlWriter) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $alpha = 1;
+
+ if ($color instanceof Alpha) {
+ $alpha = $color->getAlpha() / 100;
+ }
+
+ $this->startPathElement($path);
+ $this->xmlWriter->writeAttribute('fill', $this->getColorString($color));
+
+ if ($alpha < 1) {
+ $this->xmlWriter->writeAttribute('fill-opacity', (string) $alpha);
+ }
+
+ $this->xmlWriter->endElement();
+ }
+
+ public function drawPathWithGradient(
+ Path $path,
+ Gradient $gradient,
+ float $x,
+ float $y,
+ float $width,
+ float $height
+ ) : void {
+ if (null === $this->xmlWriter) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ $gradientId = $this->createGradientFill($gradient, $x, $y, $width, $height);
+ $this->startPathElement($path);
+ $this->xmlWriter->writeAttribute('fill', 'url(#' . $gradientId . ')');
+ $this->xmlWriter->endElement();
+ }
+
+ public function done() : string
+ {
+ if (null === $this->xmlWriter) {
+ throw new RuntimeException('No image has been started');
+ }
+
+ foreach ($this->stack as $openElements) {
+ for ($i = $openElements; $i > 0; --$i) {
+ $this->xmlWriter->endElement();
+ }
+ }
+
+ $this->xmlWriter->endDocument();
+ $blob = $this->xmlWriter->outputMemory(true);
+ $this->xmlWriter = null;
+ $this->stack = null;
+ $this->currentStack = null;
+ $this->gradientCount = null;
+
+ return $blob;
+ }
+
+ private function startPathElement(Path $path) : void
+ {
+ $pathData = [];
+
+ foreach ($path as $op) {
+ switch (true) {
+ case $op instanceof Move:
+ $pathData[] = sprintf(
+ 'M%s %s',
+ round($op->getX(), self::PRECISION),
+ round($op->getY(), self::PRECISION)
+ );
+ break;
+
+ case $op instanceof Line:
+ $pathData[] = sprintf(
+ 'L%s %s',
+ round($op->getX(), self::PRECISION),
+ round($op->getY(), self::PRECISION)
+ );
+ break;
+
+ case $op instanceof EllipticArc:
+ $pathData[] = sprintf(
+ 'A%s %s %s %u %u %s %s',
+ round($op->getXRadius(), self::PRECISION),
+ round($op->getYRadius(), self::PRECISION),
+ round($op->getXAxisAngle(), self::PRECISION),
+ $op->isLargeArc(),
+ $op->isSweep(),
+ round($op->getX(), self::PRECISION),
+ round($op->getY(), self::PRECISION)
+ );
+ break;
+
+ case $op instanceof Curve:
+ $pathData[] = sprintf(
+ 'C%s %s %s %s %s %s',
+ round($op->getX1(), self::PRECISION),
+ round($op->getY1(), self::PRECISION),
+ round($op->getX2(), self::PRECISION),
+ round($op->getY2(), self::PRECISION),
+ round($op->getX3(), self::PRECISION),
+ round($op->getY3(), self::PRECISION)
+ );
+ break;
+
+ case $op instanceof Close:
+ $pathData[] = 'Z';
+ break;
+
+ default:
+ throw new RuntimeException('Unexpected draw operation: ' . get_class($op));
+ }
+ }
+
+ $this->xmlWriter->startElement('path');
+ $this->xmlWriter->writeAttribute('fill-rule', 'evenodd');
+ $this->xmlWriter->writeAttribute('d', implode('', $pathData));
+ }
+
+ private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : string
+ {
+ $this->xmlWriter->startElement('defs');
+
+ $startColor = $gradient->getStartColor();
+ $endColor = $gradient->getEndColor();
+
+ if ($gradient->getType() === GradientType::RADIAL()) {
+ $this->xmlWriter->startElement('radialGradient');
+ } else {
+ $this->xmlWriter->startElement('linearGradient');
+ }
+
+ $this->xmlWriter->writeAttribute('gradientUnits', 'userSpaceOnUse');
+
+ switch ($gradient->getType()) {
+ case GradientType::HORIZONTAL():
+ $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION));
+ $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION));
+ $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION));
+ $this->xmlWriter->writeAttribute('y2', (string) round($y, self::PRECISION));
+ break;
+
+ case GradientType::VERTICAL():
+ $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION));
+ $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION));
+ $this->xmlWriter->writeAttribute('x2', (string) round($x, self::PRECISION));
+ $this->xmlWriter->writeAttribute('y2', (string) round($y + $height, self::PRECISION));
+ break;
+
+ case GradientType::DIAGONAL():
+ $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION));
+ $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION));
+ $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION));
+ $this->xmlWriter->writeAttribute('y2', (string) round($y + $height, self::PRECISION));
+ break;
+
+ case GradientType::INVERSE_DIAGONAL():
+ $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION));
+ $this->xmlWriter->writeAttribute('y1', (string) round($y + $height, self::PRECISION));
+ $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION));
+ $this->xmlWriter->writeAttribute('y2', (string) round($y, self::PRECISION));
+ break;
+
+ case GradientType::RADIAL():
+ $this->xmlWriter->writeAttribute('cx', (string) round(($x + $width) / 2, self::PRECISION));
+ $this->xmlWriter->writeAttribute('cy', (string) round(($y + $height) / 2, self::PRECISION));
+ $this->xmlWriter->writeAttribute('r', (string) round(max($width, $height) / 2, self::PRECISION));
+ break;
+ }
+
+ $id = sprintf('g%d', ++$this->gradientCount);
+ $this->xmlWriter->writeAttribute('id', $id);
+
+ $this->xmlWriter->startElement('stop');
+ $this->xmlWriter->writeAttribute('offset', '0%');
+ $this->xmlWriter->writeAttribute('stop-color', $this->getColorString($startColor));
+
+ if ($startColor instanceof Alpha) {
+ $this->xmlWriter->writeAttribute('stop-opacity', $startColor->getAlpha());
+ }
+
+ $this->xmlWriter->endElement();
+
+ $this->xmlWriter->startElement('stop');
+ $this->xmlWriter->writeAttribute('offset', '100%');
+ $this->xmlWriter->writeAttribute('stop-color', $this->getColorString($endColor));
+
+ if ($endColor instanceof Alpha) {
+ $this->xmlWriter->writeAttribute('stop-opacity', $endColor->getAlpha());
+ }
+
+ $this->xmlWriter->endElement();
+
+ $this->xmlWriter->endElement();
+ $this->xmlWriter->endElement();
+
+ return $id;
+ }
+
+ private function getColorString(ColorInterface $color) : string
+ {
+ $color = $color->toRgb();
+
+ return sprintf(
+ '#%02x%02x%02x',
+ $color->getRed(),
+ $color->getGreen(),
+ $color->getBlue()
+ );
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php
new file mode 100644
index 0000000..b41ee09
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php
@@ -0,0 +1,67 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Image;
+
+final class TransformationMatrix
+{
+ /**
+ * @var float[]
+ */
+ private $values;
+
+ public function __construct()
+ {
+ $this->values = [1, 0, 0, 1, 0, 0];
+ }
+
+ public function multiply(self $other) : self
+ {
+ $matrix = new self();
+ $matrix->values[0] = $this->values[0] * $other->values[0] + $this->values[2] * $other->values[1];
+ $matrix->values[1] = $this->values[1] * $other->values[0] + $this->values[3] * $other->values[1];
+ $matrix->values[2] = $this->values[0] * $other->values[2] + $this->values[2] * $other->values[3];
+ $matrix->values[3] = $this->values[1] * $other->values[2] + $this->values[3] * $other->values[3];
+ $matrix->values[4] = $this->values[0] * $other->values[4] + $this->values[2] * $other->values[5]
+ + $this->values[4];
+ $matrix->values[5] = $this->values[1] * $other->values[4] + $this->values[3] * $other->values[5]
+ + $this->values[5];
+
+ return $matrix;
+ }
+
+ public static function scale(float $size) : self
+ {
+ $matrix = new self();
+ $matrix->values = [$size, 0, 0, $size, 0, 0];
+ return $matrix;
+ }
+
+ public static function translate(float $x, float $y) : self
+ {
+ $matrix = new self();
+ $matrix->values = [1, 0, 0, 1, $x, $y];
+ return $matrix;
+ }
+
+ public static function rotate(int $degrees) : self
+ {
+ $matrix = new self();
+ $matrix->values = [cos($degrees), sin($degrees), -sin($degrees), cos($degrees), 0, 0];
+ return $matrix;
+ }
+
+
+ /**
+ * Applies this matrix onto a point and returns the resulting viewport point.
+ *
+ * @return float[]
+ */
+ public function apply(float $x, float $y) : array
+ {
+ return [
+ $x * $this->values[0] + $y * $this->values[2] + $this->values[4],
+ $x * $this->values[2] + $x * $this->values[3] + $this->values[5],
+ ];
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php
new file mode 100644
index 0000000..ab16276
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php
@@ -0,0 +1,152 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer;
+
+use BaconQrCode\Encoder\MatrixUtil;
+use BaconQrCode\Encoder\QrCode;
+use BaconQrCode\Exception\InvalidArgumentException;
+use BaconQrCode\Renderer\Image\ImageBackEndInterface;
+use BaconQrCode\Renderer\Path\Path;
+use BaconQrCode\Renderer\RendererStyle\EyeFill;
+use BaconQrCode\Renderer\RendererStyle\RendererStyle;
+
+final class ImageRenderer implements RendererInterface
+{
+ /**
+ * @var RendererStyle
+ */
+ private $rendererStyle;
+
+ /**
+ * @var ImageBackEndInterface
+ */
+ private $imageBackEnd;
+
+ public function __construct(RendererStyle $rendererStyle, ImageBackEndInterface $imageBackEnd)
+ {
+ $this->rendererStyle = $rendererStyle;
+ $this->imageBackEnd = $imageBackEnd;
+ }
+
+ /**
+ * @throws InvalidArgumentException if matrix width doesn't match height
+ */
+ public function render(QrCode $qrCode) : string
+ {
+ $size = $this->rendererStyle->getSize();
+ $margin = $this->rendererStyle->getMargin();
+ $matrix = $qrCode->getMatrix();
+ $matrixSize = $matrix->getWidth();
+
+ if ($matrixSize !== $matrix->getHeight()) {
+ throw new InvalidArgumentException('Matrix must have the same width and height');
+ }
+
+ $totalSize = $matrixSize + ($margin * 2);
+ $moduleSize = $size / $totalSize;
+ $fill = $this->rendererStyle->getFill();
+
+ $this->imageBackEnd->new($size, $fill->getBackgroundColor());
+ $this->imageBackEnd->scale((float) $moduleSize);
+ $this->imageBackEnd->translate((float) $margin, (float) $margin);
+
+ $module = $this->rendererStyle->getModule();
+ $moduleMatrix = clone $matrix;
+ MatrixUtil::removePositionDetectionPatterns($moduleMatrix);
+ $modulePath = $this->drawEyes($matrixSize, $module->createPath($moduleMatrix));
+
+ if ($fill->hasGradientFill()) {
+ $this->imageBackEnd->drawPathWithGradient(
+ $modulePath,
+ $fill->getForegroundGradient(),
+ 0,
+ 0,
+ $matrixSize,
+ $matrixSize
+ );
+ } else {
+ $this->imageBackEnd->drawPathWithColor($modulePath, $fill->getForegroundColor());
+ }
+
+ return $this->imageBackEnd->done();
+ }
+
+ private function drawEyes(int $matrixSize, Path $modulePath) : Path
+ {
+ $fill = $this->rendererStyle->getFill();
+
+ $eye = $this->rendererStyle->getEye();
+ $externalPath = $eye->getExternalPath();
+ $internalPath = $eye->getInternalPath();
+
+ $modulePath = $this->drawEye(
+ $externalPath,
+ $internalPath,
+ $fill->getTopLeftEyeFill(),
+ 3.5,
+ 3.5,
+ 0,
+ $modulePath
+ );
+ $modulePath = $this->drawEye(
+ $externalPath,
+ $internalPath,
+ $fill->getTopRightEyeFill(),
+ $matrixSize - 3.5,
+ 3.5,
+ 90,
+ $modulePath
+ );
+ $modulePath = $this->drawEye(
+ $externalPath,
+ $internalPath,
+ $fill->getBottomLeftEyeFill(),
+ 3.5,
+ $matrixSize - 3.5,
+ -90,
+ $modulePath
+ );
+
+ return $modulePath;
+ }
+
+ private function drawEye(
+ Path $externalPath,
+ Path $internalPath,
+ EyeFill $fill,
+ float $xTranslation,
+ float $yTranslation,
+ int $rotation,
+ Path $modulePath
+ ) : Path {
+ if ($fill->inheritsBothColors()) {
+ return $modulePath
+ ->append($externalPath->translate($xTranslation, $yTranslation))
+ ->append($internalPath->translate($xTranslation, $yTranslation));
+ }
+
+ $this->imageBackEnd->push();
+ $this->imageBackEnd->translate($xTranslation, $yTranslation);
+
+ if (0 !== $rotation) {
+ $this->imageBackEnd->rotate($rotation);
+ }
+
+ if ($fill->inheritsExternalColor()) {
+ $modulePath = $modulePath->append($externalPath->translate($xTranslation, $yTranslation));
+ } else {
+ $this->imageBackEnd->drawPathWithColor($externalPath, $fill->getExternalColor());
+ }
+
+ if ($fill->inheritsInternalColor()) {
+ $modulePath = $modulePath->append($internalPath->translate($xTranslation, $yTranslation));
+ } else {
+ $this->imageBackEnd->drawPathWithColor($internalPath, $fill->getInternalColor());
+ }
+
+ $this->imageBackEnd->pop();
+
+ return $modulePath;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php
new file mode 100644
index 0000000..f536e5a
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php
@@ -0,0 +1,63 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Module;
+
+use BaconQrCode\Encoder\ByteMatrix;
+use BaconQrCode\Exception\InvalidArgumentException;
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Renders individual modules as dots.
+ */
+final class DotsModule implements ModuleInterface
+{
+ public const LARGE = 1;
+ public const MEDIUM = .8;
+ public const SMALL = .6;
+
+ /**
+ * @var float
+ */
+ private $size;
+
+ public function __construct(float $size)
+ {
+ if ($size <= 0 || $size > 1) {
+ throw new InvalidArgumentException('Size must between 0 (exclusive) and 1 (inclusive)');
+ }
+
+ $this->size = $size;
+ }
+
+ public function createPath(ByteMatrix $matrix) : Path
+ {
+ $width = $matrix->getWidth();
+ $height = $matrix->getHeight();
+ $path = new Path();
+ $halfSize = $this->size / 2;
+ $margin = (1 - $this->size) / 2;
+
+ for ($y = 0; $y < $height; ++$y) {
+ for ($x = 0; $x < $width; ++$x) {
+ if (! $matrix->get($x, $y)) {
+ continue;
+ }
+
+ $pathX = $x + $margin;
+ $pathY = $y + $margin;
+
+ $path = $path
+ ->move($pathX + $this->size, $pathY + $halfSize)
+ ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $halfSize, $pathY + $this->size)
+ ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX, $pathY + $halfSize)
+ ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $halfSize, $pathY)
+ ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $this->size, $pathY + $halfSize)
+ ->close()
+ ;
+ }
+ }
+
+ return $path;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php
new file mode 100644
index 0000000..90482f2
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php
@@ -0,0 +1,100 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Module\EdgeIterator;
+
+final class Edge
+{
+ /**
+ * @var bool
+ */
+ private $positive;
+
+ /**
+ * @var array<int[]>
+ */
+ private $points = [];
+
+ /**
+ * @var array<int[]>|null
+ */
+ private $simplifiedPoints;
+
+ /**
+ * @var int
+ */
+ private $minX = PHP_INT_MAX;
+
+ /**
+ * @var int
+ */
+ private $minY = PHP_INT_MAX;
+
+ /**
+ * @var int
+ */
+ private $maxX = -1;
+
+ /**
+ * @var int
+ */
+ private $maxY = -1;
+
+ public function __construct(bool $positive)
+ {
+ $this->positive = $positive;
+ }
+
+ public function addPoint(int $x, int $y) : void
+ {
+ $this->points[] = [$x, $y];
+ $this->minX = min($this->minX, $x);
+ $this->minY = min($this->minY, $y);
+ $this->maxX = max($this->maxX, $x);
+ $this->maxY = max($this->maxY, $y);
+ }
+
+ public function isPositive() : bool
+ {
+ return $this->positive;
+ }
+
+ /**
+ * @return array<int[]>
+ */
+ public function getPoints() : array
+ {
+ return $this->points;
+ }
+
+ public function getMaxX() : int
+ {
+ return $this->maxX;
+ }
+
+ public function getSimplifiedPoints() : array
+ {
+ if (null !== $this->simplifiedPoints) {
+ return $this->simplifiedPoints;
+ }
+
+ $points = [];
+ $length = count($this->points);
+
+ for ($i = 0; $i < $length; ++$i) {
+ $previousPoint = $this->points[(0 === $i ? $length : $i) - 1];
+ $nextPoint = $this->points[($length - 1 === $i ? -1 : $i) + 1];
+ $currentPoint = $this->points[$i];
+
+ if (($previousPoint[0] === $currentPoint[0] && $currentPoint[0] === $nextPoint[0])
+ || ($previousPoint[1] === $currentPoint[1] && $currentPoint[1] === $nextPoint[1])
+ ) {
+ continue;
+ }
+
+ $points[] = $currentPoint;
+ }
+
+ return $this->simplifiedPoints = $points;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php
new file mode 100644
index 0000000..af52d52
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php
@@ -0,0 +1,169 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Module\EdgeIterator;
+
+use BaconQrCode\Encoder\ByteMatrix;
+use IteratorAggregate;
+use Traversable;
+
+/**
+ * Edge iterator based on potrace.
+ */
+final class EdgeIterator implements IteratorAggregate
+{
+ /**
+ * @var int[]
+ */
+ private $bytes = [];
+
+ /**
+ * @var int
+ */
+ private $size;
+
+ /**
+ * @var int
+ */
+ private $width;
+
+ /**
+ * @var int
+ */
+ private $height;
+
+ public function __construct(ByteMatrix $matrix)
+ {
+ $this->bytes = iterator_to_array($matrix->getBytes());
+ $this->size = count($this->bytes);
+ $this->width = $matrix->getWidth();
+ $this->height = $matrix->getHeight();
+ }
+
+ /**
+ * @return Edge[]
+ */
+ public function getIterator() : Traversable
+ {
+ $originalBytes = $this->bytes;
+ $point = $this->findNext(0, 0);
+
+ while (null !== $point) {
+ $edge = $this->findEdge($point[0], $point[1]);
+ $this->xorEdge($edge);
+
+ yield $edge;
+
+ $point = $this->findNext($point[0], $point[1]);
+ }
+
+ $this->bytes = $originalBytes;
+ }
+
+ /**
+ * @return int[]|null
+ */
+ private function findNext(int $x, int $y) : ?array
+ {
+ $i = $this->width * $y + $x;
+
+ while ($i < $this->size && 1 !== $this->bytes[$i]) {
+ ++$i;
+ }
+
+ if ($i < $this->size) {
+ return $this->pointOf($i);
+ }
+
+ return null;
+ }
+
+ private function findEdge(int $x, int $y) : Edge
+ {
+ $edge = new Edge($this->isSet($x, $y));
+ $startX = $x;
+ $startY = $y;
+ $dirX = 0;
+ $dirY = 1;
+
+ while (true) {
+ $edge->addPoint($x, $y);
+ $x += $dirX;
+ $y += $dirY;
+
+ if ($x === $startX && $y === $startY) {
+ break;
+ }
+
+ $left = $this->isSet($x + ($dirX + $dirY - 1 ) / 2, $y + ($dirY - $dirX - 1) / 2);
+ $right = $this->isSet($x + ($dirX - $dirY - 1) / 2, $y + ($dirY + $dirX - 1) / 2);
+
+ if ($right && ! $left) {
+ $tmp = $dirX;
+ $dirX = -$dirY;
+ $dirY = $tmp;
+ } elseif ($right) {
+ $tmp = $dirX;
+ $dirX = -$dirY;
+ $dirY = $tmp;
+ } elseif (! $left) {
+ $tmp = $dirX;
+ $dirX = $dirY;
+ $dirY = -$tmp;
+ }
+ }
+
+ return $edge;
+ }
+
+ private function xorEdge(Edge $path) : void
+ {
+ $points = $path->getPoints();
+ $y1 = $points[0][1];
+ $length = count($points);
+ $maxX = $path->getMaxX();
+
+ for ($i = 1; $i < $length; ++$i) {
+ $y = $points[$i][1];
+
+ if ($y === $y1) {
+ continue;
+ }
+
+ $x = $points[$i][0];
+ $minY = min($y1, $y);
+
+ for ($j = $x; $j < $maxX; ++$j) {
+ $this->flip($j, $minY);
+ }
+
+ $y1 = $y;
+ }
+ }
+
+ private function isSet(int $x, int $y) : bool
+ {
+ return (
+ $x >= 0
+ && $x < $this->width
+ && $y >= 0
+ && $y < $this->height
+ ) && 1 === $this->bytes[$this->width * $y + $x];
+ }
+
+ /**
+ * @return int[]
+ */
+ private function pointOf(int $i) : array
+ {
+ $y = intdiv($i, $this->width);
+ return [$i - $y * $this->width, $y];
+ }
+
+ private function flip(int $x, int $y) : void
+ {
+ $this->bytes[$this->width * $y + $x] = (
+ $this->isSet($x, $y) ? 0 : 1
+ );
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php
new file mode 100644
index 0000000..0ccb0e0
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php
@@ -0,0 +1,18 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Module;
+
+use BaconQrCode\Encoder\ByteMatrix;
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Interface describing how modules should be rendered.
+ *
+ * A module always receives a byte matrix (with values either being 1 or 0). It returns a path, where the origin
+ * coordinate (0, 0) equals the top left corner of the first matrix value.
+ */
+interface ModuleInterface
+{
+ public function createPath(ByteMatrix $matrix) : Path;
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/RoundnessModule.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/RoundnessModule.php
new file mode 100644
index 0000000..01b83c6
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/RoundnessModule.php
@@ -0,0 +1,129 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Module;
+
+use BaconQrCode\Encoder\ByteMatrix;
+use BaconQrCode\Exception\InvalidArgumentException;
+use BaconQrCode\Renderer\Module\EdgeIterator\EdgeIterator;
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Rounds the corners of module groups.
+ */
+final class RoundnessModule implements ModuleInterface
+{
+ public const STRONG = 1;
+ public const MEDIUM = .5;
+ public const SOFT = .25;
+
+ /**
+ * @var float
+ */
+ private $intensity;
+
+ public function __construct(float $intensity)
+ {
+ if ($intensity <= 0 || $intensity > 1) {
+ throw new InvalidArgumentException('Intensity must between 0 (exclusive) and 1 (inclusive)');
+ }
+
+ $this->intensity = $intensity / 2;
+ }
+
+ public function createPath(ByteMatrix $matrix) : Path
+ {
+ $path = new Path();
+
+ foreach (new EdgeIterator($matrix) as $edge) {
+ $points = $edge->getSimplifiedPoints();
+ $length = count($points);
+
+ $currentPoint = $points[0];
+ $nextPoint = $points[1];
+ $horizontal = ($currentPoint[1] === $nextPoint[1]);
+
+ if ($horizontal) {
+ $right = $nextPoint[0] > $currentPoint[0];
+ $path = $path->move(
+ $currentPoint[0] + ($right ? $this->intensity : -$this->intensity),
+ $currentPoint[1]
+ );
+ } else {
+ $up = $nextPoint[0] < $currentPoint[0];
+ $path = $path->move(
+ $currentPoint[0],
+ $currentPoint[1] + ($up ? -$this->intensity : $this->intensity)
+ );
+ }
+
+ for ($i = 1; $i <= $length; ++$i) {
+ if ($i === $length) {
+ $previousPoint = $points[$length - 1];
+ $currentPoint = $points[0];
+ $nextPoint = $points[1];
+ } else {
+ $previousPoint = $points[(0 === $i ? $length : $i) - 1];
+ $currentPoint = $points[$i];
+ $nextPoint = $points[($length - 1 === $i ? -1 : $i) + 1];
+ }
+
+ $horizontal = ($previousPoint[1] === $currentPoint[1]);
+
+ if ($horizontal) {
+ $right = $previousPoint[0] < $currentPoint[0];
+ $up = $nextPoint[1] < $currentPoint[1];
+ $sweep = ($up xor $right);
+
+ if ($this->intensity < 0.5
+ || ($right && $previousPoint[0] !== $currentPoint[0] - 1)
+ || (! $right && $previousPoint[0] - 1 !== $currentPoint[0])
+ ) {
+ $path = $path->line(
+ $currentPoint[0] + ($right ? -$this->intensity : $this->intensity),
+ $currentPoint[1]
+ );
+ }
+
+ $path = $path->ellipticArc(
+ $this->intensity,
+ $this->intensity,
+ 0,
+ false,
+ $sweep,
+ $currentPoint[0],
+ $currentPoint[1] + ($up ? -$this->intensity : $this->intensity)
+ );
+ } else {
+ $up = $previousPoint[1] > $currentPoint[1];
+ $right = $nextPoint[0] > $currentPoint[0];
+ $sweep = ! ($up xor $right);
+
+ if ($this->intensity < 0.5
+ || ($up && $previousPoint[1] !== $currentPoint[1] + 1)
+ || (! $up && $previousPoint[0] + 1 !== $currentPoint[0])
+ ) {
+ $path = $path->line(
+ $currentPoint[0],
+ $currentPoint[1] + ($up ? $this->intensity : -$this->intensity)
+ );
+ }
+
+ $path = $path->ellipticArc(
+ $this->intensity,
+ $this->intensity,
+ 0,
+ false,
+ $sweep,
+ $currentPoint[0] + ($right ? $this->intensity : -$this->intensity),
+ $currentPoint[1]
+ );
+ }
+ }
+
+ $path = $path->close();
+ }
+
+ return $path;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php
new file mode 100644
index 0000000..9ab4607
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php
@@ -0,0 +1,47 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Module;
+
+use BaconQrCode\Encoder\ByteMatrix;
+use BaconQrCode\Renderer\Module\EdgeIterator\EdgeIterator;
+use BaconQrCode\Renderer\Path\Path;
+
+/**
+ * Groups modules together to a single path.
+ */
+final class SquareModule implements ModuleInterface
+{
+ /**
+ * @var self|null
+ */
+ private static $instance;
+
+ private function __construct()
+ {
+ }
+
+ public static function instance() : self
+ {
+ return self::$instance ?: self::$instance = new self();
+ }
+
+ public function createPath(ByteMatrix $matrix) : Path
+ {
+ $path = new Path();
+
+ foreach (new EdgeIterator($matrix) as $edge) {
+ $points = $edge->getSimplifiedPoints();
+ $length = count($points);
+ $path = $path->move($points[0][0], $points[0][1]);
+
+ for ($i = 1; $i < $length; ++$i) {
+ $path = $path->line($points[$i][0], $points[$i][1]);
+ }
+
+ $path = $path->close();
+ }
+
+ return $path;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php
new file mode 100644
index 0000000..b07feb0
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php
@@ -0,0 +1,29 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Path;
+
+final class Close implements OperationInterface
+{
+ /**
+ * @var self|null
+ */
+ private static $instance;
+
+ private function __construct()
+ {
+ }
+
+ public static function instance() : self
+ {
+ return self::$instance ?: self::$instance = new self();
+ }
+
+ /**
+ * @return self
+ */
+ public function translate(float $x, float $y) : OperationInterface
+ {
+ return $this;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Curve.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Curve.php
new file mode 100644
index 0000000..c067c74
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Curve.php
@@ -0,0 +1,92 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Path;
+
+final class Curve implements OperationInterface
+{
+ /**
+ * @var float
+ */
+ private $x1;
+
+ /**
+ * @var float
+ */
+ private $y1;
+
+ /**
+ * @var float
+ */
+ private $x2;
+
+ /**
+ * @var float
+ */
+ private $y2;
+
+ /**
+ * @var float
+ */
+ private $x3;
+
+ /**
+ * @var float
+ */
+ private $y3;
+
+ public function __construct(float $x1, float $y1, float $x2, float $y2, float $x3, float $y3)
+ {
+ $this->x1 = $x1;
+ $this->y1 = $y1;
+ $this->x2 = $x2;
+ $this->y2 = $y2;
+ $this->x3 = $x3;
+ $this->y3 = $y3;
+ }
+
+ public function getX1() : float
+ {
+ return $this->x1;
+ }
+
+ public function getY1() : float
+ {
+ return $this->y1;
+ }
+
+ public function getX2() : float
+ {
+ return $this->x2;
+ }
+
+ public function getY2() : float
+ {
+ return $this->y2;
+ }
+
+ public function getX3() : float
+ {
+ return $this->x3;
+ }
+
+ public function getY3() : float
+ {
+ return $this->y3;
+ }
+
+ /**
+ * @return self
+ */
+ public function translate(float $x, float $y) : OperationInterface
+ {
+ return new self(
+ $this->x1 + $x,
+ $this->y1 + $y,
+ $this->x2 + $x,
+ $this->y2 + $y,
+ $this->x3 + $x,
+ $this->y3 + $y
+ );
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php
new file mode 100644
index 0000000..eff7deb
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php
@@ -0,0 +1,278 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Path;
+
+final class EllipticArc implements OperationInterface
+{
+ private const ZERO_TOLERANCE = 1e-05;
+
+ /**
+ * @var float
+ */
+ private $xRadius;
+
+ /**
+ * @var float
+ */
+ private $yRadius;
+
+ /**
+ * @var float
+ */
+ private $xAxisAngle;
+
+ /**
+ * @var bool
+ */
+ private $largeArc;
+
+ /**
+ * @var bool
+ */
+ private $sweep;
+
+ /**
+ * @var float
+ */
+ private $x;
+
+ /**
+ * @var float
+ */
+ private $y;
+
+ public function __construct(
+ float $xRadius,
+ float $yRadius,
+ float $xAxisAngle,
+ bool $largeArc,
+ bool $sweep,
+ float $x,
+ float $y
+ ) {
+ $this->xRadius = abs($xRadius);
+ $this->yRadius = abs($yRadius);
+ $this->xAxisAngle = $xAxisAngle % 360;
+ $this->largeArc = $largeArc;
+ $this->sweep = $sweep;
+ $this->x = $x;
+ $this->y = $y;
+ }
+
+ public function getXRadius() : float
+ {
+ return $this->xRadius;
+ }
+
+ public function getYRadius() : float
+ {
+ return $this->yRadius;
+ }
+
+ public function getXAxisAngle() : float
+ {
+ return $this->xAxisAngle;
+ }
+
+ public function isLargeArc() : bool
+ {
+ return $this->largeArc;
+ }
+
+ public function isSweep() : bool
+ {
+ return $this->sweep;
+ }
+
+ public function getX() : float
+ {
+ return $this->x;
+ }
+
+ public function getY() : float
+ {
+ return $this->y;
+ }
+
+ /**
+ * @return self
+ */
+ public function translate(float $x, float $y) : OperationInterface
+ {
+ return new self(
+ $this->xRadius,
+ $this->yRadius,
+ $this->xAxisAngle,
+ $this->largeArc,
+ $this->sweep,
+ $this->x + $x,
+ $this->y + $y
+ );
+ }
+
+ /**
+ * Converts the elliptic arc to multiple curves.
+ *
+ * Since not all image back ends support elliptic arcs, this method allows to convert the arc into multiple curves
+ * resembling the same result.
+ *
+ * @see https://mortoray.com/2017/02/16/rendering-an-svg-elliptical-arc-as-bezier-curves/
+ * @return array<Curve|Line>
+ */
+ public function toCurves(float $fromX, float $fromY) : array
+ {
+ if (sqrt(($fromX - $this->x) ** 2 + ($fromY - $this->y) ** 2) < self::ZERO_TOLERANCE) {
+ return [];
+ }
+
+ if ($this->xRadius < self::ZERO_TOLERANCE || $this->yRadius < self::ZERO_TOLERANCE) {
+ return [new Line($this->x, $this->y)];
+ }
+
+ return $this->createCurves($fromX, $fromY);
+ }
+
+ /**
+ * @return Curve[]
+ */
+ private function createCurves(float $fromX, $fromY) : array
+ {
+ $xAngle = deg2rad($this->xAxisAngle);
+ list($centerX, $centerY, $radiusX, $radiusY, $startAngle, $deltaAngle) =
+ $this->calculateCenterPointParameters($fromX, $fromY, $xAngle);
+
+ $s = $startAngle;
+ $e = $s + $deltaAngle;
+ $sign = ($e < $s) ? -1 : 1;
+ $remain = abs($e - $s);
+ $p1 = self::point($centerX, $centerY, $radiusX, $radiusY, $xAngle, $s);
+ $curves = [];
+
+ while ($remain > self::ZERO_TOLERANCE) {
+ $step = min($remain, pi() / 2);
+ $signStep = $step * $sign;
+ $p2 = self::point($centerX, $centerY, $radiusX, $radiusY, $xAngle, $s + $signStep);
+
+ $alphaT = tan($signStep / 2);
+ $alpha = sin($signStep) * (sqrt(4 + 3 * $alphaT ** 2) - 1) / 3;
+ $d1 = self::derivative($radiusX, $radiusY, $xAngle, $s);
+ $d2 = self::derivative($radiusX, $radiusY, $xAngle, $s + $signStep);
+
+ $curves[] = new Curve(
+ $p1[0] + $alpha * $d1[0],
+ $p1[1] + $alpha * $d1[1],
+ $p2[0] - $alpha * $d2[0],
+ $p2[1] - $alpha * $d2[1],
+ $p2[0],
+ $p2[1]
+ );
+
+ $s += $signStep;
+ $remain -= $step;
+ $p1 = $p2;
+ }
+
+ return $curves;
+ }
+
+ /**
+ * @return float[]
+ */
+ private function calculateCenterPointParameters(float $fromX, float $fromY, float $xAngle)
+ {
+ $rX = $this->xRadius;
+ $rY = $this->yRadius;
+
+ // F.6.5.1
+ $dx2 = ($fromX - $this->x) / 2;
+ $dy2 = ($fromY - $this->y) / 2;
+ $x1p = cos($xAngle) * $dx2 + sin($xAngle) * $dy2;
+ $y1p = -sin($xAngle) * $dx2 + cos($xAngle) * $dy2;
+
+ // F.6.5.2
+ $rxs = $rX ** 2;
+ $rys = $rY ** 2;
+ $x1ps = $x1p ** 2;
+ $y1ps = $y1p ** 2;
+ $cr = $x1ps / $rxs + $y1ps / $rys;
+
+ if ($cr > 1) {
+ $s = sqrt($cr);
+ $rX *= $s;
+ $rY *= $s;
+ $rxs = $rX ** 2;
+ $rys = $rY ** 2;
+ }
+
+ $dq = ($rxs * $y1ps + $rys * $x1ps);
+ $pq = ($rxs * $rys - $dq) / $dq;
+ $q = sqrt(max(0, $pq));
+
+ if ($this->largeArc === $this->sweep) {
+ $q = -$q;
+ }
+
+ $cxp = $q * $rX * $y1p / $rY;
+ $cyp = -$q * $rY * $x1p / $rX;
+
+ // F.6.5.3
+ $cx = cos($xAngle) * $cxp - sin($xAngle) * $cyp + ($fromX + $this->x) / 2;
+ $cy = sin($xAngle) * $cxp + cos($xAngle) * $cyp + ($fromY + $this->y) / 2;
+
+ // F.6.5.5
+ $theta = self::angle(1, 0, ($x1p - $cxp) / $rX, ($y1p - $cyp) / $rY);
+
+ // F.6.5.6
+ $delta = self::angle(($x1p - $cxp) / $rX, ($y1p - $cyp) / $rY, (-$x1p - $cxp) / $rX, (-$y1p - $cyp) / $rY);
+ $delta = fmod($delta, pi() * 2);
+
+ if (! $this->sweep) {
+ $delta -= 2 * pi();
+ }
+
+ return [$cx, $cy, $rX, $rY, $theta, $delta];
+ }
+
+ private static function angle(float $ux, float $uy, float $vx, float $vy) : float
+ {
+ // F.6.5.4
+ $dot = $ux * $vx + $uy * $vy;
+ $length = sqrt($ux ** 2 + $uy ** 2) * sqrt($vx ** 2 + $vy ** 2);
+ $angle = acos(min(1, max(-1, $dot / $length)));
+
+ if (($ux * $vy - $uy * $vx) < 0) {
+ return -$angle;
+ }
+
+ return $angle;
+ }
+
+ /**
+ * @return float[]
+ */
+ private static function point(
+ float $centerX,
+ float $centerY,
+ float $radiusX,
+ float $radiusY,
+ float $xAngle,
+ float $angle
+ ) : array {
+ return [
+ $centerX + $radiusX * cos($xAngle) * cos($angle) - $radiusY * sin($xAngle) * sin($angle),
+ $centerY + $radiusX * sin($xAngle) * cos($angle) + $radiusY * cos($xAngle) * sin($angle),
+ ];
+ }
+
+ /**
+ * @return float[]
+ */
+ private static function derivative(float $radiusX, float $radiusY, float $xAngle, float $angle) : array
+ {
+ return [
+ -$radiusX * cos($xAngle) * sin($angle) - $radiusY * sin($xAngle) * cos($angle),
+ -$radiusX * sin($xAngle) * sin($angle) + $radiusY * cos($xAngle) * cos($angle),
+ ];
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php
new file mode 100644
index 0000000..3149a39
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php
@@ -0,0 +1,41 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Path;
+
+final class Line implements OperationInterface
+{
+ /**
+ * @var float
+ */
+ private $x;
+
+ /**
+ * @var float
+ */
+ private $y;
+
+ public function __construct(float $x, float $y)
+ {
+ $this->x = $x;
+ $this->y = $y;
+ }
+
+ public function getX() : float
+ {
+ return $this->x;
+ }
+
+ public function getY() : float
+ {
+ return $this->y;
+ }
+
+ /**
+ * @return self
+ */
+ public function translate(float $x, float $y) : OperationInterface
+ {
+ return new self($this->x + $x, $this->y + $y);
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php
new file mode 100644
index 0000000..007b77c
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php
@@ -0,0 +1,41 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Path;
+
+final class Move implements OperationInterface
+{
+ /**
+ * @var float
+ */
+ private $x;
+
+ /**
+ * @var float
+ */
+ private $y;
+
+ public function __construct(float $x, float $y)
+ {
+ $this->x = $x;
+ $this->y = $y;
+ }
+
+ public function getX() : float
+ {
+ return $this->x;
+ }
+
+ public function getY() : float
+ {
+ return $this->y;
+ }
+
+ /**
+ * @return self
+ */
+ public function translate(float $x, float $y) : OperationInterface
+ {
+ return new self($this->x + $x, $this->x + $y);
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php
new file mode 100644
index 0000000..a5fa0ed
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php
@@ -0,0 +1,12 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Path;
+
+interface OperationInterface
+{
+ /**
+ * Translates the operation's coordinates.
+ */
+ public function translate(float $x, float $y) : self;
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Path.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Path.php
new file mode 100644
index 0000000..8e5e298
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/Path/Path.php
@@ -0,0 +1,106 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\Path;
+
+use IteratorAggregate;
+use Traversable;
+
+/**
+ * Internal Representation of a vector path.
+ */
+final class Path implements IteratorAggregate
+{
+ /**
+ * @var OperationInterface[]
+ */
+ private $operations = [];
+
+ /**
+ * Moves the drawing operation to a certain position.
+ */
+ public function move(float $x, float $y) : self
+ {
+ $path = clone $this;
+ $path->operations[] = new Move($x, $y);
+ return $path;
+ }
+
+ /**
+ * Draws a line from the current position to another position.
+ */
+ public function line(float $x, float $y) : self
+ {
+ $path = clone $this;
+ $path->operations[] = new Line($x, $y);
+ return $path;
+ }
+
+ /**
+ * Draws an elliptic arc from the current position to another position.
+ */
+ public function ellipticArc(
+ float $xRadius,
+ float $yRadius,
+ float $xAxisRotation,
+ bool $largeArc,
+ bool $sweep,
+ float $x,
+ float $y
+ ) : self {
+ $path = clone $this;
+ $path->operations[] = new EllipticArc($xRadius, $yRadius, $xAxisRotation, $largeArc, $sweep, $x, $y);
+ return $path;
+ }
+
+ /**
+ * Draws a curve from the current position to another position.
+ */
+ public function curve(float $x1, float $y1, float $x2, float $y2, float $x3, float $y3) : self
+ {
+ $path = clone $this;
+ $path->operations[] = new Curve($x1, $y1, $x2, $y2, $x3, $y3);
+ return $path;
+ }
+
+ /**
+ * Closes a sub-path.
+ */
+ public function close() : self
+ {
+ $path = clone $this;
+ $path->operations[] = Close::instance();
+ return $path;
+ }
+
+ /**
+ * Appends another path to this one.
+ */
+ public function append(self $other) : self
+ {
+ $path = clone $this;
+ $path->operations = array_merge($this->operations, $other->operations);
+ return $path;
+ }
+
+ public function translate(float $x, float $y) : self
+ {
+ $path = new self();
+
+ foreach ($this->operations as $operation) {
+ $path->operations[] = $operation->translate($x, $y);
+ }
+
+ return $path;
+ }
+
+ /**
+ * @return OperationInterface[]|Traversable
+ */
+ public function getIterator() : Traversable
+ {
+ foreach ($this->operations as $operation) {
+ yield $operation;
+ }
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php
new file mode 100644
index 0000000..8aa7652
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php
@@ -0,0 +1,86 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer;
+
+use BaconQrCode\Encoder\QrCode;
+use BaconQrCode\Exception\InvalidArgumentException;
+
+final class PlainTextRenderer implements RendererInterface
+{
+ /**
+ * UTF-8 full block (U+2588)
+ */
+ private const FULL_BLOCK = "\xe2\x96\x88";
+
+ /**
+ * UTF-8 upper half block (U+2580)
+ */
+ private const UPPER_HALF_BLOCK = "\xe2\x96\x80";
+
+ /**
+ * UTF-8 lower half block (U+2584)
+ */
+ private const LOWER_HALF_BLOCK = "\xe2\x96\x84";
+
+ /**
+ * UTF-8 no-break space (U+00A0)
+ */
+ private const EMPTY_BLOCK = "\xc2\xa0";
+
+ /**
+ * @var int
+ */
+ private $margin;
+
+ public function __construct(int $margin = 2)
+ {
+ $this->margin = $margin;
+ }
+
+ /**
+ * @throws InvalidArgumentException if matrix width doesn't match height
+ */
+ public function render(QrCode $qrCode) : string
+ {
+ $matrix = $qrCode->getMatrix();
+ $matrixSize = $matrix->getWidth();
+
+ if ($matrixSize !== $matrix->getHeight()) {
+ throw new InvalidArgumentException('Matrix must have the same width and height');
+ }
+
+ $rows = $matrix->getArray()->toArray();
+
+ if (0 !== $matrixSize % 2) {
+ $rows[] = array_fill(0, $matrixSize, 0);
+ }
+
+ $horizontalMargin = str_repeat(self::EMPTY_BLOCK, $this->margin);
+ $result = str_repeat("\n", (int) ceil($this->margin / 2));
+
+ for ($i = 0; $i < $matrixSize; $i += 2) {
+ $result .= $horizontalMargin;
+
+ $upperRow = $rows[$i];
+ $lowerRow = $rows[$i + 1];
+
+ for ($j = 0; $j < $matrixSize; ++$j) {
+ $upperBit = $upperRow[$j];
+ $lowerBit = $lowerRow[$j];
+
+ if ($upperBit) {
+ $result .= $lowerBit ? self::FULL_BLOCK : self::UPPER_HALF_BLOCK;
+ } else {
+ $result .= $lowerBit ? self::LOWER_HALF_BLOCK : self::EMPTY_BLOCK;
+ }
+ }
+
+ $result .= $horizontalMargin . "\n";
+ }
+
+ $result .= str_repeat("\n", (int) ceil($this->margin / 2));
+
+ return $result;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php
new file mode 100644
index 0000000..b0aae39
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php
@@ -0,0 +1,11 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer;
+
+use BaconQrCode\Encoder\QrCode;
+
+interface RendererInterface
+{
+ public function render(QrCode $qrCode) : string;
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/EyeFill.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/EyeFill.php
new file mode 100644
index 0000000..46abc22
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/EyeFill.php
@@ -0,0 +1,74 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\RendererStyle;
+
+use BaconQrCode\Exception\RuntimeException;
+use BaconQrCode\Renderer\Color\ColorInterface;
+
+final class EyeFill
+{
+ /**
+ * @var ColorInterface|null
+ */
+ private $externalColor;
+
+ /**
+ * @var ColorInterface|null
+ */
+ private $internalColor;
+
+ /**
+ * @var self|null
+ */
+ private static $inherit;
+
+ public function __construct(?ColorInterface $externalColor, ?ColorInterface $internalColor)
+ {
+ $this->externalColor = $externalColor;
+ $this->internalColor = $internalColor;
+ }
+
+ public static function uniform(ColorInterface $color) : self
+ {
+ return new self($color, $color);
+ }
+
+ public static function inherit() : self
+ {
+ return self::$inherit ?: self::$inherit = new self(null, null);
+ }
+
+ public function inheritsBothColors() : bool
+ {
+ return null === $this->externalColor && null === $this->internalColor;
+ }
+
+ public function inheritsExternalColor() : bool
+ {
+ return null === $this->externalColor;
+ }
+
+ public function inheritsInternalColor() : bool
+ {
+ return null === $this->internalColor;
+ }
+
+ public function getExternalColor() : ColorInterface
+ {
+ if (null === $this->externalColor) {
+ throw new RuntimeException('External eye color inherits foreground color');
+ }
+
+ return $this->externalColor;
+ }
+
+ public function getInternalColor() : ColorInterface
+ {
+ if (null === $this->internalColor) {
+ throw new RuntimeException('Internal eye color inherits foreground color');
+ }
+
+ return $this->internalColor;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php
new file mode 100644
index 0000000..d54268e
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php
@@ -0,0 +1,168 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\RendererStyle;
+
+use BaconQrCode\Exception\RuntimeException;
+use BaconQrCode\Renderer\Color\ColorInterface;
+use BaconQrCode\Renderer\Color\Gray;
+
+final class Fill
+{
+ /**
+ * @var ColorInterface
+ */
+ private $backgroundColor;
+
+ /**
+ * @var ColorInterface|null
+ */
+ private $foregroundColor;
+
+ /**
+ * @var Gradient|null
+ */
+ private $foregroundGradient;
+
+ /**
+ * @var EyeFill
+ */
+ private $topLeftEyeFill;
+
+ /**
+ * @var EyeFill
+ */
+ private $topRightEyeFill;
+
+ /**
+ * @var EyeFill
+ */
+ private $bottomLeftEyeFill;
+
+ /**
+ * @var self|null
+ */
+ private static $default;
+
+ private function __construct(
+ ColorInterface $backgroundColor,
+ ?ColorInterface $foregroundColor,
+ ?Gradient $foregroundGradient,
+ EyeFill $topLeftEyeFill,
+ EyeFill $topRightEyeFill,
+ EyeFill $bottomLeftEyeFill
+ ) {
+ $this->backgroundColor = $backgroundColor;
+ $this->foregroundColor = $foregroundColor;
+ $this->foregroundGradient = $foregroundGradient;
+ $this->topLeftEyeFill = $topLeftEyeFill;
+ $this->topRightEyeFill = $topRightEyeFill;
+ $this->bottomLeftEyeFill = $bottomLeftEyeFill;
+ }
+
+ public static function default() : self
+ {
+ return self::$default ?: self::$default = self::uniformColor(new Gray(100), new Gray(0));
+ }
+
+ public static function withForegroundColor(
+ ColorInterface $backgroundColor,
+ ColorInterface $foregroundColor,
+ EyeFill $topLeftEyeFill,
+ EyeFill $topRightEyeFill,
+ EyeFill $bottomLeftEyeFill
+ ) : self {
+ return new self(
+ $backgroundColor,
+ $foregroundColor,
+ null,
+ $topLeftEyeFill,
+ $topRightEyeFill,
+ $bottomLeftEyeFill
+ );
+ }
+
+ public static function withForegroundGradient(
+ ColorInterface $backgroundColor,
+ Gradient $foregroundGradient,
+ EyeFill $topLeftEyeFill,
+ EyeFill $topRightEyeFill,
+ EyeFill $bottomLeftEyeFill
+ ) : self {
+ return new self(
+ $backgroundColor,
+ null,
+ $foregroundGradient,
+ $topLeftEyeFill,
+ $topRightEyeFill,
+ $bottomLeftEyeFill
+ );
+ }
+
+ public static function uniformColor(ColorInterface $backgroundColor, ColorInterface $foregroundColor) : self
+ {
+ return new self(
+ $backgroundColor,
+ $foregroundColor,
+ null,
+ EyeFill::inherit(),
+ EyeFill::inherit(),
+ EyeFill::inherit()
+ );
+ }
+
+ public static function uniformGradient(ColorInterface $backgroundColor, Gradient $foregroundGradient) : self
+ {
+ return new self(
+ $backgroundColor,
+ null,
+ $foregroundGradient,
+ EyeFill::inherit(),
+ EyeFill::inherit(),
+ EyeFill::inherit()
+ );
+ }
+
+ public function hasGradientFill() : bool
+ {
+ return null !== $this->foregroundGradient;
+ }
+
+ public function getBackgroundColor() : ColorInterface
+ {
+ return $this->backgroundColor;
+ }
+
+ public function getForegroundColor() : ColorInterface
+ {
+ if (null === $this->foregroundColor) {
+ throw new RuntimeException('Fill uses a gradient, thus no foreground color is available');
+ }
+
+ return $this->foregroundColor;
+ }
+
+ public function getForegroundGradient() : Gradient
+ {
+ if (null === $this->foregroundGradient) {
+ throw new RuntimeException('Fill uses a single color, thus no foreground gradient is available');
+ }
+
+ return $this->foregroundGradient;
+ }
+
+ public function getTopLeftEyeFill() : EyeFill
+ {
+ return $this->topLeftEyeFill;
+ }
+
+ public function getTopRightEyeFill() : EyeFill
+ {
+ return $this->topRightEyeFill;
+ }
+
+ public function getBottomLeftEyeFill() : EyeFill
+ {
+ return $this->bottomLeftEyeFill;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php
new file mode 100644
index 0000000..3813dfd
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php
@@ -0,0 +1,46 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\RendererStyle;
+
+use BaconQrCode\Renderer\Color\ColorInterface;
+
+final class Gradient
+{
+ /**
+ * @var ColorInterface
+ */
+ private $startColor;
+
+ /**
+ * @var ColorInterface
+ */
+ private $endColor;
+
+ /**
+ * @var GradientType
+ */
+ private $type;
+
+ public function __construct(ColorInterface $startColor, ColorInterface $endColor, GradientType $type)
+ {
+ $this->startColor = $startColor;
+ $this->endColor = $endColor;
+ $this->type = $type;
+ }
+
+ public function getStartColor() : ColorInterface
+ {
+ return $this->startColor;
+ }
+
+ public function getEndColor() : ColorInterface
+ {
+ return $this->endColor;
+ }
+
+ public function getType() : GradientType
+ {
+ return $this->type;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php
new file mode 100644
index 0000000..c1ca754
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\RendererStyle;
+
+use DASPRiD\Enum\AbstractEnum;
+
+/**
+ * @method static self VERTICAL()
+ * @method static self HORIZONTAL()
+ * @method static self DIAGONAL()
+ * @method static self INVERSE_DIAGONAL()
+ * @method static self RADIAL()
+ */
+final class GradientType extends AbstractEnum
+{
+ protected const VERTICAL = null;
+ protected const HORIZONTAL = null;
+ protected const DIAGONAL = null;
+ protected const INVERSE_DIAGONAL = null;
+ protected const RADIAL = null;
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/RendererStyle.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/RendererStyle.php
new file mode 100644
index 0000000..e03e099
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/RendererStyle.php
@@ -0,0 +1,90 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode\Renderer\RendererStyle;
+
+use BaconQrCode\Renderer\Eye\EyeInterface;
+use BaconQrCode\Renderer\Eye\ModuleEye;
+use BaconQrCode\Renderer\Module\ModuleInterface;
+use BaconQrCode\Renderer\Module\SquareModule;
+
+final class RendererStyle
+{
+ /**
+ * @var int
+ */
+ private $size;
+
+ /**
+ * @var int
+ */
+ private $margin;
+
+ /**
+ * @var ModuleInterface
+ */
+ private $module;
+
+ /**
+ * @var EyeInterface|null
+ */
+ private $eye;
+
+ /**
+ * @var Fill
+ */
+ private $fill;
+
+ public function __construct(
+ int $size,
+ int $margin = 4,
+ ?ModuleInterface $module = null,
+ ?EyeInterface $eye = null,
+ ?Fill $fill = null
+ ) {
+ $this->margin = $margin;
+ $this->size = $size;
+ $this->module = $module ?: SquareModule::instance();
+ $this->eye = $eye ?: new ModuleEye($this->module);
+ $this->fill = $fill ?: Fill::default();
+ }
+
+ public function withSize(int $size) : self
+ {
+ $style = clone $this;
+ $style->size = $size;
+ return $style;
+ }
+
+ public function withMargin(int $margin) : self
+ {
+ $style = clone $this;
+ $style->margin = $margin;
+ return $style;
+ }
+
+ public function getSize() : int
+ {
+ return $this->size;
+ }
+
+ public function getMargin() : int
+ {
+ return $this->margin;
+ }
+
+ public function getModule() : ModuleInterface
+ {
+ return $this->module;
+ }
+
+ public function getEye() : EyeInterface
+ {
+ return $this->eye;
+ }
+
+ public function getFill() : Fill
+ {
+ return $this->fill;
+ }
+}
diff --git a/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Writer.php b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Writer.php
new file mode 100644
index 0000000..6688901
--- /dev/null
+++ b/srcs/phpmyadmin/vendor/bacon/bacon-qr-code/src/Writer.php
@@ -0,0 +1,68 @@
+<?php
+declare(strict_types = 1);
+
+namespace BaconQrCode;
+
+use BaconQrCode\Common\ErrorCorrectionLevel;
+use BaconQrCode\Encoder\Encoder;
+use BaconQrCode\Exception\InvalidArgumentException;
+use BaconQrCode\Renderer\RendererInterface;
+
+/**
+ * QR code writer.
+ */
+final class Writer
+{
+ /**
+ * Renderer instance.
+ *
+ * @var RendererInterface
+ */
+ private $renderer;
+
+ /**
+ * Creates a new writer with a specific renderer.
+ */
+ public function __construct(RendererInterface $renderer)
+ {
+ $this->renderer = $renderer;
+ }
+
+ /**
+ * Writes QR code and returns it as string.
+ *
+ * Content is a string which *should* be encoded in UTF-8, in case there are
+ * non ASCII-characters present.
+ *
+ * @throws InvalidArgumentException if the content is empty
+ */
+ public function writeString(
+ string $content,
+ string $encoding = Encoder::DEFAULT_BYTE_MODE_ECODING,
+ ?ErrorCorrectionLevel $ecLevel = null
+ ) : string {
+ if (strlen($content) === 0) {
+ throw new InvalidArgumentException('Found empty contents');
+ }
+
+ if (null === $ecLevel) {
+ $ecLevel = ErrorCorrectionLevel::L();
+ }
+
+ return $this->renderer->render(Encoder::encode($content, $ecLevel, $encoding));
+ }
+
+ /**
+ * Writes QR code to a file.
+ *
+ * @see Writer::writeString()
+ */
+ public function writeFile(
+ string $content,
+ string $filename,
+ string $encoding = Encoder::DEFAULT_BYTE_MODE_ECODING,
+ ?ErrorCorrectionLevel $ecLevel = null
+ ) : void {
+ file_put_contents($filename, $this->writeString($content, $encoding, $ecLevel));
+ }
+}