Compare commits

..

13 Commits
2.0.0 ... main

52 changed files with 2570 additions and 17493 deletions

60
.htaccess Normal file
View File

@ -0,0 +1,60 @@
# Empêcher l'accès direct aux fichiers PHP
<FilesMatch "\.php$">
<IfModule !mod_authz_core.c>
Order Allow,Deny
Deny from all
</IfModule>
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
</FilesMatch>
<Files "api.php">
<IfModule !mod_authz_core.c>
Order Allow,Deny
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Files>
# Autoriser l'accès aux points d'entrée spécifiques
<Files ~ "^(index|admin|login|logout|share)\.php$">
<IfModule !mod_authz_core.c>
Order Allow,Deny
Allow from all
</IfModule>
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Files>
# Définir les types MIME corrects
AddType text/css .css
AddType application/javascript .js
AddType image/x-icon .ico
AddType image/svg+xml .svg
AddType application/x-font-woff .woff
AddType application/x-font-woff2 .woff2
# Activer la compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
</IfModule>
# Cache headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
</IfModule>
# Protection des dossiers
Options -Indexes

View File

@ -1,8 +1,4 @@
# Cyla
Site d'hébergement de fichiers simple, réduit au strict nécessaire.
Le projet se base sur la première version de [QuadFile](https://github.com/QuadPiece/QuadFile).
![image](https://concepts.esenjin.xyz/cyla/v2/file/CE513E.png)
![image](https://concepts.esenjin.xyz/cyla/fichiers/6787d3fe886e4_1736954878.png)

441
admin.php Normal file
View File

@ -0,0 +1,441 @@
<?php
// debug :
ob_start();
ini_set('display_errors', 1);
error_reporting(E_ALL);
define('CYLA_CORE', true);
require_once 'core.php';
// Vérifions si des headers ont déjà été envoyés
if (headers_sent($filename, $linenum)) {
exit("Headers already sent in $filename on line $linenum");
}
// Vérifier si l'utilisateur est connecté
if (!Cyla::isLoggedIn()) {
header('Location: login.php');
exit;
}
$error = $_GET['error'] ?? null;
$success = $_GET['success'] ?? null;
// Traitement du changement de mot de passe
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'change_password') {
if (!isset($_POST['csrf_token']) || !Cyla::verifyCSRFToken($_POST['csrf_token'])) {
$error = 'Token de sécurité invalide';
} else {
$current_password = $_POST['current_password'] ?? '';
$new_password = $_POST['new_password'] ?? '';
$confirm_password = $_POST['confirm_password'] ?? '';
if (empty($current_password) || empty($new_password) || empty($confirm_password)) {
$error = 'Tous les champs sont requis';
} else if ($new_password !== $confirm_password) {
$error = 'Les nouveaux mots de passe ne correspondent pas';
} else {
global $ADMIN_USERS;
$username = $_SESSION['user'];
$user = $ADMIN_USERS[$username];
// Vérifier l'ancien mot de passe
if (hash(HASH_ALGO, $current_password . $user['salt']) !== $user['password']) {
$error = 'Mot de passe actuel incorrect';
} else {
// Mettre à jour le mot de passe
$ADMIN_USERS[$username]['password'] = hash(HASH_ALGO, $new_password . $user['salt']);
// Sauvegarder dans le fichier de configuration
$config_content = file_get_contents('config.php');
$config_content = preg_replace(
'/\'password\' => \'' . preg_quote($user['password'], '/') . '\'/',
'\'password\' => \'' . $ADMIN_USERS[$username]['password'] . '\'',
$config_content
);
file_put_contents('config.php', $config_content);
$success = 'Mot de passe modifié avec succès';
}
}
}
}
// Traitement de l'upload de fichier
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upload') {
if (!isset($_POST['csrf_token']) || !Cyla::verifyCSRFToken($_POST['csrf_token'])) {
$error = 'Token de sécurité invalide';
} else if (!isset($_FILES['file'])) {
$error = 'Aucun fichier n\'a été envoyé';
} else {
$validation = Cyla::validateUpload($_FILES['file']);
if (!$validation['valid']) {
$error = $validation['error'];
} else {
$filename = Cyla::generateUniqueFilename($_FILES['file']['name']);
$destination = UPLOAD_DIR . $filename;
if (move_uploaded_file($_FILES['file']['tmp_name'], $destination)) {
$success = 'Fichier uploadé avec succès';
} else {
$error = 'Erreur lors de l\'upload du fichier';
}
}
}
}
// Liste des fichiers
$files = Cyla::listFiles();
// Contenu de la page
$pageTitle = 'Administration';
ob_start(); ?>
<div class="admin-container">
<div class="card">
<h2>Téléversement de fichier</h2>
<div class="upload-zone" id="uploadZone">
<input type="file" id="fileInput" multiple class="file-input" name="files[]">
<div class="upload-content">
<div class="upload-icon">
<svg width="50" height="50" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
<polyline points="17 8 12 3 7 8" />
<line x1="12" y1="3" x2="12" y2="15" />
</svg>
</div>
<p class="upload-text">
Glissez-déposez vos fichiers ici<br>
<span class="upload-text-sub">ou cliquez pour sélectionner</span>
</p>
<p class="upload-limit">
Taille maximale : 100 Mo<br>
Extensions : <?php echo implode(', ', ALLOWED_EXTENSIONS); ?>
</p>
</div>
</div>
<div id="fileList" class="file-list"></div>
</div>
<script>
const uploadZone = document.getElementById('uploadZone');
const fileInput = document.getElementById('fileInput');
const fileList = document.getElementById('fileList');
const maxFileSize = <?php echo MAX_FILE_SIZE; ?>;
const allowedExtensions = <?php echo json_encode(ALLOWED_EXTENSIONS); ?>;
// Gestion du drag & drop
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
uploadZone.addEventListener(eventName, preventDefaults, false);
document.body.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
['dragenter', 'dragover'].forEach(eventName => {
uploadZone.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
uploadZone.addEventListener(eventName, unhighlight, false);
});
function highlight(e) {
uploadZone.classList.add('upload-zone-active');
}
function unhighlight(e) {
uploadZone.classList.remove('upload-zone-active');
}
// Gestion du drop
uploadZone.addEventListener('drop', handleDrop, false);
fileInput.addEventListener('change', handleFiles, false);
uploadZone.addEventListener('click', () => fileInput.click());
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles({ target: { files: files } });
}
function isValidFile(file) {
const ext = file.name.split('.').pop().toLowerCase();
if (!allowedExtensions.includes(ext)) {
return { valid: false, error: `Extension .${ext} non autorisée` };
}
if (file.size > maxFileSize) {
return { valid: false, error: 'Fichier trop volumineux (max 100 Mo)' };
}
return { valid: true };
}
function handleFiles(e) {
const files = Array.from(e.target.files);
// Vider la liste précédente
fileList.innerHTML = '';
files.forEach(file => {
const validation = isValidFile(file);
const fileElement = createFileElement(file, validation);
fileList.appendChild(fileElement);
if (validation.valid) {
uploadFile(file, fileElement);
}
});
}
function createFileElement(file, validation) {
const div = document.createElement('div');
div.className = 'file-item ' + (validation.valid ? '' : 'file-item-error');
div.innerHTML = `
<div class="file-item-content">
<div class="file-item-name">${file.name}</div>
<div class="file-item-size">${(file.size / 1024 / 1024).toFixed(2)} Mo</div>
${validation.valid ?
'<div class="file-item-progress"><div class="progress-bar"></div></div>' :
`<div class="file-item-error-message">${validation.error}</div>`
}
</div>
`;
return div;
}
async function uploadFile(file, element) {
const formData = new FormData();
formData.append('file', file);
formData.append('csrf_token', '<?php echo Cyla::generateCSRFToken(); ?>');
try {
const response = await fetch('api.php', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error('Erreur lors de l\'upload');
}
const result = await response.json();
if (result.success) {
element.classList.add('file-item-success');
} else {
element.classList.add('file-item-error');
}
} catch (error) {
element.classList.add('file-item-error');
console.error('Error:', error);
}
}
</script>
<?php
// Traitement de la suppression de fichier
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete_file') {
if (!isset($_POST['csrf_token']) || !Cyla::verifyCSRFToken($_POST['csrf_token'])) {
header('Location: admin.php?error=' . urlencode('Token de sécurité invalide'));
exit;
} else if (!isset($_POST['filename'])) {
header('Location: admin.php?error=' . urlencode('Nom de fichier manquant'));
exit;
} else {
$result = Cyla::deleteFile($_POST['filename']);
if ($result['success']) {
header('Location: admin.php?success=' . urlencode('Fichier supprimé avec succès'));
exit;
} else {
header('Location: admin.php?error=' . urlencode($result['error']));
exit;
}
}
}
// Récupération de la page courante depuis l'URL
$currentPage = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$filesPerPage = 20;
// Récupération des fichiers avec pagination
$fileData = Cyla::listFiles($currentPage, $filesPerPage);
$files = $fileData['files'];
?>
<div class="card">
<h2>Fichiers hébergés</h2>
<?php if (empty($files)): ?>
<p class="text-muted">Aucun fichier hébergé</p>
<?php else: ?>
<div class="files-header">
<p class="files-count">
<?php
$start = (($fileData['currentPage'] - 1) * $fileData['perPage']) + 1;
$end = min($start + count($files) - 1, $fileData['total']);
echo "Affichage de $start-$end sur {$fileData['total']} fichiers";
?>
</p>
</div>
<div class="file-list">
<?php foreach ($files as $file): ?>
<div class="file-item">
<div class="file-preview">
<?php if ($file['preview_type'] === 'image'): ?>
<img src="<?php echo $file['path'] . Cyla::escape($file['name']); ?>"
alt="<?php echo Cyla::escape($file['name']); ?>">
<?php else: ?>
<div class="preview-placeholder">
<?php echo strtoupper($file['extension']); ?>
</div>
<?php endif; ?>
</div>
<div class="file-info">
<p class="file-name"><?php echo Cyla::escape($file['name']); ?></p>
<p class="file-meta">
<?php echo Cyla::escape(round($file['size'] / 1024, 2)); ?> Ko
· <?php echo date('d/m/Y H:i', $file['uploaded']); ?>
· <?php echo $file['path']; ?>
</p>
<div class="file-actions">
<a href="share.php?file=<?php echo urlencode($file['name']); ?>&path=<?php echo urlencode($file['path']); ?>"
class="btn btn-secondary"
target="_blank">Voir</a>
<button class="btn"
onclick="copyShareLink('<?php echo SITE_URL; ?>share.php?file=<?php echo urlencode($file['name']); ?>&path=<?php echo urlencode($file['path']); ?>')">
Copier le lien
</button>
<button class="btn btn-danger"
onclick="confirmDelete('<?php echo Cyla::escape($file['name']); ?>', '<?php echo Cyla::escape($file['path']); ?>')">
×
</button>
</div>
</div>
</div>
<!-- Formulaire caché pour la suppression -->
<form id="deleteForm-<?php echo Cyla::escape($file['name']); ?>"
action="admin.php"
method="POST"
style="display: none;">
<input type="hidden" name="action" value="delete_file">
<input type="hidden" name="filename" value="<?php echo Cyla::escape($file['name']); ?>">
<input type="hidden" name="path" value="<?php echo Cyla::escape($file['path']); ?>">
<input type="hidden" name="csrf_token" value="<?php echo Cyla::generateCSRFToken(); ?>">
</form>
<?php endforeach; ?>
<?php if ($fileData['totalPages'] > 1): ?>
<div class="pagination">
<?php if ($fileData['currentPage'] > 1): ?>
<a href="?page=<?php echo $fileData['currentPage'] - 1; ?>"
class="pagination-link">&laquo;</a>
<?php endif; ?>
<?php
// Afficher max 5 pages autour de la page courante
$start = max(1, $fileData['currentPage'] - 2);
$end = min($fileData['totalPages'], $fileData['currentPage'] + 2);
if ($start > 1) {
echo '<a href="?page=1" class="pagination-link">1</a>';
if ($start > 2) echo '<span class="pagination-ellipsis">...</span>';
}
for ($i = $start; $i <= $end; $i++) {
$isActive = $i === $fileData['currentPage'];
echo '<a href="?page=' . $i . '" class="pagination-link ' .
($isActive ? 'pagination-active' : '') . '">' . $i . '</a>';
}
if ($end < $fileData['totalPages']) {
if ($end < $fileData['totalPages'] - 1) echo '<span class="pagination-ellipsis">...</span>';
echo '<a href="?page=' . $fileData['totalPages'] .
'" class="pagination-link">' . $fileData['totalPages'] . '</a>';
}
if ($fileData['currentPage'] < $fileData['totalPages']): ?>
<a href="?page=<?php echo $fileData['currentPage'] + 1; ?>"
class="pagination-link">&raquo;</a>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<script>
function copyShareLink(url) {
navigator.clipboard.writeText(url).then(() => {
// Créer et afficher la notification
const notification = document.createElement('div');
notification.className = 'notification';
notification.textContent = 'Lien copié dans le presse-papier !';
document.body.appendChild(notification);
// Supprimer la notification après l'animation
setTimeout(() => {
notification.remove();
}, 3000);
}).catch(err => {
console.error('Erreur lors de la copie :', err);
// En cas d'erreur, afficher une notification d'erreur
const notification = document.createElement('div');
notification.className = 'notification error';
notification.textContent = 'Erreur lors de la copie';
document.body.appendChild(notification);
setTimeout(() => {
notification.remove();
}, 3000);
});
}
// Fonction de confirmation de suppression
function confirmDelete(filename) {
const overlay = document.createElement('div');
overlay.className = 'confirmation-overlay';
const dialog = document.createElement('div');
dialog.className = 'confirmation-dialog';
dialog.innerHTML = `
<h3>Confirmer la suppression</h3>
<p>Voulez-vous vraiment supprimer le fichier "${filename}" ?</p>
<div class="confirmation-actions">
<button class="btn btn-secondary" onclick="closeConfirmDialog()">Annuler</button>
<button class="btn" onclick="submitDelete('${filename}')">Supprimer</button>
</div>
`;
document.body.appendChild(overlay);
document.body.appendChild(dialog);
}
// Fonction pour fermer la modale
function closeConfirmDialog() {
document.querySelector('.confirmation-overlay')?.remove();
document.querySelector('.confirmation-dialog')?.remove();
}
// Fonction pour soumettre la suppression
function submitDelete(filename) {
document.getElementById('deleteForm-' + filename).submit();
closeConfirmDialog();
}
</script>
<script>
window.CSRF_TOKEN = "<?php echo Cyla::generateCSRFToken(); ?>";
</script>
<script src="js/password-modal.js"></script>
<?php
$content = ob_get_clean();
require 'layout.php';
ob_end_flush();

75
api.php Normal file
View File

@ -0,0 +1,75 @@
<?php
define('CYLA_CORE', true);
require_once 'core.php';
// Augmenter la limite de temps d'exécution pour les uploads multiples
set_time_limit(300); // 5 minutes
// Vérifier si l'utilisateur est connecté
if (!Cyla::isLoggedIn()) {
header('Content-Type: application/json');
http_response_code(401);
echo json_encode(['error' => 'Non autorisé']);
exit;
}
// Vérifier le token CSRF
if (!isset($_POST['csrf_token']) || !Cyla::verifyCSRFToken($_POST['csrf_token'])) {
header('Content-Type: application/json');
http_response_code(403);
echo json_encode(['error' => 'Token CSRF invalide']);
exit;
}
// Gérer l'upload de fichier
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
header('Content-Type: application/json');
try {
// Vérification de l'espace disque disponible
$uploadDir = UPLOAD_DIR;
$freeSpace = disk_free_space($uploadDir);
if ($freeSpace < $_FILES['file']['size']) {
throw new Exception('Espace disque insuffisant');
}
$validation = Cyla::validateUpload($_FILES['file']);
if (!$validation['valid']) {
throw new Exception($validation['error']);
}
$filename = Cyla::generateUniqueFilename($_FILES['file']['name']);
$destination = $uploadDir . $filename;
// Upload avec gestion de la mémoire
if (!move_uploaded_file($_FILES['file']['tmp_name'], $destination)) {
throw new Exception('Erreur lors du déplacement du fichier');
}
// Vérifier l'intégrité du fichier
if (!file_exists($destination) || filesize($destination) !== $_FILES['file']['size']) {
unlink($destination); // Nettoyer en cas d'erreur
throw new Exception('Erreur d\'intégrité du fichier');
}
echo json_encode([
'success' => true,
'file' => [
'name' => $filename,
'size' => filesize($destination),
'url' => 'share.php?file=' . urlencode($filename)
]
]);
} catch (Exception $e) {
http_response_code(400);
echo json_encode([
'error' => $e->getMessage(),
'details' => error_get_last()
]);
}
exit;
}
// Méthode non autorisée
http_response_code(405);
echo json_encode(['error' => 'Méthode non autorisée']);

80
config.php Normal file
View File

@ -0,0 +1,80 @@
<?php
// Prevent direct access to this file
if (!defined('CYLA_CORE')) {
header('HTTP/1.0 403 Forbidden');
exit('Accès direct interdit');
}
// Site configuration
define('SITE_NAME', 'Cyla');
define('SITE_VERSION', '3.0.2');
define('SITE_URL', 'https://concepts.esenjin.xyz/cyla/');
// Files configuration
define('LEGACY_UPLOAD_DIRS', [
__DIR__ . '/v1/img/fichiers/',
__DIR__ . '/v2/file/'
]);
define('UPLOAD_DIR', __DIR__ . '/fichiers/');
define('MAX_FILE_SIZE', 100 * 1024 * 1024); // 100 Mo en octets
define('ALLOWED_EXTENSIONS', [
'png', 'jpg', 'jpeg', 'gif', 'webm', 'mp4', 'wmv',
'mp3', 'flac', 'ogg', 'zip', 'css', 'pdf',
'zip', 'rar', 'm3u', 'm3u8', 'txt'
]);
// Preview configuration
define('PREVIEW_IMAGES', ['png', 'jpg', 'jpeg', 'gif']);
define('PREVIEW_VIDEOS', ['webm', 'mp4', 'wmv']);
define('PREVIEW_AUDIOS', ['mp3', 'flac', 'ogg']);
define('PREVIEW_TEXTS', ['txt', 'css', 'm3u', 'm3u8']);
// Security configuration
define('HASH_ALGO', 'sha256'); // Algorithme de hachage pour les mots de passe
define('SALT_LENGTH', 32); // Longueur du sel pour le hachage
// Admin users (format: 'username' => ['password' => 'hashed_password', 'salt' => 'random_salt'])
$ADMIN_USERS = [
'admin' => [
'password' => 'a94637ad7685d8a3e64c97eddd7751a0ff55434a607361b7304edf41b39ab7f8', // Default: 'password'
'salt' => 'defaultsalt123'
]
];
// Session configuration
define('SESSION_LIFETIME', 3600); // Durée de vie de la session en secondes (1 heure)
define('SESSION_NAME', 'CYLA_SESSION');
// Error reporting
define('DEBUG_MODE', false); // À mettre à false en production
if (DEBUG_MODE) {
error_reporting(E_ALL);
ini_set('display_errors', 1);
} else {
error_reporting(0);
ini_set('display_errors', 0);
}
// Fonction pour vérifier si une extension est autorisée
function isAllowedExtension($extension) {
return in_array(strtolower($extension), ALLOWED_EXTENSIONS);
}
// Fonction pour vérifier si un fichier peut avoir un aperçu
function canPreview($extension) {
$extension = strtolower($extension);
return in_array($extension, PREVIEW_IMAGES) ||
in_array($extension, PREVIEW_VIDEOS) ||
in_array($extension, PREVIEW_AUDIOS) ||
in_array($extension, PREVIEW_TEXTS);
}
// Fonction pour obtenir le type d'aperçu
function getPreviewType($extension) {
$extension = strtolower($extension);
if (in_array($extension, PREVIEW_IMAGES)) return 'image';
if (in_array($extension, PREVIEW_VIDEOS)) return 'video';
if (in_array($extension, PREVIEW_AUDIOS)) return 'audio';
if (in_array($extension, PREVIEW_TEXTS)) return 'text';
return 'none';
}

257
core.php Normal file
View File

@ -0,0 +1,257 @@
<?php
// Charger la configuration avant tout
require_once __DIR__ . '/config.php';
// Démarrer la session
session_name(SESSION_NAME);
session_start();
/**
* Classe principale de Cyla
*/
class Cyla {
/**
* Vérifie si un utilisateur est connecté
* @return bool
*/
public static function isLoggedIn() {
return isset($_SESSION['user']) && isset($_SESSION['last_activity']) &&
(time() - $_SESSION['last_activity']) < SESSION_LIFETIME;
}
/**
* Met à jour le timestamp de dernière activité
*/
public static function updateActivity() {
$_SESSION['last_activity'] = time();
}
/**
* Authentifie un utilisateur
* @param string $username Nom d'utilisateur
* @param string $password Mot de passe
* @return bool
*/
public static function authenticate($username, $password) {
global $ADMIN_USERS;
if (!isset($ADMIN_USERS[$username])) {
return false;
}
$user = $ADMIN_USERS[$username];
$hashed = hash(HASH_ALGO, $password . $user['salt']);
if ($hashed === $user['password']) {
$_SESSION['user'] = $username;
self::updateActivity();
return true;
}
return false;
}
/**
* Déconnecte l'utilisateur
*/
public static function logout() {
session_destroy();
}
/**
* Génère un nom de fichier unique
* @param string $originalName Nom original du fichier
* @return string
*/
public static function generateUniqueFilename($originalName) {
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
return uniqid() . '_' . time() . '.' . $extension;
}
/**
* Vérifie si un fichier peut être uploadé
* @param array $file Informations du fichier ($_FILES)
* @return array ['valid' => bool, 'error' => string|null]
*/
public static function validateUpload($file) {
$result = ['valid' => true, 'error' => null];
// Vérifier les erreurs d'upload PHP
if ($file['error'] !== UPLOAD_ERR_OK) {
$result['valid'] = false;
$result['error'] = 'Erreur lors de l\'upload';
return $result;
}
// Vérifier la taille
if ($file['size'] > MAX_FILE_SIZE) {
$result['valid'] = false;
$result['error'] = 'Le fichier dépasse la taille maximale autorisée';
return $result;
}
// Vérifier l'extension
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!isAllowedExtension($extension)) {
$result['valid'] = false;
$result['error'] = 'Extension de fichier non autorisée';
return $result;
}
return $result;
}
/**
* Sécurise les sorties HTML
* @param string $text Texte à sécuriser
* @return string
*/
public static function escape($text) {
return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
}
/**
* Génère un token CSRF
* @return string
*/
public static function generateCSRFToken() {
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
return $_SESSION['csrf_token'];
}
/**
* Vérifie un token CSRF
* @param string $token Token à vérifier
* @return bool
*/
public static function verifyCSRFToken($token) {
return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}
/**
* Liste les fichiers uploadés avec pagination
* @param int $page Numéro de la page (commence à 1)
* @param int $perPage Nombre d'éléments par page
* @return array ['files' => array, 'total' => int, 'totalPages' => int]
*/
public static function listFiles($page = 1, $perPage = 20) {
$files = [];
$allFiles = [];
// Ajouter les fichiers du dossier principal
$allFiles = array_merge($allFiles, glob(UPLOAD_DIR . '*'));
// Ajouter les fichiers des dossiers hérités
foreach (LEGACY_UPLOAD_DIRS as $dir) {
if (is_dir($dir)) {
$allFiles = array_merge($allFiles, glob($dir . '*'));
}
}
// Trier les fichiers par date de modification (plus récent en premier)
usort($allFiles, function($a, $b) {
return filemtime($b) - filemtime($a);
});
// Calculer la pagination
$total = count($allFiles);
$totalPages = ceil($total / $perPage);
$page = max(1, min($page, $totalPages));
$offset = ($page - 1) * $perPage;
// Récupérer uniquement les fichiers de la page courante
$pageFiles = array_slice($allFiles, $offset, $perPage);
foreach ($pageFiles as $file) {
$info = pathinfo($file);
$relativePath = '';
// Déterminer le chemin relatif selon le dossier
if (strpos($file, UPLOAD_DIR) === 0) {
$relativePath = 'fichiers/';
} elseif (strpos($file, __DIR__ . '/v1/img/fichiers/') === 0) {
$relativePath = 'v1/img/fichiers/';
} elseif (strpos($file, __DIR__ . '/v2/file/') === 0) {
$relativePath = 'v2/file/';
}
$files[] = [
'name' => basename($file),
'size' => filesize($file),
'extension' => strtolower($info['extension'] ?? ''),
'uploaded' => filemtime($file),
'preview_type' => getPreviewType($info['extension'] ?? ''),
'path' => $relativePath // Ajout du chemin relatif
];
}
return [
'files' => $files,
'total' => $total,
'totalPages' => $totalPages,
'currentPage' => $page,
'perPage' => $perPage
];
}
/**
* Supprime un fichier
* @param string $filename Nom du fichier à supprimer
* @param string $path Chemin relatif du fichier
* @return array ['success' => bool, 'error' => string|null]
*/
public static function deleteFile($filename, $path = 'fichiers/') {
// Déterminer le chemin complet selon le dossier
$basePath = '';
switch ($path) {
case 'v1/img/fichiers/':
$basePath = __DIR__ . '/v1/img/fichiers/';
break;
case 'v2/file/':
$basePath = __DIR__ . '/v2/file/';
break;
default:
$basePath = UPLOAD_DIR;
}
$filepath = $basePath . $filename;
// Vérifier que le fichier existe et est dans le bon dossier
if (!file_exists($filepath) || !is_file($filepath)) {
return ['success' => false, 'error' => 'Fichier introuvable'];
}
// Vérifier que le fichier est bien dans un des dossiers autorisés
$realpath = realpath($filepath);
$allowed = false;
if (strpos($realpath, realpath(UPLOAD_DIR)) === 0) {
$allowed = true;
} else {
foreach (LEGACY_UPLOAD_DIRS as $dir) {
if (strpos($realpath, realpath($dir)) === 0) {
$allowed = true;
break;
}
}
}
if (!$allowed) {
return ['success' => false, 'error' => 'Chemin de fichier non autorisé'];
}
// Supprimer le fichier
if (unlink($filepath)) {
return ['success' => true];
} else {
return ['success' => false, 'error' => 'Erreur lors de la suppression du fichier'];
}
}
}
// Vérifier et mettre à jour l'activité si l'utilisateur est connecté
if (Cyla::isLoggedIn()) {
Cyla::updateActivity();
}

720
css/style.css Normal file
View File

