/home/kueuepay/www/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php
<?php declare(strict_types=1);

namespace PhpParser\Lexer;

use PhpParser\Error;
use PhpParser\ErrorHandler;
use PhpParser\Lexer;
use PhpParser\Lexer\TokenEmulator\AttributeEmulator;
use PhpParser\Lexer\TokenEmulator\EnumTokenEmulator;
use PhpParser\Lexer\TokenEmulator\CoaleseEqualTokenEmulator;
use PhpParser\Lexer\TokenEmulator\ExplicitOctalEmulator;
use PhpParser\Lexer\TokenEmulator\FlexibleDocStringEmulator;
use PhpParser\Lexer\TokenEmulator\FnTokenEmulator;
use PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
use PhpParser\Lexer\TokenEmulator\NullsafeTokenEmulator;
use PhpParser\Lexer\TokenEmulator\NumericLiteralSeparatorEmulator;
use PhpParser\Lexer\TokenEmulator\ReadonlyFunctionTokenEmulator;
use PhpParser\Lexer\TokenEmulator\ReadonlyTokenEmulator;
use PhpParser\Lexer\TokenEmulator\ReverseEmulator;
use PhpParser\Lexer\TokenEmulator\TokenEmulator;
use PhpParser\PhpVersion;
use PhpParser\Token;

class Emulative extends Lexer {
    /** @var array{int, string, string}[] Patches used to reverse changes introduced in the code */
    private array $patches = [];

    /** @var list<TokenEmulator> */
    private array $emulators = [];

    private PhpVersion $targetPhpVersion;

    private PhpVersion $hostPhpVersion;

    /**
     * @param PhpVersion|null $phpVersion PHP version to emulate. Defaults to newest supported.
     */
    public function __construct(?PhpVersion $phpVersion = null) {
        $this->targetPhpVersion = $phpVersion ?? PhpVersion::getNewestSupported();
        $this->hostPhpVersion = PhpVersion::getHostVersion();

        $emulators = [
            new MatchTokenEmulator(),
            new NullsafeTokenEmulator(),
            new AttributeEmulator(),
            new EnumTokenEmulator(),
            new ReadonlyTokenEmulator(),
            new ExplicitOctalEmulator(),
            new ReadonlyFunctionTokenEmulator(),
        ];

        // Collect emulators that are relevant for the PHP version we're running
        // and the PHP version we're targeting for emulation.
        foreach ($emulators as $emulator) {
            $emulatorPhpVersion = $emulator->getPhpVersion();
            if ($this->isForwardEmulationNeeded($emulatorPhpVersion)) {
                $this->emulators[] = $emulator;
            } elseif ($this->isReverseEmulationNeeded($emulatorPhpVersion)) {
                $this->emulators[] = new ReverseEmulator($emulator);
            }
        }
    }

    public function tokenize(string $code, ?ErrorHandler $errorHandler = null): array {
        $emulators = array_filter($this->emulators, function ($emulator) use ($code) {
            return $emulator->isEmulationNeeded($code);
        });

        if (empty($emulators)) {
            // Nothing to emulate, yay
            return parent::tokenize($code, $errorHandler);
        }

        if ($errorHandler === null) {
            $errorHandler = new ErrorHandler\Throwing();
        }

        $this->patches = [];
        foreach ($emulators as $emulator) {
            $code = $emulator->preprocessCode($code, $this->patches);
        }

        $collector = new ErrorHandler\Collecting();
        $tokens = parent::tokenize($code, $collector);
        $this->sortPatches();
        $tokens = $this->fixupTokens($tokens);

        $errors = $collector->getErrors();
        if (!empty($errors)) {
            $this->fixupErrors($errors);
            foreach ($errors as $error) {
                $errorHandler->handleError($error);
            }
        }

        foreach ($emulators as $emulator) {
            $tokens = $emulator->emulate($code, $tokens);
        }

        return $tokens;
    }

    private function isForwardEmulationNeeded(PhpVersion $emulatorPhpVersion): bool {
        return $this->hostPhpVersion->older($emulatorPhpVersion)
            && $this->targetPhpVersion->newerOrEqual($emulatorPhpVersion);
    }

