Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
recca0120 committed Aug 25, 2024
1 parent 03399b1 commit 404ced3
Show file tree
Hide file tree
Showing 32 changed files with 196 additions and 63 deletions.
9 changes: 9 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
* text=auto

/.github export-ignore
/demo export-ignore
/tests export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.nitpick.json export-ignore
File renamed without changes.
97 changes: 97 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Laravel ERD

[![Latest Version on Packagist](https://img.shields.io/packagist/v/recca0120/laravel-erd.svg?style=flat-square)](https://packagist.org/packages/recca0120/laravel-erd)
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/recca0120/laravel-erd/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/recca0120/laravel-erd/actions?query=workflow%3Arun-tests+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/recca0120/laravel-erd.svg?style=flat-square)](https://packagist.org/packages/recca0120/laravel-erd)

Laravel ERD automatically generates Entity-Relationship Diagrams from your Laravel models and displays them
using [Vuerd](https://github.com/dineug/erd-editor).

## Preview

Here's a sample of what you can expect, generated from [migrations](database/migrations)
and [models](tests/Fixtures/Models):

> [View Live Demo](https://previewhtml.github.io/?url=https%3A%2F%2Fgithub.com%2Frecca0120%2Flaravel-erd%2Fblob%2Fmain%2Fdemo%2Findex.html)
![Vuerd](demo/vuerd.jpg)

## Requirements

| Lang | Version |
|:--------|:------------------------|
| PHP | 7.4, 8.0, 8.1, 8.2, 8.3 |
| Laravel | 8, 9, 10, 11 |

## Installation

Install the package via Composer:

```bash
composer require recca0120/laravel-erd:^0.1 --dev
```

## Usage

### Step 1: Generate the ERD

Run the following command:

```bash
php artisan erd:generate
```

Step 2: View the ERD

Open the following URL in your browser:

http://localhost/laravel-erd

## Advanced Usage

### Exclude Tables and Save to a Different Filename

#### step 1.

Run the command:

```bash
php artisan erd:generate --file=exclude-users.sql --exclude=users
```

#### step 2.

Open the URL:

http://localhost/laravel-erd/exclude-users

### Generate an SVG Version

#### step 1.

Install [erd-go](https://github.com/kaishuu0123/erd-go)
and [graphviz-dot.js](https://github.com/kaishuu0123/graphviz-dot.js) using:

```bash
php artisan erd:install
```

#### step 2.

Generate the SVG file:

```php
php artisan generate --file=laravel-erd.svg
```

#### step 3.

View the SVG version:

http://localhost/laravel-erd/laravel-erd.svg

![svg](tests/Fixtures/expected_artisan.svg)

> The SVG file can be found at storage/framework/cache/laravel-erd.
Feel free to ask if you have any questions or need further assistance!
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "recca0120/laravel-erd",
"description": "",
"description": "Laravel ERD automatically generates Entity-Relationship Diagrams from your Laravel models and displays them using Vuerd.",
"type": "library",
"license": "MIT",
"authors": [
Expand Down
41 changes: 41 additions & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Laravel Erd</title>
<style>
body {
margin: 0;
height: 100vh;
}
</style>
</head>
<body>
<erd-editor automatic-layout></erd-editor>
<script>
function loadScript(src, fallback, callback) {
const script = document.createElement('script');
if (callback) {
script.onload = () => callback();
}

if (fallback) {
script.onerror = () => loadScript(fallback, undefined, callback);
}

script.src = src;
document.body.appendChild(script);
}

function init() {
const editor = document.querySelector('erd-editor');
editor.loadSQLDDL(atob('Q1JFQVRFIFRBQkxFIGNhcnMgKAogICAgaWQgaW50ZWdlcigxMSkgTk9UIE5VTEwgQVVUT19JTkNSRU1FTlQsCiAgICBtb2RlbCB2YXJjaGFyKDI1NSkgTk9UIE5VTEwsCiAgICBtZWNoYW5pY19pZCBpbnRlZ2VyKDExKSBOT1QgTlVMTCwKICAgIFBSSU1BUlkgS0VZKGlkKQopCkNSRUFURSBUQUJMRSBjb21tZW50cyAoCiAgICBpZCBpbnRlZ2VyKDExKSBOT1QgTlVMTCBBVVRPX0lOQ1JFTUVOVCwKICAgIHBvc3RfaWQgaW50ZWdlcigxMSkgTk9UIE5VTEwsCiAgICB0aXRsZSB2YXJjaGFyKDI1NSkgTk9UIE5VTEwsCiAgICBjcmVhdGVkX2F0IGRhdGV0aW1lLAogICAgdXBkYXRlZF9hdCBkYXRldGltZSwKICAgIFBSSU1BUlkgS0VZKGlkKQopCkNSRUFURSBUQUJMRSBpbWFnZXMgKAogICAgaWQgaW50ZWdlcigxMSkgTk9UIE5VTEwgQVVUT19JTkNSRU1FTlQsCiAgICB1cmwgdmFyY2hhcigyNTUpIE5PVCBOVUxMLAogICAgaW1hZ2VhYmxlX3R5cGUgdmFyY2hhcigyNTUpIE5PVCBOVUxMLAogICAgaW1hZ2VhYmxlX2lkIGludGVnZXIoMTEpIE5PVCBOVUxMLAogICAgY3JlYXRlZF9hdCBkYXRldGltZSwKICAgIHVwZGF0ZWRfYXQgZGF0ZXRpbWUsCiAgICBQUklNQVJZIEtFWShpZCkKKQpDUkVBVEUgVEFCTEUgbWVjaGFuaWNzICgKICAgIGlkIGludGVnZXIoMTEpIE5PVCBOVUxMIEFVVE9fSU5DUkVNRU5ULAogICAgbmFtZSB2YXJjaGFyKDI1NSkgTk9UIE5VTEwsCiAgICBQUklNQVJZIEtFWShpZCkKKQpDUkVBVEUgVEFCTEUgbW9kZWxfaGFzX3Blcm1pc3Npb25zICgKICAgIHBlcm1pc3Npb25faWQgaW50ZWdlcigxMSkgTk9UIE5VTEwsCiAgICBtb2RlbF90eXBlIHZhcmNoYXIoMjU1KSBOT1QgTlVMTCwKICAgIG1vZGVsX2lkIGludGVnZXIoMTEpIE5PVCBOVUxMLAogICAgUFJJTUFSWSBLRVkocGVybWlzc2lvbl9pZCwgbW9kZWxfaWQsIG1vZGVsX3R5cGUpCikKQ1JFQVRFIFRBQkxFIG1vZGVsX2hhc19yb2xlcyAoCiAgICByb2xlX2lkIGludGVnZXIoMTEpIE5PVCBOVUxMLAogICAgbW9kZWxfdHlwZSB2YXJjaGFyKDI1NSkgTk9UIE5VTEwsCiAgICBtb2RlbF9pZCBpbnRlZ2VyKDExKSBOT1QgTlVMTCwKICAgIFBSSU1BUlkgS0VZKHJvbGVfaWQsIG1vZGVsX2lkLCBtb2RlbF90eXBlKQopCkNSRUFURSBUQUJMRSBvd25lcnMgKAogICAgaWQgaW50ZWdlcigxMSkgTk9UIE5VTEwgQVVUT19JTkNSRU1FTlQsCiAgICBuYW1lIHZhcmNoYXIoMjU1KSBOT1QgTlVMTCwKICAgIGNhcl9pZCBpbnRlZ2VyKDExKSBOT1QgTlVMTCwKICAgIFBSSU1BUlkgS0VZKGlkKQopCkNSRUFURSBUQUJMRSBwZXJtaXNzaW9ucyAoCiAgICBpZCBpbnRlZ2VyKDExKSBOT1QgTlVMTCBBVVRPX0lOQ1JFTUVOVCwKICAgIG5hbWUgdmFyY2hhcigyNTUpIE5PVCBOVUxMLAogICAgZ3VhcmRfbmFtZSB2YXJjaGFyKDI1NSkgTk9UIE5VTEwsCiAgICBjcmVhdGVkX2F0IGRhdGV0aW1lLAogICAgdXBkYXRlZF9hdCBkYXRldGltZSwKICAgIFBSSU1BUlkgS0VZKGlkKQopCkNSRUFURSBUQUJMRSBwaG9uZXMgKAogICAgaWQgaW50ZWdlcigxMSkgTk9UIE5VTEwgQVVUT19JTkNSRU1FTlQsCiAgICB1c2VyX2lkIGludGVnZXIoMTEpIE5PVCBOVUxMLAogICAgcGhvbmVfbnVtYmVycyB2YXJjaGFyKDI1NSkgTk9UIE5VTEwsCiAgICBQUklNQVJZIEtFWShpZCkKKQpDUkVBVEUgVEFCTEUgcG9zdHMgKAogICAgaWQgaW50ZWdlcigxMSkgTk9UIE5VTEwgQVVUT19JTkNSRU1FTlQsCiAgICB1c2VyX2lkIGludGVnZXIoMTEpIE5PVCBOVUxMLAogICAgdGl0bGUgdmFyY2hhcigyNTUpIE5PVCBOVUxMIERFRkFVTFQgZm9vLAogICAgY3JlYXRlZF9hdCBkYXRldGltZSwKICAgIHVwZGF0ZWRfYXQgZGF0ZXRpbWUsCiAgICBQUklNQVJZIEtFWShpZCkKKQpDUkVBVEUgVEFCTEUgcm9sZV9oYXNfcGVybWlzc2lvbnMgKAogICAgcGVybWlzc2lvbl9pZCBpbnRlZ2VyKDExKSBOT1QgTlVMTCwKICAgIHJvbGVfaWQgaW50ZWdlcigxMSkgTk9UIE5VTEwsCiAgICBQUklNQVJZIEtFWShwZXJtaXNzaW9uX2lkLCByb2xlX2lkKQopCkNSRUFURSBUQUJMRSByb2xlcyAoCiAgICBpZCBpbnRlZ2VyKDExKSBOT1QgTlVMTCBBVVRPX0lOQ1JFTUVOVCwKICAgIG5hbWUgdmFyY2hhcigyNTUpIE5PVCBOVUxMLAogICAgZ3VhcmRfbmFtZSB2YXJjaGFyKDI1NSkgTk9UIE5VTEwsCiAgICBjcmVhdGVkX2F0IGRhdGV0aW1lLAogICAgdXBkYXRlZF9hdCBkYXRldGltZSwKICAgIFBSSU1BUlkgS0VZKGlkKQopCkNSRUFURSBUQUJMRSB1c2VycyAoCiAgICBpZCBpbnRlZ2VyKDExKSBOT1QgTlVMTCBBVVRPX0lOQ1JFTUVOVCwKICAgIG5hbWUgdmFyY2hhcigyNTUpIE5PVCBOVUxMLAogICAgZW1haWwgdmFyY2hhcigyNTUpIE5PVCBOVUxMLAogICAgZW1haWxfdmVyaWZpZWRfYXQgZGF0ZXRpbWUsCiAgICBwYXNzd29yZCB2YXJjaGFyKDI1NSkgTk9UIE5VTEwsCiAgICByZW1lbWJlcl90b2tlbiB2YXJjaGFyKDI1NSksCiAgICBjcmVhdGVkX2F0IGRhdGV0aW1lLAogICAgdXBkYXRlZF9hdCBkYXRldGltZSwKICAgIFBSSU1BUlkgS0VZKGlkKQopCkFMVEVSIFRBQkxFIGNhcnMgQUREIEZPUkVJR04gS0VZIChpZCkgUkVGRVJFTkNFUyBvd25lcnMgKGNhcl9pZCkKQUxURVIgVEFCTEUgY2FycyBBREQgRk9SRUlHTiBLRVkgKG1lY2hhbmljX2lkKSBSRUZFUkVOQ0VTIG1lY2hhbmljcyAoaWQpCkFMVEVSIFRBQkxFIGNvbW1lbnRzIEFERCBGT1JFSUdOIEtFWSAocG9zdF9pZCkgUkVGRVJFTkNFUyBwb3N0cyAoaWQpCkFMVEVSIFRBQkxFIGltYWdlcyBBREQgRk9SRUlHTiBLRVkgKGltYWdlYWJsZV9pZCkgUkVGRVJFTkNFUyBwb3N0cyAoaWQpCkFMVEVSIFRBQkxFIGltYWdlcyBBREQgRk9SRUlHTiBLRVkgKGltYWdlYWJsZV9pZCkgUkVGRVJFTkNFUyB1c2VycyAoaWQpCkFMVEVSIFRBQkxFIG1vZGVsX2hhc19wZXJtaXNzaW9ucyBBREQgRk9SRUlHTiBLRVkgKG1vZGVsX2lkKSBSRUZFUkVOQ0VTIHVzZXJzIChpZCkKQUxURVIgVEFCTEUgbW9kZWxfaGFzX3Blcm1pc3Npb25zIEFERCBGT1JFSUdOIEtFWSAocGVybWlzc2lvbl9pZCkgUkVGRVJFTkNFUyBwZXJtaXNzaW9ucyAoaWQpCkFMVEVSIFRBQkxFIG1vZGVsX2hhc19yb2xlcyBBREQgRk9SRUlHTiBLRVkgKG1vZGVsX2lkKSBSRUZFUkVOQ0VTIHVzZXJzIChpZCkKQUxURVIgVEFCTEUgbW9kZWxfaGFzX3JvbGVzIEFERCBGT1JFSUdOIEtFWSAocm9sZV9pZCkgUkVGRVJFTkNFUyByb2xlcyAoaWQpCkFMVEVSIFRBQkxFIHBlcm1pc3Npb25zIEFERCBGT1JFSUdOIEtFWSAoaWQpIFJFRkVSRU5DRVMgcm9sZV9oYXNfcGVybWlzc2lvbnMgKHBlcm1pc3Npb25faWQpCkFMVEVSIFRBQkxFIHBob25lcyBBREQgRk9SRUlHTiBLRVkgKHVzZXJfaWQpIFJFRkVSRU5DRVMgdXNlcnMgKGlkKQpBTFRFUiBUQUJMRSBwb3N0cyBBREQgRk9SRUlHTiBLRVkgKHVzZXJfaWQpIFJFRkVSRU5DRVMgdXNlcnMgKGlkKQpBTFRFUiBUQUJMRSByb2xlX2hhc19wZXJtaXNzaW9ucyBBREQgRk9SRUlHTiBLRVkgKHJvbGVfaWQpIFJFRkVSRU5DRVMgcm9sZXMgKGlkKQ=='));
}

loadScript('../resources/dist/vuerd.min.js', 'https://cdn.jsdelivr.net/npm/vuerd/dist/vuerd.min.js', init);
</script>
</body>
</html>
Binary file added demo/vuerd.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 7 additions & 15 deletions resources/views/vuerd.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,25 @@
<erd-editor automatic-layout></erd-editor>
<script>
function loadScript(src, fallback, callback) {
var script = document.createElement('script');
script.onload = function () {
if (callback) {
callback();
}
const script = document.createElement('script');
if (callback) {
script.onload = () => callback();
}
if (fallback) {
script.onerror = function () {
loadScript(fallback, undefined, callback);
}
script.onerror = () => loadScript(fallback, undefined, callback);
}
script.src = src
script.src = src;
document.body.appendChild(script);
}
function init() {
var editor = document.querySelector('erd-editor');
const editor = document.querySelector('erd-editor');
editor.loadSQLDDL(atob('{{ base64_encode(File::get($path)) }}'));
}
loadScript(
"{{ asset('vendor/laravel-erd/vuerd.min.js') }}",
"https://cdn.jsdelivr.net/npm/vuerd/dist/vuerd.min.js",
init
);
loadScript("{{ asset('vendor/laravel-erd/vuerd.min.js') }}", 'https://cdn.jsdelivr.net/npm/vuerd/dist/vuerd.min.js', init);
</script>
</body>
</html>
8 changes: 4 additions & 4 deletions src/Template/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class Factory
{
/** @var array<string, string> */
private array $lookup = [
private array $templates = [
'sql' => DDL::class,
'er' => Er::class,
'svg' => Er::class,
Expand All @@ -16,16 +16,16 @@ class Factory
public function create(string $file): Template
{
$extension = $this->getExtension($file);
$class = $this->lookup[$extension] ?? Er::class;
$class = $this->templates[$extension] ?? Er::class;

return new $class;
}

private function getExtension(string $file): string
{
$extension = substr($file, strrpos($file, '.') + 1);
if (! array_key_exists($extension, $this->lookup)) {
throw new RuntimeException('allow ['.implode(',', array_keys($this->lookup)).'] only');
if (! array_key_exists($extension, $this->templates)) {
throw new RuntimeException('allow ['.implode(',', array_keys($this->templates)).'] only');
}

return $extension;
Expand Down
2 changes: 1 addition & 1 deletion tests/Console/Commands/GenerateErdTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class GenerateErdTest extends TestCase
protected function setUp(): void
{
parent::setUp();
$this->storagePath = realpath(__DIR__.'/../../fixtures');
$this->storagePath = realpath(__DIR__.'/../../Fixtures');
$this->app['config']->set('laravel-erd.binary', [
'erd-go' => $this->storagePath.'/bin/erd-go',
'dot' => $this->storagePath.'/bin/dot',
Expand Down
4 changes: 2 additions & 2 deletions tests/ErdFinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Recca0120\LaravelErd\Factory;
use Recca0120\LaravelErd\Template\Er;
use Recca0120\LaravelErd\Template\Template;
use Recca0120\LaravelErd\Tests\fixtures\Models\Car;
use Recca0120\LaravelErd\Tests\Fixtures\Models\Car;
use ReflectionException;
use Spatie\Snapshots\MatchesSnapshots;

Expand Down Expand Up @@ -75,7 +75,7 @@ public function test_find_er_model_exclude_owner(): void

private function givenFinder(): ErdFinder
{
return $this->app->make(Factory::class)->create()->in(__DIR__.'/fixtures');
return $this->app->make(Factory::class)->create()->in(__DIR__.'/Fixtures');
}

private function render(Collection $results): string
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models\Other;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models\Other;

use Illuminate\Database\Eloquent\Model;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models\Other;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models\Other;

use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models\Other;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models\Other;

use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models\Other;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models\Other;

use Illuminate\Database\Eloquent\Relations\BelongsTo;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Recca0120\LaravelErd\Tests\fixtures\Models;
namespace Recca0120\LaravelErd\Tests\Fixtures\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
Expand Down
5 changes: 5 additions & 0 deletions tests/Fixtures/NonModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Recca0120\LaravelErd\Tests\Fixtures;

class NonModel {}
File renamed without changes
Loading

0 comments on commit 404ced3

Please sign in to comment.