Changeset 3747021
- Timestamp:
- 10/14/2026 07:21:05 PM (4 weeks ago)
- Location:
- easy-optimizer
- Files:
-
- 736 added
- 18 edited
-
tags/2.7.3 (added)
-
tags/2.7.3/assets (added)
-
tags/2.7.3/assets/advanced-cache.php (added)
-
tags/2.7.3/assets/app.js (added)
-
tags/2.7.3/assets/easyopt-beacon.js (added)
-
tags/2.7.3/assets/easyopt-beacon.min.js (added)
-
tags/2.7.3/assets/easyopt-delay.min.js (added)
-
tags/2.7.3/assets/easyopt-lazy-shim.js (added)
-
tags/2.7.3/assets/easyopt-lazy-shim.min.js (added)
-
tags/2.7.3/assets/easyopt-lcp-beacon.js (added)
-
tags/2.7.3/assets/easyopt-lcp-beacon.min.js (added)
-
tags/2.7.3/assets/easyopt-media.js (added)
-
tags/2.7.3/assets/icons (added)
-
tags/2.7.3/assets/icons/icon-128x128.png (added)
-
tags/2.7.3/assets/icons/icon-256x256.png (added)
-
tags/2.7.3/assets/icons/icon.svg (added)
-
tags/2.7.3/assets/lazyload.min.js (added)
-
tags/2.7.3/assets/object-cache.php (added)
-
tags/2.7.3/assets/style.css (added)
-
tags/2.7.3/assets/wizard.js (added)
-
tags/2.7.3/easy-optimizer.php (added)
-
tags/2.7.3/includes (added)
-
tags/2.7.3/includes/backend (added)
-
tags/2.7.3/includes/backend/class-backend.php (added)
-
tags/2.7.3/includes/backend/class-profiler.php (added)
-
tags/2.7.3/includes/backend/class-query-log.php (added)
-
tags/2.7.3/includes/cache (added)
-
tags/2.7.3/includes/cache/cache-common.php (added)
-
tags/2.7.3/includes/cache/trait-easyopt-cache-htaccess.php (added)
-
tags/2.7.3/includes/cache/trait-easyopt-cache-purge.php (added)
-
tags/2.7.3/includes/class-easyopt-accessibility.php (added)
-
tags/2.7.3/includes/class-easyopt-advanced-cache.php (added)
-
tags/2.7.3/includes/class-easyopt-autoloader.php (added)
-
tags/2.7.3/includes/class-easyopt-bloat.php (added)
-
tags/2.7.3/includes/class-easyopt-cache-counter.php (added)
-
tags/2.7.3/includes/class-easyopt-cache-preload.php (added)
-
tags/2.7.3/includes/class-easyopt-cache.php (added)
-
tags/2.7.3/includes/class-easyopt-cdn-assets.php (added)
-
tags/2.7.3/includes/class-easyopt-cdn-cloud.php (added)
-
tags/2.7.3/includes/class-easyopt-cdn.php (added)
-
tags/2.7.3/includes/class-easyopt-cloudflare.php (added)
-
tags/2.7.3/includes/class-easyopt-config.php (added)
-
tags/2.7.3/includes/class-easyopt-css-tokenizer.php (added)
-
tags/2.7.3/includes/class-easyopt-database.php (added)
-
tags/2.7.3/includes/class-easyopt-db-snapshot.php (added)
-
tags/2.7.3/includes/class-easyopt-debug-log.php (added)
-
tags/2.7.3/includes/class-easyopt-defer-js.php (added)
-
tags/2.7.3/includes/class-easyopt-delay-js.php (added)
-
tags/2.7.3/includes/class-easyopt-fonts.php (added)
-
tags/2.7.3/includes/class-easyopt-hosting.php (added)
-
tags/2.7.3/includes/class-easyopt-html-mask.php (added)
-
tags/2.7.3/includes/class-easyopt-images-capability.php (added)
-
tags/2.7.3/includes/class-easyopt-images-delivery.php (added)
-
tags/2.7.3/includes/class-easyopt-images-encoder.php (added)
-
tags/2.7.3/includes/class-easyopt-images-media.php (added)
-
tags/2.7.3/includes/class-easyopt-images.php (added)
-
tags/2.7.3/includes/class-easyopt-lazyload.php (added)
-
tags/2.7.3/includes/class-easyopt-lcp.php (added)
-
tags/2.7.3/includes/class-easyopt-migration.php (added)
-
tags/2.7.3/includes/class-easyopt-minify.php (added)
-
tags/2.7.3/includes/class-easyopt-navigate.php (added)
-
tags/2.7.3/includes/class-easyopt-notices.php (added)
-
tags/2.7.3/includes/class-easyopt-object-cache.php (added)
-
tags/2.7.3/includes/class-easyopt-preconnect.php (added)
-
tags/2.7.3/includes/class-easyopt-preflight.php (added)
-
tags/2.7.3/includes/class-easyopt-preload-results.php (added)
-
tags/2.7.3/includes/class-easyopt-presets.php (added)
-
tags/2.7.3/includes/class-easyopt-queue.php (added)
-
tags/2.7.3/includes/class-easyopt-rest-cloud.php (added)
-
tags/2.7.3/includes/class-easyopt-rest-dashboard.php (added)
-
tags/2.7.3/includes/class-easyopt-rest-settings.php (added)
-
tags/2.7.3/includes/class-easyopt-save-coordinator.php (added)
-
tags/2.7.3/includes/class-easyopt-seo.php (added)
-
tags/2.7.3/includes/class-easyopt-settings-registry.php (added)
-
tags/2.7.3/includes/class-easyopt-settings.php (added)
-
tags/2.7.3/includes/class-easyopt-tracker.php (added)
-
tags/2.7.3/includes/class-easyopt-unused-css.php (added)
-
tags/2.7.3/includes/class-easyopt-wizard.php (added)
-
tags/2.7.3/includes/class-easyopt-wp-config.php (added)
-
tags/2.7.3/includes/compat (added)
-
tags/2.7.3/includes/compat/class-easyopt-compat-builders.php (added)
-
tags/2.7.3/includes/compat/class-easyopt-compat-conflicts.php (added)
-
tags/2.7.3/includes/compat/class-easyopt-compat-divi.php (added)
-
tags/2.7.3/includes/compat/class-easyopt-compat-fonts.php (added)
-
tags/2.7.3/includes/compat/class-easyopt-compat-lazyload.php (added)
-
tags/2.7.3/includes/compat/class-easyopt-compat-multilingual.php (added)
-
tags/2.7.3/includes/compat/class-easyopt-compat-woocommerce.php (added)
-
tags/2.7.3/includes/psi (added)
-
tags/2.7.3/includes/psi/class-client.php (added)
-
tags/2.7.3/readme.txt (added)
-
tags/2.7.3/uninstall.php (added)
-
tags/2.7.3/vendor (added)
-
tags/2.7.3/vendor/autoload.php (added)
-
tags/2.7.3/vendor/bin (added)
-
tags/2.7.3/vendor/bin/minifycss (added)
-
tags/2.7.3/vendor/bin/minifycss.bat (added)
-
tags/2.7.3/vendor/bin/minifyjs (added)
-
tags/2.7.3/vendor/bin/minifyjs.bat (added)
-
tags/2.7.3/vendor/composer (added)
-
tags/2.7.3/vendor/composer/ClassLoader.php (added)
-
tags/2.7.3/vendor/composer/InstalledVersions.php (added)
-
tags/2.7.3/vendor/composer/LICENSE (added)
-
tags/2.7.3/vendor/composer/autoload_classmap.php (added)
-
tags/2.7.3/vendor/composer/autoload_namespaces.php (added)
-
tags/2.7.3/vendor/composer/autoload_psr4.php (added)
-
tags/2.7.3/vendor/composer/autoload_real.php (added)
-
tags/2.7.3/vendor/composer/autoload_static.php (added)
-
tags/2.7.3/vendor/composer/installed.json (added)
-
tags/2.7.3/vendor/composer/installed.php (added)
-
tags/2.7.3/vendor/composer/platform_check.php (added)
-
tags/2.7.3/vendor/matthiasmullie (added)
-
tags/2.7.3/vendor/matthiasmullie/minify (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/LICENSE (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/bin (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/bin/minifycss (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/bin/minifyjs (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/composer.json (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/data (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/data/js (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/data/js/keywords_after.txt (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/data/js/keywords_before.txt (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/data/js/keywords_reserved.txt (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/data/js/operators.txt (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/data/js/operators_after.txt (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/data/js/operators_before.txt (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/CSS.php (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/Exception.php (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/Exceptions (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/Exceptions/BasicException.php (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/Exceptions/IOException.php (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/Exceptions/PatternMatchException.php (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/JS.php (added)
-
tags/2.7.3/vendor/matthiasmullie/minify/src/Minify.php (added)
-
tags/2.7.3/vendor/matthiasmullie/path-converter (added)
-
tags/2.7.3/vendor/matthiasmullie/path-converter/LICENSE (added)
-
tags/2.7.3/vendor/matthiasmullie/path-converter/composer.json (added)
-
tags/2.7.3/vendor/matthiasmullie/path-converter/src (added)
-
tags/2.7.3/vendor/matthiasmullie/path-converter/src/Converter.php (added)
-
tags/2.7.3/vendor/matthiasmullie/path-converter/src/ConverterInterface.php (added)
-
tags/2.7.3/vendor/matthiasmullie/path-converter/src/NoConverter.php (added)
-
tags/2.7.3/vendor/predis (added)
-
tags/2.7.3/vendor/predis/predis (added)
-
tags/2.7.3/vendor/predis/predis/LICENSE (added)
-
tags/2.7.3/vendor/predis/predis/autoload.php (added)
-
tags/2.7.3/vendor/predis/predis/composer.json (added)
-
tags/2.7.3/vendor/predis/predis/src (added)
-
tags/2.7.3/vendor/predis/predis/src/Autoloader.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Client.php (added)
-
tags/2.7.3/vendor/predis/predis/src/ClientConfiguration.php (added)
-
tags/2.7.3/vendor/predis/predis/src/ClientContextInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/ClientException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/ClientInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/ClusterStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Distributor (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Distributor/DistributorInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Distributor/EmptyRingException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Distributor/HashRing.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Distributor/KetamaRing.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Hash (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Hash/CRC16.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Hash/HashGeneratorInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/Hash/PhpiredisCRC16.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/PredisStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/RedisStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/SlotMap.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Cluster/StrategyInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Collection (added)
-
tags/2.7.3/vendor/predis/predis/src/Collection/Iterator (added)
-
tags/2.7.3/vendor/predis/predis/src/Collection/Iterator/CursorBasedIterator.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Collection/Iterator/HashKey.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Collection/Iterator/Keyspace.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Collection/Iterator/ListKey.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Collection/Iterator/SetKey.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Collection/Iterator/SortedSetKey.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/ArrayableArgument.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Geospatial (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Geospatial/AbstractBy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Geospatial/ByBox.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Geospatial/ByInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Geospatial/ByRadius.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Geospatial/FromInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Geospatial/FromLonLat.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Geospatial/FromMember.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/AggregateArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/AlterArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/CommonArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/CreateArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/CursorArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/DropArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/ExplainArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/ProfileArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SchemaFields (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SchemaFields/AbstractField.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SchemaFields/FieldInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SchemaFields/GeoField.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SchemaFields/NumericField.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SchemaFields/TagField.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SchemaFields/TextField.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SchemaFields/VectorField.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SearchArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SpellcheckArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SugAddArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SugGetArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Search/SynUpdateArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Server (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Server/LimitInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Server/LimitOffsetCount.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/Server/To.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/AddArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/AlterArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/CommonArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/CreateArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/DecrByArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/GetArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/IncrByArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/InfoArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/MGetArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/MRangeArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Argument/TimeSeries/RangeArguments.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Command.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/CommandInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Factory.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/FactoryInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/PrefixableCommandInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Processor (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Processor/KeyPrefixProcessor.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Processor/ProcessorChain.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Processor/ProcessorInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/RawCommand.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/RawFactory.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ACL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/APPEND.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/AUTH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/AbstractCommand (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/AbstractCommand/BZPOPBase.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BGREWRITEAOF.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BGSAVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BITCOUNT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BITFIELD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BITOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BITPOS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BLMOVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BLMPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BLPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BRPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BRPOPLPUSH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BZMPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BZPOPMAX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BZPOPMIN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFEXISTS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFINFO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFINSERT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFLOADCHUNK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFMADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFMEXISTS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFRESERVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/BloomFilter/BFSCANDUMP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CLIENT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CLUSTER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/COMMAND.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CONFIG.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/COPY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/ACL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/AbstractContainer.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/CLUSTER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/ContainerFactory.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/ContainerInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/FunctionContainer.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/Json (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/Json/JSONDEBUG.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/Search (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/Search/FTCONFIG.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Container/Search/FTCURSOR.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CountMinSketch (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CountMinSketch/CMSINCRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CountMinSketch/CMSINFO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CountMinSketch/CMSINITBYDIM.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CountMinSketch/CMSINITBYPROB.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CountMinSketch/CMSMERGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CountMinSketch/CMSQUERY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFADDNX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFCOUNT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFEXISTS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFINFO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFINSERT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFINSERTNX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFLOADCHUNK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFMEXISTS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFRESERVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/CuckooFilter/CFSCANDUMP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/DBSIZE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/DECR.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/DECRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/DEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/DISCARD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/DUMP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ECHO_.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EVALSHA.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EVALSHA_RO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EVAL_.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EVAL_RO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EXEC.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EXISTS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EXPIRE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EXPIREAT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/EXPIRETIME.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/FAILOVER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/FCALL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/FCALL_RO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/FLUSHALL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/FLUSHDB.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/FUNCTIONS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GEOADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GEODIST.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GEOHASH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GEOPOS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GEORADIUS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GEORADIUSBYMEMBER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GEOSEARCH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GEOSEARCHSTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GETBIT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GETDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GETEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GETRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/GETSET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HEXISTS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HGETALL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HINCRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HINCRBYFLOAT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HKEYS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HMGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HMSET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HRANDFIELD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HSCAN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HSET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HSETNX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HSTRLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/HVALS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/INCR.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/INCRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/INCRBYFLOAT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/INFO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONARRAPPEND.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONARRINDEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONARRINSERT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONARRLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONARRPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONARRTRIM.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONCLEAR.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONDEBUG.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONFORGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONMERGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONMGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONMSET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONNUMINCRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONOBJKEYS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONOBJLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONRESP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONSET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONSTRAPPEND.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONSTRLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONTOGGLE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Json/JSONTYPE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/KEYS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LASTSAVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LCS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LINDEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LINSERT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LMOVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LMPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LPUSH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LPUSHX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LREM.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LSET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/LTRIM.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/MGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/MIGRATE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/MONITOR.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/MOVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/MSET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/MSETNX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/MULTI.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/OBJECT_.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PERSIST.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PEXPIRE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PEXPIREAT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PEXPIRETIME.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PFADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PFCOUNT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PFMERGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PING.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PSETEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PSUBSCRIBE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PTTL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PUBLISH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PUBSUB.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/PUNSUBSCRIBE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/QUIT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/RANDOMKEY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/RENAME.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/RENAMENX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/RESTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/RPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/RPOPLPUSH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/RPUSH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/RPUSHX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SAVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SCAN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SCARD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SCRIPT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SDIFF.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SDIFFSTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SELECT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SENTINEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SETBIT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SETEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SETNX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SETRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SHUTDOWN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SINTER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SINTERCARD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SINTERSTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SISMEMBER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SLAVEOF.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SLOWLOG.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SMEMBERS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SMISMEMBER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SMOVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SORT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SORT_RO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SRANDMEMBER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SREM.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SSCAN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/STRLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SUBSCRIBE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SUBSTR.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SUNION.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/SUNIONSTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTAGGREGATE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTALIASADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTALIASDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTALIASUPDATE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTALTER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTCONFIG.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTCREATE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTCURSOR.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTDICTADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTDICTDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTDICTDUMP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTDROPINDEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTEXPLAIN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTINFO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTPROFILE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTSEARCH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTSPELLCHECK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTSUGADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTSUGDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTSUGGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTSUGLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTSYNDUMP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTSYNUPDATE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/Search/FTTAGVALS.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTBYRANK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTBYREVRANK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTCDF.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTCREATE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTINFO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTMAX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTMERGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTMIN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTQUANTILE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTRANK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTRESET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTREVRANK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TDigest/TDIGESTTRIMMED_MEAN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TIME.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TOUCH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TTL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TYPE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSALTER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSCREATE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSCREATERULE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSDECRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSDELETERULE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSINCRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSINFO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSMADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSMGET.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSMRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSMREVRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSQUERYINDEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TimeSeries/TSREVRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TopK (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TopK/TOPKADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TopK/TOPKINCRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TopK/TOPKINFO.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TopK/TOPKLIST.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TopK/TOPKQUERY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/TopK/TOPKRESERVE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/UNSUBSCRIBE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/UNWATCH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/WAITAOF.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/WATCH.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/XADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/XDEL.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/XLEN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/XRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/XREVRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/XTRIM.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZADD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZCARD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZCOUNT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZDIFF.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZDIFFSTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZINCRBY.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZINTER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZINTERCARD.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZINTERSTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZLEXCOUNT.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZMPOP.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZMSCORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZPOPMAX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZPOPMIN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZRANDMEMBER.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZRANGEBYLEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZRANGEBYSCORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZRANGESTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZRANK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZREM.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZREMRANGEBYLEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZREMRANGEBYRANK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZREMRANGEBYSCORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZREVRANGE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZREVRANGEBYLEX.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZREVRANGEBYSCORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZREVRANK.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZSCAN.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZSCORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZUNION.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Redis/ZUNIONSTORE.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/RedisFactory.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/ScriptCommand.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions/DeleteStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions/DumpStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions/FlushStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions/KillStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions/ListStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions/LoadStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions/RestoreStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/ContainerCommands/Functions/StatsStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/StrategyResolverInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/SubcommandStrategyInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Strategy/SubcommandStrategyResolver.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Aggregate.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BitByte.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BloomFilters (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BloomFilters/BucketSize.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BloomFilters/Capacity.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BloomFilters/Error.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BloomFilters/Expansion.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BloomFilters/Items.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BloomFilters/MaxIterations.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/BloomFilters/NoCreate.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/By (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/By/ByArgument.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/By/ByLexByScore.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/By/GeoBy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Count.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/DB.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Expire (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Expire/ExpireOptions.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/From (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/From/GeoFrom.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Get (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Get/Get.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Json (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Json/Indent.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Json/Newline.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Json/NxXxArgument.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Json/Space.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Keys.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/LeftRight.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Limit (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Limit/Limit.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Limit/LimitObject.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/MinMaxModifier.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Replace.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Rev.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Sorting.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Storedist.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Timeout.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/To (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/To/ServerTo.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/Weights.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/With (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/With/WithCoord.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/With/WithDist.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/With/WithHash.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/With/WithScores.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Command/Traits/With/WithValues.php (added)
-
tags/2.7.3/vendor/predis/predis/src/CommunicationException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option/Aggregate.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option/CRC16.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option/Cluster.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option/Commands.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option/Connections.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option/Exceptions.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option/Prefix.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Option/Replication.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/OptionInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/Options.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Configuration/OptionsInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/AbstractConnection.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/AggregateConnectionInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Cluster (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Cluster/ClusterInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Cluster/PredisCluster.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Cluster/RedisCluster.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/CompositeConnectionInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/CompositeStreamConnection.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/ConnectionException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/ConnectionInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Factory.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/FactoryInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/NodeConnectionInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Parameters.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/ParametersInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/PhpiredisSocketConnection.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/PhpiredisStreamConnection.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/RelayConnection.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/RelayMethods.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Replication (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Replication/MasterSlaveReplication.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Replication/ReplicationInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/Replication/SentinelReplication.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/StreamConnection.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Connection/WebdisConnection.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Monitor (added)
-
tags/2.7.3/vendor/predis/predis/src/Monitor/Consumer.php (added)
-
tags/2.7.3/vendor/predis/predis/src/NotSupportedException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Pipeline (added)
-
tags/2.7.3/vendor/predis/predis/src/Pipeline/Atomic.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Pipeline/ConnectionErrorProof.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Pipeline/FireAndForget.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Pipeline/Pipeline.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Pipeline/RelayAtomic.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Pipeline/RelayPipeline.php (added)
-
tags/2.7.3/vendor/predis/predis/src/PredisException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/ProtocolException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/ProtocolProcessorInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/RequestSerializerInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/ResponseReaderInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/CompositeProtocolProcessor.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/Handler (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/Handler/BulkResponse.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/Handler/ErrorResponse.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/Handler/IntegerResponse.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/Handler/MultiBulkResponse.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/Handler/ResponseHandlerInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/Handler/StatusResponse.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/Handler/StreamableMultiBulkResponse.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/ProtocolProcessor.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/RequestSerializer.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Protocol/Text/ResponseReader.php (added)
-
tags/2.7.3/vendor/predis/predis/src/PubSub (added)
-
tags/2.7.3/vendor/predis/predis/src/PubSub/AbstractConsumer.php (added)
-
tags/2.7.3/vendor/predis/predis/src/PubSub/Consumer.php (added)
-
tags/2.7.3/vendor/predis/predis/src/PubSub/DispatcherLoop.php (added)
-
tags/2.7.3/vendor/predis/predis/src/PubSub/RelayConsumer.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Replication (added)
-
tags/2.7.3/vendor/predis/predis/src/Replication/MissingMasterException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Replication/ReplicationStrategy.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Replication/RoleException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Response (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/Error.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/ErrorInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/Iterator (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/Iterator/MultiBulk.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/Iterator/MultiBulkIterator.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/Iterator/MultiBulkTuple.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/ResponseInterface.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/ServerException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Response/Status.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Session (added)
-
tags/2.7.3/vendor/predis/predis/src/Session/Handler.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Transaction (added)
-
tags/2.7.3/vendor/predis/predis/src/Transaction/AbortedMultiExecException.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Transaction/MultiExec.php (added)
-
tags/2.7.3/vendor/predis/predis/src/Transaction/MultiExecState.php (added)
-
trunk/assets/app.js (modified) (3 diffs)
-
trunk/assets/easyopt-beacon.js (modified) (2 diffs)
-
trunk/assets/easyopt-beacon.min.js (modified) (1 diff)
-
trunk/assets/easyopt-media.js (added)
-
trunk/easy-optimizer.php (modified) (4 diffs)
-
trunk/includes/class-easyopt-accessibility.php (modified) (3 diffs)
-
trunk/includes/class-easyopt-autoloader.php (modified) (1 diff)
-
trunk/includes/class-easyopt-cache-preload.php (modified) (2 diffs)
-
trunk/includes/class-easyopt-cdn-cloud.php (modified) (2 diffs)
-
trunk/includes/class-easyopt-images-media.php (added)
-
trunk/includes/class-easyopt-images.php (modified) (16 diffs)
-
trunk/includes/class-easyopt-lcp.php (modified) (1 diff)
-
trunk/includes/class-easyopt-queue.php (modified) (5 diffs)
-
trunk/includes/class-easyopt-rest-cloud.php (modified) (1 diff)
-
trunk/includes/class-easyopt-rest-dashboard.php (modified) (4 diffs)
-
trunk/includes/class-easyopt-save-coordinator.php (modified) (1 diff)
-
trunk/includes/class-easyopt-settings-registry.php (modified) (1 diff)
-
trunk/includes/class-easyopt-settings.php (modified) (1 diff)
-
trunk/includes/class-easyopt-tracker.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
easy-optimizer/trunk/assets/app.js
r3697647 r3747021 724 724 : React.createElement(FixNextCard, { psiData: psiData, dev: psiDev, switchTab: switchTab, settings: settings }), React.createElement("div", { className: "eop-card" }, React.createElement("div", { className: "eop-card__header" }, React.createElement("div", null, React.createElement("div", { className: "eop-card__kicker" }, "Operations"), React.createElement("div", { className: "eop-card__title" }, "Quick actions"))), cacheOn && preloadOn && React.createElement(React.Fragment, null, React.createElement("button", { type: "button", className: "eop-btn eop-btn--primary eop-btn--full", disabled: !!busy, "aria-busy": busy === 'preload', onClick: startPreload }, React.createElement("span", { className: "eop-btn-icon" }, React.createElement(Icon, { id: "refresh" })), React.createElement("span", { className: "eop-btn-label" }, "Preload Cache"), React.createElement("span", { className: "eop-btn-spinner" })), React.createElement("button", { type: "button", className: "eop-btn eop-btn--ghost eop-btn--full", disabled: !!busy, "aria-busy": busy === 'both', onClick: clearAndPreload }, React.createElement("span", { className: "eop-btn-icon" }, React.createElement(Icon, { id: "trash" })), React.createElement("span", { className: "eop-btn-label" }, "Clear Cache & Preload"), React.createElement("span", { className: "eop-btn-spinner" })), cfConnected && React.createElement("button", { type: "button", className: "eop-btn eop-btn--ghost eop-btn--full", disabled: !!busy, "aria-busy": busy === 'cf', onClick: clearCfCache }, React.createElement("span", { className: "eop-btn-icon" }, React.createElement(Icon, { id: "cloud" })), React.createElement("span", { className: "eop-btn-label" }, "Clear Cloudflare Cache"), React.createElement("span", { className: "eop-btn-spinner" })), ps.status === 'paused' && React.createElement("div", { className: "eop-action-status", style: { color: '#d97706' } }, "Paused — server busy", ps.paused_reason ? ` (${ps.paused_reason})` : '', ". Resumes automatically.")), cacheOn && !preloadOn && React.createElement(React.Fragment, null, React.createElement("button", { type: "button", className: "eop-btn eop-btn--primary eop-btn--full", disabled: !!busy, onClick: clearCache }, React.createElement("span", { className: "eop-btn-icon" }, React.createElement(Icon, { id: "trash" })), React.createElement("span", { className: "eop-btn-label" }, "Clear Cache"), React.createElement("span", { className: "eop-btn-spinner" })), cfConnected && React.createElement("button", { type: "button", className: "eop-btn eop-btn--ghost eop-btn--full", disabled: !!busy, "aria-busy": busy === 'cf', onClick: clearCfCache }, React.createElement("span", { className: "eop-btn-icon" }, React.createElement(Icon, { id: "cloud" })), React.createElement("span", { className: "eop-btn-label" }, "Clear Cloudflare Cache"), React.createElement("span", { className: "eop-btn-spinner" }))), !cacheOn && React.createElement("div", { className: "eop-empty-state" }, React.createElement("div", { className: "eop-empty-state__icon" }, React.createElement(Icon, { id: "info" })), React.createElement("div", { className: "eop-empty-state__text" }, "Enable Page Cache in the Caching tab to access quick actions."), React.createElement("a", { href: "#", className: "eop-tab eop-btn eop-btn--soft eop-btn--sm", onClick: (e) => { e.preventDefault(); switchTab('cache'); } }, "Go to Caching")), React.createElement("div", { id: "eop-action-msg", className: "eop-action-msg", style: { color: actionMsg.ok === false ? 'var(--eop-danger)' : actionMsg.ok === true ? 'var(--eop-success)' : 'var(--eop-text-muted)' } }, actionMsg.text), 725 725 // Pro upgrade card — inside the Quick actions card, below the buttons. 726 (settings.easyopt_cloud_account || Number(settings.easyopt_fluxcdn_verified) === 1) ? null : React.createElement("div", { className: "eop-upsell eop-upsell--dash" }, React.createElement("div", { className: "eop-upsell__tag" }, "⚡ Pro"), React.createElement("div", { className: "eop-upsell__title" }, "Unlock the edge"), React.createElement("div", { className: "eop-upsell__body" }, "Guaranteed 90+ PageSpeed. Images, CSS, JS & fonts served from 119 locations."), React.createElement("button", { type: "button", className: "eop-upsell__btn", onClick: () => switchTab('flux') }, "Unlock 90+ PageSpeed Now")))), (() => { 726 // Hidden once connected, and once the mobile "after" score is 727 // already 90+: the card's pitch is a 90+ score. 728 (settings.easyopt_cloud_account || Number(settings.easyopt_fluxcdn_verified) === 1 || (psiData?.results?.mobile?.after?.score ?? 0) >= 90) ? null : React.createElement("div", { className: "eop-upsell eop-upsell--dash" }, React.createElement("div", { className: "eop-upsell__tag" }, "⚡ Pro"), React.createElement("div", { className: "eop-upsell__title" }, "Unlock the edge"), React.createElement("div", { className: "eop-upsell__body" }, "Guaranteed 90+ PageSpeed. Images, CSS, JS & fonts served from 119 locations."), React.createElement("button", { type: "button", className: "eop-upsell__btn", onClick: () => switchTab('flux') }, "Unlock 90+ PageSpeed Now")))), (() => { 727 729 const sc = liveStats?.server_cache; 728 730 const layers = sc?.layers || []; … … 1012 1014 const total = stats ? Number(stats.total) : 0; 1013 1015 const done = stats ? Number(stats.optimized) : 0; 1016 // Live, and on the same clock as `pending`, so processed + pending = total 1017 // on every poll (skipped and failed images count as processed). 1018 const processed = stats ? Number(stats.processed || 0) : 0; 1014 1019 const pending = stats ? Number(stats.pending || 0) : 0; 1020 const restoring = stats ? Number(stats.restoring || 0) : 0; 1015 1021 const failed = stats ? Number(stats.failed || 0) : 0; 1016 1022 const skipped = stats ? Number(stats.skipped || 0) : 0; 1023 const excluded = stats ? Number(stats.excluded || 0) : 0; 1017 1024 const running = !!(stats && stats.running); 1018 const pct = total > 0 ? Math.round(done / total * 100) : 0; 1025 const restoringOnly = running && pending === 0 && restoring > 0; 1026 // floor, not round: 201 of 202 must not read 100%. 1027 const pct = total > 0 ? Math.floor(processed / total * 100) : 0; 1019 1028 return React.createElement("div", null, stats && React.createElement("div", { className: "eop-callout", style: noFormats ? { borderLeft: '3px solid var(--eop-warn, #dba617)', marginBottom: '16px' } : { marginBottom: '16px' } }, React.createElement("p", { style: { margin: 0, fontSize: '13px' } }, React.createElement("strong", null, noFormats ? 'Limited on this host: ' : 'This host supports: '), stats.capability)), React.createElement(Check, { name: "easyopt_images", label: "Optimize images on this server", bold: true, settings: settings, onChange: onChange, disabled: noFormats, 1020 1029 desc: noFormats ? "Nothing to enable until this host can encode WebP or AVIF." : "AVIF and WebP copies are made next to your originals, which are never modified." }), on && stats && React.createElement("div", { className: "eop-imgstat", style: { marginTop: '18px' } }, 1021 1030 // Live headline. During a run it reads "Optimizing N of M"; at 1022 1031 // rest it reads how many are done and what was saved. 1023 React.createElement("div", { className: "eop-imgstat__head" }, React.createElement("div", null, running 1024 ? React.createElement("span", null, React.createElement("span", { className: "eop-imgstat__spin" }), " Optimizing \u2014 ", React.createElement("strong", null, nf(done) + " of " + nf(total)), " done, ", nf(pending), " to go") 1025 : React.createElement("span", null, React.createElement("strong", null, nf(done) + " of " + nf(total) + " images"), " optimized", stats.saved > 0 ? React.createElement("span", null, " \u00b7 ", React.createElement("strong", null, stats.saved_human), " saved") : null)), React.createElement("div", { className: "eop-imgstat__pct" }, pct + "%")), React.createElement("div", { className: "eop-imgstat__bar" }, React.createElement("div", { className: "eop-imgstat__fill" + (running ? " is-running" : ""), style: { width: pct + '%' } })), (skipped + failed) > 0 && React.createElement("p", { className: "description", style: { margin: '8px 0 0', color: 'var(--eop-warn-fg, #92400e)' } }, nf(skipped + failed) + " couldn't be optimized (unsupported, animated, too large, or already small) and were skipped."), React.createElement("p", { style: { margin: '14px 0 0' } }, React.createElement("button", { type: "button", className: "button button-primary", disabled: !!busy || running || stats.remaining === 0, onClick: () => act('/images/optimize', 'optimize') }, running ? 'Optimizing\u2026' : (stats.remaining > 0 ? 'Optimize ' + nf(stats.remaining) + ' remaining' : 'All images optimized')), React.createElement("button", { type: "button", className: "button", style: { marginLeft: '8px' }, disabled: !!busy || running || done === 0, 1032 React.createElement("div", { className: "eop-imgstat__head" }, React.createElement("div", null, restoringOnly 1033 ? React.createElement("span", null, React.createElement("span", { className: "eop-imgstat__spin" }), " Restoring originals \u2014 ", React.createElement("strong", null, nf(restoring)), " to go") 1034 : running 1035 ? React.createElement("span", null, React.createElement("span", { className: "eop-imgstat__spin" }), " Optimizing \u2014 ", React.createElement("strong", null, nf(processed) + " of " + nf(total)), " done, ", nf(pending), " to go") 1036 : React.createElement("span", null, React.createElement("strong", null, nf(done) + " of " + nf(total) + " images"), " optimized", stats.saved > 0 ? React.createElement("span", null, " \u00b7 ", React.createElement("strong", null, stats.saved_human), " saved") : null)), React.createElement("div", { className: "eop-imgstat__pct" }, pct + "%")), React.createElement("div", { className: "eop-imgstat__bar" }, React.createElement("div", { className: "eop-imgstat__fill" + (running ? " is-running" : ""), style: { width: pct + '%' } })), (skipped + failed) > 0 && React.createElement("p", { className: "description", style: { margin: '8px 0 0', color: 'var(--eop-warn-fg, #92400e)' } }, nf(skipped + failed) + " couldn't be optimized (unsupported, animated, too large, or already small) and were skipped."), excluded > 0 && React.createElement("p", { className: "description", style: { margin: '8px 0 0' } }, nf(excluded) + " restored to the original in the Media Library. Bulk runs leave " + (excluded === 1 ? "it" : "them") + " alone."), React.createElement("p", { style: { margin: '14px 0 0' } }, React.createElement("button", { type: "button", className: "button button-primary", disabled: !!busy || running || stats.remaining === 0, onClick: () => act('/images/optimize', 'optimize') }, running ? (restoringOnly ? 'Restoring\u2026' : 'Optimizing\u2026') : (stats.remaining > 0 ? 'Optimize ' + nf(stats.remaining) + ' remaining' : 'All images optimized')), 1037 // Drops the queue; the image being encoded finishes, finished 1038 // images stay optimized, and "Optimize N remaining" resumes. 1039 running && React.createElement("button", { type: "button", className: "button", style: { marginLeft: '8px' }, disabled: !!busy, onClick: () => act('/images/stop', 'stop') }, busy === 'stop' ? 'Stopping\u2026' : 'Stop'), React.createElement("button", { type: "button", className: "button", style: { marginLeft: '8px' }, disabled: !!busy || running || done === 0, 1026 1040 onClick: () => { if (window.confirm('Delete every optimized copy and restore your originals? Your originals were never modified, so nothing is lost.')) { 1027 1041 act('/images/restore', 'restore'); … … 1849 1863 ['easyopt_a11y_progressbar', 'ARIA progressbar elements do not have accessible names'], 1850 1864 ['easyopt_a11y_tabindex', 'Some elements have a [tabindex] value greater than 0'], 1865 ['easyopt_a11y_skip_link', 'Skip links are not focusable'], 1866 ['easyopt_a11y_main_landmark', 'Document does not have a main landmark'], 1851 1867 ]; 1852 1868 return (React.createElement("div", { style: { display: "block" }, className: "eop-panel", id: "eop-panel-accessibility" }, React.createElement("h2", { className: "eop-section-h" }, "Accessibility"), React.createElement("p", { className: "description", style: { marginBottom: '18px' } }, "Fix common Lighthouse accessibility audits. Enable only the options relevant to your site."), a11y.map(([key, label]) => React.createElement(Check, { key: key, name: key, label: label, settings: settings, onChange: onChange })), React.createElement("h2", { className: "eop-section-h", style: { marginTop: '34px' } }, "SEO"), React.createElement("p", { className: "description", style: { marginBottom: '18px' } }, "Fix common Lighthouse SEO audits."), React.createElement(Check, { name: "easyopt_seo_crawlable_links", label: "Make non-crawlable links crawlable", settings: settings, onChange: onChange, desc: 'Any <a> with missing/empty/javascript:void(0) href is rewritten to "#".' }), React.createElement(Check, { name: "easyopt_seo_image_alts", label: "Add missing image alt attributes", settings: settings, onChange: onChange, desc: "Fills missing alt from image title or filename." }))); -
easy-optimizer/trunk/assets/easyopt-beacon.js
r3731476 r3747021 282 282 } 283 283 284 /* ── Per-session de-dupe─────────────────────────────────────────── */284 /* ── De-dupe ─────────────────────────────────────────────────────── */ 285 285 // Once this browser session has reported a given (url_type, viewport) we 286 286 // skip re-sending on later page loads in the same session. The server … … 288 288 // trims redundant in-session reports so the origin isn't hit repeatedly. 289 289 function ssKey() { return 'eo_beacon:' + (cfg.urlType || '') + ':' + viewport; } 290 291 // (2.7.3) Per-browser memory of THIS page, across sessions. A page that a 292 // full-page or CDN cache keeps serving with the beacon in it would 293 // otherwise be reported again by the same visitor on every visit. Tied to 294 // the render (cfg.rendered) and to what the page asks for, so a page 295 // re-rendered after its data was cleared reports again. Kept to the 50 296 // most recent pages so the stored list cannot grow without bound. 297 var LS_KEY = 'eo_beacon_pages'; 298 function pageKey() { return (cfg.pageUrl || location.href) + '|' + viewport; } 299 function pageVal() { return (cfg.rendered || '') + ':' + need.lcp + need.classes + need.fonts; } 300 function pageMap() { 301 try { var m = JSON.parse(window.localStorage.getItem(LS_KEY) || '{}'); return m && typeof m === 'object' ? m : {}; } catch (e) { return {}; } 302 } 303 290 304 function alreadyReported() { 291 try { return !!window.sessionStorage && !!sessionStorage.getItem(ssKey()); } catch (e) { return false; } 305 try { if (window.sessionStorage && sessionStorage.getItem(ssKey())) { return true; } } catch (e) {} 306 return pageMap()[pageKey()] === pageVal(); 292 307 } 293 308 function markReported() { 294 309 try { if (window.sessionStorage) { sessionStorage.setItem(ssKey(), '1'); } } catch (e) {} 310 try { 311 var m = pageMap(), k = pageKey(); 312 delete m[k]; 313 var keys = Object.keys(m); 314 for (var i = 0; i < keys.length - 49; i++) { delete m[keys[i]]; } 315 m[k] = pageVal(); 316 window.localStorage.setItem(LS_KEY, JSON.stringify(m)); 317 } catch (e) {} 295 318 } 296 319 -
easy-optimizer/trunk/assets/easyopt-beacon.min.js
r3731476 r3747021 14 14 * Build: this is the readable source; assets/easyopt-beacon.min.js is the 15 15 * shipped, minified copy. 16 */ 17 (function(){if(typeof easyoptBeacon==='undefined'){return} 18 var cfg=easyoptBeacon;var rawNeed=cfg.need||{};var need={lcp:+rawNeed.lcp||0,classes:+rawNeed.classes||0,fonts:+rawNeed.fonts||0};var viewport=window.innerWidth<(cfg.mobileBreak||768)?'mobile':'desktop';var sent=!1;var lcpEntry=null;var lcpObserver=null;var classSet=Object.create(null);var haveClasses=!1;function lcpApiSupported(){return('PerformanceObserver' in window)&&!!PerformanceObserver.supportedEntryTypes&&PerformanceObserver.supportedEntryTypes.indexOf('largest-contentful-paint')!==-1} 19 var lcpApiOk=lcpApiSupported();if(need.lcp&&lcpApiOk){try{lcpObserver=new PerformanceObserver(function(list){var entries=list.getEntries();for(var i=0;i<entries.length;i++){lcpEntry=entries[i]}});lcpObserver.observe({type:'largest-contentful-paint',buffered:!0})}catch(e){lcpApiOk=!1}} 20 function isVisible(el){if(!el||el.nodeType!==1){return!1} 21 if(el.offsetWidth===0||el.offsetHeight===0){return!1} 22 var cs=window.getComputedStyle?window.getComputedStyle(el):null;if(!cs){return!0} 23 if(cs.display==='none'){return!1} 24 if(cs.visibility==='hidden'||cs.visibility==='collapse'){return!1} 25 var o=parseFloat(cs.opacity||'1');return!(!isNaN(o)&&o<0.1)} 26 function bgUrls(value){if(!value||value==='none'){return[]} 27 var out=[],seen={},re=/url\((?:"([^"]+)"|'([^']+)'|([^)]+))\)/g,m;while((m=re.exec(value))!==null){var u=(m[1]||m[2]||m[3]||'').trim();if(u&&!seen[u]&&u.indexOf('data:')!==0){seen[u]=1;out.push(u)}} 28 return out} 29 function bgImageSetSrcset(value){var inner=String(value).match(/image-set\(([\s\S]*)\)/i);if(!inner){return''} 30 var parts=[],seen={};var re=/url\((?:"([^"]+)"|'([^']+)'|([^)]+))\)\s*([0-9.]+(?:x|w|dppx)?)?/g,m;while((m=re.exec(inner[1]))!==null){var u=(m[1]||m[2]||m[3]||'').trim();if(!u||u.indexOf('data:')===0||seen[u]){continue} 31 seen[u]=1;var d=(m[4]||'').trim();if(d&&/^[0-9.]+$/.test(d)){d+='x'} 32 parts.push(d?(u+' '+d):u)} 33 return parts.length?parts.join(', '):''} 34 function resolveLcp(el){if(!el){return null} 35 var tag=(el.tagName||'').toLowerCase();if(tag==='img'){var url=el.currentSrc||el.src||'';if(!url){return null} 36 var inPicture=el.parentNode&&(el.parentNode.tagName||'').toLowerCase()==='picture';return{tag:'img',kind:inPicture?'picture':(el.srcset?'img-srcset':'img'),url:url,srcset:el.srcset||'',sizes:el.sizes||''}} 37 if(tag==='video'&&el.poster){return{tag:'video',kind:'video-poster',url:el.poster,srcset:'',sizes:''}} 38 if(window.getComputedStyle){var bgRaw=window.getComputedStyle(el).backgroundImage||'';var urls=bgUrls(bgRaw);if(urls.length){if(/image-set\(/i.test(bgRaw)){var ss=bgImageSetSrcset(bgRaw);if(ss){return{tag:tag,kind:'background-set',url:urls[0],srcset:ss,sizes:''}}} 39 return{tag:tag,kind:'background',url:urls[0],srcset:'',sizes:''}}} 40 return{tag:tag,kind:tag,url:'',srcset:'',sizes:''}} 41 function findLcpFallback(){var vh=window.innerHeight||(document.documentElement&&document.documentElement.clientHeight)||0;var vw=window.innerWidth||(document.documentElement&&document.documentElement.clientWidth)||0;if(!vh||!vw){return null} 42 var best=null,bestArea=0,i;function consider(el){if(!isVisible(el)){return} 43 var rect;try{rect=el.getBoundingClientRect()}catch(e){return} 44 if(rect.top>=vh||rect.left>=vw||rect.bottom<=0||rect.right<=0){return} 45 var h=Math.min(rect.bottom,vh)-Math.max(rect.top,0);var w=Math.min(rect.right,vw)-Math.max(rect.left,0);var area=(h>0&&w>0)?(h*w):0;if(area>bestArea){bestArea=area;best=el}} 46 var imgs=document.getElementsByTagName('img');for(i=0;i<imgs.length&&i<600;i++){consider(imgs[i])} 47 var vids=document.querySelectorAll('video[poster]');for(i=0;i<vids.length&&i<50;i++){consider(vids[i])} 48 var bgs=document.querySelectorAll('[style*="background-image"]');for(i=0;i<bgs.length&&i<200;i++){consider(bgs[i])} 49 if(!best||bestArea<(cfg.minLcpSize||10000)){return null} 50 return{element:best,size:bestArea,url:''}} 51 function cssPath(el){if(!el||!el.nodeType){return''} 52 var parts=[],node=el,depth=0;while(node&&node.nodeType===1&&depth<6){var name=node.nodeName.toLowerCase();if(node.id){parts.unshift(name+'#'+node.id);break} 53 var cls=typeof node.className==='string'?node.className.trim():'';if(cls){name+='.'+cls.split(/\s+/).slice(0,2).join('.')} 54 parts.unshift(name);node=node.parentElement;depth++} 55 return parts.join(' > ')} 56 function snapshotClasses(){if(!need.classes){return} 57 try{var els=document.querySelectorAll('[class]');for(var i=0;i<els.length;i++){var list=els[i].classList;if(!list){continue} 58 for(var j=0;j<list.length;j++){classSet[list[j]]=1}} 59 haveClasses=!0}catch(e){}} 60 var GENERIC={'serif':1,'sans-serif':1,'monospace':1,'cursive':1,'fantasy':1,'system-ui':1,'ui-sans-serif':1,'ui-serif':1,'ui-monospace':1,'ui-rounded':1,'math':1,'emoji':1,'fangsong':1,'-apple-system':1,'blinkmacsystemfont':1,'inherit':1,'initial':1,'unset':1,'revert':1};function primaryFamily(ff){var first=(String(ff).split(',')[0]||'').trim().replace(/^['"]+|['"]+$/g,'');if(!first||GENERIC[first.toLowerCase()]){return''} 61 return first} 62 function normWeight(w){w=String(w).toLowerCase();if(w==='normal'){return'400'} 63 if(w==='bold'){return'700'} 64 var n=parseInt(w,10);return isNaN(n)?'400':String(n)} 65 function directText(el){var t='';for(var n=el.firstChild;n;n=n.nextSibling){if(n.nodeType===3&&n.nodeValue){t+=n.nodeValue}} 66 return t} 67 var fontSigCache=null,fontSigDone=!1;function collectFonts(){if(!need.fonts){return null} 68 if(fontSigDone){return fontSigCache} 69 fontSigDone=!0;try{var vh=window.innerHeight||(document.documentElement&&document.documentElement.clientHeight)||0;var vw=window.innerWidth||(document.documentElement&&document.documentElement.clientWidth)||0;if(!vh||!document.body){return null} 70 var map=Object.create(null);var els=document.body.getElementsByTagName('*');var MAXEL=5000,MAXKEYS=12,MAXCP=300;for(var i=0;i<els.length&&i<MAXEL;i++){var el=els[i];var txt=directText(el);if(!txt||!/\S/.test(txt)){continue} 71 var rect;try{rect=el.getBoundingClientRect()}catch(e){continue} 72 if(!rect||rect.width===0||rect.height===0){continue} 73 if(rect.top>=vh||rect.bottom<=0||rect.left>=vw||rect.right<=0){continue} 74 var cs=window.getComputedStyle?window.getComputedStyle(el):null;if(!cs||cs.display==='none'||cs.visibility==='hidden'||cs.visibility==='collapse'){continue} 75 var fam=primaryFamily(cs.fontFamily||'');if(!fam){continue} 76 var key=fam+'|'+normWeight(cs.fontWeight||'400')+'|'+(String(cs.fontStyle||'').indexOf('italic')===0?'italic':'normal');var rec=map[key];if(!rec){if(Object.keys(map).length>=MAXKEYS){continue} 77 rec=map[key]={cp:Object.create(null),n:0}} 78 for(var c=0;c<txt.length&&rec.n<MAXCP;c++){var cp=txt.charCodeAt(c);if(cp>32&&!rec.cp[cp]){rec.cp[cp]=1;rec.n++}}} 79 var out=[];for(var k in map){var p=k.split('|');var cps=Object.keys(map[k].cp).map(Number);cps.sort(function(a,b){return a-b});out.push({f:p[0],w:p[1],s:p[2],u:cps})} 80 fontSigCache=out.length?out:null;return fontSigCache}catch(e){fontSigCache=null;return null}} 81 function ssKey(){return'eo_beacon:'+(cfg.urlType||'')+':'+viewport} 82 function alreadyReported(){try{return!!window.sessionStorage&&!!sessionStorage.getItem(ssKey())}catch(e){return!1}} 83 function markReported(){try{if(window.sessionStorage){sessionStorage.setItem(ssKey(),'1')}}catch(e){}} 84 function send(){if(sent){return} 85 sent=!0;if(alreadyReported()){return} 86 if(lcpObserver){try{lcpObserver.disconnect()}catch(e){}} 87 snapshotClasses();var data=new FormData();data.append('action','easyopt_beacon');data.append('nonce',cfg.nonce);if(cfg.token){data.append('token',cfg.token)} 88 data.append('url_type',cfg.urlType||'');data.append('page_url',cfg.pageUrl||location.href);data.append('viewport',viewport);var anything=!1;if(need.lcp&&!lcpEntry&&!lcpApiOk){lcpEntry=findLcpFallback()} 89 if(need.lcp&&lcpEntry){var el=lcpEntry.element;var size=lcpEntry.size||0;if(el&&isVisible(el)&&size>=(cfg.minLcpSize||10000)){var r=resolveLcp(el);var url=r&&r.url?r.url:(lcpEntry.url||'');var kind=r?r.kind:'';if(r&&'video'===r.kind){url=el.currentSrc||url}else if(r&&!url){kind='none'} 90 if(r&&(url||'none'===kind)){data.append('element_tag',r.tag);data.append('element_kind',kind);data.append('image_url',url);data.append('srcset',r.srcset||'');data.append('sizes',r.sizes||'');data.append('selector',cssPath(el));data.append('lcp_size',String(Math.round(size)));anything=!0}}} 91 if(need.classes&&haveClasses){var classes=Object.keys(classSet);if(classes.length){if(classes.length>5000){classes=classes.slice(0,5000)} 92 data.append('classes',classes.join(','));anything=!0}} 93 if(need.fonts){var fontSig=collectFonts();if(fontSig){data.append('fonts',JSON.stringify(fontSig));anything=!0}} 94 if(!anything){return} 95 if(navigator.sendBeacon){try{if(navigator.sendBeacon(cfg.ajaxUrl,data)){markReported()}return}catch(e){}} 96 try{fetch(cfg.ajaxUrl,{method:'POST',body:data,keepalive:!0,credentials:'same-origin'});markReported()}catch(e){}} 97 function onInteract(){snapshotClasses()} 98 function idle(fn,timeout){if(window.requestIdleCallback){window.requestIdleCallback(fn,{timeout:timeout||2000})}else{setTimeout(fn,200)}} 99 if(document.readyState==='complete'){idle(snapshotClasses)}else{window.addEventListener('load',function(){idle(snapshotClasses)},{once:!0})} 100 var interactEvents=['pointerdown','keydown','touchstart','scroll'];interactEvents.forEach(function(ev){window.addEventListener(ev,function(){idle(onInteract)},{once:!0,passive:!0})});setTimeout(function(){idle(snapshotClasses)},3500);idle(function(){try{collectFonts()}catch(e){}},4000);document.addEventListener('visibilitychange',function(){if(document.visibilityState==='hidden'){send()}},{once:!0});window.addEventListener('pagehide',send,{once:!0});setTimeout(send,8000)})() 16 */ !function(){if("undefined"!=typeof easyoptBeacon){var e=easyoptBeacon,t=e.need||{},n={lcp:+t.lcp||0,classes:+t.classes||0,fonts:+t.fonts||0},r=window.innerWidth<(e.mobileBreak||768)?"mobile":"desktop",i=!1,a=null,o=null,l=Object.create(null),s=!1,c="PerformanceObserver"in window&&!!PerformanceObserver.supportedEntryTypes&&-1!==PerformanceObserver.supportedEntryTypes.indexOf("largest-contentful-paint");if(n.lcp&&c)try{(o=new PerformanceObserver(function(e){for(var t=e.getEntries(),n=0;n<t.length;n++)a=t[n]})).observe({type:"largest-contentful-paint",buffered:!0})}catch(u){c=!1}var f={serif:1,"sans-serif":1,monospace:1,cursive:1,fantasy:1,"system-ui":1,"ui-sans-serif":1,"ui-serif":1,"ui-monospace":1,"ui-rounded":1,math:1,emoji:1,fangsong:1,"-apple-system":1,blinkmacsystemfont:1,inherit:1,initial:1,unset:1,revert:1},d=null,p=!1;"complete"===document.readyState?E(m):window.addEventListener("load",function(){E(m)},{once:!0}),["pointerdown","keydown","touchstart","scroll"].forEach(function(e){window.addEventListener(e,function(){E(S)},{once:!0,passive:!0})}),setTimeout(function(){E(m)},3500),E(function(){try{y()}catch(e){}},4e3),document.addEventListener("visibilitychange",function(){"hidden"===document.visibilityState&&k()},{once:!0}),window.addEventListener("pagehide",k,{once:!0}),setTimeout(k,8e3)}function $(e){if(!e||1!==e.nodeType||0===e.offsetWidth||0===e.offsetHeight)return!1;var t=window.getComputedStyle?window.getComputedStyle(e):null;if(!t)return!0;if("none"===t.display||"hidden"===t.visibility||"collapse"===t.visibility)return!1;var n=parseFloat(t.opacity||"1");return!(!isNaN(n)&&n<.1)}function m(){if(n.classes)try{for(var e=document.querySelectorAll("[class]"),t=0;t<e.length;t++){var r=e[t].classList;if(r)for(var i=0;i<r.length;i++)l[r[i]]=1}s=!0}catch(a){}}function g(e){var t=(String(e).split(",")[0]||"").trim().replace(/^['"]+|['"]+$/g,"");return!t||f[t.toLowerCase()]?"":t}function v(e){if("normal"===(e=String(e).toLowerCase()))return"400";if("bold"===e)return"700";var t=parseInt(e,10);return isNaN(t)?"400":String(t)}function h(e){for(var t="",n=e.firstChild;n;n=n.nextSibling)3===n.nodeType&&n.nodeValue&&(t+=n.nodeValue);return t}function y(){if(!n.fonts)return null;if(p)return d;p=!0;try{var e=window.innerHeight||document.documentElement&&document.documentElement.clientHeight||0,t=window.innerWidth||document.documentElement&&document.documentElement.clientWidth||0;if(!e||!document.body)return null;for(var r=Object.create(null),i=document.body.getElementsByTagName("*"),a=0;a<i.length&&a<5e3;a++){var o,l=i[a],s=h(l);if(s&&/\S/.test(s)){try{o=l.getBoundingClientRect()}catch(c){continue}if(o&&0!==o.width&&0!==o.height&&!(o.top>=e)&&!(o.bottom<=0)&&!(o.left>=t)&&!(o.right<=0)){var u=window.getComputedStyle?window.getComputedStyle(l):null;if(u&&"none"!==u.display&&"hidden"!==u.visibility&&"collapse"!==u.visibility){var f=g(u.fontFamily||"");if(f){var $=f+"|"+v(u.fontWeight||"400")+"|"+(0===String(u.fontStyle||"").indexOf("italic")?"italic":"normal"),m=r[$];if(!m){if(Object.keys(r).length>=12)continue;m=r[$]={cp:Object.create(null),n:0}}for(var y=0;y<s.length&&m.n<300;y++){var _=s.charCodeAt(y);_>32&&!m.cp[_]&&(m.cp[_]=1,m.n++)}}}}}}var b=[];for(var k in r){var S=k.split("|"),E=Object.keys(r[k].cp).map(Number);E.sort(function(e,t){return e-t}),b.push({f:S[0],w:S[1],s:S[2],u:E})}return d=b.length?b:null}catch(C){return d=null,null}}function _(){return"eo_beacon:"+(e.urlType||"")+":"+r}function L(){return(e.pageUrl||location.href)+"|"+r}function P(){return(e.rendered||"")+":"+n.lcp+n.classes+n.fonts}function M(){try{var e=JSON.parse(window.localStorage.getItem("eo_beacon_pages")||"{}");return e&&"object"==typeof e?e:{}}catch(t){return{}}}function b(){try{window.sessionStorage&&sessionStorage.setItem(_(),"1")}catch(e){}try{var t=M(),n=L();delete t[n];for(var r=Object.keys(t),i=0;i<r.length-49;i++)delete t[r[i]];t[n]=P(),window.localStorage.setItem("eo_beacon_pages",JSON.stringify(t))}catch(a){}}function k(){if(!(i||(i=!0,function e(){try{if(window.sessionStorage&&sessionStorage.getItem(_()))return!0}catch(t){}return M()[L()]===P()}()))){if(o)try{o.disconnect()}catch(t){}m();var u=new FormData;u.append("action","easyopt_beacon"),u.append("nonce",e.nonce),e.token&&u.append("token",e.token),u.append("url_type",e.urlType||""),u.append("page_url",e.pageUrl||location.href),u.append("viewport",r);var f=!1;if(!n.lcp||a||c||(a=function t(){var n=window.innerHeight||document.documentElement&&document.documentElement.clientHeight||0,r=window.innerWidth||document.documentElement&&document.documentElement.clientWidth||0;if(!n||!r)return null;var i,a=null,o=0;function l(e){if($(e)){try{i=e.getBoundingClientRect()}catch(t){return}if(!(i.top>=n)&&!(i.left>=r)&&!(i.bottom<=0)&&!(i.right<=0)){var i,l=Math.min(i.bottom,n)-Math.max(i.top,0),s=Math.min(i.right,r)-Math.max(i.left,0),c=l>0&&s>0?l*s:0;c>o&&(o=c,a=e)}}}var s=document.getElementsByTagName("img");for(i=0;i<s.length&&i<600;i++)l(s[i]);var c=document.querySelectorAll("video[poster]");for(i=0;i<c.length&&i<50;i++)l(c[i]);var u=document.querySelectorAll('[style*="background-image"]');for(i=0;i<u.length&&i<200;i++)l(u[i]);return!a||o<(e.minLcpSize||1e4)?null:{element:a,size:o,url:""}}()),n.lcp&&a){var d=a.element,p=a.size||0;if(d&&$(d)&&p>=(e.minLcpSize||1e4)){var g=function e(t){if(!t)return null;var n=(t.tagName||"").toLowerCase();if("img"===n){var r=t.currentSrc||t.src||"";return r?{tag:"img",kind:t.parentNode&&"picture"===(t.parentNode.tagName||"").toLowerCase()?"picture":t.srcset?"img-srcset":"img",url:r,srcset:t.srcset||"",sizes:t.sizes||""}:null}if("video"===n&&t.poster)return{tag:"video",kind:"video-poster",url:t.poster,srcset:"",sizes:""};if(window.getComputedStyle){var i=window.getComputedStyle(t).backgroundImage||"",a=function e(t){if(!t||"none"===t)return[];for(var n,r=[],i={},a=/url\((?:"([^"]+)"|'([^']+)'|([^)]+))\)/g;null!==(n=a.exec(t));){var o=(n[1]||n[2]||n[3]||"").trim();o&&!i[o]&&0!==o.indexOf("data:")&&(i[o]=1,r.push(o))}return r}(i);if(a.length){if(/image-set\(/i.test(i)){var o=function e(t){var n=String(t).match(/image-set\(([\s\S]*)\)/i);if(!n)return"";for(var r,i=[],a={},o=/url\((?:"([^"]+)"|'([^']+)'|([^)]+))\)\s*([0-9.]+(?:x|w|dppx)?)?/g;null!==(r=o.exec(n[1]));){var l=(r[1]||r[2]||r[3]||"").trim();if(l&&0!==l.indexOf("data:")&&!a[l]){a[l]=1;var s=(r[4]||"").trim();s&&/^[0-9.]+$/.test(s)&&(s+="x"),i.push(s?l+" "+s:l)}}return i.length?i.join(", "):""}(i);if(o)return{tag:n,kind:"background-set",url:a[0],srcset:o,sizes:""}}return{tag:n,kind:"background",url:a[0],srcset:"",sizes:""}}}return{tag:n,kind:n,url:"",srcset:"",sizes:""}}(d),v=g&&g.url?g.url:a.url||"",h=g?g.kind:"";g&&"video"===g.kind?v=d.currentSrc||v:g&&!v&&(h="none"),g&&(v||"none"===h)&&(u.append("element_tag",g.tag),u.append("element_kind",h),u.append("image_url",v),u.append("srcset",g.srcset||""),u.append("sizes",g.sizes||""),u.append("selector",function e(t){if(!t||!t.nodeType)return"";for(var n=[],r=t,i=0;r&&1===r.nodeType&&i<6;){var a=r.nodeName.toLowerCase();if(r.id){n.unshift(a+"#"+r.id);break}var o="string"==typeof r.className?r.className.trim():"";o&&(a+="."+o.split(/\s+/).slice(0,2).join(".")),n.unshift(a),r=r.parentElement,i++}return n.join(" > ")}(d)),u.append("lcp_size",String(Math.round(p))),f=!0)}}if(n.classes&&s){var k=Object.keys(l);k.length&&(k.length>5e3&&(k=k.slice(0,5e3)),u.append("classes",k.join(",")),f=!0)}if(n.fonts){var S=y();S&&(u.append("fonts",JSON.stringify(S)),f=!0)}if(f){if(navigator.sendBeacon)try{navigator.sendBeacon(e.ajaxUrl,u)&&b();return}catch(E){}try{fetch(e.ajaxUrl,{method:"POST",body:u,keepalive:!0,credentials:"same-origin"}),b()}catch(C){}}}}function S(){m()}function E(e,t){window.requestIdleCallback?window.requestIdleCallback(e,{timeout:t||2e3}):setTimeout(e,200)}}(); -
easy-optimizer/trunk/easy-optimizer.php
r3731476 r3747021 4 4 * Plugin URI: https://fluxpress.io 5 5 * Description: Page cache, lazy load, used CSS, delay JS, font optimization, image CDN, LCP preload and more — everything you need to ace Core Web Vitals, in one plugin. 6 * Version: 2.7. 26 * Version: 2.7.3 7 7 * Author: FluxPress 8 8 * Author URI: https://fluxpress.io … … 25 25 } 26 26 if ( ! defined( 'EASYOPT_VERSION' ) ) { 27 define( 'EASYOPT_VERSION', '2.7. 2' );27 define( 'EASYOPT_VERSION', '2.7.3' ); 28 28 } 29 29 if ( ! defined( 'EASYOPT_CSS_LOGIC_VERSION' ) ) { … … 466 466 $a11y_keys = array( 'easyopt_a11y_inputs', 'easyopt_a11y_links', 'easyopt_a11y_buttons', 467 467 'easyopt_a11y_viewport', 'easyopt_a11y_role_elements', 'easyopt_a11y_iframes', 468 'easyopt_a11y_progressbar', 'easyopt_a11y_tabindex' ); 468 'easyopt_a11y_progressbar', 'easyopt_a11y_tabindex', 469 'easyopt_a11y_skip_link', 'easyopt_a11y_main_landmark' ); 469 470 foreach ( $a11y_keys as $ak ) { 470 471 if ( ! empty( $easyopt_opts[ $ak ] ) ) { … … 1042 1043 $a11y = array( 'a11y_inputs', 'a11y_links', 'a11y_buttons', 'a11y_viewport', 1043 1044 'a11y_role_elements', 'a11y_iframes', 'a11y_progressbar', 'a11y_tabindex', 1045 'a11y_skip_link', 'a11y_main_landmark', 1044 1046 'seo_crawlable_links', 'seo_image_alts' ); 1045 1047 $checks = array_merge( $checks, $a11y ); -
easy-optimizer/trunk/includes/class-easyopt-accessibility.php
r3617492 r3747021 82 82 } 83 83 84 // (2.7.3) Skip-link target + main landmark — one shared pass, a no-op 85 // unless the page actually fails one of the two audits. 86 if ( self::$enabled['skip_link'] || self::$enabled['main_landmark'] ) { 87 $html = self::fix_landmarks( $html ); 88 } 89 84 90 return $html; 85 91 } … … 100 106 'progressbar' => (int) EasyOpt_Config::get( 'a11y_progressbar', 0 ), 101 107 'tabindex' => (int) EasyOpt_Config::get( 'a11y_tabindex', 0 ), 108 'skip_link' => (int) EasyOpt_Config::get( 'a11y_skip_link', 0 ), 109 'main_landmark' => (int) EasyOpt_Config::get( 'a11y_main_landmark', 0 ), 102 110 ); 103 111 … … 355 363 $p->set_attribute( 'tabindex', '0' ); 356 364 } 365 } 366 367 /* ───────────────────────────────────────────── 368 * (2.7.3) Skip-link target + main landmark 369 * ───────────────────────────────────────────── */ 370 371 /** data-elementor-type values that hold the page's OWN content — never a header, footer, popup or embedded template. */ 372 const CONTENT_DOC_TYPES = array( 'wp-page', 'wp-post', 'single', 'single-post', 'single-page', 'archive', 'search-results', 'error-404', 'product', 'product-archive' ); 373 374 /** Landmarks the main content is never inside. Mega menus embed whole Elementor posts in the header. */ 375 const OUTSIDE_MAIN_TAGS = array( 'HEADER', 'FOOTER', 'NAV', 'ASIDE' ); 376 377 /** 378 * Lighthouse: "Skip links are not focusable" and "Document does not have a 379 * main landmark". 380 * 381 * Page-builder layouts (Elementor full width / canvas / Theme Builder, 382 * Divi) print no <main>, while the theme still prints its "Skip to 383 * content" link to #content — a link to nothing. Both are fixed on one 384 * element, the page's main content block: 385 * 386 * - the existing <main> / [role=main], else 387 * - the first Elementor page/post/single/archive document, or Divi's 388 * #main-content, that is NOT inside a header, footer, nav or aside. 389 * 390 * Only attributes change: role="main" on that block, an id on it when it 391 * has none (easyopt-main — never "content", which themes style), and the 392 * skip link's href pointed at it. Nothing is moved, wrapped or removed; a 393 * page that already passes, or has no recognisable content block, is 394 * returned unchanged. 395 */ 396 private static function fix_landmarks( $html ) { 397 398 $has_main = self::has_main_landmark( $html ); 399 $want_main = self::$enabled['main_landmark'] && ! $has_main; 400 $want_skip = self::$enabled['skip_link'] && self::has_broken_skip_link( $html ); 401 402 if ( ! $want_main && ! $want_skip ) { 403 return $html; 404 } 405 406 // Nothing to point at → nothing to walk for. 407 if ( ! $has_main && ! preg_match( '#data-elementor-type=["\'](?:' . implode( '|', array_map( 'preg_quote', self::CONTENT_DOC_TYPES ) ) . ')["\']|\sid\s*=\s*["\']?main-content["\'\s>]#', $html ) ) { 408 return $html; 409 } 410 411 $p = new WP_HTML_Tag_Processor( $html ); 412 $outside = 0; // Depth inside header / footer / nav / aside. 413 $in_links = true; // Still before the first ordinary page link (where skip links live). 414 $skips = 0; 415 $found = false; 416 417 while ( $p->next_tag( array( 'tag_closers' => 'visit' ) ) ) { 418 $tag = $p->get_tag(); 419 420 if ( in_array( $tag, self::OUTSIDE_MAIN_TAGS, true ) ) { 421 $outside = $p->is_tag_closer() ? max( 0, $outside - 1 ) : $outside + 1; 422 continue; 423 } 424 425 if ( $p->is_tag_closer() ) { 426 continue; 427 } 428 429 if ( 'A' === $tag ) { 430 if ( $in_links ) { 431 $href = $p->get_attribute( 'href' ); 432 $href = is_string( $href ) ? trim( $href ) : ''; 433 434 if ( $want_skip && $skips < 5 && self::is_skip_link( $p, $href ) && ! self::target_exists( $html, substr( $href, 1 ) ) ) { 435 $p->set_bookmark( 'easyopt_skip_' . $skips ); 436 $skips++; 437 } elseif ( '' !== $href && '#' !== $href[0] && 0 !== stripos( $href, 'javascript:' ) ) { 438 $in_links = false; 439 } 440 } 441 continue; 442 } 443 444 if ( self::is_main_block( $p, $tag, $outside ) ) { 445 $found = true; 446 break; 447 } 448 } 449 450 if ( ! $found ) { 451 return $html; 452 } 453 454 if ( $want_main && null === $p->get_attribute( 'role' ) ) { 455 $p->set_attribute( 'role', 'main' ); 456 } 457 458 if ( $skips > 0 ) { 459 $id = $p->get_attribute( 'id' ); 460 $id = is_string( $id ) ? trim( $id ) : ''; 461 462 if ( '' === $id ) { 463 $id = self::unique_id( $html, 'easyopt-main' ); 464 $p->set_attribute( 'id', $id ); 465 } 466 467 if ( ! preg_match( '/\s/', $id ) ) { 468 for ( $i = 0; $i < $skips; $i++ ) { 469 if ( $p->seek( 'easyopt_skip_' . $i ) ) { 470 $p->set_attribute( 'href', '#' . $id ); 471 } 472 } 473 } 474 } 475 476 return $p->get_updated_html(); 477 } 478 479 /** A <main> element or role="main" anywhere in the document. */ 480 private static function has_main_landmark( $html ) { 481 return (bool) preg_match( '#<main[\s>/]|\srole\s*=\s*["\']?main["\'\s/>]#i', $html ); 482 } 483 484 /** Any skip link whose #target does not exist. Cheap gate before the tag walk. */ 485 private static function has_broken_skip_link( $html ) { 486 if ( false === stripos( $html, 'skip' ) 487 || ! preg_match_all( '#<a\s(?=[^>]*skip)[^>]*?\bhref\s*=\s*["\']?\#([^"\'\s>]+)#i', $html, $m ) ) { 488 return false; 489 } 490 491 foreach ( $m[1] as $fragment ) { 492 if ( '/' !== $fragment[0] && '!' !== $fragment[0] && ! self::target_exists( $html, $fragment ) ) { 493 return true; 494 } 495 } 496 return false; 497 } 498 499 /** 500 * A skip link the way the audit sees one: an in-page link (#name, not #/ 501 * or #!) — and, so a menu toggle or "back to top" is never repointed, one 502 * that names itself a skip link in its class or id. 503 */ 504 private static function is_skip_link( $p, $href ) { 505 if ( strlen( $href ) < 2 || '#' !== $href[0] || '/' === $href[1] || '!' === $href[1] ) { 506 return false; 507 } 508 509 $class = $p->get_attribute( 'class' ); 510 $id = $p->get_attribute( 'id' ); 511 512 return ( is_string( $class ) && false !== stripos( $class, 'skip' ) ) 513 || ( is_string( $id ) && false !== stripos( $id, 'skip' ) ); 514 } 515 516 /** An element with this id (or name, as the audit also accepts) exists. */ 517 private static function target_exists( $html, $fragment ) { 518 return (bool) preg_match( '#\s(?:[iI][dD]|[nN][aA][mM][eE])\s*=\s*(["\']?)' . preg_quote( $fragment, '#' ) . '\1(?=[\s/>])#', $html ); 519 } 520 521 /** The page's main content block, at the processor's current tag. */ 522 private static function is_main_block( $p, $tag, $outside ) { 523 $role = $p->get_attribute( 'role' ); 524 525 if ( 'MAIN' === $tag || ( is_string( $role ) && 'main' === strtolower( trim( $role ) ) ) ) { 526 return true; 527 } 528 529 if ( $outside > 0 ) { 530 return false; 531 } 532 533 $type = $p->get_attribute( 'data-elementor-type' ); 534 535 if ( is_string( $type ) && in_array( $type, self::CONTENT_DOC_TYPES, true ) ) { 536 return true; 537 } 538 539 return 'main-content' === $p->get_attribute( 'id' ); 540 } 541 542 /** $base, or $base-2, -3 … when the document already uses it. */ 543 private static function unique_id( $html, $base ) { 544 $id = $base; 545 for ( $n = 2; self::target_exists( $html, $id ) && $n < 50; $n++ ) { 546 $id = $base . '-' . $n; 547 } 548 return $id; 357 549 } 358 550 -
easy-optimizer/trunk/includes/class-easyopt-autoloader.php
r3697647 r3747021 59 59 'EasyOpt_Images_Delivery' => 'includes/class-easyopt-images-delivery.php', 60 60 'EasyOpt_Images_Encoder' => 'includes/class-easyopt-images-encoder.php', 61 'EasyOpt_Images_Media' => 'includes/class-easyopt-images-media.php', 61 62 'EasyOpt_Config' => 'includes/class-easyopt-config.php', 62 63 'EasyOpt_CSS_Tokenizer' => 'includes/class-easyopt-css-tokenizer.php', -
easy-optimizer/trunk/includes/class-easyopt-cache-preload.php
r3633323 r3747021 1090 1090 // per minute; logs only when the queue stalls or grows abnormally. 1091 1091 add_action( 'easyopt_queue_watchdog', array( __CLASS__, 'watchdog_health_check' ) ); 1092 // (2.7.3) The watchdog is only scheduled while there is work now; keep 1093 // it ticking while the check above still has something to watch. 1094 add_filter( 'easyopt_queue_watchdog_keep', array( __CLASS__, 'watchdog_keep' ) ); 1092 1095 1093 1096 // Phase 7 — traffic-aware retention. Opt-in stale page-cache pruning on … … 1138 1141 * Cost: one option read + one option write per minute. No filesystem work. 1139 1142 */ 1143 /** 1144 * (2.7.3) Keep the watchdog scheduled while watchdog_health_check() can 1145 * still act: a running or paused run, or the 30 min post-done reconcile. 1146 * Same conditions it checks before taking its fast exit. 1147 */ 1148 public static function watchdog_keep( $keep ) { 1149 if ( $keep ) { 1150 return true; 1151 } 1152 $status = (string) get_option( 'easyopt_cache_preload_status', 'idle' ); 1153 return 'running' === $status || 'paused' === $status 1154 || ( 'done' === $status && false !== get_transient( 'easyopt_preload_post_done_reconcile' ) ); 1155 } 1156 1140 1157 public static function watchdog_health_check() { 1141 1158 if ( ! class_exists( 'EasyOpt_Debug_Log' ) ) { -
easy-optimizer/trunk/includes/class-easyopt-cdn-cloud.php
r3731476 r3747021 936 936 // EasyOpt_REST_Cloud::arm_maintenance(). 937 937 set_transient( 'easyopt_cloud_maint', 1, 10 * MINUTE_IN_SECONDS ); 938 update_option( self::CHECKED_OPTION, time(), true ); 938 939 939 940 self::usage( true ); … … 942 943 self::map_refresh( self::collect_originals() ); 943 944 } 945 } 946 947 /** 948 * (2.7.3) Last time the status was asked for. Autoloaded: it is read on 949 * front-end requests by EasyOpt_REST_Cloud::arm_frontend_check(). 950 */ 951 const CHECKED_OPTION = 'easyopt_cloud_checked_at'; 952 953 /** 954 * (2.7.3) The status check for sites whose WP-Cron never runs — see 955 * EasyOpt_REST_Cloud::arm_frontend_check(). Same throttle as maintain(); 956 * only the usage call, which is what learns of a revoked licence. 957 */ 958 public static function check_now() { 959 if ( ! self::is_connected() || get_transient( 'easyopt_cloud_maint' ) ) { 960 return; 961 } 962 set_transient( 'easyopt_cloud_maint', 1, 10 * MINUTE_IN_SECONDS ); 963 update_option( self::CHECKED_OPTION, time(), true ); 964 self::usage( true ); 944 965 } 945 966 -
easy-optimizer/trunk/includes/class-easyopt-images.php
r3697647 r3747021 55 55 const META_CLIENTSIDE = '_easyopt_img_clientside'; 56 56 57 /** 58 * Set when the user restores ONE image from the Media Library. Bulk runs 59 * leave it alone until they optimize it again — otherwise the next 60 * "Optimize all" would simply redo what they just undid. Kept apart from 61 * META so restore (which deletes META) never clears it. 62 */ 63 const META_EXCLUDE = '_easyopt_img_exclude'; 64 57 65 /** Queue wiring. */ 58 66 const QUEUE_GROUP = 'images'; … … 66 74 /** Sources we will process. */ 67 75 const MIME = array( 'image/jpeg', 'image/png', 'image/gif' ); 76 77 /** True while restore regenerates core's sizes — not a new upload. */ 78 private static $restoring = false; 68 79 69 80 /** … … 101 112 add_filter( 'wp_generate_attachment_metadata', array( __CLASS__, 'on_generate_metadata' ), 20, 3 ); 102 113 } 114 115 // Per-image status, Restore and Optimize in the Media Library. 116 if ( is_admin() ) { 117 EasyOpt_Images_Media::init(); 118 } 103 119 } 104 120 … … 176 192 */ 177 193 public static function on_generate_metadata( $metadata, $attachment_id, $context = 'create' ) { 178 if ( 'create' !== $context ) { 194 // Restore regenerates sizes through this same filter with 'create'. 195 // Queueing then would re-optimize (and re-shrink) what was just restored. 196 if ( 'create' !== $context || self::$restoring ) { 179 197 return $metadata; 180 198 } … … 225 243 } 226 244 if ( $n ) { 245 // Queued images leave the cached "untouched" count (see stats()). 246 delete_transient( self::STATS_CACHE ); 227 247 $q->start_queue(); 228 248 } … … 243 263 } 244 264 if ( $n ) { 265 delete_transient( self::STATS_CACHE ); 245 266 $q->start_queue(); 246 267 } 247 268 return $n; 269 } 270 271 /** 272 * Stop a bulk run (or a restore-all). Drops every queued task; the image 273 * being encoded right now finishes, and everything already done stays 274 * done. "Optimize N remaining" picks up where it stopped. 275 */ 276 public static function stop() { 277 self::queue( self::HOOK_OPTIMIZE )->clear_queue(); 278 self::queue( self::HOOK_RESTORE )->clear_queue(); 279 delete_transient( self::STATS_CACHE ); 248 280 } 249 281 … … 310 342 public static function run_optimize( $task ) { 311 343 $id = isset( $task['id'] ) ? (int) $task['id'] : 0; 312 if ( $id <= 0 ) {344 if ( $id <= 0 || self::is_excluded( $id ) ) { 313 345 return; 314 346 } … … 396 428 $meta['sig'] = self::settings_signature(); 397 429 update_post_meta( $id, self::META, $meta ); 430 431 // Restored from the Media Library while this encode ran: undo the run 432 // (variants and any shrink) so the user's restore holds. The meta cache 433 // was filled when this run started, so drop it to see the restore. 434 wp_cache_delete( $id, 'post_meta' ); 435 if ( self::is_excluded( $id ) ) { 436 self::run_restore( array( 'id' => $id ) ); 437 } 398 438 } 399 439 … … 498 538 require_once ABSPATH . 'wp-admin/includes/image.php'; 499 539 } 500 $regenerated = wp_generate_attachment_metadata( $id, $main ); 540 self::$restoring = true; 541 $regenerated = wp_generate_attachment_metadata( $id, $main ); 542 self::$restoring = false; 501 543 if ( is_array( $regenerated ) ) { 502 544 wp_update_attachment_metadata( $id, $regenerated ); … … 509 551 delete_post_meta( $id, self::META ); 510 552 delete_post_meta( $id, self::META_CLIENTSIDE ); 553 } 554 555 /** 556 * Restore ONE image now (Media Library) and keep bulk runs off it. 557 * Exclusion first, so an encode of this image already in flight sees it 558 * when it finishes and undoes itself (see run_optimize()). 559 */ 560 public static function restore_one( $id ) { 561 $id = (int) $id; 562 update_post_meta( $id, self::META_EXCLUDE, 1 ); 563 self::run_restore( array( 'id' => $id ) ); 564 delete_transient( self::STATS_CACHE ); 565 } 566 567 /** 568 * Optimize ONE image (Media Library): lift a restore's exclusion, queue it. 569 * 570 * @return bool Queued. 571 */ 572 public static function optimize_one( $id ) { 573 $id = (int) $id; 574 delete_post_meta( $id, self::META_EXCLUDE ); 575 delete_transient( self::STATS_CACHE ); 576 return self::enqueue( array( $id ) ) > 0; 511 577 } 512 578 … … 622 688 } 623 689 690 /** Restored by hand from the Media Library (see META_EXCLUDE). */ 691 public static function is_excluded( $id ) { 692 return (bool) get_post_meta( (int) $id, self::META_EXCLUDE, true ); 693 } 694 624 695 /** 625 696 * Has this attachment already been through the optimizer at all — including … … 630 701 */ 631 702 public static function has_been_attempted( $id ) { 703 if ( self::is_excluded( $id ) ) { 704 return true; // Restored by hand: bulk runs skip it. 705 } 632 706 $meta = get_post_meta( (int) $id, self::META, true ); 633 707 // Sig-aware: an attempt made under DIFFERENT settings is stale, so the … … 662 736 */ 663 737 public static function stats() { 664 // The expensive half — a scan of every _easyopt_img row — is cached665 // briefly and keyed on the settings signature, so a 2s progress poll on666 // a large library does not re-scan every tick (and a settings change667 // invalidates it at once). Queue depth is always live below.668 $agg = get_transient( self::STATS_CACHE );669 if ( ! is_array( $agg ) || ( $agg['sig'] ?? '' ) !== self::settings_signature() ) {670 $agg = self::compute_aggregate();671 set_transient( self::STATS_CACHE, $agg, 20 );672 }673 674 738 // Live queue depth — cheap, and must stay real-time for the poll. 675 739 $oq = self::queue( self::HOOK_OPTIMIZE ); … … 678 742 $failed = $oq->get_failed_count(); 679 743 $restoring = $rq->get_pending_count(); 744 $busy = ( $pending + $restoring ) > 0; 745 746 // The expensive half — a scan of every _easyopt_img row — is cached 747 // briefly and keyed on the settings signature, so a 2s progress poll on 748 // a large library does not re-scan every tick (and a settings change 749 // invalidates it at once). Also re-scanned once when the queue goes 750 // idle, so the resting numbers are exact rather than up to 20s old. 751 $agg = get_transient( self::STATS_CACHE ); 752 if ( ! is_array( $agg ) || ( $agg['sig'] ?? '' ) !== self::settings_signature() 753 || ( ! empty( $agg['busy'] ) && ! $busy ) ) { 754 $agg = self::compute_aggregate(); 755 $agg['busy'] = $busy; 756 // Images neither processed nor queued. Unlike `current`, this does 757 // not move while the queue works (it only moves when something is 758 // queued or restored, and both clear this cache), so the live 759 // `processed` below stays exact on every poll with no re-scan. 760 $agg['untouched'] = max( 0, $agg['total'] - $agg['current'] - $pending - $failed ); 761 set_transient( self::STATS_CACHE, $agg, 20 ); 762 } 680 763 681 764 return array( 682 765 'total' => $agg['total'], 766 // Live. Every image that is neither queued nor untouched has been 767 // processed: optimized, skipped, failed or restored by hand. So 768 // processed + pending = total for a full run, on every poll. 769 'processed' => max( 0, min( $agg['total'], $agg['total'] - $pending - $agg['untouched'] ) ), 683 770 'optimized' => $agg['optimized'], 684 771 // Reaches 100% even when some images can't be shrunk, and re-opens … … 687 774 // Attempted at the current settings but produced no servable variant. 688 775 'skipped' => $agg['skipped'], 776 // Restored one by one in the Media Library; bulk runs skip them. 777 'excluded' => $agg['excluded'], 689 778 'saved' => $agg['saved'], 690 779 'saved_human' => size_format( $agg['saved'] ), … … 743 832 } 744 833 834 // Restored by hand: done as far as bulk runs are concerned, so they 835 // count as current or "Optimize N remaining" could never reach zero. 836 // Restore deleted their _easyopt_img row, so no double count. 837 $excluded = (int) $wpdb->get_var( 838 $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = %s", self::META_EXCLUDE ) 839 ); 840 745 841 return array( 746 842 'total' => $total, 747 843 'optimized' => $optimized, 748 'current' => $current,844 'current' => min( $total, $current + $excluded ), 749 845 'skipped' => $skipped, 846 'excluded' => $excluded, 750 847 'saved' => $saved, 751 848 'sig' => $sig, -
easy-optimizer/trunk/includes/class-easyopt-lcp.php
r3731476 r3747021 303 303 'mobileBreak' => self::MOBILE_BREAK, 304 304 'minLcpSize' => self::MIN_LCP_SIZE, 305 // (2.7.3) Render time: the beacon's per-page memory is keyed to 306 // it, so a cached copy is reported once per browser, while a 307 // re-render (e.g. after the data was cleared) reports again. 308 'rendered' => time(), 305 309 'need' => array( 306 310 'lcp' => $need_lcp ? 1 : 0, -
easy-optimizer/trunk/includes/class-easyopt-queue.php
r3621746 r3747021 216 216 add_action( 'plugins_loaded', array( __CLASS__, 'maybe_create_table' ), 5 ); 217 217 218 // Watchdog: schedule on init, run on its hook. 218 // Watchdog: run on its hook. (2.7.3) Scheduled only while there is 219 // work: add_task() arms it, run_watchdog() drops it once the queue is 220 // empty, and admin + cron requests re-arm it as a safety net. It used 221 // to be a permanent every-minute event, which on WP-Cron-driven hosts 222 // spawned wp-cron.php about once a minute forever to find nothing. 223 // Front-end and admin-ajax requests (beacons, heartbeat) never check: 224 // the flag it needs is not autoloaded, so checking there would cost a 225 // query per request. Priority 99 so modules that keep it alive 226 // (preload, on init:10) have registered. 219 227 add_filter( 'cron_schedules', array( __CLASS__, 'register_schedule' ) ); 220 add_action( 'init', array( __CLASS__, 'setup_watchdog' ) ); 228 if ( ( is_admin() && ! wp_doing_ajax() ) || wp_doing_cron() ) { 229 add_action( 'init', array( __CLASS__, 'maybe_setup_watchdog' ), 99 ); 230 } 221 231 add_action( self::WATCHDOG_HOOK, array( __CLASS__, 'run_watchdog' ) ); 222 232 … … 323 333 update_option( 'easyopt_queue_active', '1', false ); 324 334 } 335 // (2.7.3) Work exists: make sure the watchdog is ticking. 336 self::setup_watchdog(); 325 337 } 326 338 … … 535 547 } 536 548 549 /** (2.7.3) Re-arm while there is work, drop the event when idle. */ 550 public static function maybe_setup_watchdog() { 551 if ( self::watchdog_needed() ) { 552 self::setup_watchdog(); 553 } elseif ( wp_next_scheduled( self::WATCHDOG_HOOK ) ) { 554 wp_clear_scheduled_hook( self::WATCHDOG_HOOK ); 555 } 556 } 557 558 /** 559 * Does the per-minute tick have anything to do? Queue work (the flag 560 * add_task() raises; missing counts as yes, as in run_watchdog()), or a 561 * module still watching on the tick (preload's health check). 562 */ 563 private static function watchdog_needed() { 564 return '0' !== (string) get_option( 'easyopt_queue_active', 'unset' ) 565 || (bool) apply_filters( 'easyopt_queue_watchdog_keep', false ); 566 } 567 537 568 public static function clear_watchdog() { 538 569 wp_clear_scheduled_hook( self::WATCHDOG_HOOK ); … … 737 768 $easyopt_active_flag = get_option( 'easyopt_queue_active', 'unset' ); 738 769 if ( '0' === (string) $easyopt_active_flag ) { 770 self::maybe_setup_watchdog(); // (2.7.3) idle: stop ticking 739 771 return; // one option read and done. 740 772 } … … 781 813 if ( null === $easyopt_any ) { 782 814 update_option( 'easyopt_queue_active', '0', false ); 815 // (2.7.3) About to stop ticking, so close the gap first: a task 816 // queued between the check above and the flag write saw the 817 // flag still up and did not raise it again. 818 if ( null !== $wpdb->get_var( "SELECT 1 FROM $table WHERE status IN ('pending','processing') LIMIT 1" ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 819 update_option( 'easyopt_queue_active', '1', false ); 820 } else { 821 self::maybe_setup_watchdog(); 822 } 783 823 } 784 824 return; -
easy-optimizer/trunk/includes/class-easyopt-rest-cloud.php
r3731476 r3747021 56 56 // the trigger, which is exactly when freshness matters. 57 57 add_action( 'admin_init', array( __CLASS__, 'arm_maintenance' ), 30 ); 58 add_action( 'template_redirect', array( __CLASS__, 'arm_frontend_check' ) ); 58 59 add_action( 'easyopt_cloud_maintain', array( 'EasyOpt_CDN_Cloud', 'maintain' ) ); 59 60 if ( ! wp_next_scheduled( 'easyopt_cloud_maintain' ) ) { 60 61 wp_schedule_event( time() + 900, 'hourly', 'easyopt_cloud_maintain' ); 61 62 } 63 } 64 65 /** (2.7.3) Status-check age after which a front-end request steps in. */ 66 const FRONTEND_CHECK_AFTER = 3 * HOUR_IN_SECONDS; 67 68 /** 69 * (2.7.3) Status check for sites whose WP-Cron never runs. 70 * 71 * The hourly check is how a site learns its licence was revoked; with no 72 * cron and no admin visits it never runs, so the site keeps emitting CDN 73 * URLs and the edge 302s every asset back to origin — an extra round trip 74 * per file, for good. When the last check is over 3 hours old, the next 75 * front-end page view runs it AFTER the response has been sent, so the 76 * visitor never waits. Hosts that cannot finish a response early (no 77 * PHP-FPM or LiteSpeed) are left exactly as before. 78 * 79 * Cost on every other page view: two autoloaded option reads. 80 */ 81 public static function arm_frontend_check() { 82 // Settings read first: sites that never connected must not autoload 83 // the 40 KB cloud class on every page view for this. 84 if ( '' === (string) EasyOpt_Config::get( 'cloud_account', '' ) || ! EasyOpt_CDN_Cloud::is_connected() ) { 85 return; 86 } 87 if ( time() - (int) get_option( EasyOpt_CDN_Cloud::CHECKED_OPTION, 0 ) < self::FRONTEND_CHECK_AFTER ) { 88 return; 89 } 90 if ( ! function_exists( 'fastcgi_finish_request' ) && ! function_exists( 'litespeed_finish_request' ) ) { 91 return; 92 } 93 // Last on shutdown: the page (and Easy Optimizer's cache write, on 94 // wp_ob_end_flush_all at priority 1) is already done. 95 add_action( 'shutdown', array( __CLASS__, 'frontend_check' ), PHP_INT_MAX ); 96 } 97 98 /** Hand the page to the visitor, then ask for the status. */ 99 public static function frontend_check() { 100 if ( function_exists( 'fastcgi_finish_request' ) ) { 101 fastcgi_finish_request(); 102 } elseif ( function_exists( 'litespeed_finish_request' ) ) { 103 litespeed_finish_request(); 104 } else { 105 return; 106 } 107 EasyOpt_CDN_Cloud::check_now(); 62 108 } 63 109 -
easy-optimizer/trunk/includes/class-easyopt-rest-dashboard.php
r3700847 r3747021 133 133 ) + $admin ); 134 134 135 register_rest_route( self::NS, '/images/stop', array( 136 'methods' => 'POST', 137 'callback' => array( __CLASS__, 'images_stop' ), 138 ) + $admin ); 139 140 // One image, from the Media Library: { id, do: restore|optimize }. 141 register_rest_route( self::NS, '/images/item', array( 142 'methods' => 'POST', 143 'callback' => array( __CLASS__, 'images_item' ), 144 ) + $admin ); 145 135 146 // ── Cloudflare ─────────────────────────────────────────────── 136 147 register_rest_route( self::NS, '/cloudflare/test', array( … … 1131 1142 /** Cached bandwidth usage for the connected license (panel usage bar). */ 1132 1143 public static function fluxcdn_usage( $request = null ) { 1133 if ( class_exists( 'EasyOpt_Tracker' ) ) {1134 EasyOpt_Tracker::smartimg_tab_viewed(); // daily-throttled inside1135 }1136 1144 $force = $request && (bool) $request->get_param( 'force' ); 1137 1145 $u = class_exists( 'EasyOpt_CDN' ) ? EasyOpt_CDN::usage_status( $force ) : null; … … 1148 1156 $endpoint = ''; // filled from provisioning (per-customer zone hostname) 1149 1157 $skip_probe = (bool) $request->get_param( 'skip_probe' ); 1150 1151 if ( class_exists( 'EasyOpt_Tracker' ) ) {1152 EasyOpt_Tracker::smartimg_connect_attempted(1153 null === EasyOpt_CDN::parse_key( $input ) ? 'license' : 'key'1154 );1155 }1156 1158 1157 1159 $license_key = ''; … … 1529 1531 ) ); 1530 1532 } 1533 1534 public static function images_stop() { 1535 if ( ! class_exists( 'EasyOpt_Images' ) ) { 1536 return new WP_Error( 'easyopt_no_images', 'Image module not loaded.', array( 'status' => 500 ) ); 1537 } 1538 EasyOpt_Images::stop(); 1539 return rest_ensure_response( array( 1540 'success' => true, 1541 'message' => __( 'Stopped. Images already done stay optimized.', 'easy-optimizer' ), 1542 ) ); 1543 } 1544 1545 public static function images_item( $request ) { 1546 if ( ! class_exists( 'EasyOpt_Images' ) ) { 1547 return new WP_Error( 'easyopt_no_images', 'Image module not loaded.', array( 'status' => 500 ) ); 1548 } 1549 $id = (int) $request->get_param( 'id' ); 1550 $do = (string) $request->get_param( 'do' ); 1551 if ( $id <= 0 || 'attachment' !== get_post_type( $id ) 1552 || ! in_array( (string) get_post_mime_type( $id ), EasyOpt_Images::MIME, true ) 1553 || ! in_array( $do, array( 'restore', 'optimize' ), true ) ) { 1554 return new WP_Error( 'easyopt_bad_image', __( 'Not an image this optimizer handles.', 'easy-optimizer' ), array( 'status' => 400 ) ); 1555 } 1556 $queued = false; 1557 if ( 'restore' === $do ) { 1558 EasyOpt_Images::restore_one( $id ); 1559 } else { 1560 if ( ! EasyOpt_Images::target_formats() ) { 1561 return rest_ensure_response( array( 1562 'success' => false, 1563 'message' => EasyOpt_Images_Capability::summary(), 1564 ) ); 1565 } 1566 $queued = EasyOpt_Images::optimize_one( $id ); 1567 } 1568 return rest_ensure_response( array( 1569 'success' => true, 1570 'html' => EasyOpt_Images_Media::status_html( $id, $queued ), 1571 ) ); 1572 } 1531 1573 } -
easy-optimizer/trunk/includes/class-easyopt-save-coordinator.php
r3731476 r3747021 105 105 'easyopt_a11y_viewport', 'easyopt_a11y_role_elements', 106 106 'easyopt_a11y_iframes', 'easyopt_a11y_progressbar', 'easyopt_a11y_tabindex', 107 'easyopt_a11y_skip_link', 'easyopt_a11y_main_landmark', 107 108 'easyopt_seo_crawlable_links', 'easyopt_seo_image_alts', 108 109 ); -
easy-optimizer/trunk/includes/class-easyopt-settings-registry.php
r3700847 r3747021 291 291 'easyopt_a11y_viewport', 'easyopt_a11y_role_elements', 'easyopt_a11y_iframes', 292 292 'easyopt_a11y_progressbar', 'easyopt_a11y_tabindex', 293 'easyopt_a11y_skip_link', 'easyopt_a11y_main_landmark', 293 294 ) as $k ) { 294 295 $s[ $k ] = array( 'default' => 0 ) + $int_bool; -
easy-optimizer/trunk/includes/class-easyopt-settings.php
r3697647 r3747021 68 68 wp_enqueue_style( 'easyopt-admin', EASYOPT_URL . 'assets/style.css', array(), EASYOPT_VERSION ); 69 69 70 // Smart Images tab-view ping — top-of-funnel measurement. Fires when 71 // the imgopt tab is clicked OR is already the restored tab on load. 72 // Once per page load client-side; the tracker throttles to once per 73 // day server-side, so this is at most one tiny request daily. 74 wp_add_inline_script( 'easyopt-dashboard', " 75 (function(){ 76 var sent = false; 77 function ping(){ 78 if (sent || !window.__EASYOPT__ || !window.__EASYOPT__.restUrl) { return; } 79 sent = true; 80 fetch(window.__EASYOPT__.restUrl.replace(/\\/$/, '') + '/track/si-view', { 81 method: 'POST', 82 headers: { 'X-WP-Nonce': window.__EASYOPT__.restNonce }, 83 credentials: 'same-origin' 84 }).catch(function(){}); 85 } 86 document.addEventListener('click', function(e){ 87 var el = e.target && e.target.closest ? e.target.closest('[data-tab=\"imgopt\"]') : null; 88 if (el) { ping(); } 89 }); 90 // Restored-tab case: panel already mounted shortly after load. 91 var tries = 0; 92 var t = setInterval(function(){ 93 if (document.getElementById('eop-panel-imgopt')) { ping(); clearInterval(t); } 94 if (++tries > 20) { clearInterval(t); } 95 }, 500); 96 })(); 97 " ); 70 // (2.7.3) The Smart Images tab-view ping is gone: it logged a row per 71 // admin per hour and measured nothing analyze_started does not. 98 72 } 99 73 -
easy-optimizer/trunk/includes/class-easyopt-tracker.php
r3700847 r3747021 8 8 * Events sent (only after opt-in): 9 9 * Lifecycle: activation, deactivation (+reason), heartbeat, uninstall 10 * Smart Images: smartimg_ tab_viewed, smartimg_connect_attempted,11 * smartimg_d elivering, smartimg_fallback (+reason),12 * smartimg_disconnected10 * Smart Images: smartimg_delivering, smartimg_fallback (+reason), 11 * smartimg_disconnected (tab-view and connect-attempt 12 * events retired in 2.7.3) 13 13 * Core health: wizard_completed (+preset), safe_mode_triggered (+trigger), 14 14 * error_occurred (+code, throttled 1/code/day) … … 72 72 // Loose-coupling entry point: do_action( 'easyopt_track_error', 'EO_CODE' ) 73 73 add_action( 'easyopt_track_error', array( __CLASS__, 'error' ), 10, 2 ); 74 75 // Smart Images tab-view ping (fired by a tiny admin script when the76 // Smart Images tab is opened — connection state irrelevant, so the77 // TOP of the funnel is measured, not just already-connected sites).78 add_action( 'rest_api_init', function() {79 register_rest_route( 'easyopt/v1', '/track/si-view', array(80 'methods' => 'POST',81 'callback' => function() {82 EasyOpt_Tracker::smartimg_tab_viewed();83 return rest_ensure_response( array( 'ok' => true ) );84 },85 'permission_callback' => function() { return current_user_can( 'manage_options' ); },86 ) );87 } );88 74 } 89 75 … … 244 230 /* ── Smart Images funnel ────────────────────────────────────────────── */ 245 231 246 /** Smart Images tab opened (throttled to once per day). */247 public static function smartimg_tab_viewed() {248 if ( get_transient( 'easyopt_trk_si_tab' ) ) {249 return;250 }251 // Was DAY_IN_SECONDS. Every funnel event downstream of this one is252 // per-action, and a per-action numerator over a per-site-per-DAY253 // denominator is not a conversion rate — it made the first row of254 // the funnel uncomputable.255 set_transient( 'easyopt_trk_si_tab', 1, HOUR_IN_SECONDS );256 self::send( 'smartimg_tab_viewed' );257 }258 259 /** User submitted a license / key — {mode: license|key}. */260 public static function smartimg_connect_attempted( $mode = 'license' ) {261 self::send( 'smartimg_connect_attempted', array( 'mode' => sanitize_key( $mode ) ) );262 }263 232 264 233 /** -
easy-optimizer/trunk/readme.txt
r3731476 r3747021 4 4 Tags: performance, cache, pagespeed, core web vitals, speed 5 5 Requires at least: 6.4 6 Tested up to: 7.1 .36 Tested up to: 7.1 7 7 Requires PHP: 7.4 8 Stable tag: 2.7. 28 Stable tag: 2.7.3 9 9 License: GNU General Public License v2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 70 70 * Some elements have a [tabindex] value greater than 0 71 71 * Image elements do not have [alt] attributes 72 * Skip links are not focusable 73 * Document does not have a main landmark 72 74 73 75 **SEO** … … 210 212 211 213 == Changelog == 214 215 = 2.7.3 = 216 * New: Restore original or Optimize a single image from the Media Library. A status column in the list view and a row in the image details panel show whether each image is optimized, skipped or restored. An image you restore yourself is left alone by later "Optimize all" runs until you choose Optimize for it again. 217 * New: a Stop button for a running image optimization. Images already done stay optimized, and "Optimize remaining" continues from where it stopped. 218 * New: two Accessibility fixes, off by default. "Skip links are not focusable" points a "Skip to content" link whose target is missing (common with Elementor full-width layouts) at the page's main content. "Document does not have a main landmark" marks the main content area for screen readers on layouts that have none (Elementor, Divi). Both only add attributes; nothing on the page is moved or removed, and pages that already pass are left unchanged. 219 * Fixed: the image optimization progress ("8 of 202 done, 192 to go") now adds up on every refresh. The done count lagged up to 20 seconds behind the to-go count and left out images that were skipped because no smaller copy was possible. 220 * Fixed: restoring an image whose original had been resized no longer queues it to be optimized and resized again straight away. 221 * Improved: less background load. The every-minute background check now runs only while there is work queued (preload, image optimization), instead of all the time. On hosts where WP-Cron runs off visitor traffic, an idle site no longer starts a background request about once a minute. 222 * Improved: a visitor's browser now remembers that it already reported a page's measurements, so a page served from a page cache or CDN is not reported again by the same visitor on later visits. A page rendered again, for example after its data was cleared, still reports. 223 * Removed: two usage-statistics events (Smart Images tab viewed, connect attempted) that only opted-in sites sent. They added noise without measuring anything new. 224 * Fixed: Cloud Optimization now notices an ended licence even on sites where WP-Cron does not run. Previously such a site kept pointing its files at the CDN, which redirected every file back to the site (an extra round trip each). An overdue status check now runs after a page has been sent to the visitor, so nobody waits for it; on servers that cannot do that, nothing changes. 212 225 213 226 = 2.7.2 = … … 420 433 == Upgrade Notice == 421 434 435 = 2.7.3 = 436 Adds Restore and Optimize for single images in the Media Library, a Stop button for image optimization, and two optional accessibility fixes (skip links, main landmark). Background checks now run only while work is queued. 437 422 438 = 2.7.2 = 423 439 Fixes Remove Unused CSS dropping rules on Tailwind sites, lazy-loaded <noscript> iframes, and several Cloud Optimization issues (LCP preload, edge-served fonts, the Images toggle). Used CSS is rebuilt once after updating, so expect a short regeneration period.
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)