PHPackages                             blendbyte/livewire-honeypot - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. blendbyte/livewire-honeypot

ActiveLibrary[Security](/categories/security)

blendbyte/livewire-honeypot
===========================

Honeypot + time-trap spam protection for Livewire 4 forms. No CAPTCHAs, no external requests.

1.2.0(2mo ago)0232↓80.8%MITPHPPHP ^8.5CI passing

Since Mar 19Pushed 2mo agoCompare

[ Source](https://github.com/blendbyte/livewire-honeypot)[ Packagist](https://packagist.org/packages/blendbyte/livewire-honeypot)[ RSS](/packages/blendbyte-livewire-honeypot/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (3)Dependencies (13)Versions (4)Used By (0)

[![livewire-honeypot-banner](https://private-user-images.githubusercontent.com/4669888/578916074-bfa67e85-1864-4cb5-8df5-cf6880850f2f.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODEwNjE1ODIsIm5iZiI6MTc4MTA2MTI4MiwicGF0aCI6Ii80NjY5ODg4LzU3ODkxNjA3NC1iZmE2N2U4NS0xODY0LTRjYjUtOGRmNS1jZjY4ODA4NTBmMmYucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDYxMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjA2MTBUMDMxNDQyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9Yjg5ZDczNDQzNTc1OWFkODAyNThjZjRiNTBjYzcyNGE1YmMwOTVkZDYxNjgyY2QzMDBhYzg4YzVjM2U2NGQ3NCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmcmVzcG9uc2UtY29udGVudC10eXBlPWltYWdlJTJGcG5nIn0.WlMMRAlEvns2THvJJ7cC88j-W2UZSkktz04mq0YN5Z0)](https://private-user-images.githubusercontent.com/4669888/578916074-bfa67e85-1864-4cb5-8df5-cf6880850f2f.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODEwNjE1ODIsIm5iZiI6MTc4MTA2MTI4MiwicGF0aCI6Ii80NjY5ODg4LzU3ODkxNjA3NC1iZmE2N2U4NS0xODY0LTRjYjUtOGRmNS1jZjY4ODA4NTBmMmYucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDYxMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjA2MTBUMDMxNDQyWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9Yjg5ZDczNDQzNTc1OWFkODAyNThjZjRiNTBjYzcyNGE1YmMwOTVkZDYxNjgyY2QzMDBhYzg4YzVjM2U2NGQ3NCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmcmVzcG9uc2UtY29udGVudC10eXBlPWltYWdlJTJGcG5nIn0.WlMMRAlEvns2THvJJ7cC88j-W2UZSkktz04mq0YN5Z0)livewire-honeypot
=================

[](#livewire-honeypot)

[![Latest Version on Packagist](https://camo.githubusercontent.com/a0f7bff82e9ac22eb6bb06294df3220abf82e9ac39c9140022ca6ad722e829d2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f626c656e64627974652f6c697665776972652d686f6e6579706f742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/blendbyte/livewire-honeypot)[![License: MIT](https://camo.githubusercontent.com/a7e65aee57b11d28e4caff8b945729a66be0bb663f7f93bd24c5aa65699f148e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e7376673f7374796c653d666c61742d737175617265)](https://github.com/blendbyte/livewire-honeypot/blob/main/LICENSE)[![PHP](https://camo.githubusercontent.com/67ac4503ce7b6643d4427a7c02ae773e79c0e85b100e34f933ae85b34b227424/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e352532422d3738376362353f7374796c653d666c61742d737175617265)](https://www.php.net)[![Laravel](https://camo.githubusercontent.com/e7572f05cfaad8f83f0c2e74a5cfe06e2084ab3fcb622a2ff809c050237fa527/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31332d6666326432303f7374796c653d666c61742d737175617265)](https://laravel.com)[![Livewire](https://camo.githubusercontent.com/c80084687b7779b856a47c5fc6ab2945fafbedf8d79771d27253a6d64fc4d833/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c697665776972652d342d6662373061393f7374796c653d666c61742d737175617265)](https://livewire.laravel.com)

Lightweight **honeypot + time-trap** protection for **Livewire 4** (Laravel 13). Blocks simple bots without CAPTCHAs — privacy-friendly, zero external requests, and invisible to real users.

Forked from [darvis/livewire-honeypot](https://github.com/darvis/livewire-honeypot).

Features
--------

[](#features)

- **Honeypot bait field** — hidden input that bots fill in, legitimate users never see (`present|size:0`)
- **Time-trap** — enforces a configurable minimum time between page load and submission
- **Token validation** — cryptographically random token verified on each submission
- **Randomized field name** — optionally render the bait field with a random HTML `name` to defeat name-aware bots
- **JS fill verification** — opt-in hidden field populated only by Alpine.js; blocks headless bots that skip JavaScript
- **Livewire Trait** — drop-in protection for any Livewire component
- **Per-component config** — override any honeypot setting per component via `honeypotConfig()`
- **Controller / API Service** — use outside of Livewire for standard form controllers
- **Blade component** — `` renders all hidden fields in one line
- **Configurable spam responder** — choose how spam is handled: validation error, 403 abort, or silent redirect; or provide your own
- **`HoneypotDetected` event** — fired on every spam detection, carrying IP, user-agent, reason, and component
- **Structured logging** — optional log entry on every detection, routed to any Laravel logging channel
- **Testing support** — `HoneypotService::fake()` bypasses validation in tests
- **Multilingual** — 12 translations included
- **Zero extra dependencies** — only requires Livewire 4 / Laravel 13

Requirements
------------

[](#requirements)

DependencyVersionPHP`^8.5`Laravel`^13.0`Livewire`^4.0`Installation
------------

[](#installation)

```
composer require blendbyte/livewire-honeypot
```

The service provider is auto-discovered. No manual registration required.

Quick Start
-----------

[](#quick-start)

Add the `HasHoneypot` trait to your Livewire component and call `validateHoneypot()` in your submit action:

```
use Blendbyte\LivewireHoneypot\Traits\HasHoneypot;

class ContactForm extends Component
{
    use HasHoneypot;

    public string $name = '';
    public string $email = '';
    public string $message = '';

    public function submit(): void
    {
        $this->validateHoneypot();

        $this->validate([
            'name'    => 'required|string|min:2',
            'email'   => 'required|email',
            'message' => 'required|string|min:10',
        ]);

        // process form ...

        $this->reset(['name', 'email', 'message']);
        $this->resetHoneypot();
    }
}
```

Add the Blade component anywhere inside your form:

```

    Send

```

That's it — bots get blocked, real users never notice.

How It Works
------------

[](#how-it-works)

1. On page load, the trait/service generates a Unix timestamp (`hp_started_at`) and a cryptographically random token (`hp_token`). These are stored as hidden Livewire properties or passed to the view.
2. The Blade component renders these values as hidden inputs alongside the bait field, which is visually positioned offscreen via CSS. If `randomize_field_name` is enabled, the bait field's HTML `name` is randomised each page load.
3. On submission, `validateHoneypot()` / `HoneypotService::validate()` checks:
    - The bait field is **empty** (bots usually fill every visible and hidden input).
    - `hp_started_at` falls within the last hour (guards against replayed or stale forms).
    - `hp_token` meets the minimum length (guards against manually crafted requests).
    - If `require_js_verification` is enabled, `hp_js` must be **non-empty** — Alpine.js populates this field on page load; bots without JavaScript execution leave it empty.
    - Enough time has elapsed since page load (time-trap).
4. Any failure fires a `HoneypotDetected` event (and optionally writes a log entry), then delegates to the configured `SpamResponder`.

Usage
-----

[](#usage)

### Custom field name

[](#custom-field-name)

If you configure a custom `field_name` in your config (or via `HONEYPOT_FIELD_NAME`), you must declare a matching public property on your component:

```
// config: HONEYPOT_FIELD_NAME=hp_url

class ContactForm extends Component
{
    use HasHoneypot;

    public string $hp_url = ''; // must match the configured field_name
}
```

The trait's `mount` method will throw a `LogicException` with a clear message if the property is missing.

### Per-component configuration

[](#per-component-configuration)

Override `honeypotConfig()` to customise any honeypot setting for a specific component without touching the global config:

```
class RegistrationForm extends Component
{
    use HasHoneypot;

    protected function honeypotConfig(): array
    {
        return [
            'minimum_fill_seconds' => 10,
            'token_length'         => 32,
            'randomize_field_name' => true,
        ];
    }
}
```

Supported keys: `minimum_fill_seconds`, `field_name`, `token_length`, `token_min_length`, `randomize_field_name`, `require_js_verification`.

Component-level values take precedence over the global config; any key not present falls back to the global config.

### Randomized field name

[](#randomized-field-name)

When `randomize_field_name` is enabled (globally or per-component), the bait field is rendered in HTML with a random `name` attribute (e.g. `hp_a3f7c2`) instead of the configured `field_name`. This defeats bots that skip inputs by recognising known honeypot names.

Pass `$hp_field_name` (automatically kept in sync by the trait) to the Blade component:

```

```

The `wire:model` binding is unaffected — only the rendered HTML `name` attribute is randomised.

### JavaScript fill verification

[](#javascript-fill-verification)

When `require_js_verification` is enabled, the Blade component renders an additional hidden field (`hp_js`) that is populated client-side by Alpine.js via an `x-init` directive. Bots and headless scrapers that submit forms without executing JavaScript will leave this field empty, and the submission will be rejected.

Enable it globally:

```
HONEYPOT_JS_VERIFICATION=true
```

Or per-component via `honeypotConfig()`:

```
protected function honeypotConfig(): array
{
    return ['require_js_verification' => true];
}
```

No changes to your template are needed — `` automatically renders the `hp_js` field when the option is enabled.

> **Note:** This check requires Alpine.js. Livewire 4 bundles Alpine.js automatically, so no extra setup is needed for Livewire components. For controller/API usage, ensure Alpine.js is loaded on the page.

### Overriding the minimum time per-action

[](#overriding-the-minimum-time-per-action)

`validateHoneypot()` accepts an optional `$minimumSeconds` argument to override the config for a specific submit action:

```
public function submitQuickPoll(): void
{
    $this->validateHoneypot(minimumSeconds: 2);
    // ...
}
```

### Controllers / APIs (Service)

[](#controllers--apis-service)

Inject or resolve `HoneypotService` to validate honeypot data submitted with a standard HTML form.

```
use Blendbyte\LivewireHoneypot\Services\HoneypotService;

public function store(Request $request, HoneypotService $honeypot): RedirectResponse
{
    $honeypot->validate($request->only(
        config('livewire-honeypot.field_name', 'hp_website'),
        'hp_started_at',
        'hp_token',
    ));

    // process form ...

    return redirect()->back()->with('success', 'Sent!');
}
```

To generate the initial honeypot data server-side and pass it to a Blade view:

```
$hp = app(HoneypotService::class)->generate();
// Returns: ['hp_website' => '', 'hp_started_at' => 1234567890, 'hp_token' => 'abc...']
return view('contact', compact('hp'));
```

Then in your Blade template, use the values as hidden inputs:

```

    @csrf

    {{-- your regular fields --}}

```

`HoneypotService::validate()` also accepts an optional `$minimumSeconds` argument:

```
$honeypot->validate($data, minimumSeconds: 10);
```

Blade Component
---------------

[](#blade-component)

The `` component renders hidden fields and scoped CSS that moves them offscreen:

FieldPurposeAlways rendered`hp_website` (configurable)Bait field — must remain emptyYes`hp_started_at`Unix timestamp of page loadYes`hp_token`Random token to verify form originYes`hp_js`Populated by Alpine.js on page loadOnly when `require_js_verification = true`The component uses `aria-hidden="true"` and `tabindex="-1"` so it is invisible to screen readers and keyboard navigation.

Configuration
-------------

[](#configuration)

Publish the config file:

```
php artisan vendor:publish --tag=livewire-honeypot-config
```

This creates `config/livewire-honeypot.php`:

```
return [
    // Minimum seconds between page load and submission (0 = disabled)
    'minimum_fill_seconds' => env('HONEYPOT_MINIMUM_FILL_SECONDS', 5),

    // Name of the honeypot bait field
    'field_name' => env('HONEYPOT_FIELD_NAME', 'hp_website'),

    // Minimum accepted length of the token on validation
    'token_min_length' => env('HONEYPOT_TOKEN_MIN_LENGTH', 10),

    // Length of the token generated on page load
    'token_length' => env('HONEYPOT_TOKEN_LENGTH', 24),

    // Randomise the HTML name attribute of the bait field on each page load
    'randomize_field_name' => env('HONEYPOT_RANDOMIZE_FIELD_NAME', false),

    // Structured logging when spam is detected
    'logging' => [
        'enabled' => env('HONEYPOT_LOGGING', false),
        'channel' => env('HONEYPOT_LOG_CHANNEL', null), // null = default channel
        'level'   => env('HONEYPOT_LOG_LEVEL', 'warning'),
    ],

    // How to respond when spam is detected
    // Must implement Blendbyte\LivewireHoneypot\Contracts\SpamResponder
    'spam_responder' => \Blendbyte\LivewireHoneypot\Responders\ValidationExceptionResponder::class,

    // Require a hidden field populated by Alpine.js (opt-in JS verification)
    'require_js_verification' => env('HONEYPOT_JS_VERIFICATION', false),
];
```

### Environment variables

[](#environment-variables)

VariableDefaultDescription`HONEYPOT_MINIMUM_FILL_SECONDS``5`Seconds required before a submission is accepted`HONEYPOT_FIELD_NAME``hp_website`Name of the bait input field`HONEYPOT_TOKEN_MIN_LENGTH``10`Minimum token length accepted during validation`HONEYPOT_TOKEN_LENGTH``24`Length of the generated token`HONEYPOT_RANDOMIZE_FIELD_NAME``false`Randomise the HTML `name` of the bait field each page load`HONEYPOT_LOGGING``false`Enable structured log entries on spam detection`HONEYPOT_LOG_CHANNEL`*(default)*Laravel logging channel to write to (`null` = app default)`HONEYPOT_LOG_LEVEL``warning`PSR-3 log level (`debug`, `info`, `warning`, `error`, …)`HONEYPOT_JS_VERIFICATION``false`Require the `hp_js` field to be populated by Alpine.js> **Note:** `token_length` must be greater than or equal to `token_min_length`. The service provider throws an `InvalidArgumentException` on boot if this constraint is violated.

Spam Responders
---------------

[](#spam-responders)

When spam is detected you can control what happens via the `spam_responder` config key. Three responders are built in:

ClassBehaviour`ValidationExceptionResponder` (default)Throws a `ValidationException` — Livewire surfaces it as a field-level error`AbortResponder`Calls `abort(403)` — hard rejection with a 403 Forbidden response`RedirectResponder`Silently redirects the user back — the form appears to do nothingChange the responder globally in `config/livewire-honeypot.php`:

```
use Blendbyte\LivewireHoneypot\Responders\AbortResponder;

'spam_responder' => AbortResponder::class,
```

### Custom responder

[](#custom-responder)

Implement the `SpamResponder` contract to define your own behaviour:

```
use Blendbyte\LivewireHoneypot\Contracts\SpamResponder;

class SilentIgnoreResponder implements SpamResponder
{
    public function respond(string $fieldName, string $message): never
    {
        logger()->info('Honeypot triggered silently', ['field' => $fieldName]);
        throw new \Illuminate\Http\Exceptions\HttpResponseException(
            response()->json(['status' => 'ok'])
        );
    }
}
```

Register it in `config/livewire-honeypot.php`:

```
'spam_responder' => \App\Http\Honeypot\SilentIgnoreResponder::class,
```

Or bind it in a service provider for maximum flexibility:

```
$this->app->bind(
    \Blendbyte\LivewireHoneypot\Contracts\SpamResponder::class,
    fn () => new SilentIgnoreResponder(/* deps */),
);
```

Events
------

[](#events)

Every spam detection fires a `HoneypotDetected` event regardless of which responder is configured. Listen to it for custom alerting, rate-limiting, or analytics:

```
use Blendbyte\LivewireHoneypot\Events\HoneypotDetected;

Event::listen(HoneypotDetected::class, function (HoneypotDetected $event) {
    // $event->reason      — "honeypot_filled" | "submitted_too_quickly" | "invalid_form_data" | "js_verification_failed"
    // $event->fieldName   — the bait field name (e.g. "hp_website")
    // $event->ipAddress   — IP address of the request
    // $event->userAgent   — user-agent string of the request
    // $event->component   — FQCN of the Livewire component, or null for controller usage

    logger()->critical('Bot attempt detected', [
        'ip'     => $event->ipAddress,
        'reason' => $event->reason,
    ]);
});
```

Logging
-------

[](#logging)

Enable structured log entries so every spam detection is written to your Laravel log automatically — no manual event listener needed:

```
HONEYPOT_LOGGING=true
HONEYPOT_LOG_CHANNEL=slack
HONEYPOT_LOG_LEVEL=warning
```

Each log entry includes `reason`, `field_name`, `ip`, `user_agent`, and `component`:

```
[warning] Honeypot triggered {"reason":"honeypot_filled","field_name":"hp_website","ip":"1.2.3.4","user_agent":"curl/8.0","component":null}

```

Testing
-------

[](#testing)

Use `HoneypotService::fake()` to bypass all honeypot validation in tests:

```
use Blendbyte\LivewireHoneypot\Services\HoneypotService;

beforeEach(fn () => HoneypotService::fake());
afterEach(fn () => HoneypotService::resetFake());

it('submits the contact form', function () {
    Livewire::test(ContactForm::class)
        ->set('name', 'Alice')
        ->set('email', 'alice@example.com')
        ->set('message', 'Hello there!')
        ->call('submit')
        ->assertHasNoErrors();
});
```

When fake mode is active, `validateHoneypot()` (trait) and `HoneypotService::validate()` (service) both return immediately without checking any fields.

Translations
------------

[](#translations)

12 translations are included out of the box: English, Dutch, German, Spanish, French, Portuguese, Italian, Russian, Polish, Japanese, Chinese Simplified, and Chinese Traditional.

Publish them to customize error messages:

```
php artisan vendor:publish --tag=livewire-honeypot-translations
```

### Available translation keys

[](#available-translation-keys)

KeyDefault (English)Description`spam_detected``Spam detected.`Shown when the bait field is filled`submitted_too_quickly``Form submitted too quickly.`Shown when the time-trap triggers`honeypot_label``Website (leave empty)`Accessible label on the hidden field`invalid_form_data``Invalid form data.`Shown when `hp_started_at` is out of range`js_verification_failed``JavaScript verification failed.`Shown when `hp_js` is emptyPublishing Views
----------------

[](#publishing-views)

To customize the `` Blade component:

```
php artisan vendor:publish --tag=livewire-honeypot-views
```

This copies the component to `resources/views/vendor/livewire-honeypot/components/honeypot.blade.php`.

Recommended Additions
---------------------

[](#recommended-additions)

Honeypot protection works best as one layer of a defence-in-depth strategy. Consider pairing it with:

**Rate limiting** on your form route:

```
Route::post('/contact', [ContactController::class, 'store'])
    ->middleware('throttle:10,1');
```

**CSRF protection** — always use `@csrf` in non-Livewire forms (Livewire handles this automatically).

Maintained by Blendbyte
-----------------------

[](#maintained-by-blendbyte)

 [   ![Blendbyte](https://camo.githubusercontent.com/09962a5684a0b50fb9eb44edfd8f2560be418bc8ce3d23a31f96395f3f14d58e/68747470733a2f2f7777772e626c656e64627974652e636f6d2f6c6f676f5f686f72697a6f6e74616c2e706e67)  ](https://www.blendbyte.com)

 **[Blendbyte](https://www.blendbyte.com)** builds cloud infrastructure, web apps, and developer tools.
 We've been shipping software to production for 20+ years.

 This package runs in our own stack, which is why we keep it maintained.
 Issues and PRs get read. Good ones get merged.

 [blendbyte.com](https://www.blendbyte.com) ·

###  Health Score

43

—

FairBetter than 90% of packages

Maintenance87

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 92.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~13 days

Total

3

Last Release

70d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/69378377?v=4)[Blendbyte](/maintainers/blendbyte)[@blendbyte](https://github.com/blendbyte)

---

Top Contributors

[![bashgeek](https://avatars.githubusercontent.com/u/4669888?v=4)](https://github.com/bashgeek "bashgeek (59 commits)")[![ArvidDeJong](https://avatars.githubusercontent.com/u/7394837?v=4)](https://github.com/ArvidDeJong "ArvidDeJong (5 commits)")

---

Tags

formshoneypotlaravellivewire

###  Code Quality

TestsPest

Static AnalysisPHPStan

### Embed Badge

![Health badge](/badges/blendbyte-livewire-honeypot/health.svg)

```
[![Health](https://phpackages.com/badges/blendbyte-livewire-honeypot/health.svg)](https://phpackages.com/packages/blendbyte-livewire-honeypot)
```

###  Alternatives

[nasirkhan/laravel-starter

A CMS like modular Laravel starter project.

1.4k2.7k](/packages/nasirkhan-laravel-starter)[team-nifty-gmbh/tall-datatables

Server-side rendered datatables for Laravel and Livewire

1319.7k3](/packages/team-nifty-gmbh-tall-datatables)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.2k](/packages/tomshaw-electricgrid)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