@ -0,0 +1,720 @@
/* Variables */
:root {
/* Couleurs principales */
--color-bg: #1a1716;
--color-bg-alt: #231f1d;
--color-text: #e6d5c5;
--color-text-muted: #a18d7a;
--color-primary: #d4846a;
--color-primary-hover: #e6977c;
--color-accent: #8b4b45;
--color-border: #382f2a;
/* Alertes */
--color-error: #ff6b6b;
--color-success: #51cf66;
/* Espacements */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
/* Bordures */
--border-radius: 4px;
}
/* Reset et base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: var(--color-bg);
color: var(--color-text);
line-height: 1.6;
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Navigation */
header {
background-color: var(--color-bg-alt);
border-bottom: 1px solid var(--color-border);
padding: var(--spacing-md) var(--spacing-lg);
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1200px;
margin: 0 auto;
width: 100%;
}
.nav-brand a {
color: var(--color-primary);
font-size: 1.5rem;
font-weight: bold;
text-decoration: none;
}
.nav-menu {
display: flex;
gap: var(--spacing-md);
}
/* Navigation */
.nav-link,
button.nav-link {
color: var(--color-text);
text-decoration: none;
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius);
transition: background-color 0.3s ease;
font: inherit; /* Pour que le bouton utilise la même police */
border: none;
background: none;
cursor: pointer;
display: inline-block;
}
.nav-link:hover,
button.nav-link:hover {
background-color: var(--color-border);
}
/* Main content */
main {
flex: 1;
padding: var(--spacing-lg);
max-width: 1200px;
margin: 0 auto;
width: 100%;
}
/* Cards */
.card {
background-color: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
padding: var(--spacing-lg);
margin-bottom: var(--spacing-lg);
}
/* Forms */
.form-group {
margin-bottom: var(--spacing-md);
}
label {
display: block;
margin-bottom: var(--spacing-xs);
color: var(--color-text-muted);
}
input[type="text"],
input[type="password"],
textarea {
width: 100%;
padding: var(--spacing-sm);
background-color: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
color: var(--color-text);
}
input[type="text"]:focus,
input[type="password"]:focus,
textarea:focus {
outline: none;
border-color: var(--color-primary);
}
/* Buttons */
.btn {
display: inline-block;
padding: var(--spacing-sm) var(--spacing-md);
background-color: var(--color-primary);
color: var(--color-text);
border: none;
border-radius: var(--border-radius);
cursor: pointer;
text-decoration: none;
transition: background-color 0.3s ease;
}
.btn:hover {
background-color: var(--color-primary-hover);
}
.btn-secondary {
background-color: var(--color-border);
}
.btn-secondary:hover {
background-color: var(--color-text-muted);
}
/* Alerts */
.alert {
padding: var(--spacing-md);
border-radius: var(--border-radius);
margin-bottom: var(--spacing-md);
}
.alert-error {
background-color: var(--color-error);
color: white;
}
.alert-success {
background-color: var(--color-success);
color: white;
}
/* File list */
.file-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: var(--spacing-md);
}
.file-item {
background-color: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
padding: var(--spacing-md);
}
.file-preview {
aspect-ratio: 16/9;
background-color: var(--color-bg);
border-radius: var(--border-radius);
margin-bottom: var(--spacing-sm);
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.file-preview img,
.file-preview video {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.file-info {
color: var(--color-text-muted);
font-size: 0.9rem;
}
/* Footer */
footer {
background-color: var(--color-bg-alt);
border-top: 1px solid var(--color-border);
padding: var(--spacing-lg);
text-align: center;
color: var(--color-text-muted);
}
/* Zone d'upload */
.upload-zone {
position: relative;
border: 2px dashed var(--color-border);
border-radius: var(--border-radius);
padding: 2rem;
text-align: center;
cursor: pointer;
transition: all 0.2s ease;
}
.upload-zone:hover {
border-color: var(--color-primary);
}
.upload-zone-active {
border-color: var(--color-primary);
background-color: rgba(212, 132, 106, 0.1);
}
.file-input {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
opacity: 0;
cursor: pointer;
}
.upload-content {
pointer-events: none;
}
.upload-icon {
margin-bottom: 1rem;
}
.upload-icon svg {
stroke: var(--color-text-muted);
margin: 0 auto;
}
.upload-text {
margin-bottom: 0.5rem;
color: var(--color-text);
}
.upload-text-sub {
font-size: 0.9em;
color: var(--color-text-muted);
}
.upload-limit {
font-size: 0.8em;
color: var(--color-text-muted);
}
/* Liste des fichiers */
.file-list {
margin-top: 1rem;
}
.file-item {
background: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
padding: 1rem;
margin-bottom: 0.5rem;
}
.file-item-content {
display: grid;
gap: 0.5rem;
}
.file-item-name {
font-weight: 500;
word-break: break-all;
}
.file-item-size {
color: var(--color-text-muted);
font-size: 0.9em;
}
.file-item-progress {
height: 4px;
background: var(--color-border);
border-radius: 2px;
overflow: hidden;
}
.progress-bar {
height: 100%;
background: var(--color-primary);
width: 0;
transition: width 0.3s ease;
}
.file-item-error {
border-color: var(--color-error);
}
.file-item-error .file-item-error-message {
color: var(--color-error);
font-size: 0.9em;
}
.file-item-success {
border-color: var(--color-success);
}
/* Responsive */
@media (max-width: 768px) {
.nav-menu {
display: none;
}
main {
padding: var(--spacing-md);
}
.file-list {
grid-template-columns: 1fr;
}
}
/* Styles pour la modale */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.75);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
backdrop-filter: blur(4px);
}
.modal-container {
background-color: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
width: 100%;
max-width: 500px;
margin: 1rem;
animation: modalAppear 0.3s ease-out;
}
@keyframes modalAppear {
from {
opacity: 0;
transform: scale(0.95) translateY(10px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
/* Styles spécifiques à la page d'administration */
.admin-container {
display: flex;
flex-direction: column;
gap: var(--spacing-lg);
}
.admin-container h2 {
color: var(--color-primary);
margin-bottom: var(--spacing-md);
}
.help-text {
font-size: 0.9rem;
color: var(--color-text-muted);
margin-top: var(--spacing-xs);
}
.preview-placeholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-bg);
color: var(--color-text-muted);
font-size: 2rem;
font-weight: bold;
}
.file-name {
font-weight: bold;
word-break: break-all;
}
.file-meta {
font-size: 0.9rem;
color: var(--color-text-muted);
margin: var(--spacing-xs) 0;
}
.file-actions {
display: flex;
gap: var(--spacing-sm);
margin-top: var(--spacing-sm);
}
/* Styles pour la pagination et l'affichage des fichiers */
.files-header {
margin-bottom: var(--spacing-md);
color: var(--color-text-muted);
}
.files-count {
font-size: 0.9rem;
}
.pagination {
display: flex;
justify-content: center;
align-items: center;
gap: var(--spacing-xs);
margin: var(--spacing-lg) auto;
padding-top: var(--spacing-md);
border-top: 1px solid var(--color-border);
max-width: 100%;
}
.pagination-link {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 2rem;
height: 2rem;
padding: 0 0.5rem;
color: var(--color-text);
text-decoration: none;
background-color: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
transition: all 0.2s ease;
white-space: nowrap;
font-size: 0.9rem;
}
.pagination-link:hover {
background-color: var(--color-border);
}
.pagination-active {
background-color: var(--color-primary);
border-color: var(--color-primary);
color: var(--color-text);
}
.pagination-ellipsis {
color: var(--color-text-muted);
padding: 0 0.25rem;
user-select: none;
}
/* Bouton de suppression */
.btn-danger {
background-color: var(--color-accent);
width: 2.5rem;
height: 2.5rem;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
line-height: 1;
}
.btn-danger:hover {
background-color: #a85651;
}
/* Boîte de dialogue de confirmation */
.confirmation-dialog {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--color-bg-alt);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
padding: var(--spacing-lg);
max-width: 400px;
width: 90%;
z-index: 1000;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.confirmation-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 999;
}
.confirmation-dialog h3 {
color: var(--color-primary);
margin-bottom: var(--spacing-md);
}
.confirmation-dialog p {
margin-bottom: var(--spacing-lg);
}
.confirmation-actions {
display: flex;
gap: var(--spacing-sm);
justify-content: flex-end;
}
.confirmation-actions .btn {
min-width: 100px;
padding: var(--spacing-sm) var(--spacing-md);
}
/* Responsive */
@media (max-width: 768px) {
.pagination {
flex-wrap: wrap;
gap: var(--spacing-xs);
}
.pagination-link {
min-width: 2.25rem;
height: 2.25rem;
padding: 0 var(--spacing-sm);
font-size: 0.9rem;
}
.file-actions {
flex-wrap: wrap;
}
.btn-danger {
width: 100%;
}
}
/* Styles de notification */
.notification {
position: fixed;
bottom: var(--spacing-lg);
right: var(--spacing-lg);
background-color: var(--color-success);
color: white;
padding: var(--spacing-md) var(--spacing-lg);
border-radius: var(--border-radius);
animation: slideIn 0.3s ease-out, fadeOut 0.3s ease-in 2.7s forwards;
z-index: 1000;
pointer-events: none;
}
.notification.error {
background-color: var(--color-error);
}
@keyframes slideIn {
from { transform: translateY(100%); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
.share-container {
max-width: 800px;
margin: 0 auto;
}
.share-container h1 {
color: var(--color-primary);
margin-bottom: var(--spacing-sm);
word-break: break-all;
}
.file-meta {
color: var(--color-text-muted);
margin-bottom: var(--spacing-lg);
}
.preview-container {
background-color: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
margin-bottom: var(--spacing-lg);
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.preview-content {
max-width: 100%;
max-height: 600px;
}
.text-preview {
width: 100%;
max-height: 600px;
overflow: auto;
padding: var(--spacing-md);
background-color: var(--color-bg);
color: var(--color-text);
font-family: monospace;
white-space: pre-wrap;
}
.no-preview {
text-align: center;
padding: var(--spacing-lg);
color: var(--color-text-muted);
}
.extension-badge {
background-color: var(--color-bg-alt);
color: var(--color-primary);
padding: var(--spacing-md) var(--spacing-lg);
border-radius: var(--border-radius);
font-size: 2rem;
font-weight: bold;
margin-bottom: var(--spacing-md);
}
.share-actions {
display: flex;
flex-direction: column;
gap: var(--spacing-md);
}
.share-link {
display: flex;
flex-direction: column;
gap: var(--spacing-xs);
}
.input-group {
display: flex;
gap: var(--spacing-sm);
}
.input-group input {
flex: 1;
}
/* Styles responsifs */
@media (max-width: 768px) {
.input-group {
flex-direction: column;
}
.input-group .btn {
width: 100%;
}
}
/* Animation de notification */
.notification {
position: fixed;
bottom: var(--spacing-lg);
right: var(--spacing-lg);
background-color: var(--color-success);
color: white;
padding: var(--spacing-md) var(--spacing-lg);
border-radius: var(--border-radius);
animation: slideIn 0.3s ease-out, fadeOut 0.3s ease-in 2.7s forwards;
z-index: 1000;
}
@keyframes slideIn {
from { transform: translateY(100%); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}

View File

@ -1,32 +0,0 @@
<?php
// EDIT THIS: your auth parameters
$signature = 'a2eefde33d';
// EDIT THIS: the query parameters
$url = '<?php echo $filelocation;?>'; // URL to shrink
$format = 'simple'; // output format: 'json', 'xml' or 'simple'
// EDIT THIS: the URL of the API file
$api_url = 'http://ersatz.xyz/yourls-api.php';
// Init the CURL session
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $api_url );
curl_setopt( $ch, CURLOPT_HEADER, 0 ); // No header in the result
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // Return, do not echo result
curl_setopt( $ch, CURLOPT_POST, 1 ); // This is a POST request
curl_setopt( $ch, CURLOPT_POSTFIELDS, array( // Data to POST
'url' => $url,
'format' => $format,
'action' => 'shorturl',
'signature' => $signature,
) );
// Fetch and return content
$data = curl_exec($ch);
curl_close($ch);
// Do something with the result. Here, we just echo it.
echo $data;

View File

@ -1 +0,0 @@
Les fichiers seront stockés dans ce dossier.

View File

@ -1,311 +0,0 @@
<?php
// Configuration
define('PASSWORD', 'votre_mot_de_passe');
define('FILES_DIR', './file');
define('FILES_PER_PAGE', 50);
session_start();
$authenticated = isset($_SESSION['authenticated']) && $_SESSION['authenticated'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['password']) && $_POST['password'] === PASSWORD) {
$_SESSION['authenticated'] = true;
$authenticated = true;
} elseif (isset($_POST['page'])) {
// API pour le chargement progressif
$page = intval($_POST['page']);
$sortBy = $_POST['sortBy'] ?? 'date';
$sortDesc = $_POST['sortDesc'] ?? 'true';
$files = getFiles($page, $sortBy, $sortDesc === 'true');
header('Content-Type: application/json');
echo json_encode($files);
exit;
}
}
function getFiles($page = 0, $sortBy = 'date', $sortDesc = true) {
$allFiles = array_diff(scandir(FILES_DIR), ['.', '..']);
$files = [];
foreach ($allFiles as $file) {
$path = FILES_DIR . '/' . $file;
if (is_file($path)) {
$files[] = [
'name' => $file,
'url' => 'file/' . rawurlencode($file),
'shareUrl' => 'share/' . rawurlencode($file),
'date' => filemtime($path),
'type' => strtolower(pathinfo($file, PATHINFO_EXTENSION))
];
}
}
// Tri
usort($files, function($a, $b) use ($sortBy, $sortDesc) {
$result = $sortBy === 'date'
? $b['date'] - $a['date']
: strcasecmp($a['name'], $b['name']);
return $sortDesc ? $result : -$result;
});
// Pagination
$offset = $page * FILES_PER_PAGE;
return array_slice($files, $offset, FILES_PER_PAGE);
}
if (!$authenticated) {
// Afficher le formulaire de connexion
include 'header.php';
?>
<form class="login-form" method="POST">
<input type="password" name="password" placeholder="Mot de passe">
<button type="submit">Accéder</button>
</form>
<?php
include 'footer.php';
exit;
}
$initialFiles = getFiles();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Galerie de fichiers</title>
<style>
:root {
--bg-dark: #1a1a1a;
--bg-card: #2d2d2d;
--color-beige: #d4c4a8;
--color-beige-dark: #8b7355;
}
body {
background: var(--bg-dark);
color: var(--color-beige);
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
.controls {
position: sticky;
top: 0;
background: var(--bg-dark);
padding: 10px 0;
margin-bottom: 20px;
z-index: 100;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
.file-card {
background: var(--bg-card);
border-radius: 8px;
overflow: hidden;
}
.preview {
height: 150px;
position: relative;
background: #000;
}
.preview img, .preview video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
.preview audio {
position: absolute;
bottom: 10px;
left: 5%;
width: 90%;
}
.info {
padding: 10px;
}
.date {
font-size: 0.8em;
color: var(--color-beige-dark);
}
#loading {
text-align: center;
padding: 20px;
display: none;
}
.file-icon {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
padding: 10px;
text-align: center;
word-break: break-word;
font-size: 1.2em;
}
.info .name {
color: var(--color-beige);
text-decoration: none;
word-break: break-all;
display: block;
padding: 5px 0;
}
.info .name:hover {
color: white;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="controls">
<button onclick="changeSortBy('date')" id="sortDate">
Date <?= $sortBy === 'date' ? ($sortDesc ? '↓' : '↑') : '' ?>
</button>
<button onclick="changeSortBy('name')" id="sortName">
Nom <?= $sortBy === 'name' ? ($sortDesc ? '↓' : '↑') : '' ?>
</button>
</div>
<div class="grid" id="fileGrid">
</div>
<div id="loading">Chargement...</div>
<script>
let page = 0;
let loading = false;
let sortBy = 'date';
let sortDesc = true;
let noMoreFiles = false;
function createFileCard(file) {
const card = document.createElement('div');
card.className = 'file-card';
const preview = document.createElement('div');
preview.className = 'preview';
const ext = file.type.toLowerCase();
let previewContent = '';
if (['jpg', 'jpeg', 'png', 'gif'].includes(ext)) {
previewContent = `<img src="${file.url}" loading="lazy" alt="${file.name}">`;
} else if (['mp3', 'flac', 'ogg'].includes(ext)) {
previewContent = `<audio controls src="${file.url}"></audio>`;
} else if (['mp4', 'webm', 'wmv'].includes(ext)) {
previewContent = `<video controls loading="lazy"><source src="${file.url}" type="video/${ext}"></video>`;
} else {
const icon = getFileIcon(ext);
previewContent = `<div class="file-icon">${icon} ${file.name}</div>`;
}
card.innerHTML = `
<div class="preview">${previewContent}</div>
<div class="info">
<a href="${file.shareUrl}" target="_blank" class="name" title="Ouvrir dans un nouvel onglet">${file.name}</a>
<div class="date">${new Date(file.date * 1000).toLocaleString()}</div>
</div>
`;
return card;
}
function getFileIcon(ext) {
const icons = {
'pdf': '📄',
'zip': '📦',
'rar': '📦',
'txt': '📝',
'm3u': '🎵',
'm3u8': '🎵',
'css': '📰'
};
return icons[ext] || '📎';
}
async function loadFiles() {
if (loading || noMoreFiles) return;
loading = true;
document.getElementById('loading').style.display = 'block';
const formData = new FormData();
formData.append('page', page);
formData.append('sortBy', sortBy);
formData.append('sortDesc', sortDesc);
try {
const response = await fetch('', {
method: 'POST',
body: formData
});
const files = await response.json();
if (files.length < <?= FILES_PER_PAGE ?>) {
noMoreFiles = true;
}
const grid = document.getElementById('fileGrid');
files.forEach(file => {
grid.appendChild(createFileCard(file));
});
page++;
} catch (error) {
console.error('Erreur de chargement:', error);
} finally {
loading = false;
document.getElementById('loading').style.display = 'none';
}
}
function changeSortBy(newSortBy) {
if (newSortBy === sortBy) {
sortDesc = !sortDesc;
} else {
sortBy = newSortBy;
sortDesc = true;
}
// Réinitialiser
page = 0;
noMoreFiles = false;
document.getElementById('fileGrid').innerHTML = '';
loadFiles();
// Mettre à jour les boutons
document.getElementById('sortDate').textContent =
`Date ${sortBy === 'date' ? (sortDesc ? '↓' : '↑') : ''}`;
document.getElementById('sortName').textContent =
`Nom ${sortBy === 'name' ? (sortDesc ? '↓' : '↑') : ''}`;
}
// Détecter le scroll pour charger plus de fichiers
window.addEventListener('scroll', () => {
if ((window.innerHeight + window.scrollY) >= document.documentElement.scrollHeight - 500) {
loadFiles();
}
});
// Charger les premiers fichiers
loadFiles();
</script>
</body>
</html>

170
index.php
View File

@ -1,57 +1,121 @@
<html>
<?php
define('CYLA_CORE', true);
require_once 'core.php';
<head>
<title>Cyla - hébergement de fichiers</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="static/CSS/uploadpage.css" media="screen" title="no title" charset="utf-8">
</head>
<body>
<p class="dltext title">
Cyla
</p>
<p class="dltext subtle">
Un fichier ne peut dépasser 100 Mo. Les extensions autorisées sont 'png', 'jpg', 'jpeg', 'gif', 'webm', 'mp4', 'wmv', 'mp3', 'flac', 'ogg', 'zip', 'css', 'pdf', 'zip', 'rar', 'm3u', 'm3u8', 'txt'.
</p>
<!-- File upload form -->
<form class="uploadinterface" id="uploadform" action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" class="fileselector">
<input type="submit" name="uploadbutton" value="héberger" class="submitbutton">
</form>
<p class="dltext subtle">
En utilisant ce service, vous acceptez les limites situées à la page <a href="md/info.html">info</a>.
</p>
<div class="sidebar">
<div class="separator"><p class="buttontxt">Liens utiles</p></div>
<a href="md/info.html">
<div class="button orangeBG"><p class="buttontxt">Info</p></div>
</a>
<a href="md/faq.html">
<div class="button orangeBG"><p class="buttontxt">F.A.Q</p></div>
</a>
<a href="http://paypal.me/esenjin" target="blank">
<div class="button orangeBG"><p class="buttontxt">Don</p></div>
</a>
<a href="gallery.php">
<div class="button orangeBG"><p class="buttontxt">Admin</p></div>
</a>
// Rediriger vers l'admin si déjà connecté
if (Cyla::isLoggedIn()) {
header('Location: admin.php');
exit;
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo SITE_NAME; ?> - Accueil</title>
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="home-container">
<main class="home-hero">
<div class="home-content">
<h1>Cyla</h1>
<p class="home-description">Le disque nuagique personnel d'Esenjin.</p>
<a href="admin.php" class="home-button">
Accéder à l'administration
<svg class="home-button-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7"/>
</svg>
</a>
</div>
</main>
<footer class="home-footer">
<p>&copy; <?php echo date('Y'); ?> <?php echo SITE_NAME; ?> - Version <?php echo SITE_VERSION; ?></p>
</footer>
</div>
</body>
</body>
</html>
<style>
/* Styles spécifiques à la page d'accueil */
.home-container {
min-height: 100vh;
display: flex;
flex-direction: column;
background-color: var(--color-bg);
}
.home-hero {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: var(--spacing-lg);
}
.home-content {
text-align: center;
}
.home-content h1 {
font-size: 4rem;
font-weight: bold;
color: var(--color-primary);
margin-bottom: var(--spacing-md);
}
.home-description {
font-size: 1.5rem;
color: var(--color-text-muted);
margin-bottom: var(--spacing-lg);
}
.home-button {
display: inline-flex;
align-items: center;
padding: var(--spacing-md) var(--spacing-lg);
background-color: var(--color-primary);
color: var(--color-text);
text-decoration: none;
border-radius: var(--border-radius);
font-weight: 500;
transition: background-color 0.2s ease;
}
.home-button:hover {
background-color: var(--color-primary-hover);
}
.home-button-icon {
width: 1.25rem;
height: 1.25rem;
margin-left: var(--spacing-sm);
}
.home-footer {
text-align: center;
padding: var(--spacing-lg);
color: var(--color-text-muted);
background-color: var(--color-bg-alt);
border-top: 1px solid var(--color-border);
}
/* Animation d'entrée */
.home-content {
animation: fadeInUp 0.8s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>

189
js/UploadZone.jsx Normal file
View File

@ -0,0 +1,189 @@
import React, { useState, useRef, useCallback } from 'react';
import { X, Upload, CheckCircle, AlertCircle, Loader } from 'lucide-react';
const UploadZone = () => {
const [isDragging, setIsDragging] = useState(false);
const [files, setFiles] = useState([]);
const fileInputRef = useRef(null);
const MAX_FILES = 10; // Limite stricte à 10 fichiers
const MAX_FILE_SIZE = 100 * 1024 * 1024;
const ALLOWED_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'webm', 'mp4', 'wmv', 'mp3', 'flac', 'ogg', 'zip', 'css', 'pdf', 'rar', 'm3u', 'm3u8', 'txt'];
const validateFile = useCallback((file) => {
const extension = file.name.split('.').pop().toLowerCase();
if (!ALLOWED_EXTENSIONS.includes(extension)) {
return { valid: false, error: `Extension .${extension} non autorisée` };
}
if (file.size > MAX_FILE_SIZE) {
return { valid: false, error: 'Fichier trop volumineux (max 100 Mo)' };
}
return { valid: true, error: null };
}, []);
const uploadFile = async (fileInfo) => {
try {
const formData = new FormData();
formData.append('file', fileInfo.file);
formData.append('csrf_token', document.querySelector('input[name="csrf_token"]')?.value || '');
// Mettre le statut en uploading
setFiles(files =>
files.map(f =>
f.id === fileInfo.id ? { ...f, status: 'uploading' } : f
)
);
const response = await fetch('api.php', {
method: 'POST',
body: formData
});
const result = await response.json();
if (!response.ok || !result.success) {
throw new Error(result.error || 'Erreur lors du téléversement');
}
setFiles(files =>
files.map(f =>
f.id === fileInfo.id ? { ...f, status: 'complete' } : f
)
);
} catch (error) {
setFiles(files =>
files.map(f =>
f.id === fileInfo.id
? { ...f, status: 'error', error: error.message }
: f
)
);
}
};
const handleFiles = (newFiles) => {
// Vérifier si on n'a pas déjà atteint la limite
if (files.length >= MAX_FILES) {
alert(`Vous pouvez téléverser uniquement ${MAX_FILES} fichiers à la fois`);
return;
}
// Calculer combien de fichiers on peut encore ajouter
const remainingSlots = MAX_FILES - files.length;
const filesToAdd = Array.from(newFiles).slice(0, remainingSlots);
if (filesToAdd.length < newFiles.length) {
alert(`Seuls les ${remainingSlots} premiers fichiers seront traités. Maximum ${MAX_FILES} fichiers à la fois.`);
}
const processedFiles = filesToAdd.map(file => ({
file,
id: Math.random().toString(36).substring(7),
status: validateFile(file).valid ? 'pending' : 'error',
error: validateFile(file).error
}));
setFiles(current => [...current, ...processedFiles]);
// Lancer l'upload pour chaque fichier valide
processedFiles
.filter(f => f.status === 'pending')
.forEach(uploadFile);
};
const handleDrop = useCallback((e) => {
e.preventDefault();
setIsDragging(false);
handleFiles(e.dataTransfer.files);
}, []);
const removeFile = (id) => {
setFiles(files => files.filter(f => f.id !== id));
};
return (
<div className="w-full">
<div
className={`relative border-2 border-dashed rounded-lg p-8 text-center mb-4 transition-colors
${isDragging ? 'border-primary-500 bg-primary-50' : 'border-gray-600'}
hover:border-primary-500`}
onDragOver={e => {
e.preventDefault();
setIsDragging(true);
}}
onDragLeave={e => {
e.preventDefault();
setIsDragging(false);
}}
onDrop={handleDrop}
onClick={() => fileInputRef.current?.click()}
>
<input
ref={fileInputRef}
type="file"
multiple
onChange={e => handleFiles(e.target.files)}
className="hidden"
accept={ALLOWED_EXTENSIONS.map(ext => `.${ext}`).join(',')}
/>
<Upload className="w-12 h-12 mx-auto mb-4 text-gray-400" />
<p className="text-lg mb-2">
Glissez-déposez vos fichiers ici
</p>
<p className="text-sm text-gray-400">
ou cliquez pour sélectionner des fichiers
</p>
<p className="text-xs text-gray-400 mt-2">
Maximum {MAX_FILES} fichiers à la fois · 100 Mo par fichier
<br />
Extensions : {ALLOWED_EXTENSIONS.join(', ')}
</p>
</div>
{files.length > 0 && (
<div className="border border-gray-700 rounded-lg overflow-hidden">
<div className="p-4 bg-gray-800 border-b border-gray-700">
<h3 className="font-medium">Fichiers ({files.length}/{MAX_FILES})</h3>
</div>
<div className="divide-y divide-gray-700">
{files.map((fileInfo) => (
<div key={fileInfo.id} className="p-4 flex items-center gap-4">
<div className="flex-1 min-w-0">
<p className="truncate font-medium">{fileInfo.file.name}</p>
<p className="text-sm text-gray-400">
{(fileInfo.file.size / 1024 / 1024).toFixed(2)} Mo
</p>
{fileInfo.error && (
<p className="text-sm text-red-500">{fileInfo.error}</p>
)}
</div>
<div className={`
${fileInfo.status === 'complete' ? 'text-green-500' : ''}
${fileInfo.status === 'error' ? 'text-red-500' : ''}
${fileInfo.status === 'uploading' ? 'text-blue-500' : ''}
`}>
{fileInfo.status === 'complete' && <CheckCircle className="w-5 h-5" />}
{fileInfo.status === 'error' && <AlertCircle className="w-5 h-5" />}
{fileInfo.status === 'uploading' && <Loader className="w-5 h-5 animate-spin" />}
</div>
<button
onClick={() => removeFile(fileInfo.id)}
className="p-1 hover:bg-gray-700 rounded"
title={fileInfo.status === 'uploading' ? 'Annuler' : 'Supprimer'}
>
<X className="w-5 h-5" />
</button>
</div>
))}
</div>
</div>
)}
</div>
);
};
export default UploadZone;

21
js/main.js Normal file
View File

@ -0,0 +1,21 @@
// Fonction pour copier dans le presse-papier
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
alert('Copié dans le presse-papier !');
}).catch(err => {
console.error('Erreur lors de la copie :', err);
alert('Erreur lors de la copie');
});
}
// Fonction pour prévisualiser un fichier avant l'upload
function previewFile(input) {
if (input.files && input.files[0]) {
const file = input.files[0];
const fileSize = (file.size / 1024 / 1024).toFixed(2); // Taille en Mo
// Afficher les informations du fichier
document.getElementById('fileInfo').textContent =
`${file.name} (${fileSize} Mo)`;
}
}

200
js/password-modal.js Normal file
View File

@ -0,0 +1,200 @@
const ChangePasswordModal = ({ isOpen, onClose, onSubmit, csrfToken }) => {
if (!isOpen) return null;
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Object.fromEntries(formData.entries());
onSubmit(data);
};
return React.createElement('div', {
className: 'modal-overlay',
onClick: (e) => {
if (e.target === e.currentTarget) onClose();
}
},
React.createElement('div', {
className: 'modal-container'
}, [
React.createElement('div', {
key: 'header',
className: 'flex justify-between items-center p-4 border-b border-neutral-700'
}, [
React.createElement('h2', {
className: 'text-xl font-semibold text-rose-400'
}, 'Changer le mot de passe'),
React.createElement('button', {
onClick: onClose,
className: 'btn btn-secondary'
}, '×')
]),
React.createElement('form', {
key: 'form',
onSubmit: handleSubmit,
className: 'p-4 space-y-4'
}, [
React.createElement('input', {
type: 'hidden',
name: 'csrf_token',
value: csrfToken
}),
React.createElement('input', {
type: 'hidden',
name: 'action',
value: 'change_password'
}),
React.createElement('div', {
className: 'space-y-2'
}, [
React.createElement('label', {
className: 'block text-sm text-neutral-400'
}, 'Mot de passe actuel'),
React.createElement('input', {
type: 'password',
name: 'current_password',
required: true,
className: 'w-full p-2 bg-neutral-800 border border-neutral-700 rounded focus:border-rose-500 focus:outline-none'
})
]),
React.createElement('div', {
className: 'space-y-2'
}, [
React.createElement('label', {
className: 'block text-sm text-neutral-400'
}, 'Nouveau mot de passe'),
React.createElement('input', {
type: 'password',
name: 'new_password',
required: true,
className: 'w-full p-2 bg-neutral-800 border border-neutral-700 rounded focus:border-rose-500 focus:outline-none'
})
]),
React.createElement('div', {
className: 'space-y-2'
}, [
React.createElement('label', {
className: 'block text-sm text-neutral-400'
}, 'Confirmer le nouveau mot de passe'),
React.createElement('input', {
type: 'password',
name: 'confirm_password',
required: true,
className: 'w-full p-2 bg-neutral-800 border border-neutral-700 rounded focus:border-rose-500 focus:outline-none'
})
]),
React.createElement('div', {
className: 'flex justify-end gap-2 pt-4'
}, [
React.createElement('button', {
type: 'button',
onClick: onClose,
className: 'btn btn-secondary'
}, 'Annuler'),
React.createElement('button', {
type: 'submit',
className: 'btn'
}, 'Changer le mot de passe')
])
])
])
);
};
// App wrapper
function PasswordModalApp({ csrfToken }) {
const [isOpen, setIsOpen] = React.useState(false);
React.useEffect(() => {
const btn = document.getElementById('changePasswordBtn');
if (btn) {
btn.addEventListener('click', () => {
setIsOpen(true);
document.body.classList.add('modal-open');
});
}
}, []);
const handleClose = () => {
setIsOpen(false);
document.body.classList.remove('modal-open');
};
// Gérer la fermeture avec la touche Echap
React.useEffect(() => {
const handleEscape = (e) => {
if (e.key === 'Escape' && isOpen) {
handleClose();
}
};
document.addEventListener('keydown', handleEscape);
return () => document.removeEventListener('keydown', handleEscape);
}, [isOpen]);
// Ajouter la gestion du clic en dehors de la modale
const handleOutsideClick = (e) => {
if (e.target === e.currentTarget) {
handleClose();
}
};
return React.createElement(ChangePasswordModal, {
isOpen,
onClose: handleClose,
onSubmit: handleSubmit,
csrfToken: csrfToken,
onOverlayClick: handleOutsideClick
});
}
// Initialisation
document.addEventListener('DOMContentLoaded', () => {
const root = ReactDOM.createRoot(document.getElementById('passwordModalRoot'));
root.render(React.createElement(PasswordModalApp, {
csrfToken: window.CSRF_TOKEN
}));
});
// Modifier la fonction PasswordModalApp pour accepter le token en props
function PasswordModalApp({ csrfToken }) {
const [isOpen, setIsOpen] = React.useState(false);
React.useEffect(() => {
const btn = document.getElementById('changePasswordBtn');
if (btn) {
btn.addEventListener('click', () => setIsOpen(true));
}
}, []);
const handleSubmit = async (formData) => {
try {
const form = new FormData();
Object.entries(formData).forEach(([key, value]) => {
form.append(key, value);
});
const response = await fetch('admin.php', {
method: 'POST',
body: form
});
if (response.ok) {
alert('Mot de passe modifié avec succès');
setIsOpen(false);
} else {
alert('Erreur lors du changement de mot de passe');
}
} catch (error) {
console.error('Error:', error);
alert('Erreur lors du changement de mot de passe');
}
};
return React.createElement(ChangePasswordModal, {
isOpen,
onClose: () => setIsOpen(false),
onSubmit: handleSubmit,
csrfToken: csrfToken
});
}

