1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297 |
- <?php
- namespace OpcacheGui;
- /**
- * OPcache GUI
- *
- * A simple but effective single-file GUI for the OPcache PHP extension.
- *
- * @author Andrew Collington, andy@amnuts.com
- * @version 2.4.0
- * @link https://github.com/amnuts/opcache-gui
- * @license MIT, http://acollington.mit-license.org/
- */
- /*
- * User configuration
- */
- $options = [
- 'allow_filelist' => true, // show/hide the files tab
- 'allow_invalidate' => true, // give a link to invalidate files
- 'allow_reset' => true, // give option to reset the whole cache
- 'allow_realtime' => true, // give option to enable/disable real-time updates
- 'refresh_time' => 5, // how often the data will refresh, in seconds
- 'size_precision' => 2, // Digits after decimal point
- 'size_space' => false, // have '1MB' or '1 MB' when showing sizes
- 'charts' => true, // show gauge chart or just big numbers
- 'debounce_rate' => 250, // milliseconds after key press to send keyup event when filtering
- 'cookie_name' => 'opcachegui', // name of cookie
- 'cookie_ttl' => 365 // days to store cookie
- ];
- /*
- * Shouldn't need to alter anything else below here
- */
- if (!extension_loaded('Zend OPcache')) {
- die('The Zend OPcache extension does not appear to be installed');
- }
- $ocEnabled = ini_get('opcache.enable');
- if (empty($ocEnabled)) {
- die('The Zend OPcache extension is installed but not turned on');
- }
- class OpCacheService
- {
- protected $data;
- protected $options;
- protected $defaults = [
- 'allow_filelist' => true,
- 'allow_invalidate' => true,
- 'allow_reset' => true,
- 'allow_realtime' => true,
- 'refresh_time' => 5,
- 'size_precision' => 2,
- 'size_space' => false,
- 'charts' => true,
- 'debounce_rate' => 250,
- 'cookie_name' => 'opcachegui',
- 'cookie_ttl' => 365
- ];
- private function __construct($options = [])
- {
- $this->options = array_merge($this->defaults, $options);
- $this->data = $this->compileState();
- }
- public static function init($options = [])
- {
- $self = new self($options);
- if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
- && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'
- ) {
- if (isset($_GET['reset']) && $self->getOption('allow_reset')) {
- echo '{ "success": "' . ($self->resetCache() ? 'yes' : 'no') . '" }';
- } else if (isset($_GET['invalidate']) && $self->getOption('allow_invalidate')) {
- echo '{ "success": "' . ($self->resetCache($_GET['invalidate']) ? 'yes' : 'no') . '" }';
- } else {
- echo json_encode($self->getData((empty($_GET['section']) ? null : $_GET['section'])));
- }
- exit;
- } else if (isset($_GET['reset']) && $self->getOption('allow_reset')) {
- $self->resetCache();
- header('Location: ?');
- exit;
- } else if (isset($_GET['invalidate']) && $self->getOption('allow_invalidate')) {
- $self->resetCache($_GET['invalidate']);
- header('Location: ?');
- exit;
- }
- return $self;
- }
- public function getOption($name = null)
- {
- if ($name === null) {
- return $this->options;
- }
- return (isset($this->options[$name])
- ? $this->options[$name]
- : null
- );
- }
- public function getData($section = null, $property = null)
- {
- if ($section === null) {
- return $this->data;
- }
- $section = strtolower($section);
- if (isset($this->data[$section])) {
- if ($property === null || !isset($this->data[$section][$property])) {
- return $this->data[$section];
- }
- return $this->data[$section][$property];
- }
- return null;
- }
- public function canInvalidate()
- {
- return ($this->getOption('allow_invalidate') && function_exists('opcache_invalidate'));
- }
- public function resetCache($file = null)
- {
- $success = false;
- if ($file === null) {
- $success = opcache_reset();
- } else if (function_exists('opcache_invalidate')) {
- $success = opcache_invalidate(urldecode($file), true);
- }
- if ($success) {
- $this->compileState();
- }
- return $success;
- }
- protected function size($size)
- {
- $i = 0;
- $val = array('b', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
- while (($size / 1024) > 1) {
- $size /= 1024;
- ++$i;
- }
- return sprintf('%.'.$this->getOption('size_precision').'f%s%s',
- $size, ($this->getOption('size_space') ? ' ' : ''), $val[$i]
- );
- }
- protected function compileState()
- {
- $status = opcache_get_status();
- $config = opcache_get_configuration();
- $missingConfig = array_diff_key(ini_get_all('zend opcache', false), $config['directives']);
- if (!empty($missingConfig)) {
- $config['directives'] = array_merge($config['directives'], $missingConfig);
- }
- $files = [];
- if (!empty($status['scripts']) && $this->getOption('allow_filelist')) {
- uasort($status['scripts'], function($a, $b) {
- return $a['hits'] < $b['hits'];
- });
- foreach ($status['scripts'] as &$file) {
- $file['full_path'] = str_replace('\\', '/', $file['full_path']);
- $file['readable'] = [
- 'hits' => number_format($file['hits']),
- 'memory_consumption' => $this->size($file['memory_consumption'])
- ];
- }
- $files = array_values($status['scripts']);
- }
- if ($config['directives']['opcache.file_cache_only']) {
- $overview = false;
- } else {
- $overview = array_merge(
- $status['memory_usage'], $status['opcache_statistics'], [
- 'used_memory_percentage' => round(100 * (
- ($status['memory_usage']['used_memory'] + $status['memory_usage']['wasted_memory'])
- / $config['directives']['opcache.memory_consumption'])),
- 'hit_rate_percentage' => round($status['opcache_statistics']['opcache_hit_rate']),
- 'wasted_percentage' => round($status['memory_usage']['current_wasted_percentage'], 2),
- 'readable' => [
- 'total_memory' => $this->size($config['directives']['opcache.memory_consumption']),
- 'used_memory' => $this->size($status['memory_usage']['used_memory']),
- 'free_memory' => $this->size($status['memory_usage']['free_memory']),
- 'wasted_memory' => $this->size($status['memory_usage']['wasted_memory']),
- 'num_cached_scripts' => number_format($status['opcache_statistics']['num_cached_scripts']),
- 'hits' => number_format($status['opcache_statistics']['hits']),
- 'misses' => number_format($status['opcache_statistics']['misses']),
- 'blacklist_miss' => number_format($status['opcache_statistics']['blacklist_misses']),
- 'num_cached_keys' => number_format($status['opcache_statistics']['num_cached_keys']),
- 'max_cached_keys' => number_format($status['opcache_statistics']['max_cached_keys']),
- 'interned' => null,
- 'start_time' => date('Y-m-d H:i:s', $status['opcache_statistics']['start_time']),
- 'last_restart_time' => ($status['opcache_statistics']['last_restart_time'] == 0
- ? 'never'
- : date('Y-m-d H:i:s', $status['opcache_statistics']['last_restart_time'])
- )
- ]
- ]
- );
- }
- if (!empty($status['interned_strings_usage'])) {
- $overview['readable']['interned'] = [
- 'buffer_size' => $this->size($status['interned_strings_usage']['buffer_size']),
- 'strings_used_memory' => $this->size($status['interned_strings_usage']['used_memory']),
- 'strings_free_memory' => $this->size($status['interned_strings_usage']['free_memory']),
- 'number_of_strings' => number_format($status['interned_strings_usage']['number_of_strings'])
- ];
- }
- $directives = [];
- ksort($config['directives']);
- foreach ($config['directives'] as $k => $v) {
- if (in_array($k, ['opcache.max_file_size', 'opcache.memory_consumption']) && $v) {
- $v = $this->size($v) . " ({$v})";
- }
- $directives[] = [
- 'k' => $k,
- 'v' => $v
- ];
- }
- $version = array_merge(
- $config['version'],
- [
- 'php' => phpversion(),
- 'server' => empty($_SERVER['SERVER_SOFTWARE']) ? '' : $_SERVER['SERVER_SOFTWARE'],
- 'host' => (function_exists('gethostname')
- ? gethostname()
- : (php_uname('n')
- ?: (empty($_SERVER['SERVER_NAME'])
- ? $_SERVER['HOST_NAME']
- : $_SERVER['SERVER_NAME']
- )
- )
- )
- ]
- );
- return [
- 'version' => $version,
- 'overview' => $overview,
- 'files' => $files,
- 'directives' => $directives,
- 'blacklist' => $config['blacklist'],
- 'functions' => get_extension_funcs('Zend OPcache')
- ];
- }
- }
- $opcache = OpCacheService::init($options);
- ?>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width,initial-scale=1.0">
- <title>OPcache statistics on <?php echo $opcache->getData('version', 'host'); ?></title>
- <script src="//cdn.jsdelivr.net/react/15.4.2/react.min.js"></script>
- <script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
- <script src="//cdn.jsdelivr.net/jquery/3.1.1/jquery.min.js"></script>
- <style type="text/css">
- body { font-family:sans-serif; font-size:90%; padding: 0; margin: 0 }
- nav { padding-top: 20px; }
- nav > ul { list-style-type: none; padding-left: 8px; margin: 0; border-bottom: 1px solid #ccc; }
- nav > ul > li { display: inline-block; padding: 0; margin: 0 0 -1px 0; }
- nav > ul > li > a { display: block; margin: 0 10px; padding: 15px 30px; border: 1px solid transparent; border-bottom-color: #ccc; text-decoration: none; }
- nav > ul > li > a:hover { background-color: #f4f4f4; text-decoration: underline; }
- nav > ul > li > a.active:hover { background-color: initial; }
- nav > ul > li > a[data-for].active { border: 1px solid #ccc; border-bottom-color: #ffffff; border-top: 3px solid #6ca6ef; }
- table { margin: 0 0 1em 0; border-collapse: collapse; border-color: #fff; width: 100%; table-layout: fixed; }
- table caption { text-align: left; font-size: 1.5em; }
- table tr { background-color: #99D0DF; border-color: #fff; }
- table th { text-align: left; padding: 6px; background-color: #6ca6ef; color: #fff; border-color: #fff; font-weight: normal; }
- table td { padding: 4px 6px; line-height: 1.4em; vertical-align: top; border-color: #fff; overflow: hidden; overflow-wrap: break-word; text-overflow: ellipsis;}
- table tr:nth-child(odd) { background-color: #EFFEFF; }
- table tr:nth-child(even) { background-color: #E0ECEF; }
- #filelist table tr { background-color: #EFFEFF; }
- #filelist table tr.alternate { background-color: #E0ECEF; }
- td.pathname { width: 70%; }
- footer { border-top: 1px solid #ccc; padding: 1em 2em; }
- footer a { padding: 2em; text-decoration: none; opacity: 0.7; }
- footer a:hover { opacity: 1; }
- canvas { display: block; max-width: 100%; height: auto; margin: 0 auto; }
- #tabs { padding: 2em; }
- #tabs > div { display: none; }
- #tabs > div#overview { display:block; }
- #resetCache, #toggleRealtime, footer > a { background-position: 5px 50%; background-repeat: no-repeat; background-color: transparent; }
- footer > a { background-position: 0 50%; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjE2MENCRkExNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjE2MENCRkEyNzVBQjExRTQ5NDBGRTUzMzQyMDVDNzFFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTYwQ0JGOUY3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTYwQ0JGQTA3NUFCMTFFNDk0MEZFNTMzNDIwNUM3MUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7HtUU1AAABN0lEQVR42qyUvWoCQRSF77hCLLKC+FOlCKTyIbYQUuhbWPkSFnZ2NpabUvANLGyz5CkkYGMlFtFAUmiSM8lZOVkWsgm58K079+fMnTusZl92BXbgDrTtZ2szd8fas/XBOzmBKaiCEFyTkL4pc9L8vgpNJJDyWtDna61EoXpO+xcFfXUVqtrf7Vx7m9Pub/EatvgHoYXD4ylztC14BBVwydvydgDPHPgNaErN3jLKIxAUmEvAXK21I18SJpXBGAxyBAaMlblOWOs1bMXFkMGeBFsi0pJNe/QNuV7563+gs8LfhrRfE6GaHLuRqfnUiKi6lJ034B44EXL0baTTJWujNGkG3kBX5uRyZuRkPl3WzDTBtzjnxxiDDq83yNxUk7GYuXM53jeLuMNavvAXkv4zrJkTaeGHAAMAIal3icPMsyQAAAAASUVORK5CYII='); font-size: 80%; }
- #resetCache { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjBFMUMyMjI3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjBFMUMyMjM3NDlGMTFFNEE3QzNGNjQ0OEFDQzQ1MkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MEUxQzIyMDc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2MEUxQzIyMTc0OUYxMUU0QTdDM0Y2NDQ4QUNDNDUyQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PplZ+ZkAAAD1SURBVHjazFPtDYJADIUJZAMZ4UbACWQENjBO4Ao6AW5AnODcADZQJwAnwJ55NbWhB/6zycsdpX39uDZNpsURtjgzwkDoCBecs5ITPGGMwCNAkIrQw+8ri36GhBHsavFdpILEo4wEpZxRigy009EhG760gr0VhFoyZfvJKPwsheIWIeGejBZRIxRVhMRFevbuUXBew/iE/lhlBduV0j8Jx+TvJEWPphq8n5li9utgaw6cW/h6NSt/JcnVBhQxotIgKTBrbNvIHo2G0x1rwlKqTDusxiAz6hHNL1zayTVqVKRKpa/LPljPH1sJh6l/oNSrZfwSYABtq3tFdZA5BAAAAABJRU5ErkJggg=='); }
- #toggleRealtime { position: relative; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAUCAYAAACAl21KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODE5RUU4NUE3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODE5RUU4NUI3NDlGMTFFNDkyMzA4QzY1RjRBQkIzQjUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4MTlFRTg1ODc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4MTlFRTg1OTc0OUYxMUU0OTIzMDhDNjVGNEFCQjNCNSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpXjpvMAAAD2SURBVHjarFQBEcMgDKR3E1AJldA5wMEqAQmTgINqmILdFCChdUAdMAeMcukuSwnQbbnLlZLwJPkQIcrSiT/IGNQHNb8CGQDyRw+2QWUBqC+luzo4OKQZIAVrB+ssyKp3Bkijf0+ijzIh4wQppoBauMSjyDZfMSCDxYZMsfHF120T36AqWZMkgyguQ3GOfottJ5TKnHC+wfeRsC2oDVayPgr3bbN2tHBH3tWuJCPa0JUgKtFzMQrcZH3FNHAc0yOp1cCASALyngoN6lhDopkJWxdifwY9A3u7l29ImpxOFSWIOVsGwHKENIWxss2eBVKdOeeXAAMAk/Z9h4QhXmUAAAAASUVORK5CYII='); }
- #counts { width: 270px; float: right; }
- #counts > div > div { background-color: #ededed; margin-bottom: 10px; }
- #counts > div > div > h3 { background-color: #cdcdcd; padding: 4px 6px; margin: 0; text-align: center; }
- #counts > div > div > p { margin: 0; text-align: center; }
- #counts > div > div > p span.large + span { font-size: 20pt; margin: 0; color: #6ca6ef; }
- #counts > div > div > p span.large { color: #6ca6ef; font-size: 80pt; margin: 0; padding: 0; text-align: center; }
- #info { margin-right: 280px; }
- #frmFilter { width: 520px; }
- #fileCacheOnly { margin-top: 0; }
- .moreinfo > div { padding: 10px; }
- .moreinfo > div > p { margin: 0; line-height: 1.75em; }
- .metainfo { font-size: 80%; }
- .hide { display: none; }
- #toggleRealtime.pulse::before {
- content: ""; position: absolute;
- top: 13px; left: 3px; width: 18px; height: 18px;
- z-index: 10; opacity: 0; background-color: transparent;
- border: 2px solid rgb(255, 116, 0); border-radius: 100%;
- -webkit-animation: pulse 1s linear 2;
- -moz-animation: pulse 1s linear 2;
- animation: pulse 1s linear 2;
- }
- @media screen and (max-width: 750px) {
- #info { margin-right:auto; clear:both; }
- nav > ul { border-bottom: 0; }
- nav > ul > li { display: block; margin: 0; }
- nav > ul > li > a { display: block; margin: 0 10px; padding: 10px 0 10px 30px; border: 0; }
- nav > ul > li > a[data-for].active { border-bottom-color: #ccc; }
- #counts { position:relative; display:block; width:100%; }
- #toggleRealtime.pulse::before { top: 8px; }
- }
- @media screen and (max-width: 550px) {
- #frmFilter { width: 100%; }
- }
- @keyframes pulse {
- 0% {transform: scale(1); opacity: 0;}
- 50% {transform: scale(1.3); opacity: 0.7;}
- 100% {transform: scale(1.6); opacity: 1;}
- }
- @-webkit-keyframes pulse {
- 0% {-webkit-transform: scale(1); opacity: 0;}
- 50% {-webkit-transform: scale(1.3); opacity: 0.7;}
- 100% {-webkit-transform: scale(1.6); opacity: 0;}
- }
- @-moz-keyframes pulse {
- 0% {-moz-transform: scale(1); opacity: 0;}
- 50% {-moz-transform: scale(1.3); opacity: 0.7;}
- 100% {-moz-transform: scale(1.6); opacity: 0;}
- }
- </style>
- </head>
- <body>
- <header>
- <nav>
- <ul>
- <li><a data-for="overview" href="#overview" class="active">Overview</a></li>
- <?php if ($opcache->getOption('allow_filelist')): ?>
- <li><a data-for="files" href="#files">File usage</a></li>
- <?php endif; ?>
- <?php if ($opcache->getOption('allow_reset')): ?>
- <li><a href="?reset=1" id="resetCache" onclick="return confirm('Are you sure you want to reset the cache?');">Reset cache</a></li>
- <?php endif; ?>
- <?php if ($opcache->getOption('allow_realtime')): ?>
- <li><a href="#" id="toggleRealtime">Enable real-time update</a></li>
- <?php endif; ?>
- </ul>
- </nav>
- </header>
- <div id="tabs">
- <div id="overview">
- <div class="container">
- <div id="counts"></div>
- <div id="info">
- <div id="generalInfo"></div>
- <div id="directives"></div>
- <div id="functions">
- <table>
- <thead>
- <tr><th>Available functions</th></tr>
- </thead>
- <tbody>
- <?php foreach ($opcache->getData('functions') as $func): ?>
- <tr><td><a href="http://php.net/<?php echo $func; ?>" title="View manual page" target="_blank"><?php echo $func; ?></a></td></tr>
- <?php endforeach; ?>
- </tbody>
- </table>
- </div>
- <br style="clear:both;" />
- </div>
- </div>
- </div>
- <div id="files">
- <?php if ($opcache->getOption('allow_filelist')): ?>
- <form action="#">
- <label for="frmFilter">Start typing to filter on script path</label><br>
- <input type="text" name="filter" id="frmFilter">
- </form>
- <?php endif; ?>
- <div class="container" id="filelist"></div>
- </div>
- </div>
- <footer>
- <a href="https://github.com/amnuts/opcache-gui" target="_blank">https://github.com/amnuts/opcache-gui</a>
- </footer>
- <script type="text/javascript">
- var realtime = false;
- var opstate = <?php echo json_encode($opcache->getData()); ?>;
- var canInvalidate = <?php echo json_encode($opcache->canInvalidate()); ?>;
- var useCharts = <?php echo json_encode($opcache->getOption('charts')); ?>;
- var allowFiles = <?php echo json_encode($opcache->getOption('allow_filelist')); ?>;
- var debounce = function(func, wait, immediate) {
- var timeout;
- wait = wait || 250;
- return function() {
- var context = this, args = arguments;
- var later = function() {
- timeout = null;
- if (!immediate) {
- func.apply(context, args);
- }
- };
- var callNow = immediate && !timeout;
- clearTimeout(timeout);
- timeout = setTimeout(later, wait);
- if (callNow) {
- func.apply(context, args);
- }
- };
- };
- function keyUp(event){
- var compare = $('#frmFilter').val().toLowerCase();
- $('#filelist').find('table tbody tr').each(function(index){
- if ($(this).data('path').indexOf(compare) == -1) {
- $(this).addClass('hide');
- } else {
- $(this).removeClass('hide');
- }
- });
- $('#filelist table tbody').trigger('paint');
- };
- <?php if ($opcache->getOption('charts')): ?>
- var Gauge = function(el, colour) {
- this.canvas = $(el).get(0);
- this.ctx = this.canvas.getContext('2d');
- this.width = this.canvas.width;
- this.height = this.canvas.height;
- this.colour = colour || '#6ca6ef';
- this.loop = null;
- this.degrees = 0;
- this.newdegs = 0;
- this.text = '';
- this.init = function() {
- this.ctx.clearRect(0, 0, this.width, this.height);
- this.ctx.beginPath();
- this.ctx.strokeStyle = '#e2e2e2';
- this.ctx.lineWidth = 30;
- this.ctx.arc(this.width/2, this.height/2, 100, 0, Math.PI*2, false);
- this.ctx.stroke();
- this.ctx.beginPath();
- this.ctx.strokeStyle = this.colour;
- this.ctx.lineWidth = 30;
- this.ctx.arc(this.width/2, this.height/2, 100, 0 - (90 * Math.PI / 180), (this.degrees * Math.PI / 180) - (90 * Math.PI / 180), false);
- this.ctx.stroke();
- this.ctx.fillStyle = this.colour;
- this.ctx.font = '60px sans-serif';
- this.text = Math.round((this.degrees/360)*100) + '%';
- this.ctx.fillText(this.text, (this.width/2) - (this.ctx.measureText(this.text).width/2), (this.height/2) + 20);
- };
- this.draw = function() {
- if (typeof this.loop != 'undefined') {
- clearInterval(this.loop);
- }
- var self = this;
- self.loop = setInterval(function(){ self.animate(); }, 1000/(this.newdegs - this.degrees));
- };
- this.animate = function() {
- if (this.degrees == this.newdegs) {
- clearInterval(this.loop);
- }
- if (this.degrees < this.newdegs) {
- ++this.degrees;
- } else {
- --this.degrees;
- }
- this.init();
- };
- this.setValue = function(val) {
- this.newdegs = Math.round(3.6 * val);
- this.draw();
- };
- }
- <?php endif; ?>
- $(function(){
- <?php if ($opcache->getOption('allow_realtime')): ?>
- function setCookie() {
- var d = new Date();
- var secure = (window.location.protocol === 'https:' ? ';secure' : '');
- d.setTime(d.getTime() + (<?php echo ($opcache->getOption('cookie_ttl')); ?> * 86400000));
- var expires = "expires="+d.toUTCString();
- document.cookie = "<?php echo ($opcache->getOption('cookie_name')); ?>=true;" + expires + ";path=/" + secure;
- };
- function removeCookie() {
- var secure = (window.location.protocol === 'https:' ? ';secure' : '');
- document.cookie = "<?php echo ($opcache->getOption('cookie_name')); ?>=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/" + secure;
- };
- function getCookie() {
- var v = document.cookie.match('(^|;) ?<?php echo ($opcache->getOption('cookie_name')); ?>=([^;]*)(;|$)');
- return v ? v[2] : null;
- };
- function updateStatus() {
- $('#toggleRealtime').removeClass('pulse');
- $.ajax({
- url: "#",
- dataType: "json",
- cache: false,
- success: function(data) {
- $('#toggleRealtime').addClass('pulse');
- opstate = data;
- overviewCountsObj.setState({
- data : opstate.overview
- });
- generalInfoObj.setState({
- version : opstate.version,
- start : opstate.overview.readable.start_time,
- reset : opstate.overview.readable.last_restart_time
- });
- filesObj.setState({
- data : opstate.files,
- count_formatted : opstate.overview.readable.num_cached_scripts,
- count : opstate.overview.num_cached_scripts
- });
- keyUp();
- }
- });
- }
- $('#toggleRealtime').click(function(){
- if (realtime === false) {
- realtime = setInterval(function(){updateStatus()}, <?php echo (int)$opcache->getOption('refresh_time') * 1000; ?>);
- $(this).text('Disable real-time update');
- setCookie();
- } else {
- clearInterval(realtime);
- realtime = false;
- $(this).text('Enable real-time update').removeClass('pulse');
- removeCookie();
- }
- });
- if (getCookie() == 'true') {
- realtime = setInterval(function(){updateStatus()}, <?php echo (int)$opcache->getOption('refresh_time') * 1000; ?>);
- $('#toggleRealtime').text('Disable real-time update');
- }
- <?php endif; ?>
- $('nav a[data-for]').click(function(){
- $('#tabs > div').hide();
- $('#' + $(this).data('for')).show();
- $('nav a[data-for]').removeClass('active');
- $(this).addClass('active');
- return false;
- });
- $(document).on('paint', '#filelist table tbody', function(event, params) {
- var trs = $('#filelist').find('tbody tr');
- trs.removeClass('alternate');
- trs.filter(':not(.hide):odd').addClass('alternate');
- filesObj.setState({showing: trs.filter(':not(.hide)').length});
- });
- $('#frmFilter').bind('keyup', debounce(keyUp, <?php echo $opcache->getOption('debounce_rate'); ?>));
- });
- var MemoryUsageGraph = React.createClass({
- getInitialState: function () {
- return {
- memoryUsageGauge: null
- };
- },
- componentDidMount: function () {
- if (this.props.chart) {
- this.state.memoryUsageGauge = new Gauge('#memoryUsageCanvas');
- this.state.memoryUsageGauge.setValue(this.props.value);
- }
- },
- componentDidUpdate: function () {
- if (this.state.memoryUsageGauge != null) {
- this.state.memoryUsageGauge.setValue(this.props.value);
- }
- },
- render: function () {
- if (this.props.chart == true) {
- return React.createElement("canvas", { id: "memoryUsageCanvas", width: "250", height: "250", "data-value": this.props.value });
- }
- return React.createElement(
- "p",
- null,
- React.createElement(
- "span",
- { className: "large" },
- this.props.value
- ),
- React.createElement(
- "span",
- null,
- "%"
- )
- );
- }
- });
- var HitRateGraph = React.createClass({
- getInitialState: function () {
- return {
- hitRateGauge: null
- };
- },
- componentDidMount: function () {
- if (this.props.chart) {
- this.state.hitRateGauge = new Gauge('#hitRateCanvas');
- this.state.hitRateGauge.setValue(this.props.value);
- }
- },
- componentDidUpdate: function () {
- if (this.state.hitRateGauge != null) {
- this.state.hitRateGauge.setValue(this.props.value);
- }
- },
- render: function () {
- if (this.props.chart == true) {
- return React.createElement("canvas", { id: "hitRateCanvas", width: "250", height: "250", "data-value": this.props.value });
- }
- return React.createElement(
- "p",
- null,
- React.createElement(
- "span",
- { className: "large" },
- this.props.value
- ),
- React.createElement(
- "span",
- null,
- "%"
- )
- );
- }
- });
- var MemoryUsagePanel = React.createClass({
- render: function () {
- return React.createElement(
- "div",
- { className: "moreinfo" },
- React.createElement(
- "h3",
- null,
- "memory usage"
- ),
- React.createElement(
- "div",
- null,
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "total memory:"
- ),
- " ",
- this.props.total
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "used memory:"
- ),
- " ",
- this.props.used
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "free memory:"
- ),
- " ",
- this.props.free
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "wasted memory:"
- ),
- " ",
- this.props.wasted,
- " (",
- this.props.wastedPercent,
- "%)"
- )
- )
- );
- }
- });
- var StatisticsPanel = React.createClass({
- render: function () {
- return React.createElement(
- "div",
- { className: "moreinfo" },
- React.createElement(
- "h3",
- null,
- "opcache statistics"
- ),
- React.createElement(
- "div",
- null,
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "number of cached files:"
- ),
- " ",
- this.props.num_cached_scripts
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "number of hits:"
- ),
- " ",
- this.props.hits
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "number of misses:"
- ),
- " ",
- this.props.misses
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "blacklist misses:"
- ),
- " ",
- this.props.blacklist_miss
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "number of cached keys:"
- ),
- " ",
- this.props.num_cached_keys
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "max cached keys:"
- ),
- " ",
- this.props.max_cached_keys
- )
- )
- );
- }
- });
- var InternedStringsPanel = React.createClass({
- render: function () {
- return React.createElement(
- "div",
- { className: "moreinfo" },
- React.createElement(
- "h3",
- null,
- "interned strings usage"
- ),
- React.createElement(
- "div",
- null,
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "buffer size:"
- ),
- " ",
- this.props.buffer_size
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "used memory:"
- ),
- " ",
- this.props.strings_used_memory
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "free memory:"
- ),
- " ",
- this.props.strings_free_memory
- ),
- React.createElement(
- "p",
- null,
- React.createElement(
- "b",
- null,
- "number of strings:"
- ),
- " ",
- this.props.number_of_strings
- )
- )
- );
- }
- });
- var OverviewCounts = React.createClass({
- getInitialState: function () {
- return {
- data: opstate.overview,
- chart: useCharts
- };
- },
- render: function () {
- if (this.state.data == false) {
- return React.createElement(
- "p",
- { id: "fileCacheOnly" },
- "You have ",
- React.createElement(
- "i",
- null,
- "opcache.file_cache_only"
- ),
- " turned on. As a result, the memory information is not available. Statistics and file list may also not be returned by ",
- React.createElement(
- "i",
- null,
- "opcache_get_statistics()"
- ),
- "."
- );
- }
- var interned = this.state.data.readable.interned != null ? React.createElement(InternedStringsPanel, {
- buffer_size: this.state.data.readable.interned.buffer_size,
- strings_used_memory: this.state.data.readable.interned.strings_used_memory,
- strings_free_memory: this.state.data.readable.interned.strings_free_memory,
- number_of_strings: this.state.data.readable.interned.number_of_strings
- }) : '';
- return React.createElement(
- "div",
- null,
- React.createElement(
- "div",
- null,
- React.createElement(
- "h3",
- null,
- "memory"
- ),
- React.createElement(
- "p",
- null,
- React.createElement(MemoryUsageGraph, { chart: this.state.chart, value: this.state.data.used_memory_percentage })
- )
- ),
- React.createElement(
- "div",
- null,
- React.createElement(
- "h3",
- null,
- "hit rate"
- ),
- React.createElement(
- "p",
- null,
- React.createElement(HitRateGraph, { chart: this.state.chart, value: this.state.data.hit_rate_percentage })
- )
- ),
- React.createElement(MemoryUsagePanel, {
- total: this.state.data.readable.total_memory,
- used: this.state.data.readable.used_memory,
- free: this.state.data.readable.free_memory,
- wasted: this.state.data.readable.wasted_memory,
- wastedPercent: this.state.data.wasted_percentage
- }),
- React.createElement(StatisticsPanel, {
- num_cached_scripts: this.state.data.readable.num_cached_scripts,
- hits: this.state.data.readable.hits,
- misses: this.state.data.readable.misses,
- blacklist_miss: this.state.data.readable.blacklist_miss,
- num_cached_keys: this.state.data.readable.num_cached_keys,
- max_cached_keys: this.state.data.readable.max_cached_keys
- }),
- interned
- );
- }
- });
- var GeneralInfo = React.createClass({
- getInitialState: function () {
- return {
- version: opstate.version,
- start: opstate.overview ? opstate.overview.readable.start_time : null,
- reset: opstate.overview ? opstate.overview.readable.last_restart_time : null
- };
- },
- render: function () {
- var startTime = this.state.start ? React.createElement(
- "tr",
- null,
- React.createElement(
- "td",
- null,
- "Start time"
- ),
- React.createElement(
- "td",
- null,
- this.state.start
- )
- ) : '';
- var lastReset = this.state.reset ? React.createElement(
- "tr",
- null,
- React.createElement(
- "td",
- null,
- "Last reset"
- ),
- React.createElement(
- "td",
- null,
- this.state.reset
- )
- ) : '';
- return React.createElement(
- "table",
- null,
- React.createElement(
- "thead",
- null,
- React.createElement(
- "tr",
- null,
- React.createElement(
- "th",
- { colSpan: "2" },
- "General info"
- )
- )
- ),
- React.createElement(
- "tbody",
- null,
- React.createElement(
- "tr",
- null,
- React.createElement(
- "td",
- null,
- "Zend OPcache"
- ),
- React.createElement(
- "td",
- null,
- this.state.version.version
- )
- ),
- React.createElement(
- "tr",
- null,
- React.createElement(
- "td",
- null,
- "PHP"
- ),
- React.createElement(
- "td",
- null,
- this.state.version.php
- )
- ),
- React.createElement(
- "tr",
- null,
- React.createElement(
- "td",
- null,
- "Host"
- ),
- React.createElement(
- "td",
- null,
- this.state.version.host
- )
- ),
- React.createElement(
- "tr",
- null,
- React.createElement(
- "td",
- null,
- "Server Software"
- ),
- React.createElement(
- "td",
- null,
- this.state.version.server
- )
- ),
- startTime,
- lastReset
- )
- );
- }
- });
- var Directives = React.createClass({
- getInitialState: function () {
- return { data: opstate.directives };
- },
- render: function () {
- var directiveNodes = this.state.data.map(function (directive) {
- var map = { 'opcache.': '', '_': ' ' };
- var dShow = directive.k.replace(/opcache\.|_/gi, function (matched) {
- return map[matched];
- });
- var vShow;
- if (directive.v === true || directive.v === false) {
- vShow = React.createElement('i', {}, directive.v.toString());
- } else if (directive.v === '') {
- vShow = React.createElement('i', {}, 'no value');
- } else {
- vShow = directive.v;
- }
- return React.createElement(
- "tr",
- { key: directive.k },
- React.createElement(
- "td",
- { title: 'View ' + directive.k + ' manual entry' },
- React.createElement(
- "a",
- { href: 'http://php.net/manual/en/opcache.configuration.php#ini.' + directive.k.replace(/_/g, '-'), target: "_blank" },
- dShow
- )
- ),
- React.createElement(
- "td",
- null,
- vShow
- )
- );
- });
- return React.createElement(
- "table",
- null,
- React.createElement(
- "thead",
- null,
- React.createElement(
- "tr",
- null,
- React.createElement(
- "th",
- { colSpan: "2" },
- "Directives"
- )
- )
- ),
- React.createElement(
- "tbody",
- null,
- directiveNodes
- )
- );
- }
- });
- var Files = React.createClass({
- getInitialState: function () {
- return {
- data: opstate.files,
- showing: null,
- allowFiles: allowFiles
- };
- },
- handleInvalidate: function (e) {
- e.preventDefault();
- if (realtime) {
- $.get('#', { invalidate: e.currentTarget.getAttribute('data-file') }, function (data) {
- console.log('success: ' + data.success);
- }, 'json');
- } else {
- window.location.href = e.currentTarget.href;
- }
- },
- render: function () {
- if (this.state.allowFiles) {
- var fileNodes = this.state.data.map(function (file, i) {
- var invalidate, invalidated;
- if (file.timestamp == 0) {
- invalidated = React.createElement(
- "span",
- null,
- React.createElement(
- "i",
- { className: "invalid metainfo" },
- " - has been invalidated"
- )
- );
- }
- if (canInvalidate) {
- invalidate = React.createElement(
- "span",
- null,
- ",\xA0",
- React.createElement(
- "a",
- { className: "metainfo", href: '?invalidate=' + file.full_path, "data-file": file.full_path, onClick: this.handleInvalidate },
- "force file invalidation"
- )
- );
- }
- return React.createElement(
- "tr",
- { key: file.full_path, "data-path": file.full_path.toLowerCase(), className: i % 2 ? 'alternate' : '' },
- React.createElement(
- "td",
- null,
- React.createElement(
- "div",
- null,
- React.createElement(
- "span",
- { className: "pathname" },
- file.full_path
- ),
- React.createElement("br", null),
- React.createElement(FilesMeta, { data: [file.readable.hits, file.readable.memory_consumption, file.last_used] }),
- invalidate,
- invalidated
- )
- )
- );
- }.bind(this));
- return React.createElement(
- "div",
- null,
- React.createElement(FilesListed, { showing: this.state.showing }),
- React.createElement(
- "table",
- null,
- React.createElement(
- "thead",
- null,
- React.createElement(
- "tr",
- null,
- React.createElement(
- "th",
- null,
- "Script"
- )
- )
- ),
- React.createElement(
- "tbody",
- null,
- fileNodes
- )
- )
- );
- } else {
- return React.createElement("span", null);
- }
- }
- });
- var FilesMeta = React.createClass({
- render: function () {
- return React.createElement(
- "span",
- { className: "metainfo" },
- React.createElement(
- "b",
- null,
- "hits: "
- ),
- React.createElement(
- "span",
- null,
- this.props.data[0],
- ", "
- ),
- React.createElement(
- "b",
- null,
- "memory: "
- ),
- React.createElement(
- "span",
- null,
- this.props.data[1],
- ", "
- ),
- React.createElement(
- "b",
- null,
- "last used: "
- ),
- React.createElement(
- "span",
- null,
- this.props.data[2]
- )
- );
- }
- });
- var FilesListed = React.createClass({
- getInitialState: function () {
- return {
- formatted: opstate.overview ? opstate.overview.readable.num_cached_scripts : 0,
- total: opstate.overview ? opstate.overview.num_cached_scripts : 0
- };
- },
- render: function () {
- var display = this.state.formatted + ' file' + (this.state.total == 1 ? '' : 's') + ' cached';
- if (this.props.showing !== null && this.props.showing != this.state.total) {
- display += ', ' + this.props.showing + ' showing due to filter';
- }
- return React.createElement(
- "h3",
- null,
- display
- );
- }
- });
- var overviewCountsObj = ReactDOM.render(React.createElement(OverviewCounts, null), document.getElementById('counts'));
- var generalInfoObj = ReactDOM.render(React.createElement(GeneralInfo, null), document.getElementById('generalInfo'));
- var filesObj = ReactDOM.render(React.createElement(Files, null), document.getElementById('filelist'));
- ReactDOM.render(React.createElement(Directives, null), document.getElementById('directives'));
- </script>
- </body>
- </html>
|