diff --git a/dist/prober.php b/dist/prober.php index c514ca2a..a6142442 100644 --- a/dist/prober.php +++ b/dist/prober.php @@ -1,877 +1,206 @@ -.nav { -position: fixed; -bottom: 0; -background: #333; -padding: 0 1rem; -left: 0; -right: 0; -text-align: center; -z-index: 10; -} -.nav a{ -display: inline-block; -color: #eee; -padding: .3rem .5rem; -border-left: 1px solid rgba(255,255,255,.05); -} -.nav a:first-child{ -border: none; -} -.nav a:hover, -.nav a:focus, -.nav a:active{ -background: #f8f8f8; -color: #333; -text-decoration: none; -} -.nav .long-title{ -display: none; -} -.nav .tiny-title{ -display: block; -} -@media (min-width: 579px) { -.nav .tiny-title{ -display: none; -} -.nav .long-title{ -display: block; -} -.nav a{ -padding: .3rem 1rem; -} -} - +namespace InnStudio\Prober\Components\PreDefine; \define('TIMER', \microtime(true)); \define('IS_DEV', false); \define('DEBUG', false); \define('LANG', 'eyJ6aF9DTiI6eyJQbGVhc2Ugd2FpdCAlZCBzZWNvbmRzIjoiXHU4YmY3XHU3YjQ5XHU1Zjg1ICVkIFx1NzlkMiIsIkRhdGFiYXNlIjoiXHU2NTcwXHU2MzZlXHU1ZTkzIiwiREIiOiJcdTY1NzBcdTYzNmVcdTVlOTMiLCJTUUxpdGUzIjoiIiwiU1FMaXRlIjoiIiwiTXlTUUxpIGNsaWVudCI6IiIsIk1vbmdvIjoiIiwiTW9uZ29EQiI6IiIsIlBvc3RncmVTUUwiOiIiLCJQYXJhZG94IjoiIiwiTWljcm9zb2Z0IFNRTCBTZXJ2ZXIgRHJpdmVyIGZvciBQSFAiOiIiLCJNUyBTUUwiOiIiLCJGaWxlIFBybyI6IiIsIk1heERCIGNsaWVudCI6IiIsIk1heERCIHNlcnZlciI6IiIsIkdlbmVyYXRvciAlcyI6Ilx1OGJlNVx1OTg3NVx1OTc2Mlx1NzUzMSAlcyBcdTc1MWZcdTYyMTAiLCJBdXRob3IgJXMiOiJcdTRmNWNcdTgwMDVcdTRlM2EgJXMiLCJVbmF2YWlsYWJsZSI6Ilx1NGUwZFx1NTNlZlx1NzUyOCIsIiVzIGNhY2hlIjoiJXMgXHU3ZjEzXHU1YjU4IiwiJTEkZGQgJTIkZGggJTMkZG0gJTQkZHMiOiIlMSRkIFx1NTkyOSAlMiRkIFx1NjVmNiAlMyRkIFx1NTIwNiAlNCRkIFx1NzlkMiIsIk15IGluZm9ybWF0aW9uIjoiXHU2MjExXHU3Njg0XHU0ZmUxXHU2MDZmIiwiTWluZSI6Ilx1NjIxMVx1NzY4NCIsIk15IElQIjoiXHU2MjExXHU3Njg0IElQIiwiTXkgYnJvd3NlciBVQSI6Ilx1NjIxMVx1NzY4NFx1NmQ0Zlx1ODljOFx1NTY2OCBVQSIsIk15IGJyb3dzZXIgbGFuZ3VhZ2UiOiJcdTYyMTFcdTc2ODRcdTZkNGZcdTg5YzhcdTU2NjhcdThiZWRcdThhMDAiLCJOZXR3b3JrIHN0YXRzIjoiXHU2ZDQxXHU5MWNmXHU3ZWRmXHU4YmExIiwiTmV0IjoiXHU3ZjUxXHU3ZWRjIiwiUEhQIGV4dGVuc2lvbnMiOiJQSFAgXHU2MjY5XHU1YzU1IiwiRXh0IjoiXHU2MjY5XHU1YzU1IiwiJXMgZXh0ZW5zaW9uIjoiJXMgXHU2MjY5XHU1YzU1IiwiJXMgZW5hYmxlZCI6IiVzIFx1NWRmMlx1NTQyZlx1NzUyOCIsIlplbmQgT3B0aW1pemVyIjoiIiwiTG9hZGVkIGV4dGVuc2lvbnMiOiJcdTVkZjJcdTUyYTBcdThmN2RcdTc2ODRcdTYyNjlcdTVjNTUiLCJQSFAgaW5mb3JtYXRpb24iOiJQSFAgXHU0ZmUxXHU2MDZmIiwiUEhQIjoiUEhQIiwiQ2xpY2sgZm9yIGRldGFpbCI6IlBIUCBcdThiZTZcdTdlYzZcdTRmZTFcdTYwNmYiLCJQSFAgaW5mbyBkZXRhaWwiOiJQSFAgXHU4YmU2XHU3ZWM2XHU0ZmUxXHU2MDZmIiwiVmVyc2lvbiI6Ilx1NzI0OFx1NjcyYyIsIlggUHJvYmVyIGJ1aWx0aW4gbGF0ZXN0IFBIUCBzdGFibGUgdmVyc2lvbjogJXMiOiJYIFx1NjNhMlx1OTQ4OFx1NTE4NVx1N2Y2ZVx1NjcwMFx1NjViMCBQSFAgXHU2YjYzXHU1ZjBmXHU3MjQ4XHU3MjQ4XHU2NzJjXHVmZjFhJXMiLCIoT2xkKSI6IihcdTY1ZTcpIiwiKFVwIHRvIGRhdGUpIjoiKFx1NjcwMFx1NjViMCkiLCJTQVBJIGludGVyZmFjZSI6IlNBUEkgXHU2M2E1XHU1M2UzIiwiRXJyb3IgcmVwb3J0aW5nIjoiXHU5NTE5XHU4YmVmXHU2MmE1XHU1NDRhIiwiTWF4IG1lbW9yeSBsaW1pdCI6Ilx1OGZkMFx1ODg0Y1x1NTE4NVx1NWI1OFx1OTY1MFx1NTIzNiIsIk1heCBQT1NUIHNpemUiOiJQT1NUIFx1NjNkMFx1NGVhNFx1OTY1MFx1NTIzNiIsIk1heCB1cGxvYWQgc2l6ZSI6Ilx1NGUwYVx1NGYyMFx1NjU4N1x1NGVmNlx1OTY1MFx1NTIzNiIsIk1heCBpbnB1dCB2YXJpYWJsZXMiOiJcdTYzZDBcdTRlYTRcdTg4NjhcdTUzNTVcdTk2NTBcdTUyMzYiLCJNYXggZXhlY3V0aW9uIHRpbWUiOiJcdThmZDBcdTg4NGNcdThkODVcdTY1ZjZcdTc5ZDJcdTY1NzAiLCJUaW1lb3V0IGZvciBzb2NrZXQiOiJTb2NrZXQgXHU4ZDg1XHU2NWY2XHU3OWQyXHU2NTcwIiwiRGlzcGxheSBlcnJvcnMiOiJcdTY2M2VcdTc5M2FcdTk1MTlcdThiZWYiLCJUcmVhdG1lbnQgVVJMcyBmaWxlIjoiXHU2NTg3XHU0ZWY2XHU4ZmRjXHU3YWVmXHU2MjUzXHU1ZjAwIiwiU01UUCBzdXBwb3J0IjoiU01UUCBcdTY1MmZcdTYzMDEiLCJEaXNhYmxlZCBmdW5jdGlvbnMiOiJcdTVkZjJcdTc5ODFcdTc1MjhcdTc2ODRcdTUxZmRcdTY1NzAiLCJEaXNhYmxlZCBjbGFzc2VzIjoiXHU1ZGYyXHU3OTgxXHU3NTI4XHU3Njg0XHU3YzdiIiwiXHUyM2YzIExvYWRpbmcuLi4iOiJcdTIzZjMgXHU1MmEwXHU4ZjdkXHU0ZTJkXHUyMDI2XHUyMDI2IiwiXHUyNzRjIEVycm9yLCBjbGljayB0byByZXRyeSI6Ilx1Mjc0YyBcdTk1MTlcdThiZWZcdWZmMGNcdTcwYjlcdTUxZmJcdTkxY2RcdThiZDUiLCJcdWQ4M2RcdWRjNDYgQ2xpY2sgdG8gdGVzdCI6Ilx1ZDgzZFx1ZGM0NiBcdTcwYjlcdTUxZmJcdTZkNGJcdThiZDUiLCJTZXJ2ZXIgQmVuY2htYXJrIjoiXHU2NzBkXHU1MmExXHU1NjY4XHU4ZGQxXHU1MjA2IiwiQmVuY2htYXJrIjoiXHU4ZGQxXHU1MjA2IiwiXHVkODNkXHVkY2ExIEhpZ2hlciBpcyBiZXR0ZXIuIFRoaXMgcmVzdWx0IGlzIG9ubHkgdXNlZCBhcyByZWZlcmVuY2UgZGF0YSBmb3IgYXV0aG9yIHRlc3RpbmcuIE5vdGU6IHRoZSBiZW5jaG1hcmsgbWFya3MgYXJlIG5vdCB0aGUgb25seSBjcml0ZXJpb24gZm9yIGV2YWx1YXRpbmcgdGhlIHF1YWxpdHkgb2YgYSBob3N0XC9zZXJ2ZXIuIjoiXHVkODNkXHVkY2ExIFx1NTIwNlx1NjU3MFx1OGQ4YVx1OWFkOFx1OGQ4YVx1NTk3ZFx1MzAwMlx1OGJlNVx1N2VkM1x1Njc5Y1x1NGVjNVx1NGY1Y1x1NGUzYVx1NGY1Y1x1ODAwNVx1NmQ0Ylx1OGJkNVx1NzY4NFx1NTNjMlx1ODAwM1x1NjU3MFx1NjM2ZVx1MzAwMlx1NmNlOFx1NjEwZlx1ZmYxYVx1OGRkMVx1NTIwNlx1N2VkM1x1Njc5Y1x1NGUwZFx1NjYyZlx1OGJjNFx1NGVmN1x1NjcwZFx1NTJhMVx1NTY2OFx1NGYxOFx1NTJhM1x1NzY4NFx1NTUyZlx1NGUwMFx1NjgwN1x1NTFjNlx1MzAwMiIsIkFtYXpvblwvRUMyIjoiXHU0ZTlhXHU5YTZjXHU5MDBhXC9FQzIiLCJWUFNTRVJWRVJcL0tWTSI6IlZQU1NFUlZFUlwvS1ZNIiwiU3BhcnRhbkhvc3RcL0tWTSI6Ilx1NjVhZlx1NWRmNFx1OGZiZVwvS1ZNIiwiQWxpeXVuXC9FQ1MiOiJcdTk2M2ZcdTkxY2NcdTRlOTFcL0VDUyIsIlZ1bHRyIjoiVnVsdHIiLCJSYW1Ob2RlIjoiUmFtTm9kZSIsIkxpbm9kZSI6Ikxpbm9kZSIsIlRlbmNlbnQiOiJcdTgxN2VcdThiYWZcdTRlOTEiLCJCYW5kd2Fnb25IT1NUXC9TU0QiOiJcdTY0MmNcdTc0ZTZcdTVkZTVcL1NTRCIsIk15IHNlcnZlciI6Ilx1NjIxMVx1NzY4NFx1NjcwZFx1NTJhMVx1NTY2OCIsIlNlcnZlciBpbmZvcm1hdGlvbiI6Ilx1NjcwZFx1NTJhMVx1NTY2OFx1NGZlMVx1NjA2ZiIsIkluZm8iOiJcdTRmZTFcdTYwNmYiLCJTZXJ2ZXIgbmFtZSI6Ilx1NjcwZFx1NTJhMVx1NTY2OFx1NTQwZCIsIlNlcnZlciB0aW1lIjoiXHU2NzBkXHU1MmExXHU1NjY4XHU2NWY2XHU5NWY0IiwiU2VydmVyIHVwdGltZSI6Ilx1NjMwMVx1N2VlZFx1OGZkMFx1NGY1Y1x1NjVmNlx1OTVmNCIsIlNlcnZlciBJUCI6Ilx1NjcwZFx1NTJhMVx1NTY2OCBJUCIsIlNlcnZlciBzb2Z0d2FyZSI6Ilx1NjcwZFx1NTJhMVx1NTY2OFx1OGY2Zlx1NGVmNiIsIlBIUCB2ZXJzaW9uIjoiUEhQIFx1NzI0OFx1NjcyYyIsIkNQVSBtb2RlbCI6IkNQVSBcdTU3OGJcdTUzZjciLCJTZXJ2ZXIgT1MiOiJcdTY3MGRcdTUyYTFcdTU2NjhcdTdjZmJcdTdlZGYiLCJTY3JpcHQgcGF0aCI6Ilx1ODExYVx1NjcyY1x1OGRlZlx1NWY4NCIsIkRpc2sgdXNhZ2UiOiJcdTc4YzFcdTc2ZDhcdTRmN2ZcdTc1MjhcdTkxY2YiLCJTZXJ2ZXIgc3RhdHVzIjoiXHU2NzBkXHU1MmExXHU1NjY4XHU3MmI2XHU2MDAxIiwiU3RhdHVzIjoiXHU3MmI2XHU2MDAxIiwiU3lzdGVtIGxvYWQiOiJcdTdjZmJcdTdlZGZcdThkMWZcdThmN2QiLCJDUFUgdXNhZ2UiOiJDUFUgXHU1MzYwXHU3NTI4IiwiTWVtb3J5IHVzYWdlIjoiXHU1MTg1XHU1YjU4XHU1MzYwXHU3NTI4IiwiU1dBUCB1c2FnZSI6IlNXQVAgXHU1MzYwXHU3NTI4IiwiJTEkcyBmb3VuZCB1cGRhdGUhIFZlcnNpb24gJTIkcyBcdTIxOTIge0FQUF9ORVdfVkVSU0lPTn0iOiIlMSRzIFx1NTNkMVx1NzNiMFx1NjZmNFx1NjViMFx1ZmYwMVx1NzI0OFx1NjcyYyAlMiRzIFx1MjE5MiB7QVBQX05FV19WRVJTSU9OfSIsIlVwZGF0aW5nLi4uIjoiXHU2NmY0XHU2NWIwXHU0ZTJkXHUyMDI2XHUyMDI2IiwiVXBkYXRlIGVycm9yIjoiXHU2NmY0XHU2NWIwXHU1MWZhXHU5NTE5IiwiRmlsZSBjYW4gbm90IHVwZGF0ZS4iOiJcdTY1ZTBcdTZjZDVcdTY2ZjRcdTY1YjBcdTY1ODdcdTRlZjZcdTMwMDIiLCJVcGRhdGUgZmlsZSBub3QgZm91bmQuIjoiXHU2NzJhXHU2MjdlXHU1MjMwXHU2NmY0XHU2NWIwXHU2NTg3XHU0ZWY2XHUzMDAyIiwiVXBkYXRlIHN1Y2Nlc3MuLi4iOiJcdTY2ZjRcdTY1YjBcdTYyMTBcdTUyOWZcdTIwMjZcdTIwMjYiLCJVcGRhdGUgZXJyb3IuIjoiXHU2NmY0XHU2NWIwXHU1MWZhXHU5NTE5XHUzMDAyIn0sInpoX1RXIjp7IlBsZWFzZSB3YWl0ICVkIHNlY29uZHMiOiJcdThhY2JcdTdiNDlcdTVmODUgJWQgXHU3OWQyIiwiRGF0YWJhc2UiOiJcdThjYzdcdTY1OTlcdTVlYWIiLCJEQiI6Ilx1OGNjN1x1NjU5OVx1NWVhYiIsIlNRTGl0ZTMiOiIiLCJTUUxpdGUiOiIiLCJNeVNRTGkgY2xpZW50IjoiIiwiTW9uZ28iOiIiLCJNb25nb0RCIjoiIiwiUG9zdGdyZVNRTCI6IiIsIlBhcmFkb3giOiIiLCJNaWNyb3NvZnQgU1FMIFNlcnZlciBEcml2ZXIgZm9yIFBIUCI6IiIsIk1TIFNRTCI6IiIsIkZpbGUgUHJvIjoiIiwiTWF4REIgY2xpZW50IjoiIiwiTWF4REIgc2VydmVyIjoiIiwiR2VuZXJhdG9yICVzIjoiXHU4YTcyXHU5ODAxXHU5NzYyXHU3NTMxICVzIFx1NzUxZlx1NjIxMCIsIkF1dGhvciAlcyI6Ilx1NGY1Y1x1ODAwNVx1NzBiYSAlcyIsIlVuYXZhaWxhYmxlIjoiXHU0ZTBkXHU1M2VmXHU3NTI4IiwiJXMgY2FjaGUiOiIiLCIlMSRkZCAlMiRkaCAlMyRkbSAlNCRkcyI6IiUxJGQgXHU1OTI5ICUyJGQgXHU1YzBmXHU2NjQyICUzJGQgXHU1MjA2ICU0JGQgXHU3OWQyIiwiTXkgaW5mb3JtYXRpb24iOiJcdTYyMTFcdTc2ODRcdThhMGFcdTYwNmYiLCJNaW5lIjoiXHU2MjExXHU3Njg0IiwiTXkgSVAiOiJcdTYyMTFcdTc2ODQgSVAiLCJNeSBicm93c2VyIFVBIjoiXHU2MjExXHU3Njg0XHU3MDBmXHU4OWJkXHU1NjY4IiwiTXkgYnJvd3NlciBsYW5ndWFnZSI6Ilx1NjIxMVx1NzY4NFx1NzAwZlx1ODliZFx1NTY2OFx1OGE5ZVx1OGEwMCIsIk5ldHdvcmsgc3RhdHMiOiJcdTZkNDFcdTkxY2ZcdTdkNzFcdThhMDgiLCJOZXQiOiJcdTZkNDFcdTkxY2YiLCJQSFAgZXh0ZW5zaW9ucyI6IlBIUCBcdTY0ZjRcdTVjNTUiLCJFeHQiOiJcdTY0ZjRcdTVjNTUiLCIlcyBleHRlbnNpb24iOiIlcyBcdTY0ZjRcdTVjNTUiLCIlcyBlbmFibGVkIjoiJXMgXHU1NTVmXHU3NTI4IiwiWmVuZCBPcHRpbWl6ZXIiOiIiLCJMb2FkZWQgZXh0ZW5zaW9ucyI6Ilx1OGYwOVx1NTE2NVx1NzY4NCBQSFAgXHU2NGY0XHU1YzU1IiwiUEhQIGluZm9ybWF0aW9uIjoiUEhQIFx1OGEwYVx1NjA2ZiIsIlBIUCI6IlBIUCIsIkNsaWNrIGZvciBkZXRhaWwiOiJQSFAgXHU4YTczXHU3ZDMwXHU4Y2M3XHU4YTBhIiwiUEhQIGluZm8gZGV0YWlsIjoiUEhQIFx1OGE3M1x1N2QzMFx1OGEwYVx1NjA2ZiIsIlZlcnNpb24iOiJcdTcyNDhcdTY3MmMiLCJYIFByb2JlciBidWlsdGluIGxhdGVzdCBQSFAgc3RhYmxlIHZlcnNpb246ICVzIjoiWCBcdTYzYTJcdTkxZGRcdTUxNjdcdTVlZmFcdTY3MDBcdTY1YjBcdTc2ODQgUEhQIFx1NmI2M1x1NWYwZlx1NzI0OFx1ZmYxYSVzIiwiKE9sZCkiOiIoXHU4MjBhKSIsIihVcCB0byBkYXRlKSI6IihcdTY3MDBcdTY1YjApIiwiU0FQSSBpbnRlcmZhY2UiOiJTQVBJIFx1NGVjYlx1OTc2MiIsIkVycm9yIHJlcG9ydGluZyI6Ilx1OTMyZlx1OGFhNFx1NTgzMVx1NTQ0YSIsIk1heCBtZW1vcnkgbGltaXQiOiJcdTU3ZjdcdTg4NGNcdThhMThcdTYxYjZcdTlhZDRcdTk2NTBcdTUyMzYiLCJNYXggUE9TVCBzaXplIjoiUE9TVCBcdTYzZDBcdTRlYTRcdTk2NTBcdTUyMzYiLCJNYXggdXBsb2FkIHNpemUiOiJcdTRlMGFcdTUwYjNcdTZhOTRcdTY4NDhcdTk2NTBcdTUyMzYiLCJNYXggaW5wdXQgdmFyaWFibGVzIjoiXHU2M2QwXHU0ZWE0XHU4ODY4XHU1NWFlXHU5NjUwXHU1MjM2IiwiTWF4IGV4ZWN1dGlvbiB0aW1lIjoiXHU1N2Y3XHU4ODRjXHU4ZDg1XHU2NjQyXHU3OWQyXHU2NTc4IiwiVGltZW91dCBmb3Igc29ja2V0IjoiU29ja2V0IFx1OGQ4NVx1NjY0Mlx1NzlkMlx1NjU3OCIsIkRpc3BsYXkgZXJyb3JzIjoiXHU5ODZmXHU3OTNhXHU5MzJmXHU4YWE0IiwiVHJlYXRtZW50IFVSTHMgZmlsZSI6Ilx1NmE5NFx1Njg0OFx1OTA2MFx1N2FlZlx1NjI1M1x1OTU4YiIsIlNNVFAgc3VwcG9ydCI6IlNNVFAgXHU2NTJmXHU2M2Y0IiwiRGlzYWJsZWQgZnVuY3Rpb25zIjoiXHU3OTgxXHU3NTI4XHU3Njg0XHU1MWZkXHU2NTc4IiwiRGlzYWJsZWQgY2xhc3NlcyI6Ilx1Nzk4MVx1NzUyOFx1NzY4NFx1OTg1ZSIsIlx1MjNmMyBMb2FkaW5nLi4uIjoiXHUyM2YzIFx1OGYwOVx1NTE2NVx1NGUyZFx1MjAyNlx1MjAyNiIsIlx1Mjc0YyBFcnJvciwgY2xpY2sgdG8gcmV0cnkiOiJcdTI3NGMgXHU5MzJmXHU4YWE0XHVmZjBjXHU5ZWRlXHU2NGNhXHU5MWNkXHU4YTY2IiwiXHVkODNkXHVkYzQ2IENsaWNrIHRvIHRlc3QiOiJcdWQ4M2RcdWRjNDYgXHU5ZWRlXHU2NGNhXHU2ZTJjXHU4YTY2IiwiU2VydmVyIEJlbmNobWFyayI6Ilx1NGYzYVx1NjcwZFx1NTY2OFx1NjAyN1x1ODBmZFx1OGRkMVx1NTIwNiIsIkJlbmNobWFyayI6Ilx1OGRkMVx1NTIwNiIsIlx1ZDgzZFx1ZGNhMSBIaWdoZXIgaXMgYmV0dGVyLiBUaGlzIHJlc3VsdCBpcyBvbmx5IHVzZWQgYXMgcmVmZXJlbmNlIGRhdGEgZm9yIGF1dGhvciB0ZXN0aW5nLiBOb3RlOiB0aGUgYmVuY2htYXJrIG1hcmtzIGFyZSBub3QgdGhlIG9ubHkgY3JpdGVyaW9uIGZvciBldmFsdWF0aW5nIHRoZSBxdWFsaXR5IG9mIGEgaG9zdFwvc2VydmVyLiI6Ilx1ZDgzZFx1ZGNhMSBcdTUyMDZcdTY1NzhcdThkOGFcdTlhZDhcdThkOGFcdTU5N2RcdTMwMDJcdThhNzJcdTdkNTBcdTY3OWNcdTUwYzVcdTRmNWNcdTcyMzJcdTRmNWNcdTgwMDVcdTZlMmNcdThhNjZcdTc2ODRcdTUzYzNcdTgwMDNcdTY1NzhcdTY0ZGFcdTMwMDJcdTZjZThcdWZmMWFcdThkZDFcdTUyMDZcdTY1NzhcdTUwM2NcdTRlMjZcdTRlMGRcdTY2MmZcdThhNTVcdTUwZjlcdTRlMDBcdTgxZmFcdTRlM2JcdTZhNWZcdTYyMTZcdTRmM2FcdTY3MGRcdTU2NjhcdTc2ODRcdTU1MmZcdTRlMDBcdTZlOTZcdTUyNDdcdTMwMDIiLCJBbWF6b25cL0VDMiI6Ilx1NGU5ZVx1OTlhY1x1OTA1Y1wvRUMyIiwiVlBTU0VSVkVSXC9LVk0iOiJWUFNTRVJWRVJcL0tWTSIsIlNwYXJ0YW5Ib3N0XC9LVk0iOiJcdTY1YWZcdTVkZjRcdTkwNTRcL0tWTSIsIkFsaXl1blwvRUNTIjoiXHU5NjNmXHU5MWNjXHU5NmYyXC9FQ1MiLCJWdWx0ciI6IlZ1bHRyIiwiUmFtTm9kZSI6IlJhbU5vZGUiLCJMaW5vZGUiOiJMaW5vZGUiLCJUZW5jZW50IjoiXHU5YTMwXHU4YTBhXHU5NmYyIiwiQmFuZHdhZ29uSE9TVFwvU1NEIjoiIiwiTXkgc2VydmVyIjoiXHU2MjExXHU3Njg0XHU0ZjNhXHU2NzBkXHU1NjY4IiwiU2VydmVyIGluZm9ybWF0aW9uIjoiXHU0ZjNhXHU2NzBkXHU1NjY4XHU4YTBhXHU2MDZmIiwiSW5mbyI6Ilx1OGEwYVx1NjA2ZiIsIlNlcnZlciBuYW1lIjoiXHU0ZjNhXHU2NzBkXHU1NjY4XHU1NDBkIiwiU2VydmVyIHRpbWUiOiJcdTYzMDFcdTdlOGNcdTRlMGFcdTdkZGFcdTY2NDJcdTk1OTMiLCJTZXJ2ZXIgdXB0aW1lIjoiXHU2MzAxXHU3ZThjXHU0ZTBhXHU3ZGRhXHU2NjQyXHU5NTkzIiwiU2VydmVyIElQIjoiXHU0ZjNhXHU2NzBkXHU1NjY4IElQIiwiU2VydmVyIHNvZnR3YXJlIjoiXHU0ZjNhXHU2NzBkXHU1NjY4XHU4ZWRmXHU5YWQ0IiwiUEhQIHZlcnNpb24iOiJQSFAgXHU3MjQ4XHU2NzJjIiwiQ1BVIG1vZGVsIjoiQ1BVIFx1NTc4Ylx1ODY1ZiIsIlNlcnZlciBPUyI6Ilx1NGYzYVx1NjcwZFx1NTY2OFx1N2NmYlx1N2Q3MSIsIlNjcmlwdCBwYXRoIjoiXHU4MTczXHU2NzJjXHU4ZGVmXHU1ZjkxIiwiRGlzayB1c2FnZSI6Ilx1NzhjMVx1Nzg5Zlx1NGY3Zlx1NzUyOCIsIlNlcnZlciBzdGF0dXMiOiJcdTRmM2FcdTY3MGRcdTU2NjhcdTcyYzBcdTYxNGIiLCJTdGF0dXMiOiJcdTcyYzBcdTYxNGIiLCJTeXN0ZW0gbG9hZCI6Ilx1N2NmYlx1N2Q3MVx1OGNhMFx1OGYwOSIsIkNQVSB1c2FnZSI6IkNQVSBcdTRmN2ZcdTc1MjhcdTczODciLCJNZW1vcnkgdXNhZ2UiOiJcdThhMThcdTYxYjZcdTlhZDRcdTRmN2ZcdTc1MjgiLCJTV0FQIHVzYWdlIjoiU1dBUCBcdTRmN2ZcdTc1MjgiLCIlMSRzIGZvdW5kIHVwZGF0ZSEgVmVyc2lvbiAlMiRzIFx1MjE5MiB7QVBQX05FV19WRVJTSU9OfSI6IiUxJHMgXHU3NjdjXHU3M2ZlXHU2NWIwXHU3MjQ4XHVmZjAxXHU3MjQ4XHU2NzJjICUyJHMgXHUyMTkyIHtBUFBfTkVXX1ZFUlNJT059IiwiVXBkYXRpbmcuLi4iOiJcdTY2ZjRcdTY1YjBcdTRlMmRcdTIwMjZcdTIwMjYiLCJVcGRhdGUgZXJyb3IiOiJcdTY2ZjRcdTY1YjBcdTUxZmFcdTkzMmYiLCJGaWxlIGNhbiBub3QgdXBkYXRlLiI6Ilx1NmE5NFx1Njg0OFx1NzEyMVx1NmNkNVx1ODhhYlx1NjZmNFx1NjViMFx1MzAwMiIsIlVwZGF0ZSBmaWxlIG5vdCBmb3VuZC4iOiJcdTY3MmFcdTc2N2NcdTczZmVcdTY2ZjRcdTY1YjBcdTZhOTRcdTY4NDhcdTMwMDIiLCJVcGRhdGUgc3VjY2Vzcy4uLiI6Ilx1NjZmNFx1NjViMFx1NjIxMFx1NTI5Zlx1MjAyNlx1MjAyNiIsIlVwZGF0ZSBlcnJvci4iOiJcdTY2ZjRcdTY1YjBcdTUxZmFcdTkzMmZcdTMwMDIifX0='); namespace InnStudio\Prober\Components\Nav; use InnStudio\Prober\Components\Events\EventsApi; class Nav { private $ID = 'nav'; public function __construct() { EventsApi::on('footer', array($this, 'filter')); } public function filter($content) { $content .= << HTML; -} public function filterScript() { echo << -(function(){ -var fieldsets = document.querySelectorAll('fieldset'); -if (! fieldsets.length) { -return; -} -var nav = document.createElement('div'); -nav.className = 'nav'; -for(var i = 0; i < fieldsets.length; i++) { -var fieldset = fieldsets[i]; -var a = document.createElement('a'); -a.href = '#' + encodeURIComponent(fieldset.id); -a.innerHTML = fieldset.querySelector('legend').innerHTML; -nav.appendChild(a); -} -document.body.appendChild(nav); -})() - -HTML; -} } -namespace InnStudio\Prober\PhpExtensionInfo; use InnStudio\Prober\Events\EventsApi; use InnStudio\Prober\Helper\HelperApi; use InnStudio\Prober\I18n\I18nApi; class PhpExtensionInfo { private $ID = 'phpExtensionInfo'; public function __construct() { EventsApi::on('mods', array($this, 'filter'), 400); } public function filter($mods) { $mods[$this->ID] = array( 'title' => I18nApi::_('PHP extensions'), 'tinyTitle' => I18nApi::_('Ext'), 'display' => array($this, 'display'), ); return $mods; } public function display() { return << +return $content; } } namespace InnStudio\Prober\Components\PhpExtensionInfo; use InnStudio\Prober\Components\Events\EventsApi; use InnStudio\Prober\Components\Helper\HelperApi; use InnStudio\Prober\Components\I18n\I18nApi; class PhpExtensionInfo { private $ID = 'phpExtensionInfo'; public function __construct() { EventsApi::on('mods', array($this, 'filter'), 400); } public function filter($mods) { $mods[$this->ID] = array( 'title' => I18nApi::_('PHP extensions'), 'tinyTitle' => I18nApi::_('Ext'), 'display' => array($this, 'display'), ); return $mods; } public function display() { return << {$this->getContent()} HTML; -} private function getContent() { $items = array( array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Memcache'), 'content' => HelperApi::getIni(0, \extension_loaded('memcache') && \class_exists('\\Memcache')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Memcached'), 'content' => HelperApi::getIni(0, \extension_loaded('memcached') && \class_exists('\\Memcached')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Redis'), 'content' => HelperApi::getIni(0, \extension_loaded('redis') && \class_exists('\\Redis')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Opcache'), 'content' => HelperApi::getIni(0, \function_exists('\\opcache_get_configuration')), ), array( 'label' => \sprintf(I18nApi::_('%s enabled'), 'Opcache'), 'content' => HelperApi::getIni(0, $this->isOpcEnabled()), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Swoole'), 'content' => HelperApi::getIni(0, \extension_loaded('Swoole') && \function_exists('\\swoole_version')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Imagick'), 'content' => HelperApi::getIni(0, \extension_loaded('Imagick') && \class_exists('\\Imagick')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Exif'), 'content' => HelperApi::getIni(0, \extension_loaded('Exif') && \function_exists('\\exif_imagetype')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Sockets'), 'content' => HelperApi::getIni(0, \extension_loaded('Sockets') && \function_exists('\\socket_accept')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'MySQLi'), 'content' => HelperApi::getIni(0, \extension_loaded('MySQLi') && \class_exists('\\mysqli')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Zip'), 'content' => HelperApi::getIni(0, \extension_loaded('Zip') && \class_exists('\\ZipArchive')), ), array( 'label' => \sprintf(I18nApi::_('%s extension'), 'Multibyte String'), 'content' => HelperApi::getIni(0, \extension_loaded('mbstring') && \function_exists('\\mb_substr')), ), array( 'label' => I18nApi::_('Zend Optimizer'), 'content' => HelperApi::getIni(0, \function_exists('zend_optimizer_version')), ), array( 'col' => '1-1', 'label' => I18nApi::_('Loaded extensions'), 'title' => 'loaded_extensions', 'content' => \implode(', ', $this->getLoadedExtensions(true)) ?: '-', ), ); $itemsOrder = array(); foreach ($items as $item) { $itemsOrder[] = $item['label']; } \array_multisort($items, $itemsOrder); $content = ''; foreach ($items as $item) { $title = isset($item['title']) ? "title=\"{$item['title']}\"" : ''; $col = isset($item['col']) ? $item['col'] : '1-3'; $id = isset($item['id']) ? "id=\"{$item['id']}\"" : ''; $content .= << -
' . $item . ''; } $buffer = \str_replace($foundTxt[0], $textareas, $buffer); $buffer = \str_replace($foundPre[0], $pres, $buffer); $search = array( '/\>[^\S ]+/s', '/[^\S ]+\', '<', '\\1', ); $buffer = \preg_replace($search, $replace, $buffer); $textareas = array(); foreach (\array_keys($foundTxt[0]) as $item) { $textareas[] = ''; } $pres = array(); foreach (\array_keys($foundPre[0]) as $item) { $pres[] = '
' . $item . ''; } $buffer = \str_replace($textareas, $foundTxt[0], $buffer); $buffer = \str_replace($pres, $foundPre[0], $buffer); return $buffer; } public static function getClientIp() { $keys = array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'); foreach ($keys as $key) { if ( ! isset($_SERVER[$key])) { continue; } $ip = \array_filter(\explode(',', $_SERVER[$key])); $ip = \filter_var(\end($ip), \FILTER_VALIDATE_IP); if ($ip) { return $ip; } } return ''; } public static function getCpuUsage() { static $cpu = null; if (null !== $cpu) { return $cpu; } if (self::isWin()) { $cpu = self::getWinCpuUsage(); return $cpu; } $filePath = ('/proc/stat'); if ( ! \is_readable($filePath)) { $cpu = array(); return $cpu; } $stat1 = \file($filePath); \sleep(1); $stat2 = \file($filePath); $info1 = \explode(' ', \preg_replace('!cpu +!', '', $stat1[0])); $info2 = \explode(' ', \preg_replace('!cpu +!', '', $stat2[0])); $dif = array(); $dif['user'] = $info2[0] - $info1[0]; $dif['nice'] = $info2[1] - $info1[1]; $dif['sys'] = $info2[2] - $info1[2]; $dif['idle'] = $info2[3] - $info1[3]; $total = \array_sum($dif); $cpu = array(); foreach ($dif as $x => $y) { $cpu[$x] = \round($y / $total * 100, 1); } return $cpu; } public static function getHumanCpuUsageDetail() { $cpu = self::getCpuUsage(); if ( ! $cpu) { return ''; } $html = ''; foreach ($cpu as $k => $v) { $html .= <<{$k} +{$k} {$v} HTML; -} return $html; } public static function getHumanCpuUsage() { $cpu = self::getCpuUsage(); return $cpu ?: array(); } public static function getSysLoadAvg() { if (self::isWin()) { return I18nApi::_('Not support on Windows'); } $avg = \sys_getloadavg(); $langMin = function ($n) { return \sprintf(I18nApi::_('%d minute(s)'), $n); }; $avg = \array_map(function ($load) { $load = \sprintf('%.2f', $load); return << -{$load} - -HTML; -}, $avg); return \implode('', $avg); } public static function getMemoryUsage($key) { $key = \ucfirst($key); if (self::isWin()) { return 0; } static $memInfo = null; if (null === $memInfo) { $memInfoFile = '/proc/meminfo'; if ( ! \is_readable($memInfoFile)) { $memInfo = 0; return 0; } $memInfo = \file_get_contents($memInfoFile); $memInfo = \str_replace(array( ' kB', ' ', ), '', $memInfo); $lines = array(); foreach (\explode("\n", $memInfo) as $line) { if ( ! $line) { continue; } $line = \explode(':', $line); $lines[$line[0]] = (int) $line[1]; } $memInfo = $lines; } switch ($key) { case 'MemRealUsage': $memAvailable = 0; if (isset($memInfo['MemAvailable'])) { $memAvailable = $memInfo['MemAvailable']; } elseif (isset($memInfo['MemFree'])) { $memAvailable = $memInfo['MemFree']; } return $memInfo['MemTotal'] - $memAvailable; case 'SwapRealUsage': if ( ! isset($memInfo['SwapTotal']) || ! isset($memInfo['SwapFree']) || ! isset($memInfo['SwapCached'])) { return 0; } return $memInfo['SwapTotal'] - $memInfo['SwapFree'] - $memInfo['SwapCached']; } return isset($memInfo[$key]) ? (int) $memInfo[$key] : 0; } public static function formatBytes($bytes, $precision = 2) { if ( ! $bytes) { return 0; } $base = \log($bytes, 1024); $suffixes = array('', ' K', ' M', ' G', ' T'); return \round(\pow(1024, $base - \floor($base)), $precision) . $suffixes[\floor($base)]; } public static function getHumamMemUsage($key) { return self::formatBytes(self::getMemoryUsage($key) * 1024); } public static function strcut($str, $len = 20) { if (\strlen($str) > $len) { return \mb_strcut($str, 0, $len) . '...'; } return $str; } } -namespace InnStudio\Prober\Benchmark; use InnStudio\Prober\Events\EventsApi; use InnStudio\Prober\Helper\HelperApi; use InnStudio\Prober\I18n\I18nApi; class Benchmark { private $EXPIRED = 60; public function __construct() { EventsApi::on('init', array($this, 'filter')); } public function filter() { if ( ! HelperApi::isAction('benchmark')) { return; } $this->display(); } private function getTmpRecorderPath() { return \sys_get_temp_dir() . \DIRECTORY_SEPARATOR . 'xproberBenchmarkTimer'; } private function saveTmpRecorder() { return (bool) \file_put_contents($this->getTmpRecorderPath(), \json_encode(array( 'expired' => (int) $_SERVER['REQUEST_TIME'] + $this->EXPIRED, ))); } private function getRemainingSeconds() { $path = $this->getTmpRecorderPath(); if ( ! \is_readable($path)) { return 0; } $data = (string) \file_get_contents($this->getTmpRecorderPath()); if ( ! $data) { return 0; } $data = \json_decode($data, true); if ( ! $data) { return 0; } $expired = isset($data['expired']) ? (int) $data['expired'] : 0; if ( ! $expired) { return 0; } return $expired > (int) $_SERVER['REQUEST_TIME'] ? $expired - (int) $_SERVER['REQUEST_TIME'] : 0; } private function getPointsByTime($time) { return \pow(10, 3) - (int) ($time * \pow(10, 3)); } private function getHashPoints() { $data = 'inn-studio.com'; $hash = array('md5', 'sha512', 'sha256', 'crc32'); $count = \pow(10, 5); $start = \microtime(true); for ($i = 0; $i < $count; ++$i) { foreach ($hash as $v) { \hash($v, $data); } } return $this->getPointsByTime(\microtime(true) - $start); } private function getIntLoopPoints() { $j = 0; $count = \pow(10, 7); $start = \microtime(true); for ($i = 0; $i < $count; ++$i) { ++$j; } return $this->getPointsByTime(\microtime(true) - $start); } private function getFloatLoopPoints() { $j = 1 / 3; $count = \pow(10, 7); $start = \microtime(true); for ($i = 0; $i < $count; ++$i) { ++$j; } return $this->getPointsByTime(\microtime(true) - $start); } private function getIoLoopPoints() { $tmpDir = \sys_get_temp_dir(); if ( ! \is_writable($tmpDir)) { return 0; } $count = \pow(10, 4); $start = \microtime(true); for ($i = 0; $i < $count; ++$i) { $filePath = "{$tmpDir}/innStudioIoBenchmark:{$i}"; \file_put_contents($filePath, $filePath); \unlink($filePath); } return $this->getPointsByTime(\microtime(true) - $start); } private function getPoints() { return array( 'hash' => $this->getHashPoints(), 'intLoop' => $this->getIntLoopPoints(), 'floatLoop' => $this->getFloatLoopPoints(), 'ioLoop' => $this->getIoLoopPoints(), ); } private function display() { $remainingSeconds = $this->getRemainingSeconds(); if ($remainingSeconds) { HelperApi::dieJson(array( 'code' => -1, 'msg' => \sprintf(I18nApi::_('Please wait %d seconds'), $remainingSeconds), )); } $this->saveTmpRecorder(); \set_time_limit(0); HelperApi::dieJson(array( 'code' => 0, 'data' => array( 'points' => $this->getPoints(), ), )); } } -namespace InnStudio\Prober\PhpInfoDetail; use InnStudio\Prober\Events\EventsApi; use InnStudio\Prober\Helper\HelperApi; class PhpInfoDetail { public function __construct() { EventsApi::on('init', array($this, 'filter')); } public function filter() { if (HelperApi::isAction('phpInfo')) { \phpinfo(); die; } } } -namespace InnStudio\Prober\Entry; use InnStudio\Prober\Config\ConfigApi; use InnStudio\Prober\Events\EventsApi; use InnStudio\Prober\Helper\HelperApi; use InnStudio\Prober\I18n\I18nApi; class Entry { public function __construct() { EventsApi::emit('init'); if (DEBUG === true) { $this->display(); } else { \ob_start(); $this->display(); $content = \ob_get_contents(); \ob_end_clean(); echo HelperApi::htmlMinify($content); } } private function displayContent() { $mods = EventsApi::emit('mods', array()); if ( ! $mods) { return; } foreach ($mods as $id => $mod) { $content = \call_user_func($mod['display']); echo << -