64
layout.php Normal file
View File

@ -0,0 +1,64 @@
<?php
if (!defined('CYLA_CORE')) {
header('HTTP/1.0 403 Forbidden');
exit('Accès direct interdit');
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo SITE_NAME; ?><?php echo isset($pageTitle) ? ' - ' . $pageTitle : ''; ?></title>
<link rel="icon" type="image/png" href="favicon.png">
<link rel="stylesheet" href="css/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
</head>
<body>
<div id="passwordModalRoot"></div>
<header>
<nav>
<div class="nav-brand">
<a href="index.php"><?php echo SITE_NAME; ?></a>
</div>
<?php if (Cyla::isLoggedIn()): ?>
<div class="nav-menu">
<a href="admin.php" class="nav-link">Administration</a>
<button
type="button"
id="changePasswordBtn"
class="nav-link"
onclick="console.log('Clic natif détecté')"
>
Changer le mot de passe
</button>
<a href="logout.php?csrf_token=<?php echo Cyla::generateCSRFToken(); ?>" class="nav-link">Déconnexion</a>
</div>
<?php endif; ?>
</nav>
</header>
<main>
<?php if (isset($error)): ?>
<div class="alert alert-error">
<?php echo Cyla::escape($error); ?>
</div>
<?php endif; ?>
<?php if (isset($success)): ?>
<div class="alert alert-success">
<?php echo Cyla::escape($success); ?>
</div>
<?php endif; ?>
<?php if (isset($content)) echo $content; ?>
</main>
<footer>
<p>&copy; <?php echo date('Y'); ?> <?php echo SITE_NAME; ?> - Version <?php echo SITE_VERSION; ?></p>
</footer>
<script src="js/main.js"></script>
</body>
</html>

108
login.php Normal file
View File

@ -0,0 +1,108 @@
<?php
define('CYLA_CORE', true);
require_once 'core.php';
// Rediriger si déjà connecté
if (Cyla::isLoggedIn()) {
header('Location: admin.php');
exit;
}
$error = null;
// Traitement du formulaire
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Vérification du token CSRF
if (!isset($_POST['csrf_token']) || !Cyla::verifyCSRFToken($_POST['csrf_token'])) {
$error = 'Session invalide, veuillez réessayer';
} else {
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
if (empty($username) || empty($password)) {
$error = 'Veuillez remplir tous les champs';
} else if (!Cyla::authenticate($username, $password)) {
$error = 'Identifiants incorrects';
// Protection contre le brute force
sleep(1);
} else {
header('Location: admin.php');
exit;
}
}
}
// Contenu de la page
$pageTitle = 'Connexion';
ob_start(); ?>
<div class="login-container card">
<h1>Connexion à l'administration</h1>
<form method="POST" action="login.php" class="login-form">
<input type="hidden" name="csrf_token" value="<?php echo Cyla::generateCSRFToken(); ?>">
<div class="form-group">
<label for="username">Nom d'utilisateur</label>
<input type="text"
id="username"
name="username"
required
autocomplete="username"
value="<?php echo isset($_POST['username']) ? Cyla::escape($_POST['username']) : ''; ?>">
</div>
<div class="form-group">
<label for="password">Mot de passe</label>
<input type="password"
id="password"
name="password"
required
autocomplete="current-password">
</div>
<div class="form-actions">
<button type="submit" class="btn">Se connecter</button>
</div>
</form>
</div>
<style>
/* Styles spécifiques à la page de connexion */
.login-container {
max-width: 400px;
margin: 2rem auto;
}
.login-container h1 {
margin-bottom: var(--spacing-lg);
text-align: center;
color: var(--color-primary);
}
.login-form {
display: flex;
flex-direction: column;
gap: var(--spacing-md);
}
.form-actions {
margin-top: var(--spacing-md);
text-align: center;
}
/* Animation de l'erreur */
.alert-error {
animation: shake 0.5s ease-in-out;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-5px); }
75% { transform: translateX(5px); }
}
</style>
<?php
$content = ob_get_clean();
require 'layout.php';

19
logout.php Normal file
View File

@ -0,0 +1,19 @@
<?php
define('CYLA_CORE', true);
require_once 'core.php';
// Vérification du token CSRF pour la déconnexion
$validLogout = isset($_GET['csrf_token']) && Cyla::verifyCSRFToken($_GET['csrf_token']);
if (!$validLogout) {
// Si pas de token valide, redirection avec message d'erreur
header('Location: admin.php?error=' . urlencode('Token de sécurité invalide'));
exit;
}
// Déconnexion de l'utilisateur
Cyla::logout();
// Redirection vers la page de connexion avec message de succès
header('Location: login.php?success=' . urlencode('Vous avez été déconnecté avec succès'));
exit;

View File

@ -1,39 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
html {
color: #1d1d1d;
background-color: #c7bcad;
font-size: 16pt;
font-family: 'Open Sans', sans-serif;
line-height: 1.5em;
}
blockquote {
color: #777;
border: solid 0px #777;
padding-left: 12px;
border-left-width: 5px;
font-size: 14pt;
}
p {
margin: 8px;
}
a, a:visited {
text-decoration: none;
color: #DB1A41;
transition: color 0.2s;
}
a:hover {
color: #E94769;
}
body {
max-width: 820px;
margin-left: auto;
margin-right: auto;
padding: 45px;
}

View File

@ -1,30 +0,0 @@
<html>
<head>
<title>Cyla faq</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="CSS/markdown.css">
</head>
<body>
<h1 id="frequently-asked-questions">Questions fréquemment posées</h1>
<h3 id="i-don-t-have-videos-in-webm-or-mp4-format-why-don-t-you-accept-other-video-types-">Je n'ai pas de vidéos en WebM ou MP4. Pourquoi ne pas accepter les autres formats ?</h3>
<p>Je n'accepte pas d'autres types de fichiers car ils ne sont pas optimisés pour le web. (En fait, tous les fichiers MP4 ne le sont pas).
Si vous voulez convertir des vidéos au format WebM (format recommandé) pour le téléchargement, télécharger la dernière version de convertisseur de WebM de <a href="https://github.com/nixxquality/WebMConverter/releases">4chan's</a>.</p>
<h3 id="do-you-look-at-all-my-files-">Vous regardez tous les fichiers que j'héberge ?</h3>
<p>Non, je ne regarde pas en détail tous les fichiers hébergés. Je peux cependant y jeter un œil, notamment pour vérifier qu'il n'y a pas de virus par exemple.
En tout cas, je ne partagerais jamais un fichier que je n'ai pas moi-même hébergé.</p>
<h3 id="quadfile-is-slow-what-s-going-on-">Cyla est lent, que se passe-t-il ?</h3>
<p>Il est probable que le serveur soit sous une lourde charge (par exemple si un trop grand nombre de personnes envoient des fichiers en même temps). Si cela arrive, essayez plus tard.
Le serveur utilisé n'est pas optimisé pour cela à la base.</p>
<h3 id="how-much-storage-does-the-server-have-">Quelle est la place de stockage disponible ?</h3>
<p>Cela peut évoluer avec le temps suivant les besoins.</p>
<h3 id="what-would-happen-if-quadfile-grew-past-what-you-can-afford-to-maintain-">Qu'arriverait-il si Cyla grandi delà de ce que vous pouvez vous permettre de maintenir ?</h3>
<p>S'il commence à manquer de place et que je n'ai pas les moyens d'en acheter plus, il est possible que le poids pour l'envoie d'un fichier soit réduit (passer de 100 Mo à 50 Mo (ou moins) par exemple).
Si vous voulez me permettre d'avoir un serveur plus performant et disposant de plus d'espace, vous pouvez me faire un don sur <a href="https://www.paypal.me/esenjin" target="_blank">Paypal</a>.
En dernier recours, il est possible que l'envoie de fichiers soit arrêté. Les fichiers déjà hébergés resteraient toutefois toujours disponible.</p>
<p><a href="../">Retour à l'accueil</a></p>
</body>
</html>

View File

@ -1,54 +0,0 @@
<html>
<head>
<title>Cyla info</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="CSS/markdown.css">
</head>
<body>
<h1 id="limits">Limites</h1>
<ul>
<li><b>Vous</b> êtes responsable des fichiers que vous hébergez.</li>
<li>Le poids maximum d'un fichier est de <b>100 Mo</b>.</li>
<li>Les fichiers peuvent être supprimés si demandé par le propriétaire du contenu.</li>
<li>Si je trouve le contenu illégal (par exemple. les virus et autres), il sera instantanément supprimé.</li>
<li>L'aperçu prend en charge les images et les vidéos en MP4 ou WEBM.</li>
<li>Seuls certains types de fichiers sont autorisés</li>
<li>Le temps maximum que vous êtes autorisé à dépenser pour l'hébergement d'un fichier est de 4 minutes pour éviter une charge constante.</li>
</ul>
<h2 id="allowed-filetypes">Types de ficher autorisés</h2>
<ul>
<li>png</li>
<li>jpg</li>
<li>jpeg</li>
<li>gif</li>
<li>webm</li>
<li>mp4</li>
<li>wmv</li>
<li>mp3</li>
<li>flac</li>
<li>ogg</li>
<li>zip</li>
<li>css</li>
<li>pdf</li>
<li>zip</li>
<li>rar</li>
<li>m3u</li>
<li>m3u8</li>
<li>txt</li>
</ul>
<p>Si vous pensez qu'un type de fichier spécifique doit être ajouté, dites-le moi.</p>
<h2 id="contact">Contact</h2>
<p>Vous pouvez me contacter sur <a href="https://twitter.com/Sangigi_Esenjin" target="_blank">Twitter</a>.</p>
<h2 id="credit">Credit</h2>
<p>Projet original <b>QuadFile</b> de <a href="https://twitter.com/quadpiece" target="_blank">Quad</a>.</p>
<h2 id="why-">Pourquoi ?</h2>
<p>Le but de ce site est de m'aider à apprendre et me perfectionner dans l'utilisation de PHP, ainsi que de refaire vivre ce projet qui a été arrêté par son auteur initial.</p>
<h2 id="source-code">Code source</h2>
<p>Le code source original est disponible sur <a href="https://github.com/QuadPiece/QuadFile">GitHub</a></p>
<p>Il est possible qu'il ne soit plus mis à jour.</p>
<p><a href="../">Retour à l'accueil</a></p>
</body>
</html>

218
share.php Normal file
View File

@ -0,0 +1,218 @@
<?php
define('CYLA_CORE', true);
require_once 'core.php';
$error = null;
$file_info = null;
// Vérifier si un fichier est spécifié
if (!isset($_GET['file'])) {
$error = 'Aucun fichier spécifié';
} else {
$filename = $_GET['file'];
$path = $_GET['path'] ?? 'fichiers/';
// Déterminer le chemin complet selon le dossier
$basePath = '';
switch ($path) {
case 'v1/img/fichiers/':
$basePath = __DIR__ . '/v1/img/fichiers/';
break;
case 'v2/file/':
$basePath = __DIR__ . '/v2/file/';
break;
default:
$basePath = UPLOAD_DIR;
$path = 'fichiers/'; // Assurer que le path par défaut est correct
}
$filepath = $basePath . $filename;
// Vérifier que le fichier existe et est un fichier régulier
if (!file_exists($filepath) || !is_file($filepath)) {
$error = 'Fichier introuvable';
} else {
// Vérifier que le chemin est sécurisé
$realpath = realpath($filepath);
$allowed = false;
if (strpos($realpath, realpath(UPLOAD_DIR)) === 0) {
$allowed = true;
} else {
foreach (LEGACY_UPLOAD_DIRS as $dir) {
if (strpos($realpath, realpath($dir)) === 0) {
$allowed = true;
break;
}
}
}
if (!$allowed) {
$error = 'Accès non autorisé';
} else {
// Récupérer les informations du fichier
$file_info = [
'name' => $filename,
'size' => filesize($filepath),
'extension' => strtolower(pathinfo($filename, PATHINFO_EXTENSION)),
'preview_type' => getPreviewType(pathinfo($filename, PATHINFO_EXTENSION))
];
}
}
}
// Construction des URLs
$file_url = SITE_URL . $path . ($file_info ? rawurlencode($file_info['name']) : '');
$share_url = SITE_URL . 'share.php?file=' . ($file_info ? rawurlencode($file_info['name']) : '') . '&path=' . urlencode($path);
// Contenu de la page
$pageTitle = $file_info ? $file_info['name'] : 'Fichier introuvable';
ob_start(); ?>
<?php if ($error): ?>
<div class="card">
<h1>Erreur</h1>
<p><?php echo Cyla::escape($error); ?></p>
<a href="index.php" class="btn">Retour à l'accueil</a>
</div>
<?php else: ?>
<div class="share-container">
<div class="card">
<h1><?php echo Cyla::escape($file_info['name']); ?></h1>
<div class="file-meta">
<p>
Taille : <?php echo Cyla::escape(round($file_info['size'] / 1024, 2)); ?> Ko
· Type : <?php echo Cyla::escape(strtoupper($file_info['extension'])); ?>
</p>
</div>
<div class="preview-container">
<?php if ($file_info['preview_type'] === 'image'): ?>
<img src="<?php echo Cyla::escape($file_url); ?>"
alt="<?php echo Cyla::escape($file_info['name']); ?>"
class="preview-content">
<?php elseif ($file_info['preview_type'] === 'video'): ?>
<video controls class="preview-content">
<source src="<?php echo Cyla::escape($file_url); ?>"
type="video/<?php echo $file_info['extension'] === 'webm' ? 'webm' : 'mp4'; ?>">
Votre navigateur ne supporte pas la lecture de vidéos.
</video>
<?php elseif ($file_info['preview_type'] === 'audio'): ?>
<audio controls class="preview-content">
<source src="<?php echo Cyla::escape($file_url); ?>"
type="audio/<?php echo $file_info['extension']; ?>">
Votre navigateur ne supporte pas la lecture audio.
</audio>
<?php elseif ($file_info['preview_type'] === 'text'): ?>
<pre class="text-preview"><?php
// Lire et afficher le contenu du fichier texte de manière sécurisée
$content = file_get_contents($filepath);
if ($content !== false) {
echo Cyla::escape($content);
} else {
echo "Erreur lors de la lecture du fichier";
}
?></pre>
<?php else: ?>
<div class="no-preview">
<div class="extension-badge">
<?php echo Cyla::escape(strtoupper($file_info['extension'])); ?>
</div>
<p>Aperçu non disponible pour ce type de fichier</p>
</div>
<?php endif; ?>
</div>
<div class="share-actions">
<div class="share-link">
<label for="share-url">Lien de partage :</label>
<div class="input-group">
<input type="text"
id="share-url"
value="<?php echo Cyla::escape($share_url); ?>"
readonly>
<button class="btn" onclick="handleCopy('share-url', 'Lien de partage copié !')">
Copier
</button>
</div>
</div>
<div class="share-link">
<label for="direct-url">Lien direct :</label>
<div class="input-group">
<input type="text"
id="direct-url"
value="<?php echo Cyla::escape($file_url); ?>"
readonly>
<button class="btn" onclick="handleCopy('direct-url', 'Lien direct copié !')">
Copier
</button>
</div>
</div>
<?php if (in_array($file_info['preview_type'], ['image', 'video'])): ?>
<div class="share-link">
<label for="embed-code">Code d'intégration :</label>
<div class="input-group">
<input type="text"
id="embed-code"
value="<?php
if ($file_info['preview_type'] === 'image') {
echo Cyla::escape('<img src="' . $file_url . '" alt="' . $file_info['name'] . '">');
} else {
echo Cyla::escape('<video controls><source src="' . $file_url . '" type="video/' .
($file_info['extension'] === 'webm' ? 'webm' : 'mp4') . '"></video>');
}
?>"
readonly>
<button class="btn" onclick="handleCopy('embed-code', 'Code d\'intégration copié !')">
Copier
</button>
</div>
</div>
<?php endif; ?>
<a href="<?php echo Cyla::escape($file_url); ?>"
class="btn btn-secondary"
download="<?php echo Cyla::escape($file_info['name']); ?>">
Télécharger
</a>
</div>
</div>
</div>
<script>
// Fonction pour gérer la copie
async function handleCopy(elementId, message) {
const input = document.getElementById(elementId);
if (!input) {
console.error(`Element with id ${elementId} not found`);
return;
}
try {
// Utiliser l'API Clipboard moderne
await navigator.clipboard.writeText(input.value);
// Créer et afficher la notification
const notification = document.createElement('div');
notification.className = 'notification';
notification.textContent = message;
document.body.appendChild(notification);
// Supprimer la notification après l'animation
setTimeout(() => {
notification.remove();
}, 3000);
} catch (err) {
console.error('Erreur lors de la copie :', err);
alert('Erreur lors de la copie');
}
}
</script>
<?php endif; ?>
<?php
$content = ob_get_clean();
require 'layout.php';

View File

@ -1,3 +0,0 @@
RewriteEngine On
RewriteRule ^([^?]*) index.php?filename=$1 [NC,L,QSA]

View File

@ -1,85 +0,0 @@
<?php
//Get filename from URL
if (isset($_GET["filename"]) && $_GET["filename"] != "" && $_GET["filename"] != " ") {
$filename = htmlentities($_GET["filename"]);
}
//404 if no value
else {
$filename = "404.png";
}
//404 if file doesn't exist
if (file_exists ("../file/" . $filename)) {
}
else {
header("HTTP/1.0 404 Not Found");
$filename = "404.png";
}
//Set the variables for the direct link
$filelocation = "../file/" . $filename;
//Find extensions to use for preview
$extension = explode('.', $filename);
$extension = strtolower(end($extension));
?>
<!DOCTYPE html>
<html>
<head>
<title><?php echo $filename; ?> - Cyla</title>
<meta charset="UTF-8">
<!-- Twitter cards -->
<?php
include_once("../static/includes/cards.php")
?>
<!-- OpenGraph for Facebook -->
<?php
include_once("../static/includes/opengraph.php")
?>
<!-- Stylesheets -->
<link rel="stylesheet" type="text/css" href="../static/CSS/view.css">
<link rel="stylesheet" type="text/css" href="../static/colors.css">
<?php
include_once("../static/includes/video.php")
?>
</head>
<body>
<!-- There, I use Piwik now, be happy botnet freaks -->
<?php include_once("../static/includes/botnet.php") ?>
<h1 class="dltext">"<?php echo $filename;?>"</h1>
<div class="buttoncontainer">
<a href="<?php echo $filelocation;?>" target="_blank" >
<div class="button">Voir/écouter/télécharger</div>
</a>
<a href="http://ersatz.xyz/yourls-api.php?signature=a2eefde33d&action=shorturl&format=simple&url=http://concepts.esenjin.xyz/cyla/v2/file/<?php echo $filename;?>" onclick="window.open(this.href, 'Popup', 'scrollbars=1,resizable=1,height=60,width=200'); return false;" target="_blank">
<div class="button">Raccourcir l'url</div>
</a>
<a href="../">
<div class="button">Héberger un autre fichier</div>
</a>
</div>
<?php include_once("../static/includes/preview.php") ?>
</body>
</html>

View File

@ -1,110 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
html {
background-color: #3c3934;
}
body {
padding: 25px;
font-family: "Open Sans", sans-serif;
padding-bottom: 35px;
margin: 30px;
margin-left: auto;
margin-right: auto;
margin-bottom: 0px;
max-width: 960px;
background-color: #c7bcad;
box-shadow: 0px 0px 2px rgba(13, 13, 13, 0.3);
transition: box-shadow 0.5s ease-out;
}
body:hover {
box-shadow: 0px 0px 4px rgba(13, 13, 13, 1);
}
.subtle {
font-size: 18px;
opacity: 0.6;
}
.submitbutton {
font-size: 20px;
}
.fileselector {
font-size: 20px;
color: #111;
}
.dltext {
color: #111;
text-align: center;
}
.uploadinterface {
width: 490px;
display: block;
margin-right: auto;
margin-left: auto;
height: auto;
}
.sidebar {
padding-top: 20px;
background-color: #3c3934;
position: fixed;
top: 0px;
left: 0px;
height: 100%;
width: 10%;
min-width: 120px;
}
.button {
background-color: #c7bcad;
width: 100%;
color: #111;
display: inline-block;
padding-top: 8px;
padding-bottom: 8px;
font-size: 20px;
transition: background 0.2s ease-in-out;
}
.button:hover {
background-color: #a3a3a3;
}
.buttontxt {
color: #fff;
margin: 0px;
margin-left: 8px;
}
.separator {
color: #111;
width: 100%;
display: inline-block;
padding-top: 12px;
padding-bottom: 4px;
font-size: 16px;
border: solid 0px #111;
border-bottom-width: 1px;
}
img {
display: block;
border: solid 5px #2d2d2d;
margin-right: auto;
margin-left: auto;
max-width: 80%;
height: auto;
}
.title {
font-family: Tahoma, Verdana, Segoe, sans-serif;
font-size: 72px;
color: #111;
margin-bottom: 10px;
}

View File

@ -1,115 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
html {
background-color: #3c3934;
}
body {
padding: 25px;
font-family: "Open Sans", sans-serif;
padding-bottom: 35px;
margin: 30px;
margin-left: auto;
margin-right: auto;
margin-bottom: 10px;
max-width: 960px;
background-color: #c7bcad;
box-shadow: 0px 0px 2px rgba(13, 13, 13, 0.3);
transition: box-shadow 0.5s ease-out;
}
body:hover {
box-shadow: 0px 0px 4px rgba(13, 13, 13, 1);
}
.subtle {
font-size: 12px;
opacity: 0.6;
}
.filetext {
max-width: 1024px;
min-width: 640px;
margin-left: auto;
margin-right: auto;
padding: 25px;
}
a, a:visited, a:hover {
color: #2b2b2b;
}
.dltext {
color: #2b2b2b;
text-align: center;
}
.videoprev {
display: block;
margin-right: auto;
margin-left: auto;
height: auto;
}
.audioprev {
display: block;
margin-top: 60px;
margin-right: auto;
margin-left: auto;
min-width: 640px;
max-width: 1024px;
height: auto;
}
.button {
color: #111;
font-weight: bold;
display: inline-block;
margin: 5px;
padding: 20px;
font-size: 24px;
transition: box-shadow 0.2s ease-out;
}
.uploadinterface {
width: 420px;
display: block;
margin-right: auto;
margin-left: auto;
height: auto;
}
.fileselector {
font-size: 18px;
color: #a3a3a3;
}
.submitbutton {
font-size: 18px;
}
.submitbutton:hover {
border-color: #a3a3a3;
}
.buttoncontainer {
margin-top: 20px;
margin-bottom: 20px;
display: block;
max-width: 422px;
margin-left: auto;
margin-right: auto;
}
.button:hover {
box-shadow: 0px 0px 4px rgba(13, 13, 13, 0.6);
}
img {
display: block;
border: solid 5px #2d2d2d;
margin-right: auto;
margin-left: auto;
max-width: 80%;
height: auto;
}

View File

@ -1,44 +0,0 @@
.redBG {
color: #F9F9F9;
background-color: #BF3128;
}
.blueBG {
color: #F9F9F9;
background-color: #0059A6;
}
.orangeBG {
background-color: #FF851B;
color: #111;
}
.grayBG {
background-color: #AAAAAA;
color: #111;
}
.blackBG {
background-color: #111;
color: #F9F9F9;
}
.yellowBG {
background-color: #FFDC00;
color: #111111;
}
.greenBG {
background-color: #2ECC40;
color: #F9F9F9;
}
.silverBG {
background-color: #DDDDDD;
color: #111;
}
.whiteBG {
background-color: #F9F9F9;
color: #111;
}

View File

@ -1 +0,0 @@
<!-- Place a botnet code here if you have one (Google Analytics, Piwik and that stuff) -->

View File

@ -1,38 +0,0 @@
<?php
//Site base URL
$site = "http://file.quad.moe";
if($extension == "jpg") {
echo '<meta name="twitter:card" content="photo" />
<meta name="twitter:site" content="@QuadPiece" />
<meta name="twitter:title" content="QuadFile" />
<meta name="twitter:description" content="Image uploaded to QuadFile" />
<meta name="twitter:image" content="' . $site . '/file/' . $filename . '" />
<meta name="twitter:url" content="' . $site . '/share/' . $filename . '" />';
}
elseif($extension == "jpeg") {
echo '<meta name="twitter:card" content="photo" />
<meta name="twitter:site" content="@QuadPiece" />
<meta name="twitter:title" content="QuadFile" />
<meta name="twitter:description" content="File uploaded to QuadFile" />
<meta name="twitter:image" content="' . $site . '/file/' . $filename . '" />
<meta name="twitter:url" content="' . $site . '/share/' . $filename . '" />';
}
elseif($extension == "png") {
echo '<meta name="twitter:card" content="photo" />
<meta name="twitter:site" content="@QuadPiece" />
<meta name="twitter:title" content="QuadFile" />
<meta name="twitter:description" content="File uploaded to QuadFile" />
<meta name="twitter:image" content="' . $site . '/file/' . $filename . '" />
<meta name="twitter:url" content="' . $site . '/share/' . $filename . '" />';
}
else {
echo '<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@QuadPiece" />
<meta name="twitter:title" content="QuadFile" />
<meta name="twitter:description" content="' . $extension . ' file uploaded to QuadFile" />
<meta name="twitter:image" content="' . $site . '/static/logo.png" />
<meta name="twitter:url" content="' . $site . '/share/' . $filename . '" />';
}
?>

View File