    private function isReverseEmulationNeeded(PhpVersion $emulatorPhpVersion): bool {
        return $this->hostPhpVersion->newerOrEqual($emulatorPhpVersion)
            && $this->targetPhpVersion->older($emulatorPhpVersion);
    }

    private function sortPatches(): void {
        // Patches may be contributed by different emulators.
        // Make sure they are sorted by increasing patch position.
        usort($this->patches, function ($p1, $p2) {
            return $p1[0] <=> $p2[0];
        });
    }

    /**
     * @param list<Token> $tokens
     * @return list<Token>
     */
    private function fixupTokens(array $tokens): array {
        if (\count($this->patches) === 0) {
            return $tokens;
        }

        // Load first patch
        $patchIdx = 0;
        list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];

        // We use a manual loop over the tokens, because we modify the array on the fly
        $posDelta = 0;
        $lineDelta = 0;
        for ($i = 0, $c = \count($tokens); $i < $c; $i++) {
            $token = $tokens[$i];
            $pos = $token->pos;
            $token->pos += $posDelta;
            $token->line += $lineDelta;
            $localPosDelta = 0;
            $len = \strlen($token->text);
            while ($patchPos >= $pos && $patchPos < $pos + $len) {
                $patchTextLen = \strlen($patchText);
                if ($patchType === 'remove') {
                    if ($patchPos === $pos && $patchTextLen === $len) {
                        // Remove token entirely
                        array_splice($tokens, $i, 1, []);
                        $i--;
                        $c--;
                    } else {
                        // Remove from token string
                        $token->text = substr_replace(
                            $token->text, '', $patchPos - $pos + $localPosDelta, $patchTextLen
                        );
                        $localPosDelta -= $patchTextLen;
                    }
                    $lineDelta -= \substr_count($patchText, "\n");
                } elseif ($patchType === 'add') {
                    // Insert into the token string
                    $token->text = substr_replace(
                        $token->text, $patchText, $patchPos - $pos + $localPosDelta, 0
                    );
                    $localPosDelta += $patchTextLen;
                    $lineDelta += \substr_count($patchText, "\n");
                } elseif ($patchType === 'replace') {
                    // Replace inside the token string
                    $token->text = substr_replace(
                        $token->text, $patchText, $patchPos - $pos + $localPosDelta, $patchTextLen
                    );
                } else {
                    assert(false);
                }

                // Fetch the next patch
                $patchIdx++;
                if ($patchIdx >= \count($this->patches)) {
                    // No more patches. However, we still need to adjust position.
                    $patchPos = \PHP_INT_MAX;
                    break;
                }

                list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
            }

            $posDelta += $localPosDelta;
        }
        return $tokens;
    }

    /**
     * Fixup line and position information in errors.
     *
     * @param Error[] $errors
     */
    private function fixupErrors(array $errors): void {
        foreach ($errors as $error) {
            $attrs = $error->getAttributes();

            $posDelta = 0;
            $lineDelta = 0;
            foreach ($this->patches as $patch) {
                list($patchPos, $patchType, $patchText) = $patch;
                if ($patchPos >= $attrs['startFilePos']) {
                    // No longer relevant
                    break;
                }

                if ($patchType === 'add') {
                    $posDelta += strlen($patchText);
                    $lineDelta += substr_count($patchText, "\n");
                } elseif ($patchType === 'remove') {
                    $posDelta -= strlen($patchText);
                    $lineDelta -= substr_count($patchText, "\n");
                }
            }

            $attrs['startFilePos'] += $posDelta;
            $attrs['endFilePos'] += $posDelta;
            $attrs['startLine'] += $lineDelta;
            $attrs['endLine'] += $lineDelta;
            $error->setAttributes($attrs);
        }
    }
}
Payment System
top

Simple Steps to Complete Your Payment Securely and Efficiently

Making a payment on our website is quick and secure. Start by logging in or creating an account. Select your preferred payment method, input the required details, and review the information. Once you confirm everything is correct, click on the "Submit Payment" button. You’ll receive instant confirmation and can track your payment status through your account dashboard. It’s an easy and secure process.

  • Go to the Payment Section: Access the payment area on our website or app.
  • Choose Your Payment Method: Select your preferred payment option.
  • Enter Payment Details: Provide the necessary payment information.
  • Verify Your Information: Check that all details are correct.
  • Confirm Your Payment: Click "Submit Payment" to complete the transaction.
img