Compare commits
No commits in common. '17803c1acb38e9fd8d87e1aa840f3a2a5158b227' and '0ce9cb608d1a236dc7238b2e096547fc7c624372' have entirely different histories.
17803c1acb
...
0ce9cb608d
@ -1,121 +1,53 @@ |
|||
<?php |
|||
|
|||
namespace Config; |
|||
|
|||
use CodeIgniter\Config\BaseConfig; |
|||
|
|||
class Email extends BaseConfig |
|||
{ |
|||
public string $fromEmail = ''; |
|||
public string $fromName = ''; |
|||
public string $fromEmail = 'rey342505@gmail.com'; |
|||
public string $fromName = 'motorbike'; |
|||
public string $recipients = ''; |
|||
|
|||
/** |
|||
* The "user agent" |
|||
*/ |
|||
public string $userAgent = 'CodeIgniter'; |
|||
|
|||
/** |
|||
* The mail sending protocol: mail, sendmail, smtp |
|||
*/ |
|||
public string $protocol = 'mail'; |
|||
public string $protocol = 'smtp'; |
|||
|
|||
/** |
|||
* The server path to Sendmail. |
|||
*/ |
|||
public string $mailPath = '/usr/sbin/sendmail'; |
|||
|
|||
/** |
|||
* SMTP Server Hostname |
|||
*/ |
|||
public string $SMTPHost = ''; |
|||
|
|||
/** |
|||
* SMTP Username |
|||
*/ |
|||
public string $SMTPUser = ''; |
|||
|
|||
/** |
|||
* SMTP Password |
|||
*/ |
|||
public string $SMTPPass = ''; |
|||
|
|||
/** |
|||
* SMTP Port |
|||
*/ |
|||
public int $SMTPPort = 25; |
|||
|
|||
/** |
|||
* SMTP Timeout (in seconds) |
|||
*/ |
|||
public int $SMTPTimeout = 5; |
|||
|
|||
/** |
|||
* Enable persistent SMTP connections |
|||
*/ |
|||
public string $SMTPHost = 'smtp.gmail.com'; |
|||
|
|||
public string $SMTPUser = 'rey342505@gmail.com'; |
|||
|
|||
public string $SMTPPass = 'loirqovmfuxnasrm'; // Mot de passe d’application (App Password) Gmail |
|||
|
|||
public int $SMTPPort = 587; |
|||
|
|||
public int $SMTPTimeout = 30; |
|||
|
|||
public bool $SMTPKeepAlive = false; |
|||
|
|||
/** |
|||
* SMTP Encryption. |
|||
* |
|||
* @var string '', 'tls' or 'ssl'. 'tls' will issue a STARTTLS command |
|||
* to the server. 'ssl' means implicit SSL. Connection on port |
|||
* 465 should set this to ''. |
|||
*/ |
|||
public string $SMTPCrypto = 'tls'; |
|||
|
|||
/** |
|||
* Enable word-wrap |
|||
*/ |
|||
public bool $wordWrap = true; |
|||
|
|||
/** |
|||
* Character count to wrap at |
|||
*/ |
|||
public int $wrapChars = 76; |
|||
|
|||
/** |
|||
* Type of mail, either 'text' or 'html' |
|||
*/ |
|||
public string $mailType = 'text'; |
|||
public string $mailType = 'html'; |
|||
|
|||
/** |
|||
* Character set (utf-8, iso-8859-1, etc.) |
|||
*/ |
|||
public string $charset = 'UTF-8'; |
|||
|
|||
/** |
|||
* Whether to validate the email address |
|||
*/ |
|||
public bool $validate = false; |
|||
public bool $validate = true; |
|||
|
|||
/** |
|||
* Email Priority. 1 = highest. 5 = lowest. 3 = normal |
|||
*/ |
|||
public int $priority = 3; |
|||
|
|||
/** |
|||
* Newline character. (Use “\r\n” to comply with RFC 822) |
|||
*/ |
|||
public string $CRLF = "\r\n"; |
|||
|
|||
/** |
|||
* Newline character. (Use “\r\n” to comply with RFC 822) |
|||
*/ |
|||
public string $newline = "\r\n"; |
|||
|
|||
/** |
|||
* Enable BCC Batch Mode. |
|||
*/ |
|||
public bool $BCCBatchMode = false; |
|||
|
|||
/** |
|||
* Number of emails in each BCC batch |
|||
*/ |
|||
public int $BCCBatchSize = 200; |
|||
|
|||
/** |
|||
* Enable notify message from server |
|||
*/ |
|||
public bool $DSN = false; |
|||
} |
|||
|
|||
@ -0,0 +1,14 @@ |
|||
<?php |
|||
namespace App\Controllers; |
|||
|
|||
use App\Controllers\BaseController; |
|||
|
|||
class AlertsController extends BaseController |
|||
{ |
|||
public function check() |
|||
{ |
|||
helper('alerts'); |
|||
checkDeadlineAlerts(); |
|||
return "Vérification des alertes effectuée."; |
|||
} |
|||
} |
|||
@ -1,58 +1,22 @@ |
|||
<?php |
|||
|
|||
namespace App\Controllers; |
|||
|
|||
use CodeIgniter\Controller; |
|||
use CodeIgniter\HTTP\CLIRequest; |
|||
use CodeIgniter\HTTP\IncomingRequest; |
|||
use CodeIgniter\HTTP\RequestInterface; |
|||
use CodeIgniter\HTTP\ResponseInterface; |
|||
use Psr\Log\LoggerInterface; |
|||
|
|||
/** |
|||
* Class BaseController |
|||
* |
|||
* BaseController provides a convenient place for loading components |
|||
* and performing functions that are needed by all your controllers. |
|||
* Extend this class in any new controllers: |
|||
* class Home extends BaseController |
|||
* |
|||
* For security be sure to declare any new methods as protected or private. |
|||
*/ |
|||
abstract class BaseController extends Controller |
|||
class BaseController extends Controller |
|||
{ |
|||
/** |
|||
* Instance of the main Request object. |
|||
* |
|||
* @var CLIRequest|IncomingRequest |
|||
*/ |
|||
protected $request; |
|||
|
|||
/** |
|||
* An array of helpers to be loaded automatically upon |
|||
* class instantiation. These helpers will be available |
|||
* to all other controllers that extend BaseController. |
|||
* |
|||
* @var list<string> |
|||
*/ |
|||
protected $helpers = []; |
|||
|
|||
/** |
|||
* Be sure to declare properties for any property fetch you initialized. |
|||
* The creation of dynamic property is deprecated in PHP 8.2. |
|||
*/ |
|||
// protected $session; |
|||
|
|||
/** |
|||
* @return void |
|||
*/ |
|||
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) |
|||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, |
|||
\CodeIgniter\HTTP\ResponseInterface $response, |
|||
\Psr\Log\LoggerInterface $logger) |
|||
{ |
|||
// Do Not Edit This Line |
|||
parent::initController($request, $response, $logger); |
|||
|
|||
// Preload any models, libraries, etc, here. |
|||
helper('alerts'); |
|||
|
|||
// E.g.: $this->session = \Config\Services::session(); |
|||
if (function_exists('checkDeadlineAlerts')) { |
|||
checkDeadlineAlerts(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,25 @@ |
|||
<?php |
|||
|
|||
namespace App\Controllers; |
|||
|
|||
use CodeIgniter\Controller; |
|||
|
|||
class TestDeadline extends Controller |
|||
{ |
|||
public function index() |
|||
{ |
|||
// Charger le helper qui contient ta fonction |
|||
helper('alerts'); // si ton fichier s'appelle alerts_helper.php |
|||
|
|||
// 🔹 Supprimer le cache 24h pour forcer l'exécution |
|||
$cacheFile = WRITEPATH . 'cache/check_deadline_last_run.txt'; |
|||
if (file_exists($cacheFile)) { |
|||
unlink($cacheFile); |
|||
} |
|||
|
|||
// Lancer la vérification |
|||
checkDeadlineAlerts(); |
|||
|
|||
echo "✅ Test de l'envoi d'alertes terminé."; |
|||
} |
|||
} |
|||
@ -0,0 +1,145 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="fr"> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
<link rel="stylesheet" href="' . base_url('assets/bower_components/bootstrap/dist/css/bootstrap.min.css') . '"> |
|||
<style> |
|||
body { font-size: 14px; font-family: Arial, sans-serif; } |
|||
.invoice-container { |
|||
max-width: 350px; /* Réduire la largeur du cadre */ |
|||
margin: 20px auto; |
|||
padding: 20px; |
|||
border: 2px solid #007bff; /* Bordure plus visible */ |
|||
border-radius: 10px; |
|||
background: #f0f8ff; /* Couleur de fond plus douce */ |
|||
} |
|||
.invoice-header { |
|||
background: #007bff; |
|||
color: white; |
|||
text-align: center; |
|||
font-size: 18px; |
|||
font-weight: bold; |
|||
padding: 10px; |
|||
border-radius: 10px 10px 0 0; |
|||
} |
|||
.invoice-footer { |
|||
background: #343a40; |
|||
color: white; |
|||
text-align: center; |
|||
font-size: 14px; |
|||
padding: 10px; |
|||
border-radius: 0 0 10px 10px; |
|||
margin-top: 12px; |
|||
} |
|||
table { width: 100%; border-collapse: collapse; } |
|||
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; } |
|||
th { background: #e9ecef; } |
|||
p, strong { color: #333; } |
|||
</style> |
|||
</head> |
|||
<body onload="window.print();"> |
|||
<div class="invoice-container"> |
|||
<div class="invoice-header"> |
|||
' . esc($company_info['company_name']) . ' |
|||
</div> |
|||
<p><strong>Facture ID:</strong> ' . esc($order_data['bill_no']) . '</p> |
|||
<p><strong>Nom:</strong> ' . esc($order_data['customer_name']) . '</p> |
|||
<p><strong>Adresse:</strong> ' . esc($order_data['customer_address']) . '</p> |
|||
<p><strong>Téléphone:</strong> ' . esc($order_data['customer_phone']) . '</p> |
|||
|
|||
<div style="display: flex;align-items: center;justify-content: space-around;margin-bottom: 3%;"> |
|||
<div> |
|||
<p>Signature du client</p> |
|||
</div> |
|||
<div> |
|||
<p>Signature du commercial</p> |
|||
</div> |
|||
</div> |
|||
<table class="table table-bordered"> |
|||
<thead> |
|||
<tr> |
|||
<th>Produit</th> |
|||
<th>Qté</th> |
|||
<th>Prix</th> |
|||
<th>Total</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody>'; |
|||
|
|||
foreach ($orders_items as $item) { |
|||
$product_data = $Products->getProductData($item['product_id']); |
|||
$html .= '<tr> |
|||
<td>' . esc($product_data['name']) . '</td> |
|||
<td>' . esc($item['qty']) . '</td> |
|||
<td>' . number_format((float)$item['rate'], 2, '.', ' ') . '</td> |
|||
<td>' . number_format((float)$item['amount'], 2, '.', ' ') . '</td> |
|||
</tr>'; |
|||
} |
|||
|
|||
$html .= ' </tbody> |
|||
</table> |
|||
<table class="table"> |
|||
<tr> |
|||
<th>Total:</th> |
|||
<td>' . number_format((float)$order_data['gross_amount'], 2, '.', ' ') . '</td> |
|||
</tr>'; |
|||
|
|||
if (!empty($order_data['service_charge']) && (float)$order_data['service_charge'] > 0) { |
|||
$html .= '<tr> |
|||
<th>Frais de service:</th> |
|||
<td>' . number_format((float)$order_data['service_charge'], 2, '.', ' ') . '</td> |
|||
</tr>'; |
|||
} |
|||
|
|||
if (!empty($order_data['vat_charge']) && (float)$order_data['vat_charge'] > 0) { |
|||
$html .= '<tr> |
|||
<th>TVA:</th> |
|||
<td>' . number_format((float)$order_data['vat_charge'], 2, '.', ' ') . '</td> |
|||
</tr>'; |
|||
} |
|||
|
|||
$html .= '<tr> |
|||
<th>Réduction:</th> |
|||
<td>' . number_format((float)$order_data['discount'], 2, '.', ' ') . '</td> |
|||
</tr> |
|||
<tr> |
|||
<th>Total à payer:</th> |
|||
<td><strong>' . number_format((float)$order_data['net_amount'], 2, '.', ' ') . '</strong></td> |
|||
</tr> |
|||
<tr> |
|||
<th>Statut:</th> |
|||
<td>' . $paid_status . '</td> |
|||
</tr>'; |
|||
|
|||
// Vérification et ajout des informations de paiement |
|||
if (!empty($order_data['order_payment_mode'])) { |
|||
$html .= '<tr> |
|||
<th>Mode de paiement:</th> |
|||
<td><strong>' . esc($order_data['order_payment_mode']) . '</strong></td> |
|||
</tr>'; |
|||
} |
|||
|
|||
if (!empty($order_data['tranche_1'])) { |
|||
$html .= '<tr> |
|||
<th>Tranche 1:</th> |
|||
<td><strong>' . number_format((float)$order_data['tranche_1'], 2, '.', ' ') . '</strong></td> |
|||
</tr>'; |
|||
} |
|||
|
|||
if (!empty($order_data['tranche_2'])) { |
|||
$html .= '<tr> |
|||
<th>Tranche 2:</th> |
|||
<td><strong>' . number_format((float)$order_data['tranche_2'], 2, '.', ' ') . '</strong></td> |
|||
</tr>'; |
|||
} |
|||
|
|||
$html .= '</table> |
|||
|
|||
<div class="invoice-footer"> |
|||
Merci pour votre achat !<br> |
|||
<strong>' . esc($company_info['company_name']) . '</strong> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,176 @@ |
|||
<?php |
|||
|
|||
use App\Models\Users; |
|||
use App\Models\Avance; |
|||
use App\Models\AlertMail; |
|||
|
|||
function checkDeadlineAlerts() |
|||
{ |
|||
log_message('info', "=== DÉBUT checkDeadlineAlerts ==="); |
|||
|
|||
$cacheFile = WRITEPATH . 'cache/check_deadline_last_run.txt'; |
|||
|
|||
// On enlève la vérification de 24h pour s'assurer que le script tourne quotidiennement |
|||
file_put_contents($cacheFile, time()); |
|||
|
|||
$avanceModel = new Avance(); |
|||
$alertMailModel = new AlertMail(); |
|||
$usersModel = new Users(); |
|||
|
|||
$today = date('Y-m-d'); |
|||
log_message('info', "Date du jour: {$today}"); |
|||
|
|||
// Modification pour vérifier les avances dans 0-3 jours |
|||
$avances = $avanceModel |
|||
->where('DATE(deadline) >=', $today) // Inclut le jour même |
|||
->where('DATE(deadline) <=', date('Y-m-d', strtotime('+3 days'))) |
|||
->where('active', 1) |
|||
->findAll(); |
|||
|
|||
log_message('info', "Nombre d'avances trouvées (0-3 jours): " . count($avances)); |
|||
|
|||
$users = $usersModel->select('users.email, users.firstname, users.lastname') |
|||
->join('user_group', 'user_group.user_id = users.id') |
|||
->join('groups', 'groups.id = user_group.group_id') |
|||
->where('groups.group_name', 'DAF') |
|||
->findAll(); |
|||
|
|||
log_message('info', "Utilisateurs DAF trouvés: " . json_encode($users)); |
|||
|
|||
$emails = array_column($users, 'email'); |
|||
log_message('info', "Emails extraits: " . json_encode($emails)); |
|||
|
|||
if (empty($emails)) { |
|||
log_message('error', "Aucun email DAF trouvé"); |
|||
|
|||
$db = \Config\Database::connect(); |
|||
$allGroups = $db->query("SELECT DISTINCT group_name FROM groups")->getResult(); |
|||
log_message('info', "Groupes disponibles: " . json_encode($allGroups)); |
|||
|
|||
return; |
|||
} |
|||
|
|||
foreach ($avances as $avance) { |
|||
$deadline = date('Y-m-d', strtotime($avance['deadline'])); |
|||
$daysLeft = (int) ceil((strtotime($deadline) - strtotime($today)) / 86400); |
|||
|
|||
log_message('info', "Avance ID: {$avance['avance_id']}, Deadline: {$deadline}, Jours restants: {$daysLeft}"); |
|||
|
|||
// Modification des types d'alerte pour 0, 1, 2, 3 jours |
|||
$alertType = match($daysLeft) { |
|||
3 => 'deadline_3_days', |
|||
2 => 'deadline_2_days', |
|||
1 => 'deadline_1_day', |
|||
0 => 'deadline_today', |
|||
default => null, |
|||
}; |
|||
|
|||
if ($alertType === null) { |
|||
log_message('info', "Pas d'alerte nécessaire pour {$daysLeft} jours restants"); |
|||
continue; |
|||
} |
|||
|
|||
log_message('info', "Type d'alerte: {$alertType}"); |
|||
|
|||
// Vérification si l'alerte a déjà été envoyée |
|||
$alreadySent = $alertMailModel |
|||
->where('avance_id', $avance['avance_id']) |
|||
->where('alert_type', $alertType) |
|||
->first(); |
|||
|
|||
if ($alreadySent) { |
|||
log_message('info', "Alerte déjà envoyée pour avance_id={$avance['avance_id']} type={$alertType}"); |
|||
continue; |
|||
} |
|||
|
|||
// Message modifié pour inclure le cas du jour même |
|||
$urgencyText = $daysLeft === 0 ? "ÉCHÉANCE AUJOURD'HUI" : "{$daysLeft} jour(s) restant(s)"; |
|||
$message = " |
|||
<h3>⚠️ URGENT : Avance approchant de la deadline</h3> |
|||
<p><strong>ID Avance :</strong> {$avance['avance_id']}</p> |
|||
<p><strong>Client :</strong> {$avance['customer_name']}</p> |
|||
<p><strong>Montant avance :</strong> " . number_format($avance['avance_amount'], 0, ',', ' ') . " Ar</p> |
|||
<p><strong>Montant dû :</strong> " . number_format($avance['amount_due'], 0, ',', ' ') . " Ar</p> |
|||
<p><strong>Deadline :</strong> {$deadline}</p> |
|||
<p><strong>Statut :</strong> <span style='color: red; font-weight: bold;'>{$urgencyText}</span></p> |
|||
<p><strong>Téléphone client :</strong> {$avance['customer_phone']}</p> |
|||
<p><strong>Adresse client :</strong> {$avance['customer_address']}</p> |
|||
<hr> |
|||
<p><em>Cette avance " . ($daysLeft === 0 ? "arrive à échéance aujourd'hui" : "arrivera à échéance dans {$daysLeft} jour(s)") . ". Action requise immédiatement.</em></p> |
|||
"; |
|||
|
|||
$emailsSent = 0; |
|||
foreach ($emails as $to) { |
|||
log_message('info', "Tentative d'envoi email à: {$to}"); |
|||
|
|||
$subject = $daysLeft === 0 |
|||
? "⚠️ AVANCE URGENTE - ÉCHÉANCE AUJOURD'HUI" |
|||
: "⚠️ AVANCE URGENTE - {$daysLeft} jour(s) restant(s)"; |
|||
|
|||
if (sendEmailInBackground($to, $subject, $message)) { |
|||
$emailsSent++; |
|||
log_message('info', "Email envoyé avec succès à: {$to}"); |
|||
} else { |
|||
log_message('error', "Échec envoi email à: {$to}"); |
|||
} |
|||
} |
|||
|
|||
if ($emailsSent > 0) { |
|||
log_message('info', "Insertion alerte pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
|||
$alertMailModel->insert([ |
|||
'avance_id' => $avance['avance_id'], |
|||
'alert_type' => $alertType, |
|||
'sent_date' => date('Y-m-d H:i:s'), |
|||
'status' => 'sent', |
|||
'created_at' => date('Y-m-d H:i:s'), |
|||
]); |
|||
} else { |
|||
log_message('error', "Aucun email envoyé pour avance_id={$avance['avance_id']} avec type {$alertType}"); |
|||
} |
|||
} |
|||
|
|||
log_message('info', "=== FIN checkDeadlineAlerts ==="); |
|||
} |
|||
|
|||
function sendEmailInBackground($to, $subject, $message) |
|||
{ |
|||
try { |
|||
log_message('info', "Préparation envoi email à: {$to}"); |
|||
|
|||
$email = \Config\Services::email(); |
|||
|
|||
$config = [ |
|||
'protocol' => 'smtp', |
|||
'SMTPHost' => 'smtp.gmail.com', |
|||
'SMTPUser' => 'rey342505@gmail.com', |
|||
'SMTPPass' => 'loirqovmfuxnasrm', |
|||
'SMTPPort' => 587, |
|||
'SMTPCrypto' => 'tls', |
|||
'mailType' => 'html', |
|||
'charset' => 'utf-8', |
|||
'newline' => "\r\n" |
|||
]; |
|||
|
|||
$email->initialize($config); |
|||
|
|||
$email->setFrom('rey342505@gmail.com', 'Système Motorbike - Alertes Avances'); |
|||
$email->setTo($to); |
|||
$email->setSubject($subject); |
|||
$email->setMessage($message); |
|||
|
|||
log_message('info', "Configuration email terminée, tentative d'envoi..."); |
|||
|
|||
if (!$email->send()) { |
|||
$debugInfo = $email->printDebugger(['headers']); |
|||
log_message('error', "Erreur email à {$to}: " . print_r($debugInfo, true)); |
|||
return false; |
|||
} |
|||
|
|||
log_message('info', "Email envoyé avec succès à: {$to}"); |
|||
return true; |
|||
|
|||
} catch (\Exception $e) { |
|||
log_message('error', "Exception email à {$to}: " . $e->getMessage()); |
|||
return false; |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
<?php |
|||
|
|||
namespace App\Models; |
|||
|
|||
use CodeIgniter\Model; |
|||
|
|||
class AlertMail extends Model |
|||
{ |
|||
protected $table = 'email_alerts'; |
|||
protected $primaryKey = 'id'; |
|||
|
|||
protected $allowedFields = [ |
|||
'avance_id', |
|||
'alert_type', |
|||
'sent_date', |
|||
'status', |
|||
'created_at', |
|||
]; |
|||
|
|||
// Pas de fonction checkDeadlineAlerts ici ! |
|||
} |
|||
@ -1 +0,0 @@ |
|||
icon |
|||
@ -0,0 +1 @@ |
|||
icon |
|||
@ -1 +0,0 @@ |
|||
icon |
|||
@ -0,0 +1 @@ |
|||
icon |
|||
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 16 B After Width: | Height: | Size: 88 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 0 B |
|
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 0 B |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 848 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 657 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
@ -0,0 +1 @@ |
|||
1755601005 |
|||