@ -1,26 +0,0 @@
<?php
//Site base URL
$site = "http://file.quad.moe";
if($extension == "jpg") {
echo '<meta property="og:title" content="' . $filename . ' - QuadFile">
<meta property="og:image" content="' . $site . '/file/' . $filename . '">
<meta property="og:description" content="Image file uploaded to QuadFile">';
}
elseif($extension == "jpeg") {
echo '<meta property="og:title" content="' . $filename . ' - QuadFile">
<meta property="og:image" content="' . $site . '/file/' . $filename . '">
<meta property="og:description" content="Image file uploaded to QuadFile">';
}
elseif($extension == "png") {
echo '<meta property="og:title" content="' . $filename . ' - QuadFile">
<meta property="og:image" content="' . $site . '/file/' . $filename . '">
<meta property="og:description" content="Image uploaded to QuadFile">';
}
else {
echo '<meta property="og:title" content="' . $filename . ' - QuadFile">
<meta property="og:image" content="' . $site . '/static/logo.png">
<meta property="og:description" content="' . $extension . ' file uploaded to QuadFile">';
}
?>

View File

@ -1,18 +0,0 @@
<?php
if($extension == "webm") {
echo '<link href="../../static/video-js/video-js.css" rel="stylesheet">
<script src="../../static/video-js/video.js"></script>
<script>
videojs.options.flash.swf = "../../static/video-js/video-js.swf"
</script>';
}
elseif($extension == "mp4") {
echo '<link href="../../static/video-js/video-js.css" rel="stylesheet">
<script src="../../static/video-js/video.js"></script>
<script>
videojs.options.flash.swf = "../../static/video-js/video-js.swf"
</script>';
}
?>

View File

@ -1,68 +0,0 @@
<?php
// //Echo previews for supported formats (This gon be messy son)
// if($extension == "webm") {
// echo '<video class="video-js vjs-default-skin videoprev" width="854" height="480" controls data-setup=' . "'" . '{"example_option":true}' . "'" . '><source src="../file/' . $filename . '" type="video/webm">Get a browser that supports WebM fag.</video>';
// }
// elseif($extension == "mp4") {
// echo '<video class="video-js vjs-default-skin videoprev" width="854" height="480" controls data-setup=' . "'" . '{"example_option":true}' . "'" . '><source src="../file/' . $filename . '" type="video/webm">Get a browser that supports WebM fag.</video>
// <p class="dltext subtle">Some MP4 files will play, some will not. There is unfortunately nothing we can do about this.</p>';
// }
// elseif($extension == "jpg") {
// echo '<img src="../file/' . $filename . '">';
// }
// elseif($extension == "jpeg") {
// echo '<img src="../file/' . $filename . '">';
// }
// elseif($extension == "png") {
// echo '<img src="../file/' . $filename . '">';
// }
// elseif($extension == "gif") {
// echo '<img src="../file/' . $filename . '">';
// }
// elseif($extension == "mp3") {
// echo '<audio class="audioprev" src="../file/' . $filename . '" controls>';
// }
// elseif($extension == "ogg") {
// echo '<audio class="audioprev" src="../file/' . $filename . '" controls>';
// }
// else {
// echo '<p class="dltext subtle">We do not support previews for this filetype.</p>';
// }
switch($extension) {
case "webm":
echo '<video class="video-js vjs-default-skin videoprev" width="854" height="480" controls data-setup=' . "'" . '{"example_option":true}' . "'" . '><source src="../file/' . $filename . '" type="video/webm">Get a browser that supports WebM fag.</video>';
break;
case "mp4":
echo '<video class="video-js vjs-default-skin videoprev" width="854" height="480" controls data-setup=' . "'" . '{"example_option":true}' . "'" . '><source src="../file/' . $filename . '" type="video/webm">Get a browser that supports WebM fag.</video>
<p class="dltext subtle">Some MP4 files will play, some will not. There is unfortunately nothing we can do about this.</p>';
break;
case "jpg":
case "jpeg":
case "png":
case "gif":
echo '<img src="../file/' . $filename . '">';
break;
case "mp3":
case "ogg":
echo '<audio class="audioprev" src="../file/' . $filename . '" controls>';
break;
case "txt":
$textcontent = file_get_contents('../file/' . $filename);
echo '<p class="filetext">';
echo strip_tags($textcontent);
echo '</p>' . "\n";
echo '<p class="dltext subtle">Some content may have been stripped from the file. Click download to see the original.</p>';
break;
default:
echo '<p class="dltext subtle">We do not support previews for this filetype.</p>';
}
?>

View File

@ -1,38 +0,0 @@
<?php
//Site base URL
$site = "http://file.quad.moe";
if($extension == "jpg") {
echo '<meta name="twitter:card" content="photo" />
<meta name="twitter:site" content="@QuadPiece" />
<meta name="twitter:title" content="QuadFile" />
<meta name="twitter:description" content="Image uploaded to QuadFile" />
<meta name="twitter:image" content="' . $site . '/random/file/' . $filename . '" />
<meta name="twitter:url" content="' . $site . '/random/perma/' . $filename . '" />';
}
elseif($extension == "jpeg") {
echo '<meta name="twitter:card" content="photo" />
<meta name="twitter:site" content="@QuadPiece" />
<meta name="twitter:title" content="QuadFile" />
<meta name="twitter:description" content="File uploaded to QuadFile" />
<meta name="twitter:image" content="' . $site . '/random/file/' . $filename . '" />
<meta name="twitter:url" content="' . $site . '/random/perma/' . $filename . '" />';
}
elseif($extension == "png") {
echo '<meta name="twitter:card" content="photo" />
<meta name="twitter:site" content="@QuadPiece" />
<meta name="twitter:title" content="QuadFile" />
<meta name="twitter:description" content="File uploaded to QuadFile" />
<meta name="twitter:image" content="' . $site . '/random/file/' . $filename . '" />
<meta name="twitter:url" content="' . $site . '/random/perma/' . $filename . '" />';
}
else {
echo '<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@QuadPiece" />
<meta name="twitter:title" content="QuadFile" />
<meta name="twitter:description" content="' . $extension . ' file uploaded to QuadFile" />
<meta name="twitter:image" content="' . $site . '/static/logo.png" />
<meta name="twitter:url" content="' . $site . '/random/perma/' . $filename . '" />';
}
?>

View File

@ -1,26 +0,0 @@
<?php
//Site base URL
$site = "http://file.quad.moe";
if($extension == "jpg") {
echo '<meta property="og:title" content="' . $filename . ' - QuadFile">
<meta property="og:image" content="' . $site . '/random/file/' . $filename . '">
<meta property="og:description" content="Image file uploaded to QuadFile">';
}
elseif($extension == "jpeg") {
echo '<meta property="og:title" content="' . $filename . ' - QuadFile">
<meta property="og:image" content="' . $site . '/random/file/' . $filename . '">
<meta property="og:description" content="Image file uploaded to QuadFile">';
}
elseif($extension == "png") {
echo '<meta property="og:title" content="' . $filename . ' - QuadFile">
<meta property="og:image" content="' . $site . '/random/file/' . $filename . '">
<meta property="og:description" content="Image uploaded to QuadFile">';
}
else {
echo '<meta property="og:title" content="' . $filename . ' - QuadFile">
<meta property="og:image" content="' . $site . '/static/logo.png">
<meta property="og:description" content="' . $extension . ' file uploaded to QuadFile">';
}
?>

View File

@ -1,32 +0,0 @@
<?php
//Echo previews for supported formats (This gon be messy son)
if($extension == "webm") {
echo '<video class="video-js vjs-default-skin videoprev" width="854" height="480" controls data-setup=' . "'" . '{"example_option":true}' . "'" . '><source src="file/' . $filename . '" type="video/webm">Get a browser that supports WebM fag.</video>';
}
elseif($extension == "mp4") {
echo '<video class="video-js vjs-default-skin videoprev" width="854" height="480" controls data-setup=' . "'" . '{"example_option":true}' . "'" . '><source src="file/' . $filename . '" type="video/webm">Get a browser that supports WebM fag.</video>
<p class="dltext subtle">Some MP4 files will play, some will not. There is unfortunately nothing we can do about this.</p>';
}
elseif($extension == "jpg") {
echo '<img src="file/' . $filename . '">';
}
elseif($extension == "jpeg") {
echo '<img src="file/' . $filename . '">';
}
elseif($extension == "png") {
echo '<img src="file/' . $filename . '">';
}
elseif($extension == "gif") {
echo '<img src="file/' . $filename . '">';
}
elseif($extension == "mp3") {
echo '<audio class="audioprev" src="file/' . $filename . '" controls>';
}
elseif($extension == "ogg") {
echo '<audio class="audioprev" src="file/' . $filename . '" controls>';
}
else {
echo '<p class="dltext subtle">We do not support previews for this filetype.</p>';
}
?>

View File

@ -1,12 +0,0 @@
<?php
if($extension == "webm") {
echo '<link href="../static/video-js/video-js.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.9/video.js"></script';
}
elseif($extension == "mp4") {
echo '<link href="../static/video-js/video-js.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.9/video.js"></script';
}
?>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@ -1,41 +0,0 @@
WEBVTT
00:00.700 --> 00:04.110
Captions describe all relevant audio for the hearing impaired.
[ Heroic music playing for a seagull ]
00:04.500 --> 00:05.000
[ Splash!!! ]
00:05.100 --> 00:06.000
[ Sploosh!!! ]
00:08.000 --> 00:09.225
[ Splash...splash...splash splash splash ]
00:10.525 --> 00:11.255
[ Splash, Sploosh again ]
00:13.500 --> 00:14.984
Dolphin: eeeEEEEEeeee!
00:14.984 --> 00:16.984
Dolphin: Squawk! eeeEEE?
00:25.000 --> 00:28.284
[ A whole ton of splashes ]
00:29.500 --> 00:31.000
Mine. Mine. Mine.
00:34.300 --> 00:36.000
Shark: Chomp
00:36.800 --> 00:37.900
Shark: CHOMP!!!
00:37.861 --> 00:41.193
EEEEEEOOOOOOOOOOWHALENOISE
00:42.593 --> 00:45.611
[ BIG SPLASH ]

View File

@ -1,32 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Video.js | HTML5 Video Player</title>
<!-- Chang URLs to wherever Video.js files will be hosted -->
<link href="video-js.css" rel="stylesheet" type="text/css">
<!-- video.js must be in the <head> for older IEs to work. -->
<script src="video.js"></script>
<!-- Unless using the CDN hosted version, update the URL to the Flash SWF -->
<script>
videojs.options.flash.swf = "video-js.swf";
</script>
</head>
<body>
<video id="example_video_1" class="video-js vjs-default-skin" controls preload="none" width="640" height="264"
poster="http://video-js.zencoder.com/oceans-clip.png"
data-setup="{}">
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
<track kind="captions" src="demo.captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
<track kind="subtitles" src="demo.captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
</video>
</body>
</html>

Binary file not shown.

View File

@ -1,28 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" d="" horiz-adv-x="512" />
<glyph unicode="&#xe000;" d="M1024 960v-416l-160 160-192-192-96 96 192 192-160 160zM448 288l-192-192 160-160h-416v416l160-160 192 192z" />
<glyph unicode="&#xe001;" d="M192 832l640-384-640-384z" />
<glyph unicode="&#xe002;" d="M128 832h320v-768h-320zM576 832h320v-768h-320z" />
<glyph unicode="&#xe003;" d="M401.332 881.332c25.668 25.668 46.668 16.968 46.668-19.332v-828c0-36.3-21-44.998-46.668-19.33l-241.332 241.33h-160v384h160l241.332 241.332z" />
<glyph unicode="&#xe004;" d="M549.020 218.98c-12.286 0-24.568 4.686-33.942 14.058-18.746 18.746-18.746 49.136 0 67.882 81.1 81.1 81.1 213.058 0 294.156-18.746 18.746-18.746 49.138 0 67.882 18.746 18.744 49.136 18.744 67.882 0 118.53-118.53 118.53-311.392 0-429.922-9.372-9.37-21.656-14.056-33.94-14.056zM401.332 881.332c25.668 25.668 46.668 16.968 46.668-19.332v-828c0-36.3-21-44.998-46.668-19.33l-241.332 241.33h-160v384h160l241.332 241.332z" />
<glyph unicode="&#xe005;" d="M719.53 128.47c-12.286 0-24.568 4.686-33.942 14.058-18.744 18.744-18.744 49.136 0 67.882 131.006 131.006 131.006 344.17 0 475.176-18.744 18.746-18.744 49.138 0 67.882 18.744 18.742 49.138 18.744 67.882 0 81.594-81.592 126.53-190.076 126.53-305.468 0-115.39-44.936-223.876-126.53-305.47-9.372-9.374-21.656-14.060-33.94-14.060zM549.020 218.98c-12.286 0-24.568 4.686-33.942 14.058-18.746 18.746-18.746 49.136 0 67.882 81.1 81.1 81.1 213.058 0 294.156-18.746 18.746-18.746 49.138 0 67.882 18.746 18.744 49.136 18.744 67.882 0 118.53-118.53 118.53-311.392 0-429.922-9.372-9.37-21.656-14.056-33.94-14.056zM401.332 881.332c25.668 25.668 46.668 16.968 46.668-19.332v-828c0-36.3-21-44.998-46.668-19.33l-241.332 241.33h-160v384h160l241.332 241.332z" />
<glyph unicode="&#xe006;" d="M890.040 37.96c-12.286 0-24.568 4.686-33.942 14.058-18.744 18.746-18.744 49.136 0 67.882 87.638 87.642 135.904 204.16 135.904 328.1 0 123.938-48.266 240.458-135.904 328.098-18.744 18.746-18.744 49.138 0 67.882 18.744 18.744 49.138 18.744 67.882 0 105.77-105.772 164.022-246.4 164.022-395.98 0-149.582-58.252-290.208-164.022-395.98-9.372-9.374-21.656-14.060-33.94-14.060zM719.53 128.47c-12.286 0-24.568 4.686-33.942 14.058-18.744 18.744-18.744 49.136 0 67.882 131.006 131.006 131.006 344.17 0 475.176-18.744 18.746-18.744 49.138 0 67.882 18.744 18.742 49.138 18.744 67.882 0 81.594-81.592 126.53-190.076 126.53-305.468 0-115.39-44.936-223.876-126.53-305.47-9.372-9.374-21.656-14.060-33.94-14.060zM549.020 218.98c-12.286 0-24.568 4.686-33.942 14.058-18.746 18.746-18.746 49.136 0 67.882 81.1 81.1 81.1 213.058 0 294.156-18.746 18.746-18.746 49.138 0 67.882 18.746 18.744 49.136 18.744 67.882 0 118.53-118.53 118.53-311.392 0-429.922-9.372-9.37-21.656-14.056-33.94-14.056zM401.332 881.332c25.668 25.668 46.668 16.968 46.668-19.332v-828c0-36.3-21-44.998-46.668-19.33l-241.332 241.33h-160v384h160l241.332 241.332z" horiz-adv-x="1088" />
<glyph unicode="&#xe007;" d="M512 960l-320-512 320-512 320 512z" />
<glyph unicode="&#xe008;" d="M0 960h1374.316v-1030.414h-1374.316v1030.414zM1245.462 449.276c-1.706 180.052-8.542 258.568-51.2 314.036-7.68 11.946-22.186 18.772-34.132 27.296-41.814 30.73-238.944 41.814-467.636 41.814-228.702 0-435.21-11.084-476.17-41.814-12.8-8.524-27.316-15.35-35.84-27.296-41.822-55.468-47.786-133.984-50.346-314.036 2.56-180.062 8.524-258.57 50.346-314.036 8.524-12.8 23.040-18.774 35.84-27.306 40.96-31.574 247.468-41.814 476.17-43.52 228.692 1.706 425.822 11.946 467.636 43.52 11.946 8.532 26.452 14.506 34.132 27.306 42.658 55.466 49.494 133.974 51.2 314.036zM662.358 495.904c-11.58 140.898-86.51 223.906-220.556 223.906-122.458 0-218.722-110.432-218.722-287.88 0-178.212 87.73-289.396 232.734-289.396 115.766 0 196.798 85.298 209.588 226.95h-138.302c-5.48-52.548-27.414-92.914-73.72-92.914-73.108 0-86.51 72.354-86.51 149.27 0 105.868 30.46 159.932 81.032 159.932 45.082 0 73.718-32.75 77.976-89.868h136.48zM1140.026 495.904c-11.57 140.898-86.51 223.906-220.546 223.906-122.466 0-218.722-110.432-218.722-287.88 0-178.212 87.73-289.396 232.734-289.396 115.758 0 196.788 85.298 209.58 226.95h-138.304c-5.47-52.548-27.404-92.914-73.71-92.914-73.116 0-86.518 72.354-86.518 149.27 0 105.868 30.468 159.932 81.030 159.932 45.084 0 73.728-32.75 77.986-89.868h136.47z" horiz-adv-x="1374" />
<glyph unicode="&#xe009;" d="M128 832h768v-768h-768z" />
<glyph unicode="&#xe00a;" d="M384 832c0-70.692 57.308-128 128-128s128 57.308 128 128c0 70.692-57.308 128-128 128-70.692 0-128-57.308-128-128zM655.53 719.53c0-70.692 57.308-128 128-128s128 57.308 128 128c0 70.692-57.308 128-128 128-70.692 0-128-57.308-128-128zM832 448c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64zM719.53 176.47c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64zM448.002 64c0 0 0 0 0 0 0-35.346 28.654-64 64-64 35.346 0 64 28.654 64 64 0 0 0 0 0 0 0 0 0 0 0 0 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64s0 0 0 0zM176.472 176.47c0 0 0 0 0 0 0-35.346 28.654-64 64-64 35.346 0 64 28.654 64 64 0 0 0 0 0 0 0 0 0 0 0 0 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64s0 0 0 0zM144.472 719.53c0 0 0 0 0 0 0-53.019 42.981-96 96-96 53.019 0 96 42.981 96 96 0 0 0 0 0 0 0 0 0 0 0 0 0 53.019-42.981 96-96 96-53.019 0-96-42.981-96-96s0 0 0 0zM56 448c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.765-32.235 72-72 72-39.765 0-72-32.235-72-72z" />
<glyph unicode="&#xe00b;" d="M448 384v-416l-160 160-192-192-96 96 192 192-160 160zM1024 864l-192-192 160-160h-416v416l160-160 192 192z" />
<glyph unicode="&#xe00c;" d="M512 896c282.77 0 512-186.25 512-416 0-229.752-229.23-416-512-416-27.156 0-53.81 1.734-79.824 5.044-109.978-109.978-241.25-129.7-368.176-132.596v26.916c68.536 33.578 128 94.74 128 164.636 0 9.754-0.758 19.33-2.164 28.696-115.796 76.264-189.836 192.754-189.836 323.304 0 229.75 229.23 416 512 416z" />
<glyph unicode="&#xe00d;" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 704c141.384 0 256-114.616 256-256s-114.616-256-256-256-256 114.616-256 256 114.616 256 256 256zM817.47 142.53c-81.594-81.594-190.080-126.53-305.47-126.53-115.392 0-223.876 44.936-305.47 126.53-81.594 81.594-126.53 190.078-126.53 305.47 0 115.39 44.936 223.876 126.53 305.47l67.882-67.882c0 0 0 0 0 0-131.006-131.006-131.006-344.17 0-475.176 63.462-63.462 147.838-98.412 237.588-98.412 89.748 0 174.124 34.95 237.588 98.412 131.006 131.006 131.006 344.168 0 475.176l67.882 67.882c81.594-81.594 126.53-190.080 126.53-305.47 0-115.392-44.936-223.876-126.53-305.47z" />
<glyph unicode="&#xe00e;" d="M864 256c-45.16 0-85.92-18.738-115.012-48.83l-431.004 215.502c1.314 8.252 2.016 16.706 2.016 25.328s-0.702 17.076-2.016 25.326l431.004 215.502c29.092-30.090 69.852-48.828 115.012-48.828 88.366 0 160 71.634 160 160s-71.634 160-160 160-160-71.634-160-160c0-8.622 0.704-17.076 2.016-25.326l-431.004-215.504c-29.092 30.090-69.852 48.83-115.012 48.83-88.366 0-160-71.636-160-160 0-88.368 71.634-160 160-160 45.16 0 85.92 18.738 115.012 48.828l431.004-215.502c-1.312-8.25-2.016-16.704-2.016-25.326 0-88.368 71.634-160 160-160s160 71.632 160 160c0 88.364-71.634 160-160 160z" />
<glyph unicode="&#xe01e;" d="M1024 448c-1.278 66.862-15.784 133.516-42.576 194.462-26.704 61-65.462 116.258-113.042 161.92-47.552 45.696-103.944 81.82-164.984 105.652-61.004 23.924-126.596 35.352-191.398 33.966-64.81-1.282-129.332-15.374-188.334-41.356-59.048-25.896-112.542-63.47-156.734-109.576-44.224-46.082-79.16-100.708-102.186-159.798-23.114-59.062-34.128-122.52-32.746-185.27 1.286-62.76 14.964-125.148 40.134-182.206 25.088-57.1 61.476-108.828 106.11-151.548 44.61-42.754 97.472-76.504 154.614-98.72 57.118-22.304 118.446-32.902 179.142-31.526 60.708 1.29 120.962 14.554 176.076 38.914 55.15 24.282 105.116 59.48 146.366 102.644 41.282 43.14 73.844 94.236 95.254 149.43 13.034 33.458 21.88 68.4 26.542 103.798 1.246-0.072 2.498-0.12 3.762-0.12 35.346 0 64 28.652 64 64 0 1.796-0.094 3.572-0.238 5.332h0.238zM922.306 278.052c-23.472-53.202-57.484-101.4-99.178-141.18-41.67-39.81-91-71.186-144.244-91.79-53.228-20.678-110.29-30.452-166.884-29.082-56.604 1.298-112.596 13.736-163.82 36.474-51.25 22.666-97.684 55.49-135.994 95.712-38.338 40.198-68.528 87.764-88.322 139.058-19.87 51.284-29.228 106.214-27.864 160.756 1.302 54.552 13.328 108.412 35.254 157.69 21.858 49.3 53.498 93.97 92.246 130.81 38.73 36.868 84.53 65.87 133.874 84.856 49.338 19.060 102.136 28.006 154.626 26.644 52.5-1.306 104.228-12.918 151.562-34.034 47.352-21.050 90.256-51.502 125.624-88.782 35.396-37.258 63.21-81.294 81.39-128.688 18.248-47.392 26.782-98.058 25.424-148.496h0.238c-0.144-1.76-0.238-3.536-0.238-5.332 0-33.012 24.992-60.174 57.086-63.624-6.224-34.822-16.53-68.818-30.78-100.992z" />
<glyph unicode="&#xe01f;" d="M512 960c-278.748 0-505.458-222.762-511.848-499.974 5.92 241.864 189.832 435.974 415.848 435.974 229.75 0 416-200.576 416-448 0-53.020 42.98-96 96-96 53.020 0 96 42.98 96 96 0 282.77-229.23 512-512 512zM512-64c278.748 0 505.458 222.762 511.848 499.974-5.92-241.864-189.832-435.974-415.848-435.974-229.75 0-416 200.576-416 448 0 53.020-42.98 96-96 96-53.020 0-96-42.98-96-96 0-282.77 229.23-512 512-512z" />
<glyph unicode="&#xe600;" d="M1024 351.906v192.188l-146.774 24.462c-5.958 18.132-13.222 35.668-21.694 52.5l86.454 121.034-135.896 135.898-120.826-86.304c-16.91 8.554-34.538 15.888-52.768 21.902l-24.402 146.414h-192.188l-24.402-146.416c-18.23-6.014-35.858-13.348-52.766-21.902l-120.828 86.304-135.898-135.898 86.454-121.036c-8.47-16.83-15.734-34.366-21.692-52.498l-146.774-24.46v-192.188l147.118-24.52c5.96-17.968 13.21-35.348 21.642-52.030l-86.748-121.448 135.898-135.896 121.654 86.894c16.602-8.35 33.89-15.528 51.764-21.434l24.578-147.472h192.188l24.578 147.474c17.874 5.906 35.162 13.084 51.766 21.432l121.652-86.892 135.896 135.896-86.744 121.446c8.432 16.682 15.678 34.062 21.64 52.032l147.118 24.518zM512 320c-70.692 0-128 57.306-128 128 0 70.692 57.308 128 128 128 70.694 0 128-57.308 128-128 0-70.694-57.306-128-128-128z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Binary file not shown.

View File

@ -1,26 +0,0 @@
videojs.addLanguage("fr",{
"Play": "Lecture",
"Pause": "Pause",
"Current Time": "Temps actuel",
"Duration Time": "Durée",
"Remaining Time": "Temps restant",
"Stream Type": "Type de flux",
"LIVE": "EN DIRECT",
"Loaded": "Chargé",
"Progress": "Progression",
"Fullscreen": "Plein écran",
"Non-Fullscreen": "Fenêtré",
"Mute": "Sourdine",
"Unmuted": "Son activé",
"Playback Rate": "Vitesse de lecture",
"Subtitles": "Sous-titres",
"subtitles off": "Sous-titres désactivés",
"Captions": "Sous-titres",
"captions off": "Sous-titres désactivés",
"Chapters": "Chapitres",
"You aborted the video playback": "Vous avez interrompu la lecture de la vidéo.",
"A network error caused the video download to fail part-way.": "Une erreur de réseau a interrompu le téléchargement de la vidéo.",
"The video could not be loaded, either because the server or network failed or because the format is not supported.": "Cette vidéo n'a pas pu être chargée, soit parce que le serveur ou le réseau a échoué ou parce que le format n'est pas reconnu.",
"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.": "La lecture de la vidéo a été interrompue à cause d'un problème de corruption ou parce que la vidéo utilise des fonctionnalités non prises en charge par votre navigateur.",
"No compatible source was found for this video.": "Aucune source compatible n'a été trouvée pour cette vidéo."
});

View File

@ -1,969 +0,0 @@
/*!
Video.js Default Styles (http://videojs.com)
Version 4.10.0
Create your own skin at http://designer.videojs.com
*/
/* SKIN
================================================================================
The main class name for all skin-specific styles. To make your own skin,
replace all occurances of 'vjs-default-skin' with a new name. Then add your new
skin name to your video tag instead of the default skin.
e.g. <video class="video-js my-skin-name">
*/
.vjs-default-skin {
color: #CCC;
}
/* Custom Icon Font
--------------------------------------------------------------------------------
The control icons are from a custom font. Each icon corresponds to a character
(e.g. "\e001"). Font icons allow for easy scaling and coloring of icons.
*/
@font-face {
font-family: 'VideoJS';
src: url('font/vjs.eot');
src: url('font/vjs.eot?#iefix') format('embedded-opentype'), url('font/vjs.woff') format('woff'), url('font/vjs.ttf') format('truetype'), url('font/vjs.svg#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
/* Base UI Component Classes
--------------------------------------------------------------------------------
*/
/* Slider - used for Volume bar and Seek bar */
.vjs-default-skin .vjs-slider {
/* Replace browser focus hightlight with handle highlight */
outline: 0;
position: relative;
cursor: pointer;
padding: 0;
/* background-color-with-alpha */
background-color: #333333;
background-color: rgba(51, 51, 51, 0.9);
}
.vjs-default-skin .vjs-slider:focus {
/* box-shadow */
-webkit-box-shadow: 0 0 1em #ffffff;
-moz-box-shadow: 0 0 1em #ffffff;
box-shadow: 0 0 1em #ffffff;
}
.vjs-default-skin .vjs-slider-handle {
position: absolute;
/* Needed for IE6 */
left: 0;
top: 0;
}
.vjs-default-skin .vjs-slider-handle:before {
content: "\e009";
font-family: VideoJS;
font-size: 1em;
line-height: 1;
text-align: center;
text-shadow: 0em 0em 1em #fff;
position: absolute;
top: 0;
left: 0;
/* Rotate the square icon to make a diamond */
/* transform */
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
/* Control Bar
--------------------------------------------------------------------------------
The default control bar that is a container for most of the controls.
*/
.vjs-default-skin .vjs-control-bar {
/* Start hidden */
display: none;
position: absolute;
/* Place control bar at the bottom of the player box/video.
If you want more margin below the control bar, add more height. */
bottom: 0;
/* Use left/right to stretch to 100% width of player div */
left: 0;
right: 0;
/* Height includes any margin you want above or below control items */
height: 3em;
/* background-color-with-alpha */
background-color: #111111;
}
/* Show the control bar only once the video has started playing */
.vjs-default-skin.vjs-has-started .vjs-control-bar {
display: block;
/* Visibility needed to make sure things hide in older browsers too. */
visibility: visible;
opacity: 1;
/* transition */
-webkit-transition: visibility 0.1s, opacity 0.1s;
-moz-transition: visibility 0.1s, opacity 0.1s;
-o-transition: visibility 0.1s, opacity 0.1s;
transition: visibility 0.1s, opacity 0.1s;
}
/* Hide the control bar when the video is playing and the user is inactive */
.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
display: block;
visibility: hidden;
opacity: 0;
/* transition */
-webkit-transition: visibility 1s, opacity 1s;
-moz-transition: visibility 1s, opacity 1s;
-o-transition: visibility 1s, opacity 1s;
transition: visibility 1s, opacity 1s;
}
.vjs-default-skin.vjs-controls-disabled .vjs-control-bar {
display: none;
}
.vjs-default-skin.vjs-using-native-controls .vjs-control-bar {
display: none;
}
/* The control bar shouldn't show after an error */
.vjs-default-skin.vjs-error .vjs-control-bar {
display: none;
}
/* Don't hide the control bar if it's audio */
.vjs-audio.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
opacity: 1;
visibility: visible;
}
/* IE8 is flakey with fonts, and you have to change the actual content to force
fonts to show/hide properly.
- "\9" IE8 hack didn't work for this
- Found in XP IE8 from http://modern.ie. Does not show up in "IE8 mode" in IE9
*/
@media \0screen {
.vjs-default-skin.vjs-user-inactive.vjs-playing .vjs-control-bar :before {
content: "";
}
}
/* General styles for individual controls. */
.vjs-default-skin .vjs-control {
outline: none;
position: relative;
float: left;
text-align: center;
margin: 0;
padding: 0;
height: 3.0em;
width: 4em;
}
/* Font button icons */
.vjs-default-skin .vjs-control:before {
font-family: VideoJS;
font-size: 1.5em;
line-height: 2;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
}
/* Replacement for focus outline */
.vjs-default-skin .vjs-control:focus:before,
.vjs-default-skin .vjs-control:hover:before {
text-shadow: 0em 0em 1em #ffffff;
}
.vjs-default-skin .vjs-control:focus {
/* outline: 0; */
/* keyboard-only users cannot see the focus on several of the UI elements when
this is set to 0 */
}
/* Hide control text visually, but have it available for screenreaders */
.vjs-default-skin .vjs-control-text {
/* hide-visually */
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
/* Play/Pause
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-play-control {
width: 5em;
cursor: pointer;
}
.vjs-default-skin .vjs-play-control:before {
content: "\e001";
}
.vjs-default-skin.vjs-playing .vjs-play-control:before {
content: "\e002";
}
/* Playback toggle
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-playback-rate .vjs-playback-rate-value {
font-size: 1.5em;
line-height: 2;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
}
.vjs-default-skin .vjs-playback-rate.vjs-menu-button .vjs-menu .vjs-menu-content {
width: 4em;
left: -2em;
list-style: none;
}
/* Volume/Mute
-------------------------------------------------------------------------------- */
.vjs-default-skin .vjs-mute-control,
.vjs-default-skin .vjs-volume-menu-button {
cursor: pointer;
float: right;
}
.vjs-default-skin .vjs-mute-control:before,
.vjs-default-skin .vjs-volume-menu-button:before {
content: "\e006";
}
.vjs-default-skin .vjs-mute-control.vjs-vol-0:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-0:before {
content: "\e003";
}
.vjs-default-skin .vjs-mute-control.vjs-vol-1:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-1:before {
content: "\e004";
}
.vjs-default-skin .vjs-mute-control.vjs-vol-2:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-2:before {
content: "\e005";
}
.vjs-default-skin .vjs-volume-control {
width: 5em;
float: right;
}
.vjs-default-skin .vjs-volume-bar {
width: 5em;
height: 0.6em;
margin: 1.1em auto 0;
}
.vjs-default-skin .vjs-volume-level {
position: absolute;
top: 0;
left: 0;
height: 0.5em;
/* assuming volume starts at 1.0 */
width: 100%;
background: #e65100 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat;
}
.vjs-default-skin .vjs-volume-bar .vjs-volume-handle {
width: 0.5em;
height: 0.5em;
/* Assumes volume starts at 1.0. If you change the size of the
handle relative to the volume bar, you'll need to update this value
too. */
left: 4.5em;
}
.vjs-default-skin .vjs-volume-handle:before {
font-size: 0.9em;
top: -0.2em;
left: -0.2em;
width: 1em;
height: 1em;
}
/* The volume menu button is like menu buttons (captions/subtitles) but works
a little differently. It needs to be possible to tab to the volume slider
without hitting space bar on the menu button. To do this we're not using
display:none to hide the slider menu by default, and instead setting the
width and height to zero. */
.vjs-default-skin .vjs-volume-menu-button .vjs-menu {
display: block;
width: 0;
height: 0;
border-top-color: transparent;
}
.vjs-default-skin .vjs-volume-menu-button .vjs-menu .vjs-menu-content {
height: 0;
width: 0;
}
.vjs-default-skin .vjs-volume-menu-button:hover .vjs-menu,
.vjs-default-skin .vjs-volume-menu-button .vjs-menu.vjs-lock-showing {
border-top-color: rgba(7, 40, 50, 0.5);
/* Same as ul background */
}
.vjs-default-skin .vjs-volume-menu-button:hover .vjs-menu .vjs-menu-content,
.vjs-default-skin .vjs-volume-menu-button .vjs-menu.vjs-lock-showing .vjs-menu-content {
height: 2.9em;
width: 10em;
}
/* Progress
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-progress-control {
position: absolute;
left: 0;
right: 0;
width: auto;
font-size: 0.3em;
height: 1em;
/* Set above the rest of the controls. */
top: -1em;
/* Shrink the bar slower than it grows. */
/* transition */
-webkit-transition: all 0.4s;
-moz-transition: all 0.4s;
-o-transition: all 0.4s;
transition: all 0.4s;
}
/* On hover, make the progress bar grow to something that's more clickable.
This simply changes the overall font for the progress bar, and this
updates both the em-based widths and heights, as wells as the icon font */
.vjs-default-skin:hover .vjs-progress-control {
font-size: .9em;
/* Even though we're not changing the top/height, we need to include them in
the transition so they're handled correctly. */
/* transition */
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
/* Box containing play and load progresses. Also acts as seek scrubber. */
.vjs-default-skin .vjs-progress-holder {
height: 100%;
}
/* Progress Bars */
.vjs-default-skin .vjs-progress-holder .vjs-play-progress,
.vjs-default-skin .vjs-progress-holder .vjs-load-progress,
.vjs-default-skin .vjs-progress-holder .vjs-load-progress div {
position: absolute;
display: block;
height: 100%;
margin: 0;
padding: 0;
/* updated by javascript during playback */
width: 0;
/* Needed for IE6 */
left: 0;
top: 0;
}
.vjs-default-skin .vjs-play-progress {
/*
Using a data URI to create the white diagonal lines with a transparent
background. Surprisingly works in IE8.
Created using http://www.patternify.com
Changing the first color value will change the bar color.
Also using a paralax effect to make the lines move backwards.
The -50% left position makes that happen.
*/
background: #e65100 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat;
}
.vjs-default-skin .vjs-load-progress {
background: #646464 /* IE8- Fallback */;
background: rgba(255, 255, 255, 0.2);
}
/* there are child elements of the load progress bar that represent the
specific time ranges that have been buffered */
.vjs-default-skin .vjs-load-progress div {
background: #787878 /* IE8- Fallback */;
background: rgba(255, 255, 255, 0.1);
}
.vjs-default-skin .vjs-seek-handle {
width: 1.5em;
height: 100%;
}
.vjs-default-skin .vjs-seek-handle:before {
padding-top: 0.1em /* Minor adjustment */;
}
/* Live Mode
--------------------------------------------------------------------------------
*/
.vjs-default-skin.vjs-live .vjs-time-controls,
.vjs-default-skin.vjs-live .vjs-time-divider,
.vjs-default-skin.vjs-live .vjs-progress-control {
display: none;
}
.vjs-default-skin.vjs-live .vjs-live-display {
display: block;
}
/* Live Display
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-live-display {
display: none;
font-size: 1em;
line-height: 3em;
}
/* Time Display
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-time-controls {
font-size: 1em;
/* Align vertically by making the line height the same as the control bar */
line-height: 3em;
}
.vjs-default-skin .vjs-current-time {
float: left;
}
.vjs-default-skin .vjs-duration {
float: left;
}
/* Remaining time is in the HTML, but not included in default design */
.vjs-default-skin .vjs-remaining-time {
display: none;
float: left;
}
.vjs-time-divider {
float: left;
line-height: 3em;
}
/* Fullscreen
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-fullscreen-control {
width: 3.8em;
cursor: pointer;
float: right;
}
.vjs-default-skin .vjs-fullscreen-control:before {
content: "\e000";
}
/* Switch to the exit icon when the player is in fullscreen */
.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control:before {
content: "\e00b";
}
/* Big Play Button (play button at start)
--------------------------------------------------------------------------------
Positioning of the play button in the center or other corners can be done more
easily in the skin designer. http://designer.videojs.com/
*/
.vjs-default-skin .vjs-big-play-button {
/* Center it horizontally */
left: 50%;
margin-left: -2em;
/* Center it vertically */
top: 50%;
margin-top: -1em;
font-size: 3em;
display: block;
z-index: 2;
position: absolute;
width: 4em;
height: 2em;
text-align: center;
vertical-align: middle;
cursor: pointer;
opacity: 1;
/* Need a slightly gray bg so it can be seen on black backgrounds */
/* background-color-with-alpha */
background-color: #111111;
border: 0em solid #aaaaaa;
/* border-radius */
-webkit-border-radius: 0em;
-moz-border-radius: 0em;
border-radius: 0em;
/* box-shadow */
-webkit-box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);
-moz-box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);
box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);
/* transition */
-webkit-transition: all 0.4s;
-moz-transition: all 0.4s;
-o-transition: all 0.4s;
transition: all 0.4s;
}
/* Optionally center */
.vjs-default-skin.vjs-big-play-centered .vjs-big-play-button {
/* Center it horizontally */
left: 50%;
margin-left: -2em;
/* Center it vertically */
top: 50%;
margin-top: -1em;
}
/* Hide if controls are disabled */
.vjs-default-skin.vjs-controls-disabled .vjs-big-play-button {
display: none;
}
/* Hide when video starts playing */
.vjs-default-skin.vjs-has-started .vjs-big-play-button {
display: none;
}
/* Hide on mobile devices. Remove when we stop using native controls
by default on mobile */
.vjs-default-skin.vjs-using-native-controls .vjs-big-play-button {
display: none;
}
.vjs-default-skin:hover .vjs-big-play-button,
.vjs-default-skin .vjs-big-play-button:focus {
outline: 0;
border-color: #fff;
/* IE8 needs a non-glow hover state */
background-color: #505050;
background-color: rgba(50, 50, 50, 0.75);
/* box-shadow */
-webkit-box-shadow: 0 0 3em #ffffff;
-moz-box-shadow: 0 0 3em #ffffff;
box-shadow: 0 0 3em #ffffff;
/* transition */
-webkit-transition: all 0s;
-moz-transition: all 0s;
-o-transition: all 0s;
transition: all 0s;
}
.vjs-default-skin .vjs-big-play-button:before {
content: "\e001";
font-family: VideoJS;
/* In order to center the play icon vertically we need to set the line height
to the same as the button height */
line-height: 2em;
text-shadow: 0.05em 0.05em 0.1em #000;
text-align: center /* Needed for IE8 */;
position: absolute;
left: 0;
width: 100%;
height: 100%;
}
.vjs-error .vjs-big-play-button {
display: none;
}
/* Error Display
--------------------------------------------------------------------------------
*/
.vjs-error-display {
display: none;
}
.vjs-error .vjs-error-display {
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.vjs-error .vjs-error-display:before {
content: 'X';
font-family: Arial;
font-size: 4em;
color: #666666;
/* In order to center the play icon vertically we need to set the line height
to the same as the button height */
line-height: 1;
text-shadow: 0.05em 0.05em 0.1em #000;
text-align: center /* Needed for IE8 */;
vertical-align: middle;
position: absolute;
left: 0;
top: 50%;
margin-top: -0.5em;
width: 100%;
}
.vjs-error-display div {
position: absolute;
bottom: 1em;
right: 0;
left: 0;
font-size: 1.4em;
text-align: center;
padding: 3px;
background: #000000;
background: rgba(0, 0, 0, 0.5);
}
.vjs-error-display a,
.vjs-error-display a:visited {
color: #F4A460;
}
/* Loading Spinner
--------------------------------------------------------------------------------
*/
.vjs-loading-spinner {
/* Should be hidden by default */
display: none;
position: absolute;
top: 50%;
left: 50%;
font-size: 4em;
line-height: 1;
width: 1em;
height: 1em;
margin-left: -0.5em;
margin-top: -0.5em;
opacity: 0.75;
}
/* Show the spinner when waiting for data and seeking to a new time */
.vjs-waiting .vjs-loading-spinner,
.vjs-seeking .vjs-loading-spinner {
display: block;
/* only animate when showing because it can be processor heavy */
/* animation */
-webkit-animation: spin 1.5s infinite linear;
-moz-animation: spin 1.5s infinite linear;
-o-animation: spin 1.5s infinite linear;
animation: spin 1.5s infinite linear;
}
/* Errors are unrecoverable without user interaction so hide the spinner */
.vjs-error .vjs-loading-spinner {
display: none;
/* ensure animation doesn't continue while hidden */
/* animation */
-webkit-animation: none;
-moz-animation: none;
-o-animation: none;
animation: none;
}
.vjs-default-skin .vjs-loading-spinner:before {
content: "\e01e";
font-family: VideoJS;
position: absolute;
top: 0;
left: 0;
width: 1em;
height: 1em;
text-align: center;
text-shadow: 0em 0em 0.1em #000;
}
@-moz-keyframes spin {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
}
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
}
}
@-o-keyframes spin {
0% {
-o-transform: rotate(0deg);
}
100% {
-o-transform: rotate(359deg);
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
/* Menu Buttons (Captions/Subtitles/etc.)
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-menu-button {
float: right;
cursor: pointer;
}
.vjs-default-skin .vjs-menu {
display: none;
position: absolute;
bottom: 0;
left: 0em;
/* (Width of vjs-menu - width of button) / 2 */
width: 0em;
height: 0em;
margin-bottom: 3em;
border-left: 2em solid transparent;
border-right: 2em solid transparent;
border-top: 1.55em solid #000000;
/* Same width top as ul bottom */
border-top-color: rgba(7, 40, 50, 0.5);
/* Same as ul background */
}
/* Button Pop-up Menu */
.vjs-default-skin .vjs-menu-button .vjs-menu .vjs-menu-content {
display: block;
padding: 0;
margin: 0;
position: absolute;
width: 10em;
bottom: 1.5em;
/* Same bottom as vjs-menu border-top */
max-height: 15em;
overflow: auto;
left: -5em;
/* Width of menu - width of button / 2 */
/* background-color-with-alpha */
background-color: #111111;
/* box-shadow */
-webkit-box-shadow: -0.2em -0.2em 0.3em rgba(255, 255, 255, 0.2);
-moz-box-shadow: -0.2em -0.2em 0.3em rgba(255, 255, 255, 0.2);
box-shadow: -0.2em -0.2em 0.3em rgba(255, 255, 255, 0.2);
}
.vjs-default-skin .vjs-menu-button:hover .vjs-control-content .vjs-menu,
.vjs-default-skin .vjs-control-content .vjs-menu.vjs-lock-showing {
display: block;
}
.vjs-default-skin .vjs-menu-button ul li {
list-style: none;
margin: 0;
padding: 0.3em 0 0.3em 0;
line-height: 1.4em;
font-size: 1.2em;
text-align: center;
text-transform: lowercase;
}
.vjs-default-skin .vjs-menu-button ul li.vjs-selected {
background-color: #000;
}
.vjs-default-skin .vjs-menu-button ul li:focus,
.vjs-default-skin .vjs-menu-button ul li:hover,
.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,
.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover {
outline: 0;
color: #111;
/* background-color-with-alpha */
background-color: #ffffff;
background-color: rgba(255, 255, 255, 0.75);
/* box-shadow */
-webkit-box-shadow: 0 0 1em #ffffff;
-moz-box-shadow: 0 0 1em #ffffff;
box-shadow: 0 0 1em #ffffff;
}
.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title {
text-align: center;
text-transform: uppercase;
font-size: 1em;
line-height: 2em;
padding: 0;
margin: 0 0 0.3em 0;
font-weight: bold;
cursor: default;
}
/* Subtitles Button */
.vjs-default-skin .vjs-subtitles-button:before {
content: "\e00c";
}
/* Captions Button */
.vjs-default-skin .vjs-captions-button:before {
content: "\e008";
}
/* Chapters Button */
.vjs-default-skin .vjs-chapters-button:before {
content: "\e00c";
}
.vjs-default-skin .vjs-chapters-button.vjs-menu-button .vjs-menu .vjs-menu-content {
width: 24em;
left: -12em;
}
/* Replacement for focus outline */
.vjs-default-skin .vjs-captions-button:focus .vjs-control-content:before,
.vjs-default-skin .vjs-captions-button:hover .vjs-control-content:before {
/* box-shadow */
-webkit-box-shadow: 0 0 1em #ffffff;
-moz-box-shadow: 0 0 1em #ffffff;
box-shadow: 0 0 1em #ffffff;
}
/*
REQUIRED STYLES (be careful overriding)
================================================================================
When loading the player, the video tag is replaced with a DIV,
that will hold the video tag or object tag for other playback methods.
The div contains the video playback element (Flash or HTML5) and controls,
and sets the width and height of the video.
** If you want to add some kind of border/padding (e.g. a frame), or special
positioning, use another containing element. Otherwise you risk messing up
control positioning and full window mode. **
*/
.video-js {
background-color: #000;
position: relative;
padding: 0;
/* Start with 10px for base font size so other dimensions can be em based and
easily calculable. */
font-size: 11px;
/* Allow poster to be vertially aligned. */
vertical-align: middle;
/* display: table-cell; */
/*This works in Safari but not Firefox.*/
/* Provide some basic defaults for fonts */
font-weight: normal;
font-style: normal;
/* Avoiding helvetica: issue #376 */
font-family: Arial, sans-serif;
/* Turn off user selection (text highlighting) by default.
The majority of player components will not be text blocks.
Text areas will need to turn user selection back on. */
/* user-select */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Playback technology elements expand to the width/height of the containing div
<video> or <object> */
.video-js .vjs-tech {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when
checking fullScreenEnabled. */
.video-js:-moz-full-screen {
position: absolute;
}
/* Fullscreen Styles */
body.vjs-full-window {
padding: 0;
margin: 0;
height: 100%;
/* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */
overflow-y: auto;
}
.video-js.vjs-fullscreen {
position: fixed;
overflow: hidden;
z-index: 1000;
left: 0;
top: 0;
bottom: 0;
right: 0;
width: 100% !important;
height: 100% !important;
/* IE6 full-window (underscore hack) */
_position: absolute;
}
.video-js:-webkit-full-screen {
width: 100% !important;
height: 100% !important;
}
.video-js.vjs-fullscreen.vjs-user-inactive {
cursor: none;
}
/* Poster Styles */
.vjs-poster {
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
cursor: pointer;
margin: 0;
padding: 0;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.vjs-poster img {
display: block;
margin: 0 auto;
max-height: 100%;
padding: 0;
width: 100%;
}
/* Hide the poster after the video has started playing */
.video-js.vjs-has-started .vjs-poster {
display: none;
}
/* Don't hide the poster if we're playing audio */
.video-js.vjs-audio.vjs-has-started .vjs-poster {
display: block;
}
/* Hide the poster when controls are disabled because it's clickable
and the native poster can take over */
.video-js.vjs-controls-disabled .vjs-poster {
display: none;
}
/* Hide the poster when native controls are used otherwise it covers them */
.video-js.vjs-using-native-controls .vjs-poster {
display: none;
}
/* Text Track Styles */
/* Overall track holder for both captions and subtitles */
.video-js .vjs-text-track-display {
text-align: center;
position: absolute;
bottom: 4em;
/* Leave padding on left and right */
left: 1em;
right: 1em;
}
/* Move captions down when controls aren't being shown */
.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display {
bottom: 1em;
}
/* Individual tracks */
.video-js .vjs-text-track {
display: none;
font-size: 1.4em;
text-align: center;
margin-bottom: 0.1em;
/* Transparent black background, or fallback to all black (oldIE) */
/* background-color-with-alpha */
background-color: #000000;
background-color: rgba(0, 0, 0, 0.5);
}
.video-js .vjs-subtitles {
color: #ffffff /* Subtitles are white */;
}
.video-js .vjs-captions {
color: #ffcc66 /* Captions are yellow */;
}
.vjs-tt-cue {
display: block;
}
/* Increase font-size when fullscreen */
.video-js.vjs-fullscreen .vjs-text-track {
font-size: 3em;
}
/* Hide disabled or unsupported controls */
.vjs-default-skin .vjs-hidden {
display: none;
}
.vjs-lock-showing {
display: block !important;
opacity: 1;
visibility: visible;
}
/* In IE8 w/ no JavaScript (no HTML5 shim), the video tag doesn't register.
The .video-js classname on the video tag also isn't considered.
This optional paragraph inside the video tag can provide a message to users
about what's required to play video. */
.vjs-no-js {
padding: 20px;
color: #ccc;
background-color: #333;
font-size: 18px;
font-family: Arial, sans-serif;
text-align: center;
width: 300px;
height: 150px;
margin: 0px auto;
}
.vjs-no-js a,
.vjs-no-js a:visited {
color: #F4A460;
}
/* -----------------------------------------------------------------------------
The original source of this file lives at
https://github.com/videojs/video.js/blob/master/src/css/video-js.less */

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,167 +0,0 @@
/*! Video.js v4.10.0 Copyright 2014 Brightcove, Inc. https://github.com/videojs/video.js/blob/master/LICENSE */
(function() {var b=void 0,f=!0,k=null,l=!1;function m(){return function(){}}function p(a){return function(){return this[a]}}function q(a){return function(){return a}}var s;document.createElement("video");document.createElement("audio");document.createElement("track");function t(a,c,d){if("string"===typeof a){0===a.indexOf("#")&&(a=a.slice(1));if(t.Ca[a])return t.Ca[a];a=t.w(a)}if(!a||!a.nodeName)throw new TypeError("The element or ID supplied is not valid. (videojs)");return a.player||new t.Player(a,c,d)}
var videojs=window.videojs=t;t.Vb="4.10";t.Vc="https:"==document.location.protocol?"https://":"http://";
t.options={techOrder:["html5","flash"],html5:{},flash:{},width:300,height:150,defaultVolume:0,playbackRates:[],inactivityTimeout:2E3,children:{mediaLoader:{},posterImage:{},textTrackDisplay:{},loadingSpinner:{},bigPlayButton:{},controlBar:{},errorDisplay:{}},language:document.getElementsByTagName("html")[0].getAttribute("lang")||navigator.languages&&navigator.languages[0]||navigator.ze||navigator.language||"en",languages:{},notSupportedMessage:"No compatible source was found for this video."};
"GENERATED_CDN_VSN"!==t.Vb&&(videojs.options.flash.swf=t.Vc+"vjs.zencdn.net/"+t.Vb+"/video-js.swf");t.hd=function(a,c){t.options.languages[a]=t.options.languages[a]!==b?t.ga.Va(t.options.languages[a],c):c;return t.options.languages};t.Ca={};"function"===typeof define&&define.amd?define([],function(){return videojs}):"object"===typeof exports&&"object"===typeof module&&(module.exports=videojs);t.qa=t.CoreObject=m();
t.qa.extend=function(a){var c,d;a=a||{};c=a.init||a.i||this.prototype.init||this.prototype.i||m();d=function(){c.apply(this,arguments)};d.prototype=t.g.create(this.prototype);d.prototype.constructor=d;d.extend=t.qa.extend;d.create=t.qa.create;for(var e in a)a.hasOwnProperty(e)&&(d.prototype[e]=a[e]);return d};t.qa.create=function(){var a=t.g.create(this.prototype);this.apply(a,arguments);return a};
t.c=function(a,c,d){if(t.g.isArray(c))return u(t.c,a,c,d);var e=t.getData(a);e.C||(e.C={});e.C[c]||(e.C[c]=[]);d.r||(d.r=t.r++);e.C[c].push(d);e.W||(e.disabled=l,e.W=function(c){if(!e.disabled){c=t.rc(c);var d=e.C[c.type];if(d)for(var d=d.slice(0),j=0,n=d.length;j<n&&!c.zc();j++)d[j].call(a,c)}});1==e.C[c].length&&(a.addEventListener?a.addEventListener(c,e.W,l):a.attachEvent&&a.attachEvent("on"+c,e.W))};
t.j=function(a,c,d){if(t.uc(a)){var e=t.getData(a);if(e.C){if(t.g.isArray(c))return u(t.j,a,c,d);if(c){var g=e.C[c];if(g){if(d){if(d.r)for(e=0;e<g.length;e++)g[e].r===d.r&&g.splice(e--,1)}else e.C[c]=[];t.kc(a,c)}}else for(g in e.C)c=g,e.C[c]=[],t.kc(a,c)}}};t.kc=function(a,c){var d=t.getData(a);0===d.C[c].length&&(delete d.C[c],a.removeEventListener?a.removeEventListener(c,d.W,l):a.detachEvent&&a.detachEvent("on"+c,d.W));t.Ib(d.C)&&(delete d.C,delete d.W,delete d.disabled);t.Ib(d)&&t.Ic(a)};
t.rc=function(a){function c(){return f}function d(){return l}if(!a||!a.Jb){var e=a||window.event;a={};for(var g in e)"layerX"!==g&&("layerY"!==g&&"keyLocation"!==g)&&("returnValue"==g&&e.preventDefault||(a[g]=e[g]));a.target||(a.target=a.srcElement||document);a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;a.preventDefault=function(){e.preventDefault&&e.preventDefault();a.returnValue=l;a.Cd=c;a.defaultPrevented=f};a.Cd=d;a.defaultPrevented=l;a.stopPropagation=function(){e.stopPropagation&&
e.stopPropagation();a.cancelBubble=f;a.Jb=c};a.Jb=d;a.stopImmediatePropagation=function(){e.stopImmediatePropagation&&e.stopImmediatePropagation();a.zc=c;a.stopPropagation()};a.zc=d;if(a.clientX!=k){g=document.documentElement;var h=document.body;a.pageX=a.clientX+(g&&g.scrollLeft||h&&h.scrollLeft||0)-(g&&g.clientLeft||h&&h.clientLeft||0);a.pageY=a.clientY+(g&&g.scrollTop||h&&h.scrollTop||0)-(g&&g.clientTop||h&&h.clientTop||0)}a.which=a.charCode||a.keyCode;a.button!=k&&(a.button=a.button&1?0:a.button&
4?1:a.button&2?2:0)}return a};t.l=function(a,c){var d=t.uc(a)?t.getData(a):{},e=a.parentNode||a.ownerDocument;"string"===typeof c&&(c={type:c,target:a});c=t.rc(c);d.W&&d.W.call(a,c);if(e&&!c.Jb()&&c.bubbles!==l)t.l(e,c);else if(!e&&!c.defaultPrevented&&(d=t.getData(c.target),c.target[c.type])){d.disabled=f;if("function"===typeof c.target[c.type])c.target[c.type]();d.disabled=l}return!c.defaultPrevented};
t.R=function(a,c,d){function e(){t.j(a,c,e);d.apply(this,arguments)}if(t.g.isArray(c))return u(t.R,a,c,d);e.r=d.r=d.r||t.r++;t.c(a,c,e)};function u(a,c,d,e){t.ic.forEach(d,function(d){a(c,d,e)})}var v=Object.prototype.hasOwnProperty;t.e=function(a,c){var d;c=c||{};d=document.createElement(a||"div");t.g.X(c,function(a,c){-1!==a.indexOf("aria-")||"role"==a?d.setAttribute(a,c):d[a]=c});return d};t.ba=function(a){return a.charAt(0).toUpperCase()+a.slice(1)};t.g={};
t.g.create=Object.create||function(a){function c(){}c.prototype=a;return new c};t.g.X=function(a,c,d){for(var e in a)v.call(a,e)&&c.call(d||this,e,a[e])};t.g.z=function(a,c){if(!c)return a;for(var d in c)v.call(c,d)&&(a[d]=c[d]);return a};t.g.qd=function(a,c){var d,e,g;a=t.g.copy(a);for(d in c)v.call(c,d)&&(e=a[d],g=c[d],a[d]=t.g.Ta(e)&&t.g.Ta(g)?t.g.qd(e,g):c[d]);return a};t.g.copy=function(a){return t.g.z({},a)};
t.g.Ta=function(a){return!!a&&"object"===typeof a&&"[object Object]"===a.toString()&&a.constructor===Object};t.g.isArray=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)};t.Ed=function(a){return a!==a};t.bind=function(a,c,d){function e(){return c.apply(a,arguments)}c.r||(c.r=t.r++);e.r=d?d+"_"+c.r:c.r;return e};t.va={};t.r=1;t.expando="vdata"+(new Date).getTime();t.getData=function(a){var c=a[t.expando];c||(c=a[t.expando]=t.r++,t.va[c]={});return t.va[c]};
t.uc=function(a){a=a[t.expando];return!(!a||t.Ib(t.va[a]))};t.Ic=function(a){var c=a[t.expando];if(c){delete t.va[c];try{delete a[t.expando]}catch(d){a.removeAttribute?a.removeAttribute(t.expando):a[t.expando]=k}}};t.Ib=function(a){for(var c in a)if(a[c]!==k)return l;return f};t.Sa=function(a,c){return-1!==(" "+a.className+" ").indexOf(" "+c+" ")};t.n=function(a,c){t.Sa(a,c)||(a.className=""===a.className?c:a.className+" "+c)};
t.p=function(a,c){var d,e;if(t.Sa(a,c)){d=a.className.split(" ");for(e=d.length-1;0<=e;e--)d[e]===c&&d.splice(e,1);a.className=d.join(" ")}};t.A=t.e("video");t.O=navigator.userAgent;t.bd=/iPhone/i.test(t.O);t.ad=/iPad/i.test(t.O);t.cd=/iPod/i.test(t.O);t.$c=t.bd||t.ad||t.cd;var aa=t,x;var y=t.O.match(/OS (\d+)_/i);x=y&&y[1]?y[1]:b;aa.oe=x;t.Yc=/Android/i.test(t.O);var ba=t,z;var A=t.O.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i),B,C;
A?(B=A[1]&&parseFloat(A[1]),C=A[2]&&parseFloat(A[2]),z=B&&C?parseFloat(A[1]+"."+A[2]):B?B:k):z=k;ba.Ub=z;t.dd=t.Yc&&/webkit/i.test(t.O)&&2.3>t.Ub;t.Zc=/Firefox/i.test(t.O);t.pe=/Chrome/i.test(t.O);t.ec=!!("ontouchstart"in window||window.Xc&&document instanceof window.Xc);t.Wc="backgroundSize"in t.A.style;t.Kc=function(a,c){t.g.X(c,function(c,e){e===k||"undefined"===typeof e||e===l?a.removeAttribute(c):a.setAttribute(c,e===f?"":e)})};
t.Aa=function(a){var c,d,e,g;c={};if(a&&a.attributes&&0<a.attributes.length){d=a.attributes;for(var h=d.length-1;0<=h;h--){e=d[h].name;g=d[h].value;if("boolean"===typeof a[e]||-1!==",autoplay,controls,loop,muted,default,".indexOf(","+e+","))g=g!==k?f:l;c[e]=g}}return c};
t.ve=function(a,c){var d="";document.defaultView&&document.defaultView.getComputedStyle?d=document.defaultView.getComputedStyle(a,"").getPropertyValue(c):a.currentStyle&&(d=a["client"+c.substr(0,1).toUpperCase()+c.substr(1)]+"px");return d};t.Hb=function(a,c){c.firstChild?c.insertBefore(a,c.firstChild):c.appendChild(a)};t.Oa={};t.w=function(a){0===a.indexOf("#")&&(a=a.slice(1));return document.getElementById(a)};
t.za=function(a,c){c=c||a;var d=Math.floor(a%60),e=Math.floor(a/60%60),g=Math.floor(a/3600),h=Math.floor(c/60%60),j=Math.floor(c/3600);if(isNaN(a)||Infinity===a)g=e=d="-";g=0<g||0<j?g+":":"";return g+(((g||10<=h)&&10>e?"0"+e:e)+":")+(10>d?"0"+d:d)};t.kd=function(){document.body.focus();document.onselectstart=q(l)};t.ke=function(){document.onselectstart=q(f)};t.trim=function(a){return(a+"").replace(/^\s+|\s+$/g,"")};t.round=function(a,c){c||(c=0);return Math.round(a*Math.pow(10,c))/Math.pow(10,c)};
t.zb=function(a,c){return{length:1,start:function(){return a},end:function(){return c}}};
t.get=function(a,c,d,e){var g,h,j,n;d=d||m();"undefined"===typeof XMLHttpRequest&&(window.XMLHttpRequest=function(){try{return new window.ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new window.ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(c){}try{return new window.ActiveXObject("Msxml2.XMLHTTP")}catch(d){}throw Error("This browser does not support XMLHttpRequest.");});h=new XMLHttpRequest;j=t.Xd(a);n=window.location;j.protocol+j.host!==n.protocol+n.host&&window.XDomainRequest&&!("withCredentials"in
h)?(h=new window.XDomainRequest,h.onload=function(){c(h.responseText)},h.onerror=d,h.onprogress=m(),h.ontimeout=d):(g="file:"==j.protocol||"file:"==n.protocol,h.onreadystatechange=function(){4===h.readyState&&(200===h.status||g&&0===h.status?c(h.responseText):d(h.responseText))});try{h.open("GET",a,f),e&&(h.withCredentials=f)}catch(r){d(r);return}try{h.send()}catch(w){d(w)}};
t.ae=function(a){try{var c=window.localStorage||l;c&&(c.volume=a)}catch(d){22==d.code||1014==d.code?t.log("LocalStorage Full (VideoJS)",d):18==d.code?t.log("LocalStorage not allowed (VideoJS)",d):t.log("LocalStorage Error (VideoJS)",d)}};t.tc=function(a){a.match(/^https?:\/\//)||(a=t.e("div",{innerHTML:'<a href="'+a+'">x</a>'}).firstChild.href);return a};
t.Xd=function(a){var c,d,e,g;g="protocol hostname port pathname search hash host".split(" ");d=t.e("a",{href:a});if(e=""===d.host&&"file:"!==d.protocol)c=t.e("div"),c.innerHTML='<a href="'+a+'"></a>',d=c.firstChild,c.setAttribute("style","display:none; position:absolute;"),document.body.appendChild(c);a={};for(var h=0;h<g.length;h++)a[g[h]]=d[g[h]];e&&document.body.removeChild(c);return a};
function D(a,c){var d,e;d=Array.prototype.slice.call(c);e=m();e=window.console||{log:e,warn:e,error:e};a?d.unshift(a.toUpperCase()+":"):a="log";t.log.history.push(d);d.unshift("VIDEOJS:");if(e[a].apply)e[a].apply(e,d);else e[a](d.join(" "))}t.log=function(){D(k,arguments)};t.log.history=[];t.log.error=function(){D("error",arguments)};t.log.warn=function(){D("warn",arguments)};
t.xd=function(a){var c,d;a.getBoundingClientRect&&a.parentNode&&(c=a.getBoundingClientRect());if(!c)return{left:0,top:0};a=document.documentElement;d=document.body;return{left:t.round(c.left+(window.pageXOffset||d.scrollLeft)-(a.clientLeft||d.clientLeft||0)),top:t.round(c.top+(window.pageYOffset||d.scrollTop)-(a.clientTop||d.clientTop||0))}};t.ic={};t.ic.forEach=function(a,c,d){if(t.g.isArray(a)&&c instanceof Function)for(var e=0,g=a.length;e<g;++e)c.call(d||t,a[e],e,a);return a};t.ga={};
t.ga.Va=function(a,c){var d,e,g;a=t.g.copy(a);for(d in c)c.hasOwnProperty(d)&&(e=a[d],g=c[d],a[d]=t.g.Ta(e)&&t.g.Ta(g)?t.ga.Va(e,g):c[d]);return a};
t.a=t.qa.extend({i:function(a,c,d){this.d=a;this.m=t.g.copy(this.m);c=this.options(c);this.L=c.id||c.el&&c.el.id;this.L||(this.L=(a.id&&a.id()||"no_player")+"_component_"+t.r++);this.Kd=c.name||k;this.b=c.el||this.e();this.P=[];this.Pa={};this.Qa={};this.wc();this.K(d);if(c.Jc!==l){var e,g;this.k().reportUserActivity&&(e=t.bind(this.k(),this.k().reportUserActivity),this.c("touchstart",function(){e();clearInterval(g);g=setInterval(e,250)}),a=function(){e();clearInterval(g)},this.c("touchmove",e),this.c("touchend",
a),this.c("touchcancel",a))}}});s=t.a.prototype;s.dispose=function(){this.l({type:"dispose",bubbles:l});if(this.P)for(var a=this.P.length-1;0<=a;a--)this.P[a].dispose&&this.P[a].dispose();this.Qa=this.Pa=this.P=k;this.j();this.b.parentNode&&this.b.parentNode.removeChild(this.b);t.Ic(this.b);this.b=k};s.d=f;s.k=p("d");s.options=function(a){return a===b?this.m:this.m=t.ga.Va(this.m,a)};s.e=function(a,c){return t.e(a,c)};
s.t=function(a){var c=this.d.language(),d=this.d.languages();return d&&d[c]&&d[c][a]?d[c][a]:a};s.w=p("b");s.ja=function(){return this.v||this.b};s.id=p("L");s.name=p("Kd");s.children=p("P");s.zd=function(a){return this.Pa[a]};s.ka=function(a){return this.Qa[a]};
s.V=function(a,c){var d,e;"string"===typeof a?(e=a,c=c||{},d=c.componentClass||t.ba(e),c.name=e,d=new window.videojs[d](this.d||this,c)):d=a;this.P.push(d);"function"===typeof d.id&&(this.Pa[d.id()]=d);(e=e||d.name&&d.name())&&(this.Qa[e]=d);"function"===typeof d.el&&d.el()&&this.ja().appendChild(d.el());return d};
s.removeChild=function(a){"string"===typeof a&&(a=this.ka(a));if(a&&this.P){for(var c=l,d=this.P.length-1;0<=d;d--)if(this.P[d]===a){c=f;this.P.splice(d,1);break}c&&(this.Pa[a.id]=k,this.Qa[a.name]=k,(c=a.w())&&c.parentNode===this.ja()&&this.ja().removeChild(a.w()))}};
s.wc=function(){var a,c,d,e,g,h;a=this;c=a.options();if(d=c.children)if(h=function(d,e){c[d]&&(e=c[d]);e!==l&&(a[d]=a.V(d,e))},t.g.isArray(d))for(var j=0;j<d.length;j++)e=d[j],"string"==typeof e?(g=e,e={}):g=e.name,h(g,e);else t.g.X(d,h)};s.T=q("");
s.c=function(a,c,d){var e,g,h;"string"===typeof a||t.g.isArray(a)?t.c(this.b,a,t.bind(this,c)):(e=t.bind(this,d),h=this,g=function(){h.j(a,c,e)},g.r=e.r,this.c("dispose",g),d=function(){h.j("dispose",g)},d.r=e.r,a.nodeName?(t.c(a,c,e),t.c(a,"dispose",d)):"function"===typeof a.c&&(a.c(c,e),a.c("dispose",d)));return this};
s.j=function(a,c,d){!a||"string"===typeof a||t.g.isArray(a)?t.j(this.b,a,c):(d=t.bind(this,d),this.j("dispose",d),a.nodeName?(t.j(a,c,d),t.j(a,"dispose",d)):(a.j(c,d),a.j("dispose",d)));return this};s.R=function(a,c,d){var e,g,h;"string"===typeof a||t.g.isArray(a)?t.R(this.b,a,t.bind(this,c)):(e=t.bind(this,d),g=this,h=function(){g.j(a,c,h);e.apply(this,arguments)},h.r=e.r,this.c(a,c,h));return this};s.l=function(a){t.l(this.b,a);return this};
s.K=function(a){a&&(this.la?a.call(this):(this.ab===b&&(this.ab=[]),this.ab.push(a)));return this};s.Ga=function(){this.la=f;var a=this.ab;if(a&&0<a.length){for(var c=0,d=a.length;c<d;c++)a[c].call(this);this.ab=[];this.l("ready")}};s.Sa=function(a){return t.Sa(this.b,a)};s.n=function(a){t.n(this.b,a);return this};s.p=function(a){t.p(this.b,a);return this};s.show=function(){this.b.style.display="block";return this};s.Y=function(){this.b.style.display="none";return this};
function E(a){a.p("vjs-lock-showing")}s.disable=function(){this.Y();this.show=m()};s.width=function(a,c){return F(this,"width",a,c)};s.height=function(a,c){return F(this,"height",a,c)};s.td=function(a,c){return this.width(a,f).height(c)};
function F(a,c,d,e){if(d!==b){if(d===k||t.Ed(d))d=0;a.b.style[c]=-1!==(""+d).indexOf("%")||-1!==(""+d).indexOf("px")?d:"auto"===d?"":d+"px";e||a.l("resize");return a}if(!a.b)return 0;d=a.b.style[c];e=d.indexOf("px");return-1!==e?parseInt(d.slice(0,e),10):parseInt(a.b["offset"+t.ba(c)],10)}
function G(a){var c,d,e,g,h,j,n,r;c=0;d=k;a.c("touchstart",function(a){1===a.touches.length&&(d=a.touches[0],c=(new Date).getTime(),g=f)});a.c("touchmove",function(a){1<a.touches.length?g=l:d&&(j=a.touches[0].pageX-d.pageX,n=a.touches[0].pageY-d.pageY,r=Math.sqrt(j*j+n*n),22<r&&(g=l))});h=function(){g=l};a.c("touchleave",h);a.c("touchcancel",h);a.c("touchend",function(a){d=k;g===f&&(e=(new Date).getTime()-c,250>e&&(a.preventDefault(),this.l("tap")))})}
t.u=t.a.extend({i:function(a,c){t.a.call(this,a,c);G(this);this.c("tap",this.s);this.c("click",this.s);this.c("focus",this.Ya);this.c("blur",this.Xa)}});s=t.u.prototype;
s.e=function(a,c){var d;c=t.g.z({className:this.T(),role:"button","aria-live":"polite",tabIndex:0},c);d=t.a.prototype.e.call(this,a,c);c.innerHTML||(this.v=t.e("div",{className:"vjs-control-content"}),this.xb=t.e("span",{className:"vjs-control-text",innerHTML:this.t(this.ua)||"Need Text"}),this.v.appendChild(this.xb),d.appendChild(this.v));return d};s.T=function(){return"vjs-control "+t.a.prototype.T.call(this)};s.s=m();s.Ya=function(){t.c(document,"keydown",t.bind(this,this.Z))};
s.Z=function(a){if(32==a.which||13==a.which)a.preventDefault(),this.s()};s.Xa=function(){t.j(document,"keydown",t.bind(this,this.Z))};
t.S=t.a.extend({i:function(a,c){t.a.call(this,a,c);this.jd=this.ka(this.m.barName);this.handle=this.ka(this.m.handleName);this.c("mousedown",this.Za);this.c("touchstart",this.Za);this.c("focus",this.Ya);this.c("blur",this.Xa);this.c("click",this.s);this.c(a,"controlsvisible",this.update);this.c(a,this.Ec,this.update);this.F={};this.F.move=t.bind(this,this.$a);this.F.end=t.bind(this,this.Mb)}});s=t.S.prototype;
s.dispose=function(){t.j(document,"mousemove",this.F.move,l);t.j(document,"mouseup",this.F.end,l);t.j(document,"touchmove",this.F.move,l);t.j(document,"touchend",this.F.end,l);t.j(document,"keyup",t.bind(this,this.Z));t.a.prototype.dispose.call(this)};s.e=function(a,c){c=c||{};c.className+=" vjs-slider";c=t.g.z({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0},c);return t.a.prototype.e.call(this,a,c)};
s.Za=function(a){a.preventDefault();t.kd();this.n("vjs-sliding");t.c(document,"mousemove",this.F.move);t.c(document,"mouseup",this.F.end);t.c(document,"touchmove",this.F.move);t.c(document,"touchend",this.F.end);this.$a(a)};s.$a=m();s.Mb=function(){t.ke();this.p("vjs-sliding");t.j(document,"mousemove",this.F.move,l);t.j(document,"mouseup",this.F.end,l);t.j(document,"touchmove",this.F.move,l);t.j(document,"touchend",this.F.end,l);this.update()};
s.update=function(){if(this.b){var a,c=this.Gb(),d=this.handle,e=this.jd;isNaN(c)&&(c=0);a=c;if(d){a=this.b.offsetWidth;var g=d.w().offsetWidth;a=g?g/a:0;c*=1-a;a=c+a/2;d.w().style.left=t.round(100*c,2)+"%"}e&&(e.w().style.width=t.round(100*a,2)+"%")}};
function H(a,c){var d,e,g,h;d=a.b;e=t.xd(d);h=g=d.offsetWidth;d=a.handle;if(a.options().vertical)return h=e.top,e=c.changedTouches?c.changedTouches[0].pageY:c.pageY,d&&(d=d.w().offsetHeight,h+=d/2,g-=d),Math.max(0,Math.min(1,(h-e+g)/g));g=e.left;e=c.changedTouches?c.changedTouches[0].pageX:c.pageX;d&&(d=d.w().offsetWidth,g+=d/2,h-=d);return Math.max(0,Math.min(1,(e-g)/h))}s.Ya=function(){t.c(document,"keyup",t.bind(this,this.Z))};
s.Z=function(a){if(37==a.which||40==a.which)a.preventDefault(),this.Nc();else if(38==a.which||39==a.which)a.preventDefault(),this.Oc()};s.Xa=function(){t.j(document,"keyup",t.bind(this,this.Z))};s.s=function(a){a.stopImmediatePropagation();a.preventDefault()};t.$=t.a.extend();t.$.prototype.defaultValue=0;
t.$.prototype.e=function(a,c){c=c||{};c.className+=" vjs-slider-handle";c=t.g.z({innerHTML:'<span class="vjs-control-text">'+this.defaultValue+"</span>"},c);return t.a.prototype.e.call(this,"div",c)};t.ha=t.a.extend();function ca(a,c){a.V(c);c.c("click",t.bind(a,function(){E(this)}))}
t.ha.prototype.e=function(){var a=this.options().lc||"ul";this.v=t.e(a,{className:"vjs-menu-content"});a=t.a.prototype.e.call(this,"div",{append:this.v,className:"vjs-menu"});a.appendChild(this.v);t.c(a,"click",function(a){a.preventDefault();a.stopImmediatePropagation()});return a};t.J=t.u.extend({i:function(a,c){t.u.call(this,a,c);this.selected(c.selected)}});t.J.prototype.e=function(a,c){return t.u.prototype.e.call(this,"li",t.g.z({className:"vjs-menu-item",innerHTML:this.m.label},c))};
t.J.prototype.s=function(){this.selected(f)};t.J.prototype.selected=function(a){a?(this.n("vjs-selected"),this.b.setAttribute("aria-selected",f)):(this.p("vjs-selected"),this.b.setAttribute("aria-selected",l))};t.N=t.u.extend({i:function(a,c){t.u.call(this,a,c);this.Ba=this.xa();this.V(this.Ba);this.Q&&0===this.Q.length&&this.Y();this.c("keyup",this.Z);this.b.setAttribute("aria-haspopup",f);this.b.setAttribute("role","button")}});s=t.N.prototype;s.ta=l;
s.xa=function(){var a=new t.ha(this.d);this.options().title&&a.ja().appendChild(t.e("li",{className:"vjs-menu-title",innerHTML:t.ba(this.options().title),he:-1}));if(this.Q=this.createItems())for(var c=0;c<this.Q.length;c++)ca(a,this.Q[c]);return a};s.wa=m();s.T=function(){return this.className+" vjs-menu-button "+t.u.prototype.T.call(this)};s.Ya=m();s.Xa=m();s.s=function(){this.R("mouseout",t.bind(this,function(){E(this.Ba);this.b.blur()}));this.ta?I(this):J(this)};
s.Z=function(a){a.preventDefault();32==a.which||13==a.which?this.ta?I(this):J(this):27==a.which&&this.ta&&I(this)};function J(a){a.ta=f;a.Ba.n("vjs-lock-showing");a.b.setAttribute("aria-pressed",f);a.Q&&0<a.Q.length&&a.Q[0].w().focus()}function I(a){a.ta=l;E(a.Ba);a.b.setAttribute("aria-pressed",l)}t.D=function(a){"number"===typeof a?this.code=a:"string"===typeof a?this.message=a:"object"===typeof a&&t.g.z(this,a);this.message||(this.message=t.D.rd[this.code]||"")};t.D.prototype.code=0;
t.D.prototype.message="";t.D.prototype.status=k;t.D.Ra="MEDIA_ERR_CUSTOM MEDIA_ERR_ABORTED MEDIA_ERR_NETWORK MEDIA_ERR_DECODE MEDIA_ERR_SRC_NOT_SUPPORTED MEDIA_ERR_ENCRYPTED".split(" ");
t.D.rd={1:"You aborted the video playback",2:"A network error caused the video download to fail part-way.",3:"The video playback was aborted due to a corruption problem or because the video used features your browser did not support.",4:"The video could not be loaded, either because the server or network failed or because the format is not supported.",5:"The video is encrypted and we do not have the keys to decrypt it."};for(var K=0;K<t.D.Ra.length;K++)t.D[t.D.Ra[K]]=K,t.D.prototype[t.D.Ra[K]]=K;
var L,M,N,O;
L=["requestFullscreen exitFullscreen fullscreenElement fullscreenEnabled fullscreenchange fullscreenerror".split(" "),"webkitRequestFullscreen webkitExitFullscreen webkitFullscreenElement webkitFullscreenEnabled webkitfullscreenchange webkitfullscreenerror".split(" "),"webkitRequestFullScreen webkitCancelFullScreen webkitCurrentFullScreenElement webkitCancelFullScreen webkitfullscreenchange webkitfullscreenerror".split(" "),"mozRequestFullScreen mozCancelFullScreen mozFullScreenElement mozFullScreenEnabled mozfullscreenchange mozfullscreenerror".split(" "),"msRequestFullscreen msExitFullscreen msFullscreenElement msFullscreenEnabled MSFullscreenChange MSFullscreenError".split(" ")];
M=L[0];for(O=0;O<L.length;O++)if(L[O][1]in document){N=L[O];break}if(N){t.Oa.Fb={};for(O=0;O<N.length;O++)t.Oa.Fb[M[O]]=N[O]}
t.Player=t.a.extend({i:function(a,c,d){this.I=a;a.id=a.id||"vjs_video_"+t.r++;this.ie=a&&t.Aa(a);c=t.g.z(da(a),c);this.Ua=c.language||t.options.language;this.Id=c.languages||t.options.languages;this.G={};this.Fc=c.poster||"";this.yb=!!c.controls;a.controls=l;c.Jc=l;P(this,"audio"===this.I.nodeName.toLowerCase());t.a.call(this,this,c,d);this.controls()?this.n("vjs-controls-enabled"):this.n("vjs-controls-disabled");P(this)&&this.n("vjs-audio");t.Ca[this.L]=this;c.plugins&&t.g.X(c.plugins,function(a,
c){this[a](c)},this);var e,g,h,j,n,r;e=t.bind(this,this.reportUserActivity);this.c("mousedown",function(){e();clearInterval(g);g=setInterval(e,250)});this.c("mousemove",function(a){if(a.screenX!=n||a.screenY!=r)n=a.screenX,r=a.screenY,e()});this.c("mouseup",function(){e();clearInterval(g)});this.c("keydown",e);this.c("keyup",e);h=setInterval(t.bind(this,function(){if(this.pa){this.pa=l;this.userActive(f);clearTimeout(j);var a=this.options().inactivityTimeout;0<a&&(j=setTimeout(t.bind(this,function(){this.pa||
this.userActive(l)}),a))}}),250);this.c("dispose",function(){clearInterval(h);clearTimeout(j)})}});s=t.Player.prototype;s.language=function(a){if(a===b)return this.Ua;this.Ua=a;return this};s.languages=p("Id");s.m=t.options;s.dispose=function(){this.l("dispose");this.j("dispose");t.Ca[this.L]=k;this.I&&this.I.player&&(this.I.player=k);this.b&&this.b.player&&(this.b.player=k);this.o&&this.o.dispose();t.a.prototype.dispose.call(this)};
function da(a){var c,d,e={sources:[],tracks:[]};c=t.Aa(a);d=c["data-setup"];d!==k&&t.g.z(c,t.JSON.parse(d||"{}"));t.g.z(e,c);if(a.hasChildNodes()){var g,h;a=a.childNodes;g=0;for(h=a.length;g<h;g++)c=a[g],d=c.nodeName.toLowerCase(),"source"===d?e.sources.push(t.Aa(c)):"track"===d&&e.tracks.push(t.Aa(c))}return e}
s.e=function(){var a=this.b=t.a.prototype.e.call(this,"div"),c=this.I,d;c.removeAttribute("width");c.removeAttribute("height");if(c.hasChildNodes()){var e,g,h,j,n;e=c.childNodes;g=e.length;for(n=[];g--;)h=e[g],j=h.nodeName.toLowerCase(),"track"===j&&n.push(h);for(e=0;e<n.length;e++)c.removeChild(n[e])}d=t.Aa(c);t.g.X(d,function(c){"class"==c?a.className=d[c]:a.setAttribute(c,d[c])});c.id+="_html5_api";c.className="vjs-tech";c.player=a.player=this;this.n("vjs-paused");this.width(this.m.width,f);this.height(this.m.height,
f);c.Bd=c.networkState;c.parentNode&&c.parentNode.insertBefore(a,c);t.Hb(c,a);this.b=a;this.c("loadstart",this.Pd);this.c("waiting",this.Vd);this.c(["canplay","canplaythrough","playing","ended"],this.Ud);this.c("seeking",this.Sd);this.c("seeked",this.Rd);this.c("ended",this.Ld);this.c("play",this.Ob);this.c("firstplay",this.Nd);this.c("pause",this.Nb);this.c("progress",this.Qd);this.c("durationchange",this.Cc);this.c("fullscreenchange",this.Od);return a};
function Q(a,c,d){a.o&&(a.la=l,a.o.dispose(),a.o=l);"Html5"!==c&&a.I&&(t.h.Bb(a.I),a.I=k);a.eb=c;a.la=l;var e=t.g.z({source:d,parentEl:a.b},a.m[c.toLowerCase()]);d&&(a.nc=d.type,d.src==a.G.src&&0<a.G.currentTime&&(e.startTime=a.G.currentTime),a.G.src=d.src);a.o=new window.videojs[c](a,e);a.o.K(function(){this.d.Ga()})}s.Pd=function(){this.error(k);this.paused()?(R(this,l),this.R("play",function(){R(this,f)})):this.l("firstplay")};s.vc=l;
function R(a,c){c!==b&&a.vc!==c&&((a.vc=c)?(a.n("vjs-has-started"),a.l("firstplay")):a.p("vjs-has-started"))}s.Ob=function(){this.p("vjs-paused");this.n("vjs-playing")};s.Vd=function(){this.n("vjs-waiting")};s.Ud=function(){this.p("vjs-waiting")};s.Sd=function(){this.n("vjs-seeking")};s.Rd=function(){this.p("vjs-seeking")};s.Nd=function(){this.m.starttime&&this.currentTime(this.m.starttime);this.n("vjs-has-started")};s.Nb=function(){this.p("vjs-playing");this.n("vjs-paused")};
s.Qd=function(){1==this.bufferedPercent()&&this.l("loadedalldata")};s.Ld=function(){this.m.loop?(this.currentTime(0),this.play()):this.paused()||this.pause()};s.Cc=function(){var a=S(this,"duration");a&&(0>a&&(a=Infinity),this.duration(a),Infinity===a?this.n("vjs-live"):this.p("vjs-live"))};s.Od=function(){this.isFullscreen()?this.n("vjs-fullscreen"):this.p("vjs-fullscreen")};function T(a,c,d){if(a.o&&!a.o.la)a.o.K(function(){this[c](d)});else try{a.o[c](d)}catch(e){throw t.log(e),e;}}
function S(a,c){if(a.o&&a.o.la)try{return a.o[c]()}catch(d){throw a.o[c]===b?t.log("Video.js: "+c+" method not defined for "+a.eb+" playback technology.",d):"TypeError"==d.name?(t.log("Video.js: "+c+" unavailable on "+a.eb+" playback technology element.",d),a.o.la=l):t.log(d),d;}}s.play=function(){T(this,"play");return this};s.pause=function(){T(this,"pause");return this};s.paused=function(){return S(this,"paused")===l?l:f};
s.currentTime=function(a){return a!==b?(T(this,"setCurrentTime",a),this):this.G.currentTime=S(this,"currentTime")||0};s.duration=function(a){if(a!==b)return this.G.duration=parseFloat(a),this;this.G.duration===b&&this.Cc();return this.G.duration||0};s.remainingTime=function(){return this.duration()-this.currentTime()};s.buffered=function(){var a=S(this,"buffered");if(!a||!a.length)a=t.zb(0,0);return a};
s.bufferedPercent=function(){var a=this.duration(),c=this.buffered(),d=0,e,g;if(!a)return 0;for(var h=0;h<c.length;h++)e=c.start(h),g=c.end(h),g>a&&(g=a),d+=g-e;return d/a};s.volume=function(a){if(a!==b)return a=Math.max(0,Math.min(1,parseFloat(a))),this.G.volume=a,T(this,"setVolume",a),t.ae(a),this;a=parseFloat(S(this,"volume"));return isNaN(a)?1:a};s.muted=function(a){return a!==b?(T(this,"setMuted",a),this):S(this,"muted")||l};s.Ea=function(){return S(this,"supportsFullScreen")||l};s.yc=l;
s.isFullscreen=function(a){return a!==b?(this.yc=!!a,this):this.yc};s.isFullScreen=function(a){t.log.warn('player.isFullScreen() has been deprecated, use player.isFullscreen() with a lowercase "s")');return this.isFullscreen(a)};
s.requestFullscreen=function(){var a=t.Oa.Fb;this.isFullscreen(f);a?(t.c(document,a.fullscreenchange,t.bind(this,function(c){this.isFullscreen(document[a.fullscreenElement]);this.isFullscreen()===l&&t.j(document,a.fullscreenchange,arguments.callee);this.l("fullscreenchange")})),this.b[a.requestFullscreen]()):this.o.Ea()?T(this,"enterFullScreen"):(this.qc(),this.l("fullscreenchange"));return this};
s.requestFullScreen=function(){t.log.warn('player.requestFullScreen() has been deprecated, use player.requestFullscreen() with a lowercase "s")');return this.requestFullscreen()};s.exitFullscreen=function(){var a=t.Oa.Fb;this.isFullscreen(l);if(a)document[a.exitFullscreen]();else this.o.Ea()?T(this,"exitFullScreen"):(this.Cb(),this.l("fullscreenchange"));return this};s.cancelFullScreen=function(){t.log.warn("player.cancelFullScreen() has been deprecated, use player.exitFullscreen()");return this.exitFullscreen()};
s.qc=function(){this.Dd=f;this.ud=document.documentElement.style.overflow;t.c(document,"keydown",t.bind(this,this.sc));document.documentElement.style.overflow="hidden";t.n(document.body,"vjs-full-window");this.l("enterFullWindow")};s.sc=function(a){27===a.keyCode&&(this.isFullscreen()===f?this.exitFullscreen():this.Cb())};s.Cb=function(){this.Dd=l;t.j(document,"keydown",this.sc);document.documentElement.style.overflow=this.ud;t.p(document.body,"vjs-full-window");this.l("exitFullWindow")};
s.selectSource=function(a){for(var c=0,d=this.m.techOrder;c<d.length;c++){var e=t.ba(d[c]),g=window.videojs[e];if(g){if(g.isSupported())for(var h=0,j=a;h<j.length;h++){var n=j[h];if(g.canPlaySource(n))return{source:n,o:e}}}else t.log.error('The "'+e+'" tech is undefined. Skipped browser support check for that tech.')}return l};
s.src=function(a){if(a===b)return S(this,"src");t.g.isArray(a)?U(this,a):"string"===typeof a?this.src({src:a}):a instanceof Object&&(a.type&&!window.videojs[this.eb].canPlaySource(a)?U(this,[a]):(this.G.src=a.src,this.nc=a.type||"",this.K(function(){T(this,"src",a.src);"auto"==this.m.preload&&this.load();this.m.autoplay&&this.play()})));return this};
function U(a,c){var d=a.selectSource(c),e;d?d.o===a.eb?a.src(d.source):Q(a,d.o,d.source):(e=setTimeout(t.bind(a,function(){this.error({code:4,message:this.t(this.options().notSupportedMessage)})}),0),a.Ga(),a.c("dispose",function(){clearTimeout(e)}))}s.load=function(){T(this,"load");return this};s.currentSrc=function(){return S(this,"currentSrc")||this.G.src||""};s.pd=function(){return this.nc||""};s.Da=function(a){return a!==b?(T(this,"setPreload",a),this.m.preload=a,this):S(this,"preload")};
s.autoplay=function(a){return a!==b?(T(this,"setAutoplay",a),this.m.autoplay=a,this):S(this,"autoplay")};s.loop=function(a){return a!==b?(T(this,"setLoop",a),this.m.loop=a,this):S(this,"loop")};s.poster=function(a){if(a===b)return this.Fc;a||(a="");this.Fc=a;T(this,"setPoster",a);this.l("posterchange");return this};
s.controls=function(a){return a!==b?(a=!!a,this.yb!==a&&((this.yb=a)?(this.p("vjs-controls-disabled"),this.n("vjs-controls-enabled"),this.l("controlsenabled")):(this.p("vjs-controls-enabled"),this.n("vjs-controls-disabled"),this.l("controlsdisabled"))),this):this.yb};t.Player.prototype.Tb;s=t.Player.prototype;
s.usingNativeControls=function(a){return a!==b?(a=!!a,this.Tb!==a&&((this.Tb=a)?(this.n("vjs-using-native-controls"),this.l("usingnativecontrols")):(this.p("vjs-using-native-controls"),this.l("usingcustomcontrols"))),this):this.Tb};s.da=k;s.error=function(a){if(a===b)return this.da;if(a===k)return this.da=a,this.p("vjs-error"),this;this.da=a instanceof t.D?a:new t.D(a);this.l("error");this.n("vjs-error");t.log.error("(CODE:"+this.da.code+" "+t.D.Ra[this.da.code]+")",this.da.message,this.da);return this};
s.ended=function(){return S(this,"ended")};s.seeking=function(){return S(this,"seeking")};s.pa=f;s.reportUserActivity=function(){this.pa=f};s.Sb=f;s.userActive=function(a){return a!==b?(a=!!a,a!==this.Sb&&((this.Sb=a)?(this.pa=f,this.p("vjs-user-inactive"),this.n("vjs-user-active"),this.l("useractive")):(this.pa=l,this.o&&this.o.R("mousemove",function(a){a.stopPropagation();a.preventDefault()}),this.p("vjs-user-active"),this.n("vjs-user-inactive"),this.l("userinactive"))),this):this.Sb};
s.playbackRate=function(a){return a!==b?(T(this,"setPlaybackRate",a),this):this.o&&this.o.featuresPlaybackRate?S(this,"playbackRate"):1};s.xc=l;function P(a,c){return c!==b?(a.xc=!!c,a):a.xc}t.Ja=t.a.extend();t.Ja.prototype.m={we:"play",children:{playToggle:{},currentTimeDisplay:{},timeDivider:{},durationDisplay:{},remainingTimeDisplay:{},liveDisplay:{},progressControl:{},fullscreenToggle:{},volumeControl:{},muteToggle:{},playbackRateMenuButton:{}}};t.Ja.prototype.e=function(){return t.e("div",{className:"vjs-control-bar"})};
t.Yb=t.a.extend({i:function(a,c){t.a.call(this,a,c)}});t.Yb.prototype.e=function(){var a=t.a.prototype.e.call(this,"div",{className:"vjs-live-controls vjs-control"});this.v=t.e("div",{className:"vjs-live-display",innerHTML:'<span class="vjs-control-text">'+this.t("Stream Type")+"</span>"+this.t("LIVE"),"aria-live":"off"});a.appendChild(this.v);return a};t.ac=t.u.extend({i:function(a,c){t.u.call(this,a,c);this.c(a,"play",this.Ob);this.c(a,"pause",this.Nb)}});s=t.ac.prototype;s.ua="Play";
s.T=function(){return"vjs-play-control "+t.u.prototype.T.call(this)};s.s=function(){this.d.paused()?this.d.play():this.d.pause()};s.Ob=function(){this.p("vjs-paused");this.n("vjs-playing");this.b.children[0].children[0].innerHTML=this.t("Pause")};s.Nb=function(){this.p("vjs-playing");this.n("vjs-paused");this.b.children[0].children[0].innerHTML=this.t("Play")};t.hb=t.a.extend({i:function(a,c){t.a.call(this,a,c);this.c(a,"timeupdate",this.fa)}});
t.hb.prototype.e=function(){var a=t.a.prototype.e.call(this,"div",{className:"vjs-current-time vjs-time-controls vjs-control"});this.v=t.e("div",{className:"vjs-current-time-display",innerHTML:'<span class="vjs-control-text">Current Time </span>0:00',"aria-live":"off"});a.appendChild(this.v);return a};t.hb.prototype.fa=function(){var a=this.d.bb?this.d.G.currentTime:this.d.currentTime();this.v.innerHTML='<span class="vjs-control-text">'+this.t("Current Time")+"</span> "+t.za(a,this.d.duration())};
t.ib=t.a.extend({i:function(a,c){t.a.call(this,a,c);this.c(a,"timeupdate",this.fa)}});t.ib.prototype.e=function(){var a=t.a.prototype.e.call(this,"div",{className:"vjs-duration vjs-time-controls vjs-control"});this.v=t.e("div",{className:"vjs-duration-display",innerHTML:'<span class="vjs-control-text">'+this.t("Duration Time")+"</span> 0:00","aria-live":"off"});a.appendChild(this.v);return a};
t.ib.prototype.fa=function(){var a=this.d.duration();a&&(this.v.innerHTML='<span class="vjs-control-text">'+this.t("Duration Time")+"</span> "+t.za(a))};t.gc=t.a.extend({i:function(a,c){t.a.call(this,a,c)}});t.gc.prototype.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-time-divider",innerHTML:"<div><span>/</span></div>"})};t.pb=t.a.extend({i:function(a,c){t.a.call(this,a,c);this.c(a,"timeupdate",this.fa)}});
t.pb.prototype.e=function(){var a=t.a.prototype.e.call(this,"div",{className:"vjs-remaining-time vjs-time-controls vjs-control"});this.v=t.e("div",{className:"vjs-remaining-time-display",innerHTML:'<span class="vjs-control-text">'+this.t("Remaining Time")+"</span> -0:00","aria-live":"off"});a.appendChild(this.v);return a};t.pb.prototype.fa=function(){this.d.duration()&&(this.v.innerHTML='<span class="vjs-control-text">'+this.t("Remaining Time")+"</span> -"+t.za(this.d.remainingTime()))};
t.Ka=t.u.extend({i:function(a,c){t.u.call(this,a,c)}});t.Ka.prototype.ua="Fullscreen";t.Ka.prototype.T=function(){return"vjs-fullscreen-control "+t.u.prototype.T.call(this)};t.Ka.prototype.s=function(){this.d.isFullscreen()?(this.d.exitFullscreen(),this.xb.innerHTML=this.t("Fullscreen")):(this.d.requestFullscreen(),this.xb.innerHTML=this.t("Non-Fullscreen"))};t.ob=t.a.extend({i:function(a,c){t.a.call(this,a,c)}});t.ob.prototype.m={children:{seekBar:{}}};
t.ob.prototype.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-progress-control vjs-control"})};t.cc=t.S.extend({i:function(a,c){t.S.call(this,a,c);this.c(a,"timeupdate",this.oa);a.K(t.bind(this,this.oa))}});s=t.cc.prototype;s.m={children:{loadProgressBar:{},playProgressBar:{},seekHandle:{}},barName:"playProgressBar",handleName:"seekHandle"};s.Ec="timeupdate";s.e=function(){return t.S.prototype.e.call(this,"div",{className:"vjs-progress-holder","aria-label":"video progress bar"})};
s.oa=function(){var a=this.d.bb?this.d.G.currentTime:this.d.currentTime();this.b.setAttribute("aria-valuenow",t.round(100*this.Gb(),2));this.b.setAttribute("aria-valuetext",t.za(a,this.d.duration()))};s.Gb=function(){return this.d.currentTime()/this.d.duration()};s.Za=function(a){t.S.prototype.Za.call(this,a);this.d.bb=f;this.me=!this.d.paused();this.d.pause()};s.$a=function(a){a=H(this,a)*this.d.duration();a==this.d.duration()&&(a-=0.1);this.d.currentTime(a)};
s.Mb=function(a){t.S.prototype.Mb.call(this,a);this.d.bb=l;this.me&&this.d.play()};s.Oc=function(){this.d.currentTime(this.d.currentTime()+5)};s.Nc=function(){this.d.currentTime(this.d.currentTime()-5)};t.lb=t.a.extend({i:function(a,c){t.a.call(this,a,c);this.c(a,"progress",this.update)}});t.lb.prototype.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-load-progress",innerHTML:'<span class="vjs-control-text"><span>'+this.t("Loaded")+"</span>: 0%</span>"})};
t.lb.prototype.update=function(){var a,c,d,e,g=this.d.buffered();a=this.d.duration();var h,j=this.d;h=j.buffered();j=j.duration();h=h.end(h.length-1);h>j&&(h=j);j=this.b.children;this.b.style.width=100*(h/a||0)+"%";for(a=0;a<g.length;a++)c=g.start(a),d=g.end(a),(e=j[a])||(e=this.b.appendChild(t.e())),e.style.left=100*(c/h||0)+"%",e.style.width=100*((d-c)/h||0)+"%";for(a=j.length;a>g.length;a--)this.b.removeChild(j[a-1])};t.$b=t.a.extend({i:function(a,c){t.a.call(this,a,c)}});
t.$b.prototype.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-play-progress",innerHTML:'<span class="vjs-control-text"><span>'+this.t("Progress")+"</span>: 0%</span>"})};t.La=t.$.extend({i:function(a,c){t.$.call(this,a,c);this.c(a,"timeupdate",this.fa)}});t.La.prototype.defaultValue="00:00";t.La.prototype.e=function(){return t.$.prototype.e.call(this,"div",{className:"vjs-seek-handle","aria-live":"off"})};
t.La.prototype.fa=function(){var a=this.d.bb?this.d.G.currentTime:this.d.currentTime();this.b.innerHTML='<span class="vjs-control-text">'+t.za(a,this.d.duration())+"</span>"};t.rb=t.a.extend({i:function(a,c){t.a.call(this,a,c);a.o&&a.o.featuresVolumeControl===l&&this.n("vjs-hidden");this.c(a,"loadstart",function(){a.o.featuresVolumeControl===l?this.n("vjs-hidden"):this.p("vjs-hidden")})}});t.rb.prototype.m={children:{volumeBar:{}}};
t.rb.prototype.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-volume-control vjs-control"})};t.qb=t.S.extend({i:function(a,c){t.S.call(this,a,c);this.c(a,"volumechange",this.oa);a.K(t.bind(this,this.oa))}});s=t.qb.prototype;s.oa=function(){this.b.setAttribute("aria-valuenow",t.round(100*this.d.volume(),2));this.b.setAttribute("aria-valuetext",t.round(100*this.d.volume(),2)+"%")};s.m={children:{volumeLevel:{},volumeHandle:{}},barName:"volumeLevel",handleName:"volumeHandle"};
s.Ec="volumechange";s.e=function(){return t.S.prototype.e.call(this,"div",{className:"vjs-volume-bar","aria-label":"volume level"})};s.$a=function(a){this.d.muted()&&this.d.muted(l);this.d.volume(H(this,a))};s.Gb=function(){return this.d.muted()?0:this.d.volume()};s.Oc=function(){this.d.volume(this.d.volume()+0.1)};s.Nc=function(){this.d.volume(this.d.volume()-0.1)};t.hc=t.a.extend({i:function(a,c){t.a.call(this,a,c)}});
t.hc.prototype.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-volume-level",innerHTML:'<span class="vjs-control-text"></span>'})};t.sb=t.$.extend();t.sb.prototype.defaultValue="00:00";t.sb.prototype.e=function(){return t.$.prototype.e.call(this,"div",{className:"vjs-volume-handle"})};
t.ia=t.u.extend({i:function(a,c){t.u.call(this,a,c);this.c(a,"volumechange",this.update);a.o&&a.o.featuresVolumeControl===l&&this.n("vjs-hidden");this.c(a,"loadstart",function(){a.o.featuresVolumeControl===l?this.n("vjs-hidden"):this.p("vjs-hidden")})}});t.ia.prototype.e=function(){return t.u.prototype.e.call(this,"div",{className:"vjs-mute-control vjs-control",innerHTML:'<div><span class="vjs-control-text">'+this.t("Mute")+"</span></div>"})};
t.ia.prototype.s=function(){this.d.muted(this.d.muted()?l:f)};t.ia.prototype.update=function(){var a=this.d.volume(),c=3;0===a||this.d.muted()?c=0:0.33>a?c=1:0.67>a&&(c=2);this.d.muted()?this.b.children[0].children[0].innerHTML!=this.t("Unmute")&&(this.b.children[0].children[0].innerHTML=this.t("Unmute")):this.b.children[0].children[0].innerHTML!=this.t("Mute")&&(this.b.children[0].children[0].innerHTML=this.t("Mute"));for(a=0;4>a;a++)t.p(this.b,"vjs-vol-"+a);t.n(this.b,"vjs-vol-"+c)};
t.sa=t.N.extend({i:function(a,c){t.N.call(this,a,c);this.c(a,"volumechange",this.update);a.o&&a.o.featuresVolumeControl===l&&this.n("vjs-hidden");this.c(a,"loadstart",function(){a.o.featuresVolumeControl===l?this.n("vjs-hidden"):this.p("vjs-hidden")});this.n("vjs-menu-button")}});t.sa.prototype.xa=function(){var a=new t.ha(this.d,{lc:"div"}),c=new t.qb(this.d,this.m.Ae);c.c("focus",function(){a.n("vjs-lock-showing")});c.c("blur",function(){E(a)});a.V(c);return a};
t.sa.prototype.s=function(){t.ia.prototype.s.call(this);t.N.prototype.s.call(this)};t.sa.prototype.e=function(){return t.u.prototype.e.call(this,"div",{className:"vjs-volume-menu-button vjs-menu-button vjs-control",innerHTML:'<div><span class="vjs-control-text">'+this.t("Mute")+"</span></div>"})};t.sa.prototype.update=t.ia.prototype.update;t.bc=t.N.extend({i:function(a,c){t.N.call(this,a,c);this.Tc();this.Sc();this.c(a,"loadstart",this.Tc);this.c(a,"ratechange",this.Sc)}});s=t.bc.prototype;
s.e=function(){var a=t.a.prototype.e.call(this,"div",{className:"vjs-playback-rate vjs-menu-button vjs-control",innerHTML:'<div class="vjs-control-content"><span class="vjs-control-text">'+this.t("Playback Rate")+"</span></div>"});this.Ac=t.e("div",{className:"vjs-playback-rate-value",innerHTML:1});a.appendChild(this.Ac);return a};s.xa=function(){var a=new t.ha(this.k()),c=this.k().options().playbackRates;if(c)for(var d=c.length-1;0<=d;d--)a.V(new t.nb(this.k(),{rate:c[d]+"x"}));return a};
s.oa=function(){this.w().setAttribute("aria-valuenow",this.k().playbackRate())};s.s=function(){for(var a=this.k().playbackRate(),c=this.k().options().playbackRates,d=c[0],e=0;e<c.length;e++)if(c[e]>a){d=c[e];break}this.k().playbackRate(d)};function ea(a){return a.k().o&&a.k().o.featuresPlaybackRate&&a.k().options().playbackRates&&0<a.k().options().playbackRates.length}s.Tc=function(){ea(this)?this.p("vjs-hidden"):this.n("vjs-hidden")};
s.Sc=function(){ea(this)&&(this.Ac.innerHTML=this.k().playbackRate()+"x")};t.nb=t.J.extend({lc:"button",i:function(a,c){var d=this.label=c.rate,e=this.Hc=parseFloat(d,10);c.label=d;c.selected=1===e;t.J.call(this,a,c);this.c(a,"ratechange",this.update)}});t.nb.prototype.s=function(){t.J.prototype.s.call(this);this.k().playbackRate(this.Hc)};t.nb.prototype.update=function(){this.selected(this.k().playbackRate()==this.Hc)};
t.ra=t.u.extend({i:function(a,c){t.u.call(this,a,c);this.update();a.c("posterchange",t.bind(this,this.update))}});t.ra.prototype.dispose=function(){this.k().j("posterchange",this.update);t.u.prototype.dispose.call(this)};t.ra.prototype.e=function(){var a=t.e("div",{className:"vjs-poster",tabIndex:-1});t.Wc||(this.Db=t.e("img"),a.appendChild(this.Db));return a};
t.ra.prototype.update=function(){var a=this.k().poster(),c;this.Db?this.Db.src=a:(c="",a&&(c='url("'+a+'")'),this.b.style.backgroundImage=c);a?this.b.style.display="":this.Y()};t.ra.prototype.s=function(){this.d.play()};t.Zb=t.a.extend({i:function(a,c){t.a.call(this,a,c)}});t.Zb.prototype.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-loading-spinner"})};t.fb=t.u.extend();
t.fb.prototype.e=function(){return t.u.prototype.e.call(this,"div",{className:"vjs-big-play-button",innerHTML:'<span aria-hidden="true"></span>',"aria-label":"play video"})};t.fb.prototype.s=function(){this.d.play()};t.jb=t.a.extend({i:function(a,c){t.a.call(this,a,c);this.update();this.c(a,"error",this.update)}});t.jb.prototype.e=function(){var a=t.a.prototype.e.call(this,"div",{className:"vjs-error-display"});this.v=t.e("div");a.appendChild(this.v);return a};
t.jb.prototype.update=function(){this.k().error()&&(this.v.innerHTML=this.t(this.k().error().message))};
t.q=t.a.extend({i:function(a,c,d){c=c||{};c.Jc=l;t.a.call(this,a,c,d);this.featuresProgressEvents||(this.Bc=f,this.Gc=setInterval(t.bind(this,function(){var a=this.k().bufferedPercent();this.ld!=a&&this.k().l("progress");this.ld=a;1===a&&clearInterval(this.Gc)}),500));this.featuresTimeupdateEvents||(a=this.d,this.Lb=f,this.c(a,"play",this.Rc),this.c(a,"pause",this.cb),this.R("timeupdate",function(){this.featuresTimeupdateEvents=f;fa(this)}));var e;e=this.k();a=function(){if(e.controls()&&!e.usingNativeControls()){var a;
this.c("mousedown",this.s);this.c("touchstart",function(){a=this.d.userActive()});this.c("touchmove",function(){a&&this.k().reportUserActivity()});this.c("touchend",function(a){a.preventDefault()});G(this);this.c("tap",this.Td)}};this.K(a);this.c(e,"controlsenabled",a);this.c(e,"controlsdisabled",this.Zd);this.K(function(){this.networkState&&0<this.networkState()&&this.k().l("loadstart")})}});s=t.q.prototype;
s.Zd=function(){this.j("tap");this.j("touchstart");this.j("touchmove");this.j("touchleave");this.j("touchcancel");this.j("touchend");this.j("click");this.j("mousedown")};s.s=function(a){0===a.button&&this.k().controls()&&(this.k().paused()?this.k().play():this.k().pause())};s.Td=function(){this.k().userActive(!this.k().userActive())};function fa(a){a.Lb=l;a.cb();a.j("play",a.Rc);a.j("pause",a.cb)}
s.Rc=function(){this.mc&&this.cb();this.mc=setInterval(t.bind(this,function(){this.k().l("timeupdate")}),250)};s.cb=function(){clearInterval(this.mc);this.k().l("timeupdate")};s.dispose=function(){this.Bc&&(this.Bc=l,clearInterval(this.Gc));this.Lb&&fa(this);t.a.prototype.dispose.call(this)};s.Qb=function(){this.Lb&&this.k().l("timeupdate")};s.Lc=m();t.q.prototype.featuresVolumeControl=f;t.q.prototype.featuresFullscreenResize=l;t.q.prototype.featuresPlaybackRate=l;
t.q.prototype.featuresProgressEvents=l;t.q.prototype.featuresTimeupdateEvents=l;t.media={};
t.h=t.q.extend({i:function(a,c,d){this.featuresVolumeControl=t.h.nd();this.featuresPlaybackRate=t.h.md();this.movingMediaElementInDOM=!t.$c;this.featuresProgressEvents=this.featuresFullscreenResize=f;t.q.call(this,a,c,d);for(d=t.h.kb.length-1;0<=d;d--)this.c(t.h.kb[d],this.vd);if((c=c.source)&&this.b.currentSrc!==c.src||a.I&&3===a.I.Bd)this.b.src=c.src;if(t.ec&&a.options().nativeControlsForTouch===f){alert("useNativeControls");var e,g,h,j;e=this;g=this.k();c=g.controls();e.b.controls=!!c;h=function(){e.b.controls=
f};j=function(){e.b.controls=l};g.c("controlsenabled",h);g.c("controlsdisabled",j);c=function(){g.j("controlsenabled",h);g.j("controlsdisabled",j)};e.c("dispose",c);g.c("usingcustomcontrols",c);g.usingNativeControls(f)}a.K(function(){this.I&&(this.m.autoplay&&this.paused())&&(delete this.I.poster,this.play())});this.Ga()}});s=t.h.prototype;s.dispose=function(){t.h.Bb(this.b);t.q.prototype.dispose.call(this)};
s.e=function(){var a=this.d,c=a.I,d;if(!c||this.movingMediaElementInDOM===l)c?(d=c.cloneNode(l),t.h.Bb(c),c=d,a.I=k):(c=t.e("video"),t.Kc(c,t.g.z(a.ie||{},{id:a.id()+"_html5_api","class":"vjs-tech"}))),c.player=a,t.Hb(c,a.w());d=["autoplay","preload","loop","muted"];for(var e=d.length-1;0<=e;e--){var g=d[e],h={};"undefined"!==typeof a.m[g]&&(h[g]=a.m[g]);t.Kc(c,h)}return c};s.vd=function(a){"error"==a.type&&this.error()?this.k().error(this.error().code):(a.bubbles=l,this.k().l(a))};s.play=function(){this.b.play()};
s.pause=function(){this.b.pause()};s.paused=function(){return this.b.paused};s.currentTime=function(){return this.b.currentTime};s.Qb=function(a){try{this.b.currentTime=a}catch(c){t.log(c,"Video is not ready. (Video.js)")}};s.duration=function(){return this.b.duration||0};s.buffered=function(){return this.b.buffered};s.volume=function(){return this.b.volume};s.fe=function(a){this.b.volume=a};s.muted=function(){return this.b.muted};s.ce=function(a){this.b.muted=a};s.width=function(){return this.b.offsetWidth};
s.height=function(){return this.b.offsetHeight};s.Ea=function(){return"function"==typeof this.b.webkitEnterFullScreen&&(/Android/.test(t.O)||!/Chrome|Mac OS X 10.5/.test(t.O))?f:l};
s.pc=function(){var a=this.b;"webkitDisplayingFullscreen"in a&&this.R("webkitbeginfullscreen",function(){this.d.isFullscreen(f);this.R("webkitendfullscreen",function(){this.d.isFullscreen(l);this.d.l("fullscreenchange")});this.d.l("fullscreenchange")});a.paused&&a.networkState<=a.ne?(this.b.play(),setTimeout(function(){a.pause();a.webkitEnterFullScreen()},0)):a.webkitEnterFullScreen()};s.wd=function(){this.b.webkitExitFullScreen()};s.src=function(a){if(a===b)return this.b.src;this.b.src=a};
s.load=function(){this.b.load()};s.currentSrc=function(){return this.b.currentSrc};s.poster=function(){return this.b.poster};s.Lc=function(a){this.b.poster=a};s.Da=function(){return this.b.Da};s.ee=function(a){this.b.Da=a};s.autoplay=function(){return this.b.autoplay};s.$d=function(a){this.b.autoplay=a};s.controls=function(){return this.b.controls};s.loop=function(){return this.b.loop};s.be=function(a){this.b.loop=a};s.error=function(){return this.b.error};s.seeking=function(){return this.b.seeking};
s.ended=function(){return this.b.ended};s.playbackRate=function(){return this.b.playbackRate};s.de=function(a){this.b.playbackRate=a};s.networkState=function(){return this.b.networkState};t.h.isSupported=function(){try{t.A.volume=0.5}catch(a){return l}return!!t.A.canPlayType};t.h.vb=function(a){try{return!!t.A.canPlayType(a.type)}catch(c){return""}};t.h.nd=function(){var a=t.A.volume;t.A.volume=a/2+0.1;return a!==t.A.volume};
t.h.md=function(){var a=t.A.playbackRate;t.A.playbackRate=a/2+0.1;return a!==t.A.playbackRate};var V,ga=/^application\/(?:x-|vnd\.apple\.)mpegurl/i,ha=/^video\/mp4/i;t.h.Dc=function(){4<=t.Ub&&(V||(V=t.A.constructor.prototype.canPlayType),t.A.constructor.prototype.canPlayType=function(a){return a&&ga.test(a)?"maybe":V.call(this,a)});t.dd&&(V||(V=t.A.constructor.prototype.canPlayType),t.A.constructor.prototype.canPlayType=function(a){return a&&ha.test(a)?"maybe":V.call(this,a)})};
t.h.le=function(){var a=t.A.constructor.prototype.canPlayType;t.A.constructor.prototype.canPlayType=V;V=k;return a};t.h.Dc();t.h.kb="loadstart suspend abort error emptied stalled loadedmetadata loadeddata canplay canplaythrough playing waiting seeking seeked ended durationchange timeupdate progress play pause ratechange volumechange".split(" ");
t.h.Bb=function(a){if(a){a.player=k;for(a.parentNode&&a.parentNode.removeChild(a);a.hasChildNodes();)a.removeChild(a.firstChild);a.removeAttribute("src");if("function"===typeof a.load)try{a.load()}catch(c){}}};
t.f=t.q.extend({i:function(a,c,d){t.q.call(this,a,c,d);var e=c.source;d=c.parentEl;var g=this.b=t.e("div",{id:a.id()+"_temp_flash"}),h=a.id()+"_flash_api",j=a.m,j=t.g.z({readyFunction:"videojs.Flash.onReady",eventProxyFunction:"videojs.Flash.onEvent",errorEventProxyFunction:"videojs.Flash.onError",autoplay:j.autoplay,preload:j.Da,loop:j.loop,muted:j.muted},c.flashVars),n=t.g.z({wmode:"opaque",bgcolor:"#000000"},c.params),h=t.g.z({id:h,name:h,"class":"vjs-tech"},c.attributes);e&&(e.type&&t.f.Gd(e.type)?
(e=t.f.Pc(e.src),j.rtmpConnection=encodeURIComponent(e.wb),j.rtmpStream=encodeURIComponent(e.Rb)):j.src=encodeURIComponent(t.tc(e.src)));t.Hb(g,d);c.startTime&&this.K(function(){this.load();this.play();this.currentTime(c.startTime)});t.Zc&&this.K(function(){this.c("mousemove",function(){this.k().l({type:"mousemove",bubbles:l})})});a.c("stageclick",a.reportUserActivity);this.b=t.f.oc(c.swf,g,j,n,h)}});t.f.prototype.dispose=function(){t.q.prototype.dispose.call(this)};t.f.prototype.play=function(){this.b.vjs_play()};
t.f.prototype.pause=function(){this.b.vjs_pause()};t.f.prototype.src=function(a){if(a===b)return this.currentSrc();t.f.Fd(a)?(a=t.f.Pc(a),this.xe(a.wb),this.ye(a.Rb)):(a=t.tc(a),this.b.vjs_src(a));if(this.d.autoplay()){var c=this;setTimeout(function(){c.play()},0)}};t.f.prototype.setCurrentTime=function(a){this.Jd=a;this.b.vjs_setProperty("currentTime",a);t.q.prototype.Qb.call(this)};t.f.prototype.currentTime=function(){return this.seeking()?this.Jd||0:this.b.vjs_getProperty("currentTime")};
t.f.prototype.currentSrc=function(){var a=this.b.vjs_getProperty("currentSrc");if(a==k){var c=this.rtmpConnection(),d=this.rtmpStream();c&&d&&(a=t.f.ge(c,d))}return a};t.f.prototype.load=function(){this.b.vjs_load()};t.f.prototype.poster=function(){this.b.vjs_getProperty("poster")};t.f.prototype.setPoster=m();t.f.prototype.buffered=function(){return t.zb(0,this.b.vjs_getProperty("buffered"))};t.f.prototype.Ea=q(l);t.f.prototype.pc=q(l);
function ia(){var a=W[X],c=a.charAt(0).toUpperCase()+a.slice(1);ja["set"+c]=function(c){return this.b.vjs_setProperty(a,c)}}function ka(a){ja[a]=function(){return this.b.vjs_getProperty(a)}}
var ja=t.f.prototype,W="rtmpConnection rtmpStream preload defaultPlaybackRate playbackRate autoplay loop mediaGroup controller controls volume muted defaultMuted".split(" "),la="error networkState readyState seeking initialTime duration startOffsetTime paused played seekable ended videoTracks audioTracks videoWidth videoHeight textTracks".split(" "),X;for(X=0;X<W.length;X++)ka(W[X]),ia();for(X=0;X<la.length;X++)ka(la[X]);t.f.isSupported=function(){return 10<=t.f.version()[0]};
t.f.vb=function(a){if(!a.type)return"";a=a.type.replace(/;.*/,"").toLowerCase();if(a in t.f.yd||a in t.f.Qc)return"maybe"};t.f.yd={"video/flv":"FLV","video/x-flv":"FLV","video/mp4":"MP4","video/m4v":"MP4"};t.f.Qc={"rtmp/mp4":"MP4","rtmp/flv":"FLV"};t.f.onReady=function(a){var c;if(c=(a=t.w(a))&&a.parentNode&&a.parentNode.player)a.player=c,t.f.checkReady(c.o)};t.f.checkReady=function(a){a.w()&&(a.w().vjs_getProperty?a.Ga():setTimeout(function(){t.f.checkReady(a)},50))};t.f.onEvent=function(a,c){t.w(a).player.l(c)};
t.f.onError=function(a,c){var d=t.w(a).player,e="FLASH: "+c;"srcnotfound"==c?d.error({code:4,message:e}):d.error(e)};t.f.version=function(){var a="0,0,0";try{a=(new window.ActiveXObject("ShockwaveFlash.ShockwaveFlash")).GetVariable("$version").replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}catch(c){try{navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin&&(a=(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g,",").match(/^,?(.+),?$/)[1])}catch(d){}}return a.split(",")};
t.f.oc=function(a,c,d,e,g){a=t.f.Ad(a,d,e,g);a=t.e("div",{innerHTML:a}).childNodes[0];d=c.parentNode;c.parentNode.replaceChild(a,c);var h=d.childNodes[0];setTimeout(function(){h.style.display="block"},1E3);return a};
t.f.Ad=function(a,c,d,e){var g="",h="",j="";c&&t.g.X(c,function(a,c){g+=a+"="+c+"&amp;"});d=t.g.z({movie:a,flashvars:g,allowScriptAccess:"always",allowNetworking:"all"},d);t.g.X(d,function(a,c){h+='<param name="'+a+'" value="'+c+'" />'});e=t.g.z({data:a,width:"100%",height:"100%"},e);t.g.X(e,function(a,c){j+=a+'="'+c+'" '});return'<object type="application/x-shockwave-flash"'+j+">"+h+"</object>"};t.f.ge=function(a,c){return a+"&"+c};
t.f.Pc=function(a){var c={wb:"",Rb:""};if(!a)return c;var d=a.indexOf("&"),e;-1!==d?e=d+1:(d=e=a.lastIndexOf("/")+1,0===d&&(d=e=a.length));c.wb=a.substring(0,d);c.Rb=a.substring(e,a.length);return c};t.f.Gd=function(a){return a in t.f.Qc};t.f.fd=/^rtmp[set]?:\/\//i;t.f.Fd=function(a){return t.f.fd.test(a)};
t.ed=t.a.extend({i:function(a,c,d){t.a.call(this,a,c,d);if(!a.m.sources||0===a.m.sources.length){c=0;for(d=a.m.techOrder;c<d.length;c++){var e=t.ba(d[c]),g=window.videojs[e];if(g&&g.isSupported()){Q(a,e);break}}}else a.src(a.m.sources)}});t.Player.prototype.textTracks=function(){return this.Fa=this.Fa||[]};
function ma(a,c,d,e,g){var h=a.Fa=a.Fa||[];g=g||{};g.kind=c;g.label=d;g.language=e;c=t.ba(c||"subtitles");var j=new window.videojs[c+"Track"](a,g);h.push(j);j.Ab()&&a.K(function(){setTimeout(function(){Y(j.k(),j.id())},0)})}function Y(a,c,d){for(var e=a.Fa,g=0,h=e.length,j,n;g<h;g++)j=e[g],j.id()===c?(j.show(),n=j):d&&(j.M()==d&&0<j.mode())&&j.disable();(c=n?n.M():d?d:l)&&a.l(c+"trackchange")}
t.B=t.a.extend({i:function(a,c){t.a.call(this,a,c);this.L=c.id||"vjs_"+c.kind+"_"+c.language+"_"+t.r++;this.Mc=c.src;this.sd=c["default"]||c.dflt;this.je=c.title;this.Ua=c.srclang;this.Hd=c.label;this.ca=[];this.tb=[];this.ma=this.na=0}});s=t.B.prototype;s.M=p("H");s.src=p("Mc");s.Ab=p("sd");s.title=p("je");s.language=p("Ua");s.label=p("Hd");s.od=p("ca");s.gd=p("tb");s.readyState=p("na");s.mode=p("ma");s.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-"+this.H+" vjs-text-track"})};
s.show=function(){na(this);this.ma=2;t.a.prototype.show.call(this)};s.Y=function(){na(this);this.ma=1;t.a.prototype.Y.call(this)};s.disable=function(){2==this.ma&&this.Y();this.d.j("timeupdate",t.bind(this,this.update,this.L));this.d.j("ended",t.bind(this,this.reset,this.L));this.reset();this.d.ka("textTrackDisplay").removeChild(this);this.ma=0};
function na(a){0===a.na&&a.load();0===a.ma&&(a.d.c("timeupdate",t.bind(a,a.update,a.L)),a.d.c("ended",t.bind(a,a.reset,a.L)),("captions"===a.H||"subtitles"===a.H)&&a.d.ka("textTrackDisplay").V(a))}s.load=function(){0===this.na&&(this.na=1,t.get(this.Mc,t.bind(this,this.Wd),t.bind(this,this.Md)))};s.Md=function(a){this.error=a;this.na=3;this.l("error")};
s.Wd=function(a){var c,d;a=a.split("\n");for(var e="",g=1,h=a.length;g<h;g++)if(e=t.trim(a[g])){-1==e.indexOf("--\x3e")?(c=e,e=t.trim(a[++g])):c=this.ca.length;c={id:c,index:this.ca.length};d=e.split(/[\t ]+/);c.startTime=oa(d[0]);c.ya=oa(d[2]);for(d=[];a[++g]&&(e=t.trim(a[g]));)d.push(e);c.text=d.join("<br/>");this.ca.push(c)}this.na=2;this.l("loaded")};
function oa(a){var c=a.split(":");a=0;var d,e,g;3==c.length?(d=c[0],e=c[1],c=c[2]):(d=0,e=c[0],c=c[1]);c=c.split(/\s+/);c=c.splice(0,1)[0];c=c.split(/\.|,/);g=parseFloat(c[1]);c=c[0];a+=3600*parseFloat(d);a+=60*parseFloat(e);a+=parseFloat(c);g&&(a+=g/1E3);return a}
s.update=function(){if(0<this.ca.length){var a=this.d.options().trackTimeOffset||0,a=this.d.currentTime()+a;if(this.Pb===b||a<this.Pb||this.Wa<=a){var c=this.ca,d=this.d.duration(),e=0,g=l,h=[],j,n,r,w;a>=this.Wa||this.Wa===b?w=this.Eb!==b?this.Eb:0:(g=f,w=this.Kb!==b?this.Kb:c.length-1);for(;;){r=c[w];if(r.ya<=a)e=Math.max(e,r.ya),r.Na&&(r.Na=l);else if(a<r.startTime){if(d=Math.min(d,r.startTime),r.Na&&(r.Na=l),!g)break}else g?(h.splice(0,0,r),n===b&&(n=w),j=w):(h.push(r),j===b&&(j=w),n=w),d=Math.min(d,
r.ya),e=Math.max(e,r.startTime),r.Na=f;if(g)if(0===w)break;else w--;else if(w===c.length-1)break;else w++}this.tb=h;this.Wa=d;this.Pb=e;this.Eb=j;this.Kb=n;j=this.tb;n="";a=0;for(c=j.length;a<c;a++)n+='<span class="vjs-tt-cue">'+j[a].text+"</span>";this.b.innerHTML=n;this.l("cuechange")}}};s.reset=function(){this.Wa=0;this.Pb=this.d.duration();this.Kb=this.Eb=0};t.Wb=t.B.extend();t.Wb.prototype.H="captions";t.dc=t.B.extend();t.dc.prototype.H="subtitles";t.Xb=t.B.extend();t.Xb.prototype.H="chapters";
t.fc=t.a.extend({i:function(a,c,d){t.a.call(this,a,c,d);if(a.m.tracks&&0<a.m.tracks.length){c=this.d;a=a.m.tracks;for(var e=0;e<a.length;e++)d=a[e],ma(c,d.kind,d.label,d.language,d)}}});t.fc.prototype.e=function(){return t.a.prototype.e.call(this,"div",{className:"vjs-text-track-display"})};t.aa=t.J.extend({i:function(a,c){var d=this.ea=c.track;c.label=d.label();c.selected=d.Ab();t.J.call(this,a,c);this.c(a,d.M()+"trackchange",this.update)}});
t.aa.prototype.s=function(){t.J.prototype.s.call(this);Y(this.d,this.ea.L,this.ea.M())};t.aa.prototype.update=function(){this.selected(2==this.ea.mode())};t.mb=t.aa.extend({i:function(a,c){c.track={M:function(){return c.kind},k:a,label:function(){return c.kind+" off"},Ab:q(l),mode:q(l)};t.aa.call(this,a,c);this.selected(f)}});t.mb.prototype.s=function(){t.aa.prototype.s.call(this);Y(this.d,this.ea.L,this.ea.M())};
t.mb.prototype.update=function(){for(var a=this.d.textTracks(),c=0,d=a.length,e,g=f;c<d;c++)e=a[c],e.M()==this.ea.M()&&2==e.mode()&&(g=l);this.selected(g)};t.U=t.N.extend({i:function(a,c){t.N.call(this,a,c);1>=this.Q.length&&this.Y()}});t.U.prototype.wa=function(){var a=[],c;a.push(new t.mb(this.d,{kind:this.H}));for(var d=0;d<this.d.textTracks().length;d++)c=this.d.textTracks()[d],c.M()===this.H&&a.push(new t.aa(this.d,{track:c}));return a};
t.Ha=t.U.extend({i:function(a,c,d){t.U.call(this,a,c,d);this.b.setAttribute("aria-label","Captions Menu")}});t.Ha.prototype.H="captions";t.Ha.prototype.ua="Captions";t.Ha.prototype.className="vjs-captions-button";t.Ma=t.U.extend({i:function(a,c,d){t.U.call(this,a,c,d);this.b.setAttribute("aria-label","Subtitles Menu")}});t.Ma.prototype.H="subtitles";t.Ma.prototype.ua="Subtitles";t.Ma.prototype.className="vjs-subtitles-button";
t.Ia=t.U.extend({i:function(a,c,d){t.U.call(this,a,c,d);this.b.setAttribute("aria-label","Chapters Menu")}});s=t.Ia.prototype;s.H="chapters";s.ua="Chapters";s.className="vjs-chapters-button";s.wa=function(){for(var a=[],c,d=0;d<this.d.textTracks().length;d++)c=this.d.textTracks()[d],c.M()===this.H&&a.push(new t.aa(this.d,{track:c}));return a};
s.xa=function(){for(var a=this.d.textTracks(),c=0,d=a.length,e,g,h=this.Q=[];c<d;c++)if(e=a[c],e.M()==this.H)if(0===e.readyState())e.load(),e.c("loaded",t.bind(this,this.xa));else{g=e;break}a=this.Ba;a===b&&(a=new t.ha(this.d),a.ja().appendChild(t.e("li",{className:"vjs-menu-title",innerHTML:t.ba(this.H),he:-1})));if(g){e=g.ca;for(var j,c=0,d=e.length;c<d;c++)j=e[c],j=new t.gb(this.d,{track:g,cue:j}),h.push(j),a.V(j);this.V(a)}0<this.Q.length&&this.show();return a};
t.gb=t.J.extend({i:function(a,c){var d=this.ea=c.track,e=this.cue=c.cue,g=a.currentTime();c.label=e.text;c.selected=e.startTime<=g&&g<e.ya;t.J.call(this,a,c);d.c("cuechange",t.bind(this,this.update))}});t.gb.prototype.s=function(){t.J.prototype.s.call(this);this.d.currentTime(this.cue.startTime);this.update(this.cue.startTime)};t.gb.prototype.update=function(){var a=this.cue,c=this.d.currentTime();this.selected(a.startTime<=c&&c<a.ya)};
t.g.z(t.Ja.prototype.m.children,{subtitlesButton:{},captionsButton:{},chaptersButton:{}});
if("undefined"!==typeof window.JSON&&"function"===typeof window.JSON.parse)t.JSON=window.JSON;else{t.JSON={};var Z=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;t.JSON.parse=function(a,c){function d(a,e){var j,n,r=a[e];if(r&&"object"===typeof r)for(j in r)Object.prototype.hasOwnProperty.call(r,j)&&(n=d(r,j),n!==b?r[j]=n:delete r[j]);return c.call(a,e,r)}var e;a=String(a);Z.lastIndex=0;Z.test(a)&&(a=a.replace(Z,function(a){return"\\u"+("0000"+
a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return e=eval("("+a+")"),"function"===typeof c?d({"":e},""):e;throw new SyntaxError("JSON.parse(): invalid or malformed JSON data");}}
t.jc=function(){var a,c,d,e;a=document.getElementsByTagName("video");c=document.getElementsByTagName("audio");var g=[];if(a&&0<a.length){d=0;for(e=a.length;d<e;d++)g.push(a[d])}if(c&&0<c.length){d=0;for(e=c.length;d<e;d++)g.push(c[d])}if(g&&0<g.length){d=0;for(e=g.length;d<e;d++)if((c=g[d])&&c.getAttribute)c.player===b&&(a=c.getAttribute("data-setup"),a!==k&&videojs(c));else{t.ub();break}}else t.Uc||t.ub()};t.ub=function(){setTimeout(t.jc,1)};
"complete"===document.readyState?t.Uc=f:t.R(window,"load",function(){t.Uc=f});t.ub();t.Yd=function(a,c){t.Player.prototype[a]=c};var pa=this;function $(a,c){var d=a.split("."),e=pa;!(d[0]in e)&&e.execScript&&e.execScript("var "+d[0]);for(var g;d.length&&(g=d.shift());)!d.length&&c!==b?e[g]=c:e=e[g]?e[g]:e[g]={}};$("videojs",t);$("_V_",t);$("videojs.options",t.options);$("videojs.players",t.Ca);$("videojs.TOUCH_ENABLED",t.ec);$("videojs.cache",t.va);$("videojs.Component",t.a);t.a.prototype.player=t.a.prototype.k;t.a.prototype.options=t.a.prototype.options;t.a.prototype.init=t.a.prototype.i;t.a.prototype.dispose=t.a.prototype.dispose;t.a.prototype.createEl=t.a.prototype.e;t.a.prototype.contentEl=t.a.prototype.ja;t.a.prototype.el=t.a.prototype.w;t.a.prototype.addChild=t.a.prototype.V;
t.a.prototype.getChild=t.a.prototype.ka;t.a.prototype.getChildById=t.a.prototype.zd;t.a.prototype.children=t.a.prototype.children;t.a.prototype.initChildren=t.a.prototype.wc;t.a.prototype.removeChild=t.a.prototype.removeChild;t.a.prototype.on=t.a.prototype.c;t.a.prototype.off=t.a.prototype.j;t.a.prototype.one=t.a.prototype.R;t.a.prototype.trigger=t.a.prototype.l;t.a.prototype.triggerReady=t.a.prototype.Ga;t.a.prototype.show=t.a.prototype.show;t.a.prototype.hide=t.a.prototype.Y;
t.a.prototype.width=t.a.prototype.width;t.a.prototype.height=t.a.prototype.height;t.a.prototype.dimensions=t.a.prototype.td;t.a.prototype.ready=t.a.prototype.K;t.a.prototype.addClass=t.a.prototype.n;t.a.prototype.removeClass=t.a.prototype.p;t.a.prototype.buildCSSClass=t.a.prototype.T;t.a.prototype.localize=t.a.prototype.t;t.Player.prototype.ended=t.Player.prototype.ended;t.Player.prototype.enterFullWindow=t.Player.prototype.qc;t.Player.prototype.exitFullWindow=t.Player.prototype.Cb;
t.Player.prototype.preload=t.Player.prototype.Da;t.Player.prototype.remainingTime=t.Player.prototype.remainingTime;t.Player.prototype.supportsFullScreen=t.Player.prototype.Ea;t.Player.prototype.currentType=t.Player.prototype.pd;t.Player.prototype.requestFullScreen=t.Player.prototype.requestFullScreen;t.Player.prototype.requestFullscreen=t.Player.prototype.requestFullscreen;t.Player.prototype.cancelFullScreen=t.Player.prototype.cancelFullScreen;t.Player.prototype.exitFullscreen=t.Player.prototype.exitFullscreen;
t.Player.prototype.isFullScreen=t.Player.prototype.isFullScreen;t.Player.prototype.isFullscreen=t.Player.prototype.isFullscreen;$("videojs.MediaLoader",t.ed);$("videojs.TextTrackDisplay",t.fc);$("videojs.ControlBar",t.Ja);$("videojs.Button",t.u);$("videojs.PlayToggle",t.ac);$("videojs.FullscreenToggle",t.Ka);$("videojs.BigPlayButton",t.fb);$("videojs.LoadingSpinner",t.Zb);$("videojs.CurrentTimeDisplay",t.hb);$("videojs.DurationDisplay",t.ib);$("videojs.TimeDivider",t.gc);
$("videojs.RemainingTimeDisplay",t.pb);$("videojs.LiveDisplay",t.Yb);$("videojs.ErrorDisplay",t.jb);$("videojs.Slider",t.S);$("videojs.ProgressControl",t.ob);$("videojs.SeekBar",t.cc);$("videojs.LoadProgressBar",t.lb);$("videojs.PlayProgressBar",t.$b);$("videojs.SeekHandle",t.La);$("videojs.VolumeControl",t.rb);$("videojs.VolumeBar",t.qb);$("videojs.VolumeLevel",t.hc);$("videojs.VolumeMenuButton",t.sa);$("videojs.VolumeHandle",t.sb);$("videojs.MuteToggle",t.ia);$("videojs.PosterImage",t.ra);
$("videojs.Menu",t.ha);$("videojs.MenuItem",t.J);$("videojs.MenuButton",t.N);$("videojs.PlaybackRateMenuButton",t.bc);t.N.prototype.createItems=t.N.prototype.wa;t.U.prototype.createItems=t.U.prototype.wa;t.Ia.prototype.createItems=t.Ia.prototype.wa;$("videojs.SubtitlesButton",t.Ma);$("videojs.CaptionsButton",t.Ha);$("videojs.ChaptersButton",t.Ia);$("videojs.MediaTechController",t.q);t.q.prototype.featuresVolumeControl=t.q.prototype.ue;t.q.prototype.featuresFullscreenResize=t.q.prototype.qe;
t.q.prototype.featuresPlaybackRate=t.q.prototype.re;t.q.prototype.featuresProgressEvents=t.q.prototype.se;t.q.prototype.featuresTimeupdateEvents=t.q.prototype.te;t.q.prototype.setPoster=t.q.prototype.Lc;$("videojs.Html5",t.h);t.h.Events=t.h.kb;t.h.isSupported=t.h.isSupported;t.h.canPlaySource=t.h.vb;t.h.patchCanPlayType=t.h.Dc;t.h.unpatchCanPlayType=t.h.le;t.h.prototype.setCurrentTime=t.h.prototype.Qb;t.h.prototype.setVolume=t.h.prototype.fe;t.h.prototype.setMuted=t.h.prototype.ce;
t.h.prototype.setPreload=t.h.prototype.ee;t.h.prototype.setAutoplay=t.h.prototype.$d;t.h.prototype.setLoop=t.h.prototype.be;t.h.prototype.enterFullScreen=t.h.prototype.pc;t.h.prototype.exitFullScreen=t.h.prototype.wd;t.h.prototype.playbackRate=t.h.prototype.playbackRate;t.h.prototype.setPlaybackRate=t.h.prototype.de;$("videojs.Flash",t.f);t.f.isSupported=t.f.isSupported;t.f.canPlaySource=t.f.vb;t.f.onReady=t.f.onReady;t.f.embed=t.f.oc;t.f.version=t.f.version;$("videojs.TextTrack",t.B);
t.B.prototype.label=t.B.prototype.label;t.B.prototype.kind=t.B.prototype.M;t.B.prototype.mode=t.B.prototype.mode;t.B.prototype.cues=t.B.prototype.od;t.B.prototype.activeCues=t.B.prototype.gd;$("videojs.CaptionsTrack",t.Wb);$("videojs.SubtitlesTrack",t.dc);$("videojs.ChaptersTrack",t.Xb);$("videojs.autoSetup",t.jc);$("videojs.plugin",t.Yd);$("videojs.createTimeRange",t.zb);$("videojs.util",t.ga);t.ga.mergeOptions=t.ga.Va;t.addLanguage=t.hd;})();

View File

@ -1,110 +0,0 @@
body {
color: #F9F9F9;
font-family: sans-serif;
margin: 0;
padding: 0;
padding-top: 15px;
padding-bottom: 15px;
background-color: #111;
}
.topBar {
display: inline;
position: fixed;
top: 0px;
width: 100%;
padding: 10px;
padding-left: 30px;
padding-right: 30px;
margin: 0;
height: 30px;
background-color: rgba(17, 17, 17, 0.85);
z-index: 10;
}
.subtle {
font-size: 12px;
opacity: 0.6;
}
a, a:visited, a:hover {
color: #FF851B;
}
.dltext {
color: #FF851B;
text-align: center;
}
.videoprev {
display: block;
margin-right: auto;
margin-left: auto;
height: auto;
}
.audioprev {
display: block;
margin-top: 60px;
margin-right: auto;
margin-left: auto;
min-width: 640px;
max-width: 1024px;
height: auto;
}
.button {
border: solid 4px #F9F9F9;
color: #F9F9F9;
font-weight: bold;
border-radius: 0px;
display: inline-block;
margin: 5px;
padding: 14px;
font-size: 24px;
transition: background 0.15s ease-in-out;
}
.uploadinterface {
width: 420px;
display: block;
margin-right: auto;
margin-left: auto;
height: auto;
}
.fileselector {
font-size: 18px;
color: #FF851B;
}
.submitbutton {
font-size: 18px;
}
.submitbutton:hover {
border-color: #FF851B;
}
.buttoncontainer {
margin-top: 20px;
margin-bottom: 20px;
display: block;
max-width: 440px;
margin-left: auto;
margin-right: auto;
}
.button:hover {
background-color: rgba(249, 249, 249, 1);
color: rgb(255, 133, 27);
}
img {
display: block;
border: solid 5px #2d2d2d;
margin-right: auto;
margin-left: auto;
max-width: 80%;
height: auto;
}

View File

@ -1,59 +0,0 @@
<?php
try {
//Make sure a file has been submitted
if (!isset($_FILES['file'])) {
throw new Exception("Aucun fichier trouvé !");
}
$file = $_FILES['file'];
//File information and details
$filename = $file['name'];
$filetmp = $file['tmp_name'];
$filesize = $file['size'];
$error = $file['error'];
$maxsize = 104857600;
//Find file extension for whitelisting
$extension = explode('.', $filename);
$extension = strtolower(end($extension));
//List of allowed exstensions
$allowed = array('png', 'jpg', 'jpeg', 'gif', 'webm', 'mp4', 'wmv', 'mp3', 'flac', 'ogg', 'zip', 'css', 'pdf', 'zip', 'rar', 'm3u', 'm3u8', 'txt');
//Check if file is allowed
if(!in_array($extension, $allowed)) {
throw new Exception("Ce type de fichier n'est pas encore autorisé, désolé. Si vous pensez qu'il devrait l'être, merci de mentionner @Sangigi_Esenjin sur Twitter et je regarderais cela !");
}
//Check if there is an error
if($error !== 0) {
throw new Exception("Notre serveur a détecté un problème avec ce fichier. Essaie encore.");
}
//Make sure the filesize is ok
if($filesize > $maxsize) {
throw new Exception();
}
//Generate a file name, and regenerate it if a file with that name already exists
do {
$newname = strtoupper(substr(hash("sha256", $filename . (rand() * 100)), 0, 6)) . "." . $extension;
} while (file_exists("/file/" . $newname));
//Set file location
$location = 'file/' . $newname;
//Move file to storage folder
if(!move_uploaded_file($filetmp, $location)) {
throw new Exception("Impossible de déplacer le fichier dans le dossier où il devrait être. Vous devriez probablement parler de ce sujet à @Sangigi_Fuchsia sur twitter, car la faute provient probablement du serveur.");
}
if (!header('Location: share/' . $newname)) {
throw new Exception("Echec de la redirection.");
}
}
//Catch errors and output them
catch (Exception $e) {
echo $e->getMessage();